/// <summary> /// Returns the bearing of a point relative to another. /// </summary> /// <param name="point1">The first point.</param> /// <param name="point2">The second point.</param> /// <returns> /// The bearing of <paramref name="point1"/> relative to <paramref name="point2"/>. /// </returns> public static double BearingGeodetic(MapPoint point1, MapPoint point2) { var result = GeometryEngine.DistanceGeodetic(point1, point2, LinearUnits.Meters, AngularUnits.Degrees, GeodeticCurveType.Geodesic); return(result.Azimuth1); }
private void AnimateTank() { // Return if tank already arrived. if (_tankEndPoint == null) { return; } // Get current location and distance from the destination. MapPoint location = (MapPoint)_tank.Geometry; GeodeticDistanceResult distance = GeometryEngine.DistanceGeodetic( location, _tankEndPoint, _metersUnit, _degreesUnit, GeodeticCurveType.Geodesic); // Move the tank a short distance. location = GeometryEngine.MoveGeodetic(new List <MapPoint>() { location }, 1.0, _metersUnit, distance.Azimuth1, _degreesUnit, GeodeticCurveType.Geodesic).First(); _tank.Geometry = location; // Rotate to face the destination. double heading = (double)_tank.Attributes["HEADING"]; heading = heading + (distance.Azimuth1 - heading) / 10; _tank.Attributes["HEADING"] = heading; // Clear the destination if the tank already arrived. if (distance.Distance < 5) { _tankEndPoint = null; } }
private void TimerElapsed(object sender, ElapsedEventArgs e) { // Check that there are remaining nodes. if (_nodeIndex > _gpsPoints.Count - 1) { _driveTimer.Enabled = false; return; } // Check if there is a privious node. if (_nodeIndex > 0) { // Get the distance between the current node and the previous node. GeodeticDistanceResult distance = GeometryEngine.DistanceGeodetic(_gpsPoints[_nodeIndex], _gpsPoints[_nodeIndex - 1], LinearUnits.Meters, AngularUnits.Degrees, GeodeticCurveType.Geodesic); // Get the cours in degrees. _course = distance.Azimuth2; // Calculate the speed in m/s by using the distance and the timer interval. _speed = distance.Distance / (_timerValue / 1000); } // Set the new fake location. UpdateLocation(new Location(_gpsPoints[_nodeIndex], 5, _speed, _course, false)); // Increment the node index. _nodeIndex++; }
private async void MyMapView_GeoViewTapped(object sender, Esri.ArcGISRuntime.UI.Controls.GeoViewInputEventArgs e) { DataContext = this; // search var tapPoint = e.Location; var buffer = GeometryEngine.Buffer(tapPoint, 10); QueryParameters query = new QueryParameters(); query.Geometry = buffer; var results = await fLayer.FeatureTable.QueryFeaturesAsync(query); if (results.Count() > 0) { chartValues = new ChartValues <ObservableChartMapPoint>(); var firstResult = results.First(); var randoGeom = firstResult.Geometry as Esri.ArcGISRuntime.Geometry.Polyline; randoTitle = firstResult.Attributes["NOM"].ToString(); Camera cam = new Camera(firstResult.Geometry.Extent.GetCenter(), 4200, myMapView.MapRotation, 55, 0); var viewPoint = new Viewpoint(firstResult.Geometry, cam); //scen myMapView.SetViewpointAsync(viewPoint, System.TimeSpan.FromMilliseconds(4000)); mySceneView.SetViewpointAsync(viewPoint, System.TimeSpan.FromMilliseconds(4000)); var i = 0; double distance = 0; MapPoint lastPoint = null; foreach (var part in randoGeom.Parts) { foreach (var point in part.Points) { // si on est pas sur le premier point if (i > 0) { distance += GeometryEngine.DistanceGeodetic(lastPoint, point, LinearUnits.Kilometers, AngularUnits.Degrees, GeodeticCurveType.Geodesic).Distance; } // sauvegrde du point pour distance. lastPoint = point; // on ne prend pas tous les points. if (i % 2 == 0) { double elevation = await sceneSurface.GetElevationAsync(point); chartValues.Add(new ObservableChartMapPoint(Math.Round(distance, 4), elevation, point)); } i++; } } // charts } // zoom on both scene+mapview }
private async void AssociatedObject_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) { if (!IsEnabled) { return; } e.Handled = true; var mapView = AssociatedObject; var screenPosition = e.GetPosition(AssociatedObject); if (IsCursorOutsideControl(screenPosition)) { HideTargetScale(); return; } _deltas += e.Delta; var direction = GetDirection(_deltas); double factor = (mapView.InteractionOptions.ZoomFactor * Math.Abs(_deltas / 120)); double scale = GetNewScale(factor, direction); Trace.WriteLine($"{scale}"); // TODO: stretch or shrink current map image for visual indication of direction/scale UpdateTargetScale(scale); var delta = _deltas; await Task.Delay(400); if (delta != _deltas) { // Accumulate multiple deltas before starting the actual zoom return; } _deltas = 0; var screenLocation = mapView.ScreenToLocation(screenPosition); var centerLocation = (MapPoint)mapView.GetCurrentViewpoint(ViewpointType.CenterAndScale).TargetGeometry; var distance = GeometryEngine.DistanceGeodetic(screenLocation, centerLocation, LinearUnits.Meters, AngularUnits.Degrees, GeodeticCurveType.Geodesic); double distanceValue = GetNewValue(distance.Distance, factor, direction); var targetCenter = GeometryEngine.MoveGeodetic(new[] { screenLocation }, distanceValue, LinearUnits.Meters, distance.Azimuth1, distance.AzimuthUnit, GeodeticCurveType.Geodesic) .First(); await mapView.SetViewpointAsync( new Viewpoint(targetCenter, scale), TimeSpan.Zero); HideTargetScale(); }
/// <summary> /// Gets a point a certain distance down a polyline /// </summary> /// <param name="dist">Distance in meters along the line</param> /// <param name="course"></param> /// <returns></returns> private double[] PointAlongLine(double dist, out double course) { double accDist = 0; course = double.NaN; if (dist > lineLength) //reached end - move to next direction, or start over { directionIndex++; Route currDir; if (directionIndex >= m_route.Routes.Count) { directionIndex = 0; } currDir = m_route.Routes[directionIndex]; lineLength = GeometryEngine.LengthGeodetic(currDir.RouteGeometry); totalDistance = 0; drivePath = currDir.RouteGeometry as Polyline; course = 0; dist = 0; } //else { var parts = drivePath.Parts.Select(p => p.Points).ToList(); for (int j = 0; j < parts.Count; j++) { var part = parts[j].ToList(); for (int i = 0; i < part.Count - 1; i++) { var p1 = part[i]; var p2 = part[i + 1]; if (p1.X == p2.X && p2.Y == p2.Y) { continue; } var result = GeometryEngine.DistanceGeodetic(p1, p2, LinearUnits.Meters, AngularUnits.Degrees, GeodeticCurveType.Geodesic); double distToWaypoint = result.Distance; if (dist < accDist + distToWaypoint) { var distAlongSegment = dist - accDist; double fraction = distAlongSegment / distToWaypoint; course = GetTrueBearingGeodesic(p1.X, p1.Y, p2.X, p2.Y); return(GetPointFromHeadingGeodesic(new double[] { p1.X, p1.Y }, distAlongSegment, course)); } accDist += distToWaypoint; } } } return(null); }
private void AnimationTimer_Elapsed(object sender, EventArgs e) { // Note: the contents of this function are solely related to animating the taxi // Increment the frame counter _frameIndex++; // Reset the frame counter once one segment of the path has been travelled if (_frameIndex == _frameMax) { _frameIndex = 0; // Start navigating toward the next point _pointIndex++; // Restart if finished circuit if (_pointIndex == _points.Length) { _pointIndex = 0; } } // Get the point the taxi is travelling from MapPoint starting = _points[_pointIndex]; // Get the point the taxi is travelling to MapPoint ending = _points[(_pointIndex + 1) % _points.Length]; // Calculate the progress based on the current frame double progress = _frameIndex / (double)_frameMax; // Calculate the position of the taxi when it is {progress}% of the way through MapPoint intermediatePoint = InterpolatedPoint(starting, ending, progress); // Update the taxi geometry _taxiGraphic.Geometry = intermediatePoint; // Update the taxi rotation. GeodeticDistanceResult distance = GeometryEngine.DistanceGeodetic(starting, ending, LinearUnits.Meters, AngularUnits.Degrees, GeodeticCurveType.Geodesic); ((ModelSceneSymbol)_taxiGraphic.Symbol).Heading = distance.Azimuth1; }
/// <summary> /// Returns the point at a given geodesic distance along a line. /// </summary> /// <param name="line">The line.</param> /// <param name="distance">The geodesic distance along the line.</param> /// <returns> /// A point along the line; if <paramref name="distance"/> is longer than the line, returns <c>null</c>. /// </returns> public static MapPoint CreatePointAlongGeodetic(Polyline line, double distance) { // Determine the points that bound `distance` var points = line.Parts.SelectMany(part => part.Points).ToArray(); var searchDistance = 0.0; for (int i = 0; i < points.Length - 1; i++) { var point1 = points[i]; var point2 = points[i + 1]; // Ignore part boundaries if (point1.X == point2.X && point1.Y == point2.Y) { continue; } // Find the distance between each point var pointDistanceResult = GeometryEngine.DistanceGeodetic(point1, point2, LinearUnits.Meters, AngularUnits.Degrees, GeodeticCurveType.Geodesic); var pointDistance = pointDistanceResult.Distance; var pointBearing = pointDistanceResult.Azimuth1; // Determine whether `distance` falls between these points if (distance < searchDistance + pointDistance) { var segmentDistance = distance - searchDistance; // Find the extact position of the point return(CreatePointAlongGeodetic(point1, pointBearing, segmentDistance)); } // Continue the search searchDistance += pointDistance; } // Point could not be found return(null); }
private void UpdateSeek(double speed) { if (_location == null || _target == null) { return; } // Determine distance between current location and target location var distanceResult = GeometryEngine.DistanceGeodetic(_location, _target, LinearUnits.Meters, AngularUnits.Degrees, GeodeticCurveType.Geodesic); var distance = distanceResult.Distance; if (speed <= distance) { // Move toward the point if we're not "close enough" _course = GeometryHelpers.BearingGeodetic(_location, _target); _location = GeometryHelpers.CreatePointAlongGeodetic(_location, _course, speed); } else { // We've reached the point, start following the route State = SimulationState.Following; } }
public void PlotButton_Click(object sender, RoutedEventArgs e) { azimuthPoint = double.Parse(textAzimuth.Text); distancePoint = double.Parse(textDistance.Text); //distanceList.Add(distancePoint); if (azimuthPoint <= 360) { if (azimuthPoint <= 180) { var result = azimuthPoint; //azimuthList.Add(result); //TraverseData.AzimuthList.Add(result); //azimuthList.Add(result); } if (azimuthPoint > 180) { var result = 180 - (azimuthPoint); //azimuthList.Add(result); //TraverseData.AzimuthList.Add(result); //azimuthList.Add(result); } textAzimuth.Text = ""; textDistance.Text = ""; } double result1; double result2; //GeodeticDistanceResult distance = GeometryEngine.DistanceGeodetic(start, destination, LinearUnits.Meters, AngularUnits.Degrees, GeodeticCurveType.NormalSection); IReadOnlyList <MapPoint> coordinateList = GeometryEngine.MoveGeodetic(mapPoints, distancePoint, LinearUnits.Meters, azimuthPoint, AngularUnits.Degrees, GeodeticCurveType.NormalSection); GeodeticDistanceResult travel = GeometryEngine.DistanceGeodetic(start, coordinateList[0], LinearUnits.Meters, AngularUnits.Degrees, GeodeticCurveType.NormalSection); graphic1.Geometry = coordinateList[0]; if (travel.Azimuth1 >= 0) { result1 = travel.Azimuth1; } else { result1 = travel.Azimuth1 + 360; } if (travel.Azimuth2 >= 0) { result2 = travel.Azimuth2; } else { result2 = travel.Azimuth2 + 360; } textBox.Text = string.Format($"Distance:{travel.Distance} | Azimuth1:{result1} | Azimuth2:{result2} |Initial Point :410175.775805, 552181.881083"); //textBox.Text = string.Format("{0} kilometers", (int)distance); // Get the points that define the route polyline. Esri.ArcGISRuntime.Geometry.PointCollection polylinePoints = new Esri.ArcGISRuntime.Geometry.PointCollection(new SpatialReference(3168)) { (MapPoint)_startLocationGraphic.Geometry, coordinateList[0] }; // Create the polyline for the two points. Polyline routeLine = new Polyline(polylinePoints); // Densify the polyline to show the geodesic curve. Esri.ArcGISRuntime.Geometry.Geometry pathGeometry = GeometryEngine.DensifyGeodetic(routeLine, 1, LinearUnits.Kilometers, GeodeticCurveType.Geodesic); // Apply the curved line to the path graphic. _pathGraphic.Geometry = pathGeometry; }
/// <summary> /// Checks the distance. /// </summary> private void CheckDistance() { SimpleMarkerSceneSymbol sphereSymbol = new SimpleMarkerSceneSymbol { Style = SimpleMarkerSceneSymbolStyle.Sphere, Color = Color.Red, Height = 1000, Width = 100, Depth = 100, AnchorPosition = SceneSymbolAnchorPosition.Center }; MapPoint p1 = new MapPoint(9.386941, 47.666557, SpatialReferences.Wgs84); MapPoint p2 = new MapPoint(9.172648, 47.666100, SpatialReferences.Wgs84); GraphicsOverlay symbolsOverlay = new GraphicsOverlay { Opacity = 0.5 }; symbolsOverlay.SceneProperties.SurfacePlacement = SurfacePlacement.Draped; symbolsOverlay.Graphics.Add(new Graphic(p1, sphereSymbol)); symbolsOverlay.Graphics.Add(new Graphic(p2, sphereSymbol)); Polyline p = new Polyline(new[] { p1, p2 }); symbolsOverlay.Graphics.Add(new Graphic(p, new SimpleLineSymbol { AntiAlias = true, Style = SimpleLineSymbolStyle.DashDot, Width = 4, Color = Color.Red })); //double dDistance = GeometryEngine.Distance( p1, p2 ); var result = GeometryEngine.DistanceGeodetic(p1, p2, LinearUnits.Meters, AngularUnits.Degrees, GeodeticCurveType.Geodesic); uint iPositionDistanceMeter = 500; Geometry g = GeometryEngine.DensifyGeodetic(p, iPositionDistanceMeter, LinearUnits.Meters); SimpleMarkerSymbol marker = new SimpleMarkerSymbol { Style = SimpleMarkerSymbolStyle.Circle, Color = Color.Yellow, Size = 20 }; foreach (LineSegment x in (g as Polyline).Parts[0]) { symbolsOverlay.Graphics.Add(new Graphic(x.StartPoint, marker)); } this.SceneView.GraphicsOverlays.Add(symbolsOverlay); //----------------------------------------------------------------- //this.SceneView.SetViewpointAsync( new Viewpoint( p1, 100000 ) ); }