public double GetDistanceTo(GeoCoordinate end2Coord)
        {
            var coord1 = new System.Device.Location.GeoCoordinate(this.Latitude, this.Longitude);
            var coord2 = new System.Device.Location.GeoCoordinate(end2Coord.Latitude, end2Coord.Longitude);

            return(coord1.GetDistanceTo(coord2));
        }
        public object Convert(object value, Type targetType, object parameter, Culture culture)
        {
            // Validate
            if (!(value is Location))
            {
                throw new InvalidOperationException("Only Location is supported as a source.");
            }
            if (targetType != typeof(Visibility))
            {
                throw new InvalidOperationException("Only Visibility is supported as the target type");
            }

            // Cast to proper types
            Location loc = (Location)value;

            // If it's unknown the item shouldn't be shown
            if (loc.IsUnknown())
            {
                return(Visibility.Collapsed);
            }
            else
            {
                return(Visibility.Visible);
            }
        }
Example #3
0
        public static double Get(double fromLat, double fromLon, double toLat, double toLon)
        {
            var from = new System.Device.Location.GeoCoordinate(fromLat, fromLon);
            var to   = new System.Device.Location.GeoCoordinate(toLat, toLon);

            return(from.GetDistanceTo(to));
        }
        public GeoDistance DistanceBetweenImperial()
        {
            try
            {
                string decimalFormat = ServiceConfiguration["DecimalFormat"].ToString();

                System.Device.Location.GeoCoordinate primaryCoords   = new System.Device.Location.GeoCoordinate(this.PrimaryLatitude, this.PrimaryLongitutde);
                System.Device.Location.GeoCoordinate secondaryCoords = new System.Device.Location.GeoCoordinate(this.SecondaryLatitude, this.SecondaryLongitutde);

                double distanceMetres = primaryCoords.GetDistanceTo(secondaryCoords);

                this.DistanceYards = distanceMetres * 1.09361;
                this.DistanceMiles = this.DistanceYards / 1760;

                this.DistanceYardsDisplay = this.DistanceYards.ToString(decimalFormat);
                this.DistanceMilesDisplay = this.DistanceMiles.ToString(decimalFormat);

                this.ResultStatus = "OK";

                return(this);
            }
            catch (Exception ex)
            {
                this.ResultStatus  = "Exception";
                this.ResultMessage = ex.GetBaseException().Message;
                return(this);
            }
        }
Example #5
0
        public double Distance(Stop other)
        {
            var sCoord = new System.Device.Location.GeoCoordinate(latitude, longitude);
            var eCoord = new System.Device.Location.GeoCoordinate(other.latitude, other.longitude);

            return(sCoord.GetDistanceTo(eCoord));
        }
Example #6
0
 static public bool IsUnknown(this Location location)
 {
     #if WINDOWS_PHONE
     return(location.Latitude == 0 && location.Longitude == 0 && location.Altitude == 0);
     #else
     return(location.Latitude == 0 && location.Longitude == 0);
     #endif
 }
Example #7
0
        void updateMap(System.Device.Location.GeoCoordinate location)
        {
            Pushpin pin = new Pushpin();

            pin.Location = location;
            themap.Children.Add(pin);
            themap.SetView(location, 16.0);
        }
Example #8
0
 public static LocationPair CreateLocationPair(System.Device.Location.GeoCoordinate geo)
 {
     return(new LocationPair
     {
         Longitude = geo.Longitude,
         Latitude = geo.Latitude,
     });
 }
Example #9
0
        public void weather_source_value_matches_standard_expected()
        {
            //the weather obviously changes constantly, but the credit field in the json should be pretty constant at containing 'http://weather.gov'
            //is used as a very crude, high level test to ensure nws coms and parsing works
            var nws = new flughafen.weather.service.NationalWeatherService();

            var HOUSTON_INTERNATIONAL_AIRPORT_COORDS = new System.Device.Location.GeoCoordinate(29.98, -95.36);
            var weather = nws.GetCurrentConditions(HOUSTON_INTERNATIONAL_AIRPORT_COORDS);

            Assert.IsTrue(weather.WeatherSource.Contains("weather.gov"));
        }
Example #10
0
        /// <summary>
        /// Obtain the distance using as reference origin and destiny airports
        /// </summary>
        /// <param name="originAirport">Origin airport</param>
        /// <param name="destinyAirport">Destiny airport</param>
        /// <returns></returns>
        public static double CalculateDistance(Airport originAirport, Airport destinyAirport)
        {
            // set the Geocoordinate related to origin airport
            var destinyCoord = new System.Device.Location.GeoCoordinate(originAirport.latitude, originAirport.Longitude);

            // set the Geocoordinate related to destiny airport
            var originCoord = new System.Device.Location.GeoCoordinate(destinyAirport.latitude, destinyAirport.Longitude);

            // return the distance in kms
            return(originCoord.GetDistanceTo(destinyCoord) / 1000);
        }
        public Stationenindernaehe(System.Device.Location.GeoCoordinate coord, SwissTransport.ITransport _transport)
        {
            InitializeComponent();

            Stations stations = _transport.GetCloseStations(coord.Latitude.ToString(), coord.Longitude.ToString());

            foreach (Station station in stations.StationList)
            {
                CloseStationGrid.Rows.Add(station.Name, station.Distance + " m");
            }
        }
Example #12
0
 public static Boolean TryGetLocationFromSettings(out System.Device.Location.GeoCoordinate Location)
 {
     if (!string.IsNullOrEmpty(AppSettings.ReadSettingEncrypted("Location")))
     {
         string   S    = AppSettings.ReadSettingEncrypted("Location");
         string[] Item = S.Split('|');
         Location = new System.Device.Location.GeoCoordinate(double.Parse(Item[0]), double.Parse(Item[1]));
         return(true);
     }
     Location = new System.Device.Location.GeoCoordinate(0, 0);
     return(false);
 }
Example #13
0
        // GET: api/Ping
        public Models.Pong Post([FromBody]Models.Ping value)
        {
            using (var DBCtx = new Database.DBContainer())
            {
                if (value.CurrentWayPointId == 0)
                    return null;
                var wp = DBCtx.Waypoints.Include("Hunt").FirstOrDefault(q => q.Id == value.CurrentWayPointId);
                if (wp == null)
                    throw new Exception("Invalid Waypoint ID.");

                var longs = DBCtx.Waypoints.Where(w=>w.Hunt.Id==wp.Hunt.Id).Select(s => s.Long).Distinct();
                var lats = DBCtx.Waypoints.Where(w=>w.Hunt.Id==wp.Hunt.Id).Select(s => s.Lat).Distinct();

                //object lathashset
                HotnessDetector det = new HotnessDetector(new HashSet<double>(lats), new HashSet<double>(longs));
                det.currentWaypoint = new System.Device.Location.GeoCoordinate(wp.Lat, wp.Long);
                var userLL = new System.Device.Location.GeoCoordinate(value.Lat, value.Long);

                var hotness = det.GetTemp(userLL, new System.Device.Location.GeoCoordinate(value.LastLat, value.LastLong));
                string hf;
                switch (hotness)
                {
                    case 0:
                        hf = "Cold";
                        break;
                    case 1:
                        hf = "Hot";
                        break;
                    case 2:
                        hf = "Colder";
                        break;
                    case 3:
                        hf = "Warmer";
                        break;
                    case 4:
                        hf = "Same";
                        break;
                    case 5:
                        hf = "Nothing";
                        break;
                    default:
                        hf = String.Empty;
                        break;

                }
                return new Models.Pong()
                {
                    HotnessFactor = hf,
                    Time = DateTime.Now,
                    WaypointReached = det.ReachedWaypoint(userLL, 40)
                };
            }
        }
        public double GetDistanceTo(double?i_LatitudeOfUser, double?i_LongitudeOfUser, double?i_LatitudeOfMatch, double?i_LongitudeOfMatch)
        {
            if (i_LatitudeOfUser == null || i_LongitudeOfUser == null || i_LatitudeOfMatch == null || i_LongitudeOfMatch == null)
            {
                throw new ArgumentNullException("While calculating distance, one of the inserted parameters is null.");
            }

            m_CoordinatesOfUser  = new System.Device.Location.GeoCoordinate((double)i_LatitudeOfUser, (double)i_LongitudeOfUser);
            m_CoordinatesOfMatch = new System.Device.Location.GeoCoordinate((double)i_LatitudeOfMatch, (double)i_LongitudeOfMatch);
            Distance             = m_CoordinatesOfUser.GetDistanceTo(m_CoordinatesOfMatch);

            return(Distance);
        }
Example #15
0
 public SearchVenue GetNearestPlace(List <SearchVenue> allPlaces, System.Device.Location.GeoCoordinate coord)
 {
     try
     {
         var nearest = allPlaces.Select(x => new System.Device.Location.GeoCoordinate(Double.Parse(x.Latitude), Double.Parse(x.Longitude)))
                       .OrderBy(x => x.GetDistanceTo(coord))
                       .First();
         var foundPlace = allPlaces.ToList().Find(x => Double.Parse(x.Latitude) == nearest.Latitude);
         return(foundPlace);
     }
     catch (Exception e)
     {
         _logger.Log(Logging.Enums.LogCategory.Error, e);
         return(null);
     }
 }
Example #16
0
        public static System.Device.Location.GeoCoordinate SailingsFindDestLLo(double LatIn, double LonIn, double Dist, double Course)
        {
            double LatDiff = Dist * Math.Cos(Course * Math.PI / 180d) / 60d;

            if (Course > 90d & Course < 270d)
            {
                LatDiff = -LatDiff;
            }

            double L2 = LatIn + LatDiff;

            L2 = LatIn * Math.PI / 180d + Dist / 60d * Math.PI / 180d * Math.Cos(Course * Math.PI / 180d);
            double q    = 0d;
            double dphi = 0d;

            if (Math.Abs(LatDiff) < Math.Sqrt(0.000000000000001d))
            {
                q = Math.Cos(LatIn * Math.PI / 180d);
            }
            else
            {
                dphi = Math.Log(Math.Tan(L2 / 2d + Math.PI / 4d) / Math.Tan(LatIn * Math.PI / 180d / 2d + Math.PI / 4d));
                q    = LatDiff * Math.PI / 180d / dphi;
            }

            double DLo = Dist / 60d * Math.PI / 180d * Math.Sin(Course * Math.PI / 180d) / q;

            DLo = DLo * 180d / Math.PI;
            L2  = L2 * 180d / Math.PI;
            // End If
            int    LoSign = Math.Sign(LonIn);
            double Lo2    = LoSign * (Math.Abs(LonIn) + DLo);

            while (Lo2 >= 360d)
            {
                Lo2 = Lo2 - 360d;
            }
            // Crossing IDL
            if (Math.Abs(Lo2) > 180d)
            {
                Lo2 = -Math.Sign(Lo2) * (360d - Math.Abs(Lo2));
            }

            var RtnGC = new System.Device.Location.GeoCoordinate(L2, Lo2);

            return(RtnGC);
        }
Example #17
0
        void BingMap_MapZoom(object sender, Microsoft.Phone.Controls.Maps.MapZoomEventArgs e)
        {
            e.Handled = true;
            System.Device.Location.GeoCoordinate location = this.BingMap.ViewportPointToLocation(e.ViewportPoint);

            MobileSrc.Services.GeocodeServices.GeocodeServiceClient  rclient = new MobileSrc.Services.GeocodeServices.GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
            MobileSrc.Services.GeocodeServices.ReverseGeocodeRequest req     = new MobileSrc.Services.GeocodeServices.ReverseGeocodeRequest();
            req.Credentials = new MobileSrc.Services.GeocodeServices.Credentials();
            req.Credentials.ApplicationId = BingMapsApiKey;
            req.Location           = new MobileSrc.Services.GeocodeServices.Location();
            req.Location.Latitude  = location.Latitude;
            req.Location.Longitude = location.Longitude;
            req.ExecutionOptions   = new MobileSrc.Services.GeocodeServices.ExecutionOptions();

            rclient.ReverseGeocodeCompleted += new EventHandler <MobileSrc.Services.GeocodeServices.ReverseGeocodeCompletedEventArgs>(client_ReverseGeocodeCompleted);
            rclient.ReverseGeocodeAsync(req);
        }
Example #18
0
            /**
             * Constructor
             */
            public Map()
            {
                mBingMap = new Microsoft.Phone.Controls.Maps.Map();

                mVisibleAreaUpperLeftCorner  = new System.Device.Location.GeoCoordinate();
                mVisibleAreaLowerRightCorner = new System.Device.Location.GeoCoordinate();

                mView = mBingMap;

                // occurs when the map visible area is changed (on drag/scroll)
                mBingMap.MapPan += new EventHandler <MapDragEventArgs>(
                    delegate(object from, MapDragEventArgs args)
                {
                    // update the visible area points
                    mVisibleAreaUpperLeftCorner  = mBingMap.BoundingRectangle.Northwest;
                    mVisibleAreaLowerRightCorner = mBingMap.BoundingRectangle.Southeast;

                    /**
                     * post the event to MoSync runtime
                     */
                    Memory eventData = new Memory(8);
                    const int MAWidgetEventData_eventType    = 0;
                    const int MAWidgetEventData_widgetHandle = 4;
                    eventData.WriteInt32(MAWidgetEventData_eventType, MoSync.Constants.MAW_EVENT_MAP_REGION_CHANGED);
                    eventData.WriteInt32(MAWidgetEventData_widgetHandle, mHandle);
                    mRuntime.PostCustomEvent(MoSync.Constants.EVENT_TYPE_WIDGET, eventData);
                }
                    );

                // occurs when the map zoom level is changed (on zoom in/out)
                mBingMap.MapZoom += new EventHandler <MapZoomEventArgs>(
                    delegate(object from, MapZoomEventArgs args)
                {
                    /**
                     * post the event to MoSync runtime
                     */
                    Memory eventData = new Memory(8);
                    const int MAWidgetEventData_eventType    = 0;
                    const int MAWidgetEventData_widgetHandle = 4;
                    eventData.WriteInt32(MAWidgetEventData_eventType, MoSync.Constants.MAW_EVENT_MAP_ZOOM_LEVEL_CHANGED);
                    eventData.WriteInt32(MAWidgetEventData_widgetHandle, mHandle);
                    mRuntime.PostCustomEvent(MoSync.Constants.EVENT_TYPE_WIDGET, eventData);
                }
                    );
            }
Example #19
0
 public double RunReals(double[] values)
 {
     if (values.Length >= 4)
     {
         var gc       = new System.Device.Location.GeoCoordinate(values[0], values[1]);
         var distance = gc.GetDistanceTo(new System.Device.Location.GeoCoordinate(values[2], values[3]));
         if (values.Length >= 5)
         {
             if (distance <= values[4])
             {
                 return(1.0);
             }
             return(0.0);
         }
         return(distance);
     }
     return(0.0);
 }
Example #20
0
            /**
             * Constructor
             */
            public Map()
            {
                mBingMap = new Microsoft.Phone.Controls.Maps.Map();

                mVisibleAreaUpperLeftCorner = new System.Device.Location.GeoCoordinate();
                mVisibleAreaLowerRightCorner = new System.Device.Location.GeoCoordinate();

                View = mBingMap;

                // occurs when the map visible area is changed (on drag/scroll)
                mBingMap.MapPan += new EventHandler<MapDragEventArgs>(
                    delegate(object from, MapDragEventArgs args)
                    {
                        // update the visible area points
                        mVisibleAreaUpperLeftCorner = mBingMap.BoundingRectangle.Northwest;
                        mVisibleAreaLowerRightCorner = mBingMap.BoundingRectangle.Southeast;
                        /**
                         * post the event to MoSync runtime
                         */
                        Memory eventData = new Memory(8);
                        const int MAWidgetEventData_eventType = 0;
                        const int MAWidgetEventData_widgetHandle = 4;
                        eventData.WriteInt32(MAWidgetEventData_eventType, MoSync.Constants.MAW_EVENT_MAP_REGION_CHANGED);
                        eventData.WriteInt32(MAWidgetEventData_widgetHandle, mHandle);
                        mRuntime.PostCustomEvent(MoSync.Constants.EVENT_TYPE_WIDGET, eventData);
                    }
                );

                // occurs when the map zoom level is changed (on zoom in/out)
                mBingMap.MapZoom += new EventHandler<MapZoomEventArgs>(
                    delegate(object from, MapZoomEventArgs args)
                    {
                        /**
                        * post the event to MoSync runtime
                        */
                        Memory eventData = new Memory(8);
                        const int MAWidgetEventData_eventType = 0;
                        const int MAWidgetEventData_widgetHandle = 4;
                        eventData.WriteInt32(MAWidgetEventData_eventType, MoSync.Constants.MAW_EVENT_MAP_ZOOM_LEVEL_CHANGED);
                        eventData.WriteInt32(MAWidgetEventData_widgetHandle, mHandle);
                        mRuntime.PostCustomEvent(MoSync.Constants.EVENT_TYPE_WIDGET, eventData);
                    }
                );
            }
Example #21
0
        void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
        {
            // System.Device.Location.GeoCoordinate
            // http://msdn.microsoft.com/en-us/library/system.device.location.geocoordinate.aspx

            // Windows.Devices.Geolocation.Geocoordinate
            // http://msdn.microsoft.com/fi-fi/library/windows/apps/windows.devices.geolocation.geocoordinate

            GottenLocationsCunt++;
            lastLocation = new System.Device.Location.GeoCoordinate(args.Position.Coordinate.Latitude, args.Position.Coordinate.Longitude);

            if (!RunningInBackground)
            {
                if (PositionUpdated != null)
                {
                    PositionUpdated(this, EventArgs.Empty);
                }
            }
        }
        private static TrackedPosition CreateTrackedPosition(System.Device.Location.GeoCoordinate org)
        {
            TrackedPosition res = new TrackedPosition();
            //NaN numbers cause an exception on MSSQL Server so they must be avoided.

            bool hasAccuracy = false;
            bool hasBearing  = false;
            bool hasSpeed    = false;

            if (!double.IsNaN(org.HorizontalAccuracy))
            {
                res.Accuracy = org.HorizontalAccuracy;
                hasAccuracy  = true;
            }
            if (!double.IsNaN(org.Course))
            {
                res.Bearing = org.Course;
                hasBearing  = true;
            }
            if (!double.IsNaN(org.Speed))
            {
                res.Speed = org.Speed;
                hasSpeed  = true;
            }
            //res.Building_ID = -1;

            //Latitude, longitude, altitude are non-nullable (but should also never be NaN's)
            const double errorVal = -999;

            res.Latitude  = !double.IsNaN(org.Latitude) ? org.Latitude : errorVal;
            res.Longitude = !double.IsNaN(org.Longitude) ? org.Longitude : errorVal;
            res.Altitude  = !double.IsNaN(org.Altitude) ? org.Altitude : errorVal;

            res.Provider = "MS Location API (GPS)";
            res.Time     = DateTime.Now;
            //res.VertexID = -1;
            res.HasAccuracy = hasAccuracy;
            res.HasBearing  = hasBearing;
            res.HasSpeed    = hasSpeed;
            res.ClientID    = ClientId; //A guid

            return(res);
        }
Example #23
0
        public static Boolean TryGetLocationFromDevice(out System.Device.Location.GeoCoordinate Location)
        {
            Location = new System.Device.Location.GeoCoordinate(0, 0);

            Boolean value = false;

            System.Device.Location.GeoCoordinateWatcher W = new System.Device.Location.GeoCoordinateWatcher();

            Boolean WW = W.TryStart(false, TimeSpan.FromMilliseconds(1000));

            if (WW == true && W.Position.Location.IsUnknown != true)
            {
                Location = new System.Device.Location.GeoCoordinate(W.Position.Location.Latitude, W.Position.Location.Longitude);
                value    = true;
            }
            W.Dispose();

            return(value);
        }
Example #24
0
        void SetUserTrackCurrentLocation(double latitude, double longitude)
        {
            try
            {
                if (btnTrack.Content.Equals("➤"))
                {
                    return;
                }

                foreach (var children in trvMap.Children)
                {
                    if (children.GetType().Name == "LocationIcon10m")
                    {
                        trvMap.Children.Remove(children);
                        break;
                    }
                }
                // Get the cancellation token.
                _cts  = new CancellationTokenSource();
                token = _cts.Token;
                // Get the location.

                CloseMessage();
                System.Device.Location.GeoCoordinate location = new System.Device.Location.GeoCoordinate(latitude, longitude);

                // Now set the zoom level of the map based on the accuracy of our location data.
                // Default to IP level accuracy. We only show the region at this level - No icon is displayed.
                double          zoomLevel            = 17.0f;
                LocationIcon10m _locationUserIcon10m = new LocationIcon10m();
                Callout         callout = new Callout();

                callout.Text = "Tracker's Location";
                callout.Lon  = "Lon (λ): " + location.Longitude.ToString().Substring(0, 7);;
                callout.Lat  = "Lat (φ): " + location.Latitude.ToString().Substring(0, 7);;
                _locationUserIcon10m.DataContext = callout;
                // Add the 10m icon and zoom closer.
                trvMap.Children.Add(_locationUserIcon10m);
                MapLayer.SetPosition(_locationUserIcon10m, location);
                // Set the map to the given location and zoom level.
                trvMap.SetView(location, zoomLevel);
            }
            catch { }
        }
Example #25
0
        void listener_Hold(object sender, GestureEventArgs e)
        {
            ((MenuItem)menu.Items[0]).Header = "Identifying Location...";
            menu.IsOpen = true;

            System.Device.Location.GeoCoordinate location = this.BingMap.ViewportPointToLocation(e.GetPosition(this.BingMap));

            MobileSrc.Services.GeocodeServices.GeocodeServiceClient  rclient = new MobileSrc.Services.GeocodeServices.GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
            MobileSrc.Services.GeocodeServices.ReverseGeocodeRequest req     = new MobileSrc.Services.GeocodeServices.ReverseGeocodeRequest();
            req.Credentials = new MobileSrc.Services.GeocodeServices.Credentials();
            req.Credentials.ApplicationId = BingMapsApiKey;
            req.Location           = new MobileSrc.Services.GeocodeServices.Location();
            req.Location.Latitude  = location.Latitude;
            req.Location.Longitude = location.Longitude;
            req.ExecutionOptions   = new MobileSrc.Services.GeocodeServices.ExecutionOptions();

            rclient.ReverseGeocodeCompleted += new EventHandler <MobileSrc.Services.GeocodeServices.ReverseGeocodeCompletedEventArgs>(client_ReverseGeocodeCompleted);
            rclient.ReverseGeocodeAsync(req);
        }
Example #26
0
        private async void gMapControl1_OnMarkerClick(GMapMarker item, MouseEventArgs e)
        {
            var result = MessageBox.Show("Do you want to move directly to this marker?", "Change Movement", MessageBoxButtons.YesNo);

            if (result != DialogResult.Yes)
            {
                return;
            }

            var coord = new System.Device.Location.GeoCoordinate(item.Position.Lat, item.Position.Lng);

            Logger.Write($"Walking to marker");

            try
            {
                await _logic._navigation.HumanLikeWalking(coord, _settings.WalkingSpeedInKilometerPerHour, null, true);
            }
            catch (Exception ex)
            {
            }
        }
Example #27
0
        async void timer_Tick(object sender, object e)
        {
            try
            {
                if (chkTracking.IsChecked == true)
                {
                    Geoposition pos = await _geolocator.GetGeopositionAsync().AsTask(token);

                    System.Device.Location.GeoCoordinate location = new System.Device.Location.GeoCoordinate(pos.Coordinate.Latitude, pos.Coordinate.Longitude);
                    ProxyTracker.GetInstance().MyTrackLocation    = new Services.TrackService.TrackLocation {
                        Latitude = location.Latitude, Longitude = location.Longitude
                    };
                    ProxyTracker.GetInstance().Client.PublishTrackingInfoAsync(ProxyTracker.GetInstance().MyTrackId, ProxyTracker.GetInstance().MyTrackLocation);
                }

                if (!btnTrack.Content.ToString().Equals("❌"))
                {
                    SetCurrentLocation();
                }
            }
            catch { }
        }
Example #28
0
        public ActionResult Index()
        {
            var summaries = api.GetSummary();
            var model     = new Models.SummaryIndex();

            var list = summaries.Select(x => new Models.Summary()
            {
                Id           = x.Id,
                RouteId      = x.RouteId,
                Vehicle      = x.Vehicle,
                EnterCost    = x.EnterCost,
                DistanceCost = x.DistanceCost,
                DepName      = x.DepName,
                DepLatitude  = x.DepLatitude,
                DepLongitude = x.DepLongitude,
                DesName      = x.DesName,
                DesLatitude  = x.DesLatitude,
                DesLongitude = x.DesLongitude
            }).ToList();

            var gps_src = new System.Device.Location.GeoCoordinate(0, 0);
            var gps_dst = new System.Device.Location.GeoCoordinate(0, 0);

            foreach (var summary in list)
            {
                gps_src.Latitude  = summary.DepLatitude ?? 0;
                gps_src.Longitude = summary.DepLongitude ?? 0;
                gps_dst.Latitude  = summary.DesLatitude ?? 0;
                gps_dst.Longitude = summary.DesLongitude ?? 0;

                summary.Distance = Math.Round(gps_src.GetDistanceTo(gps_dst) / 1000, 2); // in km
                summary.Cost     = Math.Round((summary.EnterCost ?? 0) + (summary.Distance ?? 0) * (summary.DistanceCost ?? 0), 2);
            }

            model.summaries = list;

            return(View(model));
        }
        public GeoDistance WithinRangeMetric()
        {
            try
            {
                string decimalFormat = ServiceConfiguration["DecimalFormat"].ToString();

                System.Device.Location.GeoCoordinate primaryCoords   = new System.Device.Location.GeoCoordinate(this.PrimaryLatitude, this.PrimaryLongitutde);
                System.Device.Location.GeoCoordinate secondaryCoords = new System.Device.Location.GeoCoordinate(this.SecondaryLatitude, this.SecondaryLongitutde);

                double distanceMetres = primaryCoords.GetDistanceTo(secondaryCoords);

                this.DistanceMetres     = distanceMetres;
                this.DistanceKilometres = distanceMetres / 1000;

                this.DistanceMetresDisplay     = this.DistanceMetres.ToString(decimalFormat);
                this.DistanceKilometresDisplay = this.DistanceKilometres.ToString(decimalFormat);

                if (distanceMetres <= this.RangeMetres)
                {
                    this.WithinRange = true;
                }
                else
                {
                    this.WithinRange = false;
                }

                this.ResultStatus = "OK";

                return(this);
            }
            catch (Exception ex)
            {
                this.ResultStatus  = "Exception";
                this.ResultMessage = ex.GetBaseException().Message;
                return(this);
            }
        }
Example #30
0
        // These are common subroutines and functions that perform common nautical and math functions
        public static System.Device.Location.GeoCoordinate C_FindDestLatLong(double LatIn, double LonIn, double Dist, double Course)
        {
            double L2 = Math.Sin(LatIn * Math.PI / 180d) * Math.Cos(Dist / 3437.75d) + Math.Cos(LatIn * Math.PI / 180d) * Math.Sin(Dist / 3437.75d) * Math.Cos(Course * Math.PI / 180d);

            L2 = Math.Atan(L2 / Math.Sqrt(-L2 * L2 + 1d));
            double Lo2 = -1 * LonIn * Math.PI / 180d - Math.Atan2(Math.Sin(Course * Math.PI / 180d) * Math.Sin(Dist / 3437.75d) * Math.Cos(LatIn * Math.PI / 180d), Math.Cos(Dist / 3437.75d) - Math.Sin(LatIn * Math.PI / 180d) * Math.Sin(L2));

            L2  = L2 * 180d / Math.PI;
            Lo2 = Lo2 * 180d / Math.PI;
            if (Course == 0d & Dist > (90d - LatIn) * 60d)
            {
                Lo2 = -(180d - Lo2);
            }

            if (Math.Abs(Lo2) > 180d)
            {
                Lo2 = -Math.Sign(Lo2) * (360d - Math.Abs(Lo2));
            }

            var RtnGC = new System.Device.Location.GeoCoordinate(L2, -1 * Lo2);

            return(RtnGC);
            // Dim DegreesToRadians As Double = System.Math.PI / 180
            // Dim RadiansToDegrees As Double = 180 / System.Math.PI
            // Dim lat1 As Double = DegreesToRadians * (LatIn)
            // Dim Lon1 As Double = LonIn
            // Dim Theta As Double = DegreesToRadians * (Course)
            // Dim R As Double = 3443.92  ' this is the radius of the earth in nautical miles
            // Dim d As Double = Dist    ' this is the distance travelled in nautical miles
            // Dim DDivR As Double = (d / R)

            // Dim lat2 As Double = RadiansToDegrees * (Math.Asin(Math.Sin(lat1) * Math.Cos(DDivR) + Math.Cos(lat1) * Math.Sin(DDivR) * Math.Cos(Theta)))
            // Dim lon2 As Double = Lon1 + RadiansToDegrees * (Math.Atan2((Math.Sin(Theta) * Math.Sin(DDivR) * Math.Cos(lat1)), (Math.Cos(DDivR) - (Math.Sin(lat1) * Math.Sin(lat2)))))
            // Dim RtnGC As System.Device.Location.GeoCoordinate = New System.Device.Location.GeoCoordinate(lat2, lon2)
            // Return RtnGC
        }
        public GeoDistance DistanceBetweenMetric()
        {
            try
            {
                string decimalFormat = ServiceConfiguration["DecimalFormat"].ToString();

                System.Device.Location.GeoCoordinate primaryCoords = new System.Device.Location.GeoCoordinate(this.PrimaryLatitude, this.PrimaryLongitutde);
                System.Device.Location.GeoCoordinate secondaryCoords = new System.Device.Location.GeoCoordinate(this.SecondaryLatitude, this.SecondaryLongitutde);

                double distanceMetres = primaryCoords.GetDistanceTo(secondaryCoords);

                this.DistanceMetres = distanceMetres;
                this.DistanceKilometres = distanceMetres / 1000;

                this.DistanceMetresDisplay = this.DistanceMetres.ToString(decimalFormat);
                this.DistanceKilometresDisplay = this.DistanceKilometres.ToString(decimalFormat);

                this.ResultStatus = "OK";

                return this;
            }
            catch (Exception ex)
            {
                this.ResultStatus = "Exception";
                this.ResultMessage = ex.GetBaseException().Message;
                return this;
            }
        }
Example #32
0
 public LabeledMapLocation(string p, System.Device.Location.GeoCoordinate geoCoordinate)
 {
     this.p = p;
     this.geoCoordinate = geoCoordinate;
 }
Example #33
0
 public SunSettings(System.Device.Location.GeoCoordinate location)
 {
     GeoCord = location;
 }
Example #34
0
        void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
        {
            // System.Device.Location.GeoCoordinate
            // http://msdn.microsoft.com/en-us/library/system.device.location.geocoordinate.aspx

            // Windows.Devices.Geolocation.Geocoordinate
            // http://msdn.microsoft.com/fi-fi/library/windows/apps/windows.devices.geolocation.geocoordinate

            GottenLocationsCunt++;
            lastLocation = new System.Device.Location.GeoCoordinate(args.Position.Coordinate.Latitude, args.Position.Coordinate.Longitude);

            if (!RunningInBackground)
            {
                if (PositionUpdated != null)
                {
                    PositionUpdated(this, EventArgs.Empty);
                }
            }
        }
        public POIDuplicates GetAllPOIDuplicates(POIManager poiManager, int countryId, double maxDupeRange = 500)
        {
            List<DuplicatePOIItem> allDuplicates = new List<DuplicatePOIItem>();

            var dataModel = new OCM.Core.Data.OCMEntities();

            double DUPLICATE_DISTANCE_METERS = 25;
            double POSSIBLE_DUPLICATE_DISTANCE_METERS = maxDupeRange;

            //TODO: better method for large number of POIs
            //grab all live POIs (30-100,000 items)
            //var allPOIs = dataModel.ChargePoints.Where(s => s.AddressInfo.CountryID == countryId && (s.SubmissionStatusTypeID == 100 || s.SubmissionStatusTypeID == 200)).ToList();
            var allPOIs = poiManager.GetChargePoints(new APIRequestParams { CountryIDs = new int[] { countryId }, MaxResults=100000 });

            foreach (var poi in allPOIs)
            {
                //find pois which duplicate the given poi
                var dupePOIs = allPOIs.Where(p => p.ID != poi.ID &&
                    (
                        p.DataProvidersReference != null && p.DataProvidersReference.Length > 0 && p.DataProvidersReference == poi.DataProvidersReference
                        || new System.Device.Location.GeoCoordinate(p.AddressInfo.Latitude, p.AddressInfo.Longitude).GetDistanceTo(new System.Device.Location.GeoCoordinate(poi.AddressInfo.Latitude, poi.AddressInfo.Longitude)) < POSSIBLE_DUPLICATE_DISTANCE_METERS
                    )
                    );

                if (dupePOIs.Any())
                {
                    var poiModel = poi;// OCM.API.Common.Model.Extensions.ChargePoint.FromDataModel(poi, true, true, true, true);

                    foreach (var dupe in dupePOIs)
                    {
                        //poi has duplicates
                        DuplicatePOIItem dupePoi = new DuplicatePOIItem { DuplicatePOI = dupe, DuplicateOfPOI = poiModel };
                        dupePoi.Reasons = new List<string>();
                        if (dupe.AddressInfo.Latitude == poi.AddressInfo.Latitude && dupe.AddressInfo.Longitude == poi.AddressInfo.Longitude)
                        {
                            dupePoi.Reasons.Add("POI location is exact match for OCM-" + poi.ID);
                            dupePoi.Confidence = 95;
                        }
                        else
                        {
                            double distanceMeters = new System.Device.Location.GeoCoordinate(dupe.AddressInfo.Latitude, dupe.AddressInfo.Longitude).GetDistanceTo(new System.Device.Location.GeoCoordinate(poi.AddressInfo.Latitude, poi.AddressInfo.Longitude));
                            if (distanceMeters < DUPLICATE_DISTANCE_METERS)
                            {
                                dupePoi.Reasons.Add("POI location is close proximity (" + distanceMeters + "m) to OCM-" + poi.ID);
                                dupePoi.Confidence = 75;
                            }
                            else
                            {
                                if (distanceMeters < POSSIBLE_DUPLICATE_DISTANCE_METERS)
                                {
                                    dupePoi.Reasons.Add("POI location is in surrounding proximity (" + distanceMeters + "m) to OCM-" + poi.ID);
                                    dupePoi.Confidence = 50;
                                }
                            }
                        }

                        allDuplicates.Add(dupePoi);
                    }
                }
            }

            //arrange all duplicates into groups
            POIDuplicates duplicatesSummary = new POIDuplicates();
            duplicatesSummary.DuplicateSummaryList = new List<DuplicatePOIGroup>();
            foreach (var dupe in allDuplicates)
            {
                bool isNewGroup = false;
                var dupeGroup = duplicatesSummary.DuplicateSummaryList.FirstOrDefault(d => d.DuplicatePOIList.Any(p => p.DuplicateOfPOI.ID == dupe.DuplicateOfPOI.ID || p.DuplicatePOI.ID == dupe.DuplicatePOI.ID) || d.SuggestedBestPOI.ID == dupe.DuplicatePOI.ID);
                if (dupeGroup == null)
                {
                    isNewGroup = true;
                    dupeGroup = new DuplicatePOIGroup();
                    dupeGroup.SuggestedBestPOI = dupe.DuplicatePOI;//TODO: select best

                    dupeGroup.DuplicatePOIList = new List<DuplicatePOIItem>();
                }

                //only add to dupe group if not already added for another reason
                if (!dupeGroup.DuplicatePOIList.Contains(dupe) && !dupeGroup.DuplicatePOIList.Any(d => d.DuplicatePOI.ID == dupe.DuplicatePOI.ID))
                {
                    dupeGroup.DuplicatePOIList.Add(dupe);
                }

                if (isNewGroup)
                {
                    duplicatesSummary.DuplicateSummaryList.Add(dupeGroup);
                }
            }

            //loop through groups and rearrange
            RearrangeDuplicates(duplicatesSummary);

            //go through all groups and populate final list of All POI per group
            foreach (var g in duplicatesSummary.DuplicateSummaryList)
            {
                var poiList = new List<OCM.API.Common.Model.ChargePoint>();
                foreach (var d in g.DuplicatePOIList)
                {
                    if (!poiList.Contains(d.DuplicatePOI))
                    {
                        poiList.Add(d.DuplicatePOI);
                    }

                    if (!poiList.Contains(d.DuplicateOfPOI))
                    {
                        poiList.Add(d.DuplicateOfPOI);
                    }

                    g.AllPOI = poiList;
                }
            }

            //TODO: go through all dupe groups and nominate best poi to be main poi (most comments, most equipment info etc)
            return duplicatesSummary;
        }
Example #36
0
 public double GetDistance(double xLa, double xLong, double yLa, double yLong)
 {
     System.Device.Location.GeoCoordinate cordx = new System.Device.Location.GeoCoordinate(xLa, xLong);
     System.Device.Location.GeoCoordinate cordy = new System.Device.Location.GeoCoordinate(yLa, yLong);
     return(cordx.GetDistanceTo(cordy));
 }
        private void computeClusters(int nb)
        {
            FileReader filereader = new FileReader("Data/data.txt");

            double[][] rawData = filereader.readfromtextfile();
            kmeans = new KMeansClustering(nb, rawData);

            List<List<double[]>> clusters = kmeans.getCalculatedClusters();

            System.Diagnostics.Debug.WriteLine(kmeans.displayResult());

            Microsoft.Phone.Maps.Controls.MapLayer points = new Microsoft.Phone.Maps.Controls.MapLayer();

            System.Windows.Media.Color[] colors = new System.Windows.Media.Color[10];

            colors[0] = System.Windows.Media.Colors.Blue;
            colors[1] = System.Windows.Media.Colors.Red;
            colors[2] = System.Windows.Media.Colors.Green;
            colors[3] = System.Windows.Media.Colors.Yellow;
            colors[4] = System.Windows.Media.Colors.Purple;
            colors[5] = System.Windows.Media.Colors.Orange;
            colors[6] = System.Windows.Media.Colors.Cyan;
            colors[7] = System.Windows.Media.Colors.DarkGray;
            colors[8] = System.Windows.Media.Colors.Magenta;
            colors[9] = System.Windows.Media.Colors.White;

            for (int j = 0; j < clusters.ToArray().Length; j++)
            {
                System.Diagnostics.Debug.WriteLine(j);
                // lire dans chacun des clusters
                for (int i = 0; i < clusters.ElementAt(j).ToArray().Length; i++)
                {
                    double[] data = clusters.ElementAt(j).ElementAt(i);

                    Microsoft.Phone.Maps.Controls.MapOverlay pointsdata = new Microsoft.Phone.Maps.Controls.MapOverlay();

                    System.Windows.Shapes.Ellipse test = new System.Windows.Shapes.Ellipse();

                    test.Fill = new System.Windows.Media.SolidColorBrush(colors[j % 10]);
                    test.Height = 6;
                    test.Width = 6;
                    test.Opacity = 75;

                    pointsdata.Content = test;

                    System.Device.Location.GeoCoordinate coord = new System.Device.Location.GeoCoordinate(data[0], data[1]);

                    pointsdata.GeoCoordinate = coord;

                    points.Add(pointsdata);
                }
            }

            carte.Layers.Clear();

            carte.Layers.Add(points);
        }
Example #38
0
        /**
         * Generic Import Process

            Provider Properties
                Import Method
                Import URL/Path
                Import Frequency
                IsMaster

            Fetch Latest Data

            For each item
                Check If Exists or Strong Duplicate, Get ID
                If New, Add
                if Exists Then
                    Prepare update, if provider supports live status, set that
                        What if item updated manually on OCM?
                    Send Update
                End
            Loop

            Log Exceptions
            Log Count of Items Added or Modified

            Way to remove item (or log items) which no longer exist in data source?
         * */

        public async Task<List<ChargePoint>> DeDuplicateList(List<ChargePoint> cpList, bool updateDuplicate, CoreReferenceData coreRefData, ImportReport report, bool allowDupeWithDifferentOperator = false)
        {
            var stopWatch = new Stopwatch();
            stopWatch.Start();

            //get list of all current POIs (in relevant countries) including most delisted ones
            int[] countryIds = (from poi in cpList
                                where poi.AddressInfo.Country != null
                                select poi.AddressInfo.Country.ID).Distinct().ToArray();

            APIRequestParams filters = new APIRequestParams { CountryIDs = countryIds, MaxResults = 1000000, EnableCaching = false, SubmissionStatusTypeID = 0 };
            //List<ChargePoint> masterList = await new OCMClient(IsSandboxedAPIMode).GetLocations(filters); //new OCMClient().FindSimilar(null, 10000); //fetch all charge points regardless of status
            var poiManager = new POIManager();

            List<ChargePoint> masterListCollection = poiManager.GetChargePoints(filters); //new OCMClient().FindSimilar(null, 10000); //fetch all charge points regardless of status

            var spec = new i4o.IndexSpecification<ChargePoint>()
                    .Add(i => i.DataProviderID)
                    .Add(i => i.DataProvidersReference)
                    ;

            var masterList = new i4o.IndexSet<ChargePoint>(masterListCollection, spec);

            List<ChargePoint> masterListCopy = new List<ChargePoint>();
            foreach (var tmp in masterList)
            {
                //fully copy of master list item so we have before/after
                masterListCopy.Add(JsonConvert.DeserializeObject<ChargePoint>(JsonConvert.SerializeObject(tmp)));
            }

            //if we failed to get a master list, quit with no result
            if (masterListCollection.Count == 0) return new List<ChargePoint>();

            List<ChargePoint> duplicateList = new List<ChargePoint>();
            List<ChargePoint> updateList = new List<ChargePoint>();

            ChargePoint previousCP = null;

            //for each item to be imported, deduplicate by adding to updateList only the items which we don't already haves
            var cpListSortedByPos = cpList.OrderBy(c => c.AddressInfo.Latitude).ThenBy(c => c.AddressInfo.Longitude);

            int poiProcessed = 0;
            int totalPOI = cpListSortedByPos.Count();

            Stopwatch dupeIdentWatch = new Stopwatch();
            dupeIdentWatch.Start();

            foreach (var item in cpListSortedByPos)
            {
                var itemGeoPos = new System.Device.Location.GeoCoordinate(item.AddressInfo.Latitude, item.AddressInfo.Longitude);

                //item is duplicate if we already seem to have it based on Data Providers reference or approx position match
                var dupeList = masterList.Where(c =>
                        (c.DataProvider != null && c.DataProviderID == item.DataProviderID && c.DataProvidersReference == item.DataProvidersReference)
                        || (c.AddressInfo.Title == item.AddressInfo.Title && c.AddressInfo.AddressLine1 == item.AddressInfo.AddressLine1 && c.AddressInfo.Postcode == item.AddressInfo.Postcode)
                        || (GeoManager.IsClose(c.AddressInfo.Latitude, c.AddressInfo.Longitude, item.AddressInfo.Latitude, item.AddressInfo.Longitude) && new System.Device.Location.GeoCoordinate(c.AddressInfo.Latitude, c.AddressInfo.Longitude).GetDistanceTo(itemGeoPos) < DUPLICATE_DISTANCE_METERS) //meters distance apart
                );

                if (dupeList.Any())
                {
                    if (updateDuplicate)
                    {
                        //if updating duplicates, get exact matching duplicate based on provider reference and update/merge with this item to update status/merge properties
                        var updatedItem = dupeList.FirstOrDefault(d => d.DataProviderID == (item.DataProvider != null ? item.DataProvider.ID : item.DataProviderID) && d.DataProvidersReference == item.DataProvidersReference);
                        if (updatedItem != null)
                        {
                            //only merge/update from live published items
                            if (updatedItem.SubmissionStatus.IsLive == (bool?)true
                                || updatedItem.SubmissionStatus.ID == (int)StandardSubmissionStatusTypes.Delisted_RemovedByDataProvider
                                 || updatedItem.SubmissionStatus.ID == (int)StandardSubmissionStatusTypes.Delisted_NotPublicInformation)
                            {
                                //item is an exact match from same data provider
                                //overwrite existing with imported data (use import as master)
                                //updatedItem = poiManager.PreviewPopulatedPOIFromModel(updatedItem);
                                MergeItemChanges(item, updatedItem, false);

                                updateList.Add(updatedItem);
                            }
                        }

                        if (updatedItem == null)
                        {
                            //duplicates are not exact match
                            //TODO: resolve whether imported data should change duplicate

                            //merge new properties from imported item
                            //if (item.StatusType != null) updatedItem.StatusType = item.StatusType;
                            //updateList.Add(updatedItem);
                        }
                    }

                    //item has one or more likely duplicates, add it to list of items to remove
                    duplicateList.Add(item);
                }

                //mark item as duplicate if location/title exactly matches previous entry or lat/long is within DuplicateDistance meters

                if (previousCP != null)
                {
                    //this branch is the most expensive part of dedupe:
                    if (IsDuplicateLocation(item, previousCP, true))
                    {
                        if (!duplicateList.Contains(item))
                        {
                            if (allowDupeWithDifferentOperator && item.OperatorID != previousCP.OperatorID)
                            {
                                Log("Duplicated allowed due to different operator:" + item.AddressInfo.Title);
                            }
                            else
                            {
                                Log("Duplicated item removed:" + item.AddressInfo.Title);
                                duplicateList.Add(item);
                            }
                        }
                    }
                }

                previousCP = item;

                poiProcessed++;

                if (poiProcessed % 300 == 0)
                {
                    System.Diagnostics.Debug.WriteLine("Deduplication: " + poiProcessed + " processed of " + totalPOI);
                }
            }

            dupeIdentWatch.Stop();
            Log("De-dupe pass took " + dupeIdentWatch.Elapsed.TotalSeconds + " seconds. " + (dupeIdentWatch.Elapsed.TotalMilliseconds / cpList.Count) + "ms per item.");

            //remove duplicates from list to apply
            foreach (var dupe in duplicateList)
            {
                cpList.Remove(dupe);
            }

            Log("Duplicates removed from import:" + duplicateList.Count);

            //add updated items (replace duplicates with property changes)

            foreach (var updatedItem in updateList)
            {
                if (!cpList.Contains(updatedItem))
                {
                    cpList.Add(updatedItem);
                }
            }

            Log("Updated items to import:" + updateList.Count);

            //populate missing location info from geolocation cache if possible
            Stopwatch geoWatch = new Stopwatch();
            geoWatch.Start();
            PopulateLocationFromGeolocationCache(cpList, coreRefData);
            geoWatch.Stop();
            Log("Populate Country from Lat/Long took " + geoWatch.Elapsed.TotalSeconds + " seconds. " + (geoWatch.Elapsed.TotalMilliseconds / cpList.Count) + "ms per item.");

            //final pass to catch duplicates present in data source, mark additional items as Delisted Duplicate so we have a record for them
            var submissionStatusDelistedDupe = coreRefData.SubmissionStatusTypes.First(s => s.ID == 1001); //delisted duplicate
            previousCP = null;

            //sort current cp list by position again
            cpListSortedByPos = cpList.OrderBy(c => c.AddressInfo.Latitude).ThenBy(c => c.AddressInfo.Longitude);

            //mark any duplicates in final list as delisted duplicates (submitted to api)
            foreach (var cp in cpListSortedByPos)
            {
                bool isDuplicate = false;
                if (previousCP != null)
                {
                    isDuplicate = IsDuplicateLocation(cp, previousCP, false);
                    if (isDuplicate)
                    {
                        cp.SubmissionStatus = submissionStatusDelistedDupe;
                        cp.SubmissionStatusTypeID = submissionStatusDelistedDupe.ID;
                        if (previousCP.ID > 0)
                        {
                            if (cp.GeneralComments == null) cp.GeneralComments = "";
                            cp.GeneralComments += " [Duplicate of OCM-" + previousCP.ID + "]";
                            cp.ParentChargePointID = previousCP.ID;
                        }
                    }
                }

                if (!isDuplicate)
                {
                    previousCP = cp;
                }
            }

            report.Added = cpListSortedByPos.Where(cp => cp.ID == 0).ToList();
            report.Updated = cpListSortedByPos.Where(cp => cp.ID > 0).ToList();
            report.Duplicates = duplicateList; //TODO: add additional pass of duplicates from above

            //determine which POIs in our master list are no longer referenced in the import
            report.Delisted = masterList.Where(cp => cp.DataProviderID == report.ProviderDetails.DataProviderID && cp.SubmissionStatus != null && (cp.SubmissionStatus.IsLive == true || cp.SubmissionStatusTypeID == (int)StandardSubmissionStatusTypes.Imported_UnderReview)
                && !cpListSortedByPos.Any(master => master.ID == cp.ID) && !report.Duplicates.Any(master => master.ID == cp.ID)
                && cp.UserComments == null && cp.MediaItems == null).ToList();
            //safety check to ensure we're not delisting items just because we have incomplete import data:
            if (cpList.Count < 50)// || (report.Delisted.Count > cpList.Count))
            {
                report.Delisted = new List<ChargePoint>();
            }

            //determine list of low quality POIs (incomplete address info etc)
            report.LowDataQuality = new List<ChargePoint>();
            report.LowDataQuality.AddRange(GetLowDataQualityPOIs(report.Added));
            report.LowDataQuality.AddRange(GetLowDataQualityPOIs(report.Updated));

            Log("Removing " + report.LowDataQuality.Count + " low quality POIs from added/updated");

            //remove references in added/updated to any low quality POIs
            foreach (var p in report.LowDataQuality)
            {
                report.Added.Remove(p);
            }
            foreach (var p in report.LowDataQuality)
            {
                report.Updated.Remove(p);
            }

            //remove updates which only change datelaststatusupdate
            var updatesToIgnore = new List<ChargePoint>();
            foreach (var poi in report.Updated)
            {
                var origPOI = masterListCopy.FirstOrDefault(p => p.ID == poi.ID);
                var updatedPOI = poiManager.PreviewPopulatedPOIFromModel(poi);
                var differences = poiManager.CheckDifferences(origPOI, updatedPOI);
                differences.RemoveAll(d => d.Context == ".MetadataValues");
                differences.RemoveAll(d => d.Context == ".DateLastStatusUpdate");
                differences.RemoveAll(d => d.Context == ".UUID");

                differences.RemoveAll(d => d.Context == ".DataProvider.DateLastImported");
                differences.RemoveAll(d => d.Context == ".IsRecentlyVerified");
                differences.RemoveAll(d => d.Context == ".DateLastVerified");
                differences.RemoveAll(d => d.Context == ".UserComments");
                differences.RemoveAll(d => d.Context == ".MediaItems");

                if (!differences.Any())
                {
                    updatesToIgnore.Add(poi);
                }
                else
                {
                    //differences exist
                    CompareLogic compareLogic = new CompareLogic();
                    compareLogic.Config.MaxDifferences = 100;
                    compareLogic.Config.IgnoreObjectTypes = false;
                    compareLogic.Config.IgnoreUnknownObjectTypes = true;
                    compareLogic.Config.CompareChildren = true;
                    ComparisonResult result = compareLogic.Compare(origPOI, updatedPOI);

                    var diffReport = new KellermanSoftware.CompareNetObjects.Reports.UserFriendlyReport();
                    result.Differences.RemoveAll(d => d.PropertyName == ".MetadataValues");
                    result.Differences.RemoveAll(d => d.PropertyName == ".DateLastStatusUpdate");
                    result.Differences.RemoveAll(d => d.PropertyName == ".UUID");
                    result.Differences.RemoveAll(d => d.PropertyName == ".DataProvider.DateLastImported");
                    result.Differences.RemoveAll(d => d.PropertyName == ".IsRecentlyVerified");
                    result.Differences.RemoveAll(d => d.PropertyName == ".DateLastVerified");
                    result.Differences.RemoveAll(d => d.PropertyName == ".UserComments");
                    result.Differences.RemoveAll(d => d.PropertyName == ".MediaItems");
                    System.Diagnostics.Debug.WriteLine("Difference:" + diffReport.OutputString(result.Differences));

                    if (!result.Differences.Any())
                    {
                        updatesToIgnore.Add(poi);
                    }
                }
            }

            foreach (var p in updatesToIgnore)
            {
                if (report.Unchanged == null) report.Unchanged = new List<ChargePoint>();
                report.Unchanged.Add(p);
                report.Updated.Remove(p);
            }

            //TODO: if POi is a duplicate ensure imported data provider reference/URL  is included as reference metadata in OCM's version of the POI

            stopWatch.Stop();
            Log("Deduplicate List took " + stopWatch.Elapsed.TotalSeconds + " seconds");

            //return final processed list ready for applying as insert/updates
            return cpListSortedByPos.ToList();
        }
        public GeoDistance WithinRangeImperial()
        {
            try
            {
                string decimalFormat = ServiceConfiguration["DecimalFormat"].ToString();

                System.Device.Location.GeoCoordinate primaryCoords = new System.Device.Location.GeoCoordinate(this.PrimaryLatitude, this.PrimaryLongitutde);
                System.Device.Location.GeoCoordinate secondaryCoords = new System.Device.Location.GeoCoordinate(this.SecondaryLatitude, this.SecondaryLongitutde);

                double distanceMetres = primaryCoords.GetDistanceTo(secondaryCoords);

                this.DistanceYards = distanceMetres * 1.09361;
                this.DistanceMiles = this.DistanceYards / 1760;

                this.DistanceYardsDisplay = this.DistanceYards.ToString(decimalFormat);
                this.DistanceMilesDisplay = this.DistanceMiles.ToString(decimalFormat);

                if (this.DistanceYards <= this.RangeYards)
                {
                    this.WithinRange = true;
                }
                else
                {
                    this.WithinRange = false;
                }
                this.ResultStatus = "OK";

                return this;
            }
            catch (Exception ex)
            {
                this.ResultStatus = "Exception";
                this.ResultMessage = ex.GetBaseException().Message;
                return this;
            }
        }