// Accept user click point and find nearest target geometry point private async Task GetNearestCoordAsync(bool vertexOnly) { var target = _targetLayer.Graphics.Select(g => g.Geometry).FirstOrDefault(); if (target == null) { return; } txtInstruct.Text = "Click the map to find the nearest coordinate in the selected geometry"; var point = await mapView.Editor.RequestPointAsync(); ProximityResult result = null; if (vertexOnly) { result = GeometryEngine.NearestVertexInGeometry(target, point); } else { result = GeometryEngine.NearestCoordinateInGeometry(target, point); } _coordinateLayer.Graphics.Clear(); _coordinateLayer.Graphics.Add(new Graphic(point, _userPointSymbol)); _coordinateLayer.Graphics.Add(new Graphic(result.Point)); txtResult.Visibility = Visibility.Visible; txtResult.Text = string.Format("Nearest Point: Index: {0}, Distance: {1:0.000}", result.PointIndex, result.Distance); }
/// <summary> /// Call this to set your current location and update directions based on that. /// </summary> /// <param name="location"></param> public void SetCurrentLocation(MapPoint location) { RouteDirection closest = null; double distance = double.NaN; MapPoint snappedLocation = null; Route direction = null; // Find the route part that we are currently on by snapping to each segment and see which one is the closest foreach (var dir in m_route.Routes) { var closestCandidate = (from a in dir.RouteDirections where a.Geometry is Polyline select new { Direction = a, Proximity = GeometryEngine.NearestCoordinateInGeometry(a.Geometry, location) }).OrderBy(b => b.Proximity.Distance).FirstOrDefault(); if (double.IsNaN(distance) || distance < closestCandidate.Proximity.Distance) { distance = closestCandidate.Proximity.Distance; closest = closestCandidate.Direction; snappedLocation = closestCandidate.Proximity.Point; direction = dir; } } if (closest != null) { var directions = direction.RouteDirections.ToList(); var idx = directions.IndexOf(closest); if (idx < directions.Count) { RouteDirection next = directions[idx + 1]; //calculate how much is left of current route segment var segment = closest.Geometry as Polyline; var proximity = GeometryEngine.NearestVertexInGeometry(segment, snappedLocation); double frac = 1 - GetFractionAlongLine(segment, proximity, snappedLocation); TimeSpan timeLeft = new TimeSpan((long)(closest.Time.Ticks * frac)); double segmentLengthLeft = (Convert.ToDouble(closest.GetLength(LinearUnits.Meters))) * frac; //Sum up the time and lengths for the remaining route segments TimeSpan totalTimeLeft = timeLeft; double totallength = segmentLengthLeft; for (int i = idx + 1; i < directions.Count; i++) { totalTimeLeft += directions[i].Time; totallength += directions[i].GetLength(LinearUnits.Meters); } //Update properties TimeToWaypoint = TimeSpan.FromSeconds(Math.Round(timeLeft.TotalSeconds)); TimeToDestination = TimeSpan.FromSeconds(Math.Round(totalTimeLeft.TotalSeconds)); DistanceToWaypoint = Math.Round(segmentLengthLeft); DistanceToDestination = Math.Round(totallength); SnappedLocation = snappedLocation; var maneuverType = next.ManeuverType; #if NETFX_CORE || WINDOWS_PHONE ManeuverImage = new Uri(string.Format("ms-appx:///Assets/Maneuvers/{0}.png", maneuverType)); #else ManeuverImage = new Uri(string.Format("pack://application:,,,/Assets/Maneuvers/{0}.png", maneuverType)); #endif NextManeuver = next.Text; RaisePropertiesChanged(new string[] { "NextManeuver", "SnappedLocation", "CurrentDirection", "TimeToWaypoint", "DistanceToDestination", "DistanceToWaypoint", "TimeToDestination", "MilesToDestination", "MilesToWaypoint", "ManeuverImage" }); } } }