Lot of times we come across the requirement to apply personalization based on visitor’s GeoCoordinates (latitude & longitude) & if visitor location is within specified distance to a ‘centre point location’.  For example, showing personalized content for visitors accessing website from certain part of city/town or show content if website visitor is walking distance to nearest store or a festival etc.

Note: This example will only work if visitor’s device (PC or Mobile) has location sharing turned on.

I’m using Episerver guide to create a very simple personalisation criterion and added following input fields.

  1. Centralize location latitude
  2. Centralize location longitude
  3. Radius (meters )

Create  Personalization criteria

GeoCoordinateRadiusCriterionSettings Class

public class GeoCoordinateRadiusCriterionSettings : CriterionModelBase
    {
        [Required]
        public double CentralizeLocationLatitude { get; set; }
        [Required]
        public double CentralizeLocationLongitude { get; set; }
        [Required]
        public double Radius { get; set; }
        public override ICriterionModel Copy()
        {
            return ShallowCopy();
        }
    }

Get Visitor’s location & Criterion

GeoCoordinateRadiusCriterion Class

[VisitorGroupCriterion(
        Category = "Geolocation",
        DisplayName = "GeoCoordinate & Radius",
        Description = "Checks visitor's location falls in specified radius")]
    public class GeoCoordinateRadiusCriterion : CriterionBase<GeoCoordinateRadiusCriterionSettings>
    {
        public override bool IsMatch(IPrincipal principal, HttpContextBase httpContext)
        {
            //user location
            var visitorlocation = GetVisitorLatLong();
            double sLatitude = visitorlocation.Latitude;
            double sLongitude = visitorlocation.Longitude;
            // center point location
            double eLatitude = Model.CentralizeLocationLatitude;
            double eLongitude = Model.CentralizeLocationLongitude;
            var sCoord = new GeoCoordinate(sLatitude, sLongitude);
            var eCoord = new GeoCoordinate(eLatitude, eLongitude);
            var distance = sCoord.GetDistanceTo(eCoord);
            if (distance <= Model.Radius)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        private GeoLocation GetVisitorLatLong()
        {
            GeoCoordinateWatcher watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
            var userLocation = new GeoLocation();
            watcher.Start();
            System.Device.Location.GeoCoordinate coord = watcher.Position.Location;
            if (!watcher.Position.Location.IsUnknown)
            {
                userLocation.Latitude = coord.Latitude;
                userLocation.Longitude = coord.Longitude;
            }
            return userLocation;
        }
    }

Radius is calculated based on center point of a circle. However, lot of time we have requirement to find visitor in a polygon area of Geo Coordinates. This custom criterion can be extended to calculate personalization criteria based on polygon area.

Source Code: The source code of this Episerver personalization criteria can be downloaded from this link.

Categorized in: