private void MyDrawObject_DrawComplete(object sender, DrawEventArgs args) { ESRI.ArcGIS.Client.Geometry.Polyline polyline = args.Geometry as ESRI.ArcGIS.Client.Geometry.Polyline; polyline.SpatialReference = MyMap.SpatialReference; Graphic polylineGraphic = new Graphic() { Geometry = polyline }; List <Graphic> polylineList = new List <Graphic>(); polylineList.Add(polylineGraphic); GeometryService geometryService = new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"); geometryService.AutoCompleteCompleted += GeometryService_AutoCompleteCompleted; geometryService.Failed += GeometryService_Failed; GraphicsLayer graphicsLayer = MyMap.Layers["ParcelsGraphicsLayer"] as GraphicsLayer; List <Graphic> polygonList = new List <Graphic>(); foreach (Graphic g in graphicsLayer.Graphics) { g.Geometry.SpatialReference = MyMap.SpatialReference; polygonList.Add(g); } geometryService.AutoCompleteAsync(polygonList, polylineList); }
/// <summary> /// Convert from ArcLogistics polyline to ArcGIS polyline. /// </summary> /// <param name="sourcePolyline">ArcLogistics polyline</param> /// <param name="spatialReferenceID">Map spatial reference.</param> /// <returns>ArcGIS polyline.</returns> internal static ESRI.ArcGIS.Client.Geometry.Geometry ConvertToArcGISPolyline(Polyline sourcePolyline, int?spatialReferenceID) { ESRI.ArcGIS.Client.Geometry.Polyline resultPolyline = new ESRI.ArcGIS.Client.Geometry.Polyline(); // Project polyline from WGS84 to Web Mercator if spatial reference of map is Web Mercator. if (spatialReferenceID != null) // REV: comapre with specific Web Mercator WKID, instead of null. { sourcePolyline = WebMercatorUtil.ProjectPolylineToWebMercator(sourcePolyline, spatialReferenceID.Value); } int[] groups = sourcePolyline.Groups; for (int groupIndex = 0; groupIndex < groups.Length; ++groupIndex) { ESRI.ArcLogistics.Geometry.Point[] points = sourcePolyline.GetGroupPoints(groupIndex); ESRI.ArcGIS.Client.Geometry.PointCollection pointsCollection = new ESRI.ArcGIS.Client.Geometry.PointCollection(); for (int index = 0; index < points.Length; index++) { ESRI.ArcGIS.Client.Geometry.MapPoint mapPoint = new ESRI.ArcGIS.Client.Geometry.MapPoint( points[index].X, points[index].Y); pointsCollection.Add(mapPoint); } resultPolyline.Paths.Add(pointsCollection); } return(resultPolyline); }
//Start a new sketch void Map_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (sketch != null) { return; } //Mark the event arg as handled so the map won't treat the action as a pan action e.Handled = true; //Get the map point (first point of the sketch) client.Map map = sender as client.Map; client.Geometry.MapPoint mapPoint = map.ScreenToMap(e.GetPosition(map)); //Create the geometry (polyline) of the sketch and add the first point to it client.Geometry.Polyline pl = new client.Geometry.Polyline(); pl.SpatialReference = mapPoint.SpatialReference; pl.Paths.Add(new client.Geometry.PointCollection()); pl.Paths[0].Add(mapPoint); //Create the sketch graphic with the geometry and the symbol sketch = new client.Graphic(); sketch.Symbol = new SimpleLineSymbol() { Color = new SolidColorBrush(SelectedColor), Width = selectedWidth }; sketch.Geometry = pl; sketch.Geometry.SpatialReference = _mapWidget.Map.SpatialReference; //Add the sketch graphic to the layer sketchLayer.Graphics.Add(sketch); }
private bool SnapPointToCacheObjects(ESRI.ArcGIS.Client.Geometry.MapPoint point, bool skipZeroDistance, out ESRI.ArcGIS.Client.Geometry.Polyline snapLine) { snapLine = null; // default return arg. ESRI.ArcGIS.Client.Geometry.Polyline bestSnapLine = null; double shortestDistance = double.MaxValue; Int32 oid = -1; foreach (KeyValuePair <Int32, ESRI.ArcGIS.Client.Geometry.Geometry> kvp in _snapObjects) { if (-1 == kvp.Key) // this should not happen { continue; } ESRI.ArcGIS.Client.Geometry.Polyline line = kvp.Value as ESRI.ArcGIS.Client.Geometry.Polyline; if (line != null) { ESRI.ArcGIS.Client.Geometry.PointCollection pathPoints = line.Paths.First(); double distance; if (GeometryUtil.FindPerpendicularDistance(line, point, out distance) && (distance <= _xmlConfiguation.SnapTolerance)) { if ((distance < shortestDistance) && (!(skipZeroDistance && (distance == 0)))) { oid = kvp.Key; bestSnapLine = line; shortestDistance = distance; } } } /* For now we don't snap to points * This does not play well with scale or rotate on its own, as * it will want to pull the geometry in the other action (rotate or scale) also. * * ESRI.ArcGIS.Client.Geometry.MapPoint cachePoint = kvp.Value as ESRI.ArcGIS.Client.Geometry.MapPoint; * if (cachePoint != null) * { * double distance = GeometryUtil.LineLength(cachePoint, point); * if ((distance < shortestDistance) && (!(skipZeroDistance && (distance == 0)))) * { * oid = kvp.Key; * bestSnapLine = null; * shortestDistance = distance; * } * } */ } if (oid != -1) { snapLine = bestSnapLine; return(true); } return(false); }
static public ESRI.ArcGIS.Client.Geometry.Polyline Line(ESRI.ArcGIS.Client.Geometry.MapPoint startPoint, ESRI.ArcGIS.Client.Geometry.MapPoint endPoint) { ESRI.ArcGIS.Client.Geometry.PointCollection pointCollection = new ESRI.ArcGIS.Client.Geometry.PointCollection(); pointCollection.Add(startPoint); pointCollection.Add(endPoint); ESRI.ArcGIS.Client.Geometry.Polyline polyline = new ESRI.ArcGIS.Client.Geometry.Polyline(); polyline.Paths.Add(pointCollection); return(polyline); }
private void QueryTask_ExecuteCompleted(object sender, QueryEventArgs args) { if (_originPoint == null) { return; } double searchDistance = (double)args.UserState; double x = _originPoint.X; double y = _originPoint.Y; Int32 id = 0; if (args.FeatureSet.Features.Count > 0) { foreach (Graphic feature in args.FeatureSet.Features) { // test type of feature, and test it's end points. if (feature.Geometry is ESRI.ArcGIS.Client.Geometry.Polygon) { ESRI.ArcGIS.Client.Geometry.Polygon featurePolygon = feature.Geometry as ESRI.ArcGIS.Client.Geometry.Polygon; foreach (ESRI.ArcGIS.Client.Geometry.PointCollection pointCollection in featurePolygon.Rings) { AddLineSegmentToCache(pointCollection, x, y, searchDistance, ref id); } } else if (feature.Geometry is ESRI.ArcGIS.Client.Geometry.Polyline) { ESRI.ArcGIS.Client.Geometry.Polyline featurePolyline = feature.Geometry as ESRI.ArcGIS.Client.Geometry.Polyline; foreach (ESRI.ArcGIS.Client.Geometry.PointCollection pointCollection in featurePolyline.Paths) { AddLineSegmentToCache(pointCollection, x, y, searchDistance, ref id); } } else if (feature.Geometry is ESRI.ArcGIS.Client.Geometry.MapPoint) { ESRI.ArcGIS.Client.Geometry.MapPoint featurePoint = feature.Geometry as ESRI.ArcGIS.Client.Geometry.MapPoint; double distance = GeometryUtil.LineLength(x, y, featurePoint); if (distance < searchDistance) { _snapObjects[id++] = feature.Geometry; } } } } System.Diagnostics.Debug.WriteLine("Async: Number of objects cached: " + args.FeatureSet.Features.Count.ToString()); CalculateAndAddLineGraphics(); // We need to redraw, so we get the right snap marker }
//For each move, get the map point and add it as a vertex of the polyline void Map_MouseMove(object sender, MouseEventArgs e) { if (sketch == null) { return; } //Get the map point client.Map map = sender as client.Map; client.Geometry.MapPoint mapPoint = map.ScreenToMap(e.GetPosition(map)); //Add the map point to the sketch client.Geometry.Polyline polyline = sketch.Geometry as client.Geometry.Polyline; polyline.Paths[0].Add(mapPoint); }
private void MyDrawObject_DrawComplete(object sender, DrawEventArgs args) { MyDrawObject.IsEnabled = false; ESRI.ArcGIS.Client.Geometry.Polyline polyline = args.Geometry as ESRI.ArcGIS.Client.Geometry.Polyline; polyline.SpatialReference = MyMap.SpatialReference; GeometryService geometryService = new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"); geometryService.CutCompleted += GeometryService_CutCompleted; geometryService.Failed += GeometryService_Failed; geometryService.CutAsync(parcelGraphicsLayer.Graphics.ToList(), polyline); }
private void MyDrawObject_DrawComplete(object sender, DrawEventArgs args) { MyDrawObject.IsEnabled = false; if (MyDrawObject.DrawMode == DrawMode.Point) { ESRI.ArcGIS.Client.Geometry.MapPoint point = args.Geometry as ESRI.ArcGIS.Client.Geometry.MapPoint; point.SpatialReference = MyMap.SpatialReference; System.Windows.Point screenPnt = MyMap.MapToScreen(point); // Account for difference between Map and application origin GeneralTransform generalTransform = MyMap.TransformToVisual(Application.Current.RootVisual); System.Windows.Point transformScreenPnt = generalTransform.Transform(screenPnt); IEnumerable <Graphic> selected = parcelGraphicsLayer.FindGraphicsInHostCoordinates(transformScreenPnt); if (selected.ToArray().Length <= 0) { MyDrawObject.IsEnabled = true; return; } selectedGraphic = selected.ToList()[0] as Graphic; selectedGraphic.Select(); MyDrawObject.DrawMode = DrawMode.Polyline; MyDrawObject.IsEnabled = true; InfoTextBlock.Text = LayoutRoot.Resources["EndText"] as string; } else { ESRI.ArcGIS.Client.Geometry.Polyline polyline = args.Geometry as ESRI.ArcGIS.Client.Geometry.Polyline; polyline.SpatialReference = MyMap.SpatialReference; GeometryService geometryService = new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"); geometryService.ReshapeCompleted += GeometryService_ReshapeCompleted; geometryService.Failed += GeometryService_Failed; geometryService.ReshapeAsync(selectedGraphic.Geometry, polyline); } }
// *********************************************************************************** // * User finished drawing a polyline on the map. Add the polyline // * barriers GraphicsLayer. // *********************************************************************************** void DrawComplete(object sender, client.DrawEventArgs e) { // Deactivate the draw object for now. if (_drawObject != null) { _drawObject.IsEnabled = false; _drawObject.DrawComplete -= DrawComplete; } client.Geometry.Polyline barrierGeometry = e.Geometry as client.Geometry.Polyline; client.Graphic barrierGraphic = new client.Graphic() { Symbol = _polylineBarrierSymbol, //(LineSymbol)this.FindResource("routeSymbol") Geometry = barrierGeometry }; _polylineBarriersGraphicLayer.Graphics.Add(barrierGraphic); }
static public ESRI.ArcGIS.Client.Geometry.Polyline Line(ESRI.ArcGIS.Client.Geometry.MapPoint startPoint, double bearing, double distance, out ESRI.ArcGIS.Client.Geometry.MapPoint endPoint) { endPoint = null; if (distance == 0) { return(null); } endPoint = ConstructPoint(startPoint, bearing, distance); ESRI.ArcGIS.Client.Geometry.PointCollection pointCollection = new ESRI.ArcGIS.Client.Geometry.PointCollection(); pointCollection.Add(startPoint); pointCollection.Add(endPoint); ESRI.ArcGIS.Client.Geometry.Polyline polyline = new ESRI.ArcGIS.Client.Geometry.Polyline(); polyline.Paths.Add(pointCollection); return(polyline); }
private void MyDrawObject_DrawComplete(object sender, DrawEventArgs args) { ESRI.ArcGIS.Client.Geometry.Polyline polyline = args.Geometry as ESRI.ArcGIS.Client.Geometry.Polyline; polyline.SpatialReference = MyMap.SpatialReference; Graphic graphic = new Graphic() { Symbol = LayoutRoot.Resources["DefaultLineSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol, Geometry = polyline }; GeometryService geometryService = new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"); geometryService.LengthsCompleted += GeometryService_LengthsCompleted; geometryService.Failed += GeometryService_Failed; GraphicsLayer graphicsLayer = MyMap.Layers["MyGraphicsLayer"] as GraphicsLayer; graphicsLayer.Graphics.Add(graphic); geometryService.LengthsAsync(graphicsLayer.Graphics.ToList(), LinearUnit.SurveyMile, CalculationType.Geodesic, null); }
private void AddLineSegmentToCache(ESRI.ArcGIS.Client.Geometry.PointCollection pointCollection, double x, double y, double searchDistance, ref Int32 id) { double distance; ESRI.ArcGIS.Client.Geometry.MapPoint lastPoint = null; ESRI.ArcGIS.Client.Geometry.MapPoint originPoint = new ESRI.ArcGIS.Client.Geometry.MapPoint(x, y); foreach (ESRI.ArcGIS.Client.Geometry.MapPoint featurePoint in pointCollection) { if (lastPoint != null) { ESRI.ArcGIS.Client.Geometry.Polyline snapLine = GeometryUtil.Line(lastPoint, featurePoint); if (GeometryUtil.FindPerpendicularDistance(snapLine, originPoint, out distance)) { if (distance < searchDistance) { _snapObjects[id++] = snapLine; } } } lastPoint = new ESRI.ArcGIS.Client.Geometry.MapPoint(featurePoint.X, featurePoint.Y); } }
public static ESRI.ArcGIS.Client.Geometry.Polyline FromIMSToPolyline(XElement item) { ESRI.ArcGIS.Client.Geometry.Polyline poly = new ESRI.ArcGIS.Client.Geometry.Polyline(); var Paths = from path in item.Element("POLYLINE").Descendants("PATH") select path; foreach (var path in Paths) { List<ImsPoints> Points = (from point in path.Descendants("POINT") select new ImsPoints { X = point.Attribute("x").Value, Y = point.Attribute("y").Value, }).ToList(); ESRI.ArcGIS.Client.Geometry.PointCollection pointcollection = GetPoints(Points); poly.Paths.Add(pointcollection); } return poly; }
public static ESRI.ArcGIS.Client.Geometry.Polyline CreateGeoForZoom(ESRI.ArcGIS.Client.Geometry.Geometry mp) { ESRI.ArcGIS.Client.Geometry.MapPoint mp1 = new ESRI.ArcGIS.Client.Geometry.MapPoint() { X = (mp as ESRI.ArcGIS.Client.Geometry.MapPoint).X + 10000, Y = (mp as ESRI.ArcGIS.Client.Geometry.MapPoint).Y + 10000 }; ESRI.ArcGIS.Client.Geometry.MapPoint mp2 = new ESRI.ArcGIS.Client.Geometry.MapPoint() { X = (mp as ESRI.ArcGIS.Client.Geometry.MapPoint).X - 10000, Y = (mp as ESRI.ArcGIS.Client.Geometry.MapPoint).Y - 10000 }; System.Collections.ObjectModel.ObservableCollection<ESRI.ArcGIS.Client.Geometry.PointCollection> path = new System.Collections.ObjectModel.ObservableCollection<ESRI.ArcGIS.Client.Geometry.PointCollection>(); ESRI.ArcGIS.Client.Geometry.PointCollection plist = new ESRI.ArcGIS.Client.Geometry.PointCollection(); plist.Add(mp2 as ESRI.ArcGIS.Client.Geometry.MapPoint); plist.Add(mp1); path.Add(plist); ESRI.ArcGIS.Client.Geometry.Polyline pl = new ESRI.ArcGIS.Client.Geometry.Polyline { Paths = path }; return pl; }
public static ESRI.ArcGIS.Client.Geometry.Polyline FromIMSToPolyline(XElement item) { ESRI.ArcGIS.Client.Geometry.Polyline poly = new ESRI.ArcGIS.Client.Geometry.Polyline(); var Paths = from path in item.Element("POLYLINE").Descendants("PATH") select path; foreach (var path in Paths) { List <ImsPoints> Points = (from point in path.Descendants("POINT") select new ImsPoints { X = point.Attribute("x").Value, Y = point.Attribute("y").Value, }).ToList(); ESRI.ArcGIS.Client.Geometry.PointCollection pointcollection = GetPoints(Points); poly.Paths.Add(pointcollection); } return(poly); }
static public bool ConstructPointLineLineIntersection(ESRI.ArcGIS.Client.Geometry.Polyline line1, ESRI.ArcGIS.Client.Geometry.Polyline line2, out ESRI.ArcGIS.Client.Geometry.MapPoint intersectionPoint) { intersectionPoint = null; if ((line1 == null) || (line2 == null)) { return(false); } // Check if line is 2 point. if ((line1.Paths.Count == 0) || (line2.Paths.Count == 0)) { return(false); } // For now we are only going to look at the first segment. ESRI.ArcGIS.Client.Geometry.PointCollection pathPoints1 = line1.Paths.First(); ESRI.ArcGIS.Client.Geometry.PointCollection pathPoints2 = line2.Paths.First(); Int32 pathPoint1Count = pathPoints1.Count; Int32 pathPoint2Count = pathPoints2.Count; if ((pathPoint1Count < 1) || (pathPoint2Count < 1)) { return(false); } // Used the following http://en.wikipedia.org/wiki/Line-line_intersection ESRI.ArcGIS.Client.Geometry.MapPoint point1f = pathPoints1[0]; ESRI.ArcGIS.Client.Geometry.MapPoint point1t = pathPoints1[pathPoint1Count - 1]; ESRI.ArcGIS.Client.Geometry.MapPoint point2f = pathPoints2[0]; ESRI.ArcGIS.Client.Geometry.MapPoint point2t = pathPoints2[pathPoint2Count - 1]; double x1 = point1f.X; double y1 = point1f.Y; double x2 = point1t.X; double y2 = point1t.Y; double x3 = point2f.X; double y3 = point2f.Y; double x4 = point2t.X; double y4 = point2t.Y; double divider = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); double intersectX = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / divider; double intersectY = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / divider; // Now that we have intersection line, lay the source line horizontal (either would do) // and rotation intersection point on that. From this we can test if the line is within. // Shift coordinates to 0,0 double x2shift = x2 - x1; double y2shift = y2 - y1; double intersectXshift = intersectX - x1; double intersectYshift = intersectY - y1; double lineAngle = Math.Atan2(y2shift, x2shift); // Rotate the to point and the test point (clockwise) // x' = x.cos(angle) + y.sin(angle) // y' = y.cos(angle) - x.sin(angle) double cosAngle = Math.Cos(lineAngle); double sinAngle = Math.Sin(lineAngle); double rotX2 = x2shift * cosAngle + y2shift * sinAngle; // No need to compute the to point rotated y position. It will just be zero. // double rotY2 = y2shift * cosAngle - x2shift * sinAngle; double rotXIntersection = intersectXshift * cosAngle + intersectYshift * sinAngle; double rotYIntersection = intersectYshift * cosAngle - intersectXshift * sinAngle; double selfIntersectTolerance = 0.01; // don't allow an intersection result to select start/end points if ((rotXIntersection < selfIntersectTolerance) || (rotXIntersection > rotX2 - selfIntersectTolerance)) { return(false); } intersectionPoint = new ESRI.ArcGIS.Client.Geometry.MapPoint(intersectX, intersectY); return(true); }
private void ParcelMap_MouseMove(object sender, MouseEventArgs e) { if (ParcelLineInfoWindow.IsOpen == true && ParcelLineInfoWindow.Visibility == System.Windows.Visibility.Visible) { const double hideDistance = 25; double width = ParcelLineInfoWindow.ActualWidth; double height = ParcelLineInfoWindow.ActualHeight; var anchorScreenPoint = ParcelMap.MapToScreen(ParcelLineInfoWindow.Anchor); double x1 = anchorScreenPoint.X - width / 2 - hideDistance; double y1 = anchorScreenPoint.Y - height - hideDistance - 10; // -ve for info indicator double x2 = anchorScreenPoint.X + width / 2 + hideDistance; double y2 = anchorScreenPoint.Y + hideDistance; var envelope = new ESRI.ArcGIS.Client.Geometry.Envelope(x1, y1, x2, y2); Point pointLoc = e.GetPosition(this); if (!envelope.Intersects(new ESRI.ArcGIS.Client.Geometry.Envelope(pointLoc.X, pointLoc.Y, pointLoc.X, pointLoc.Y))) { ParcelLineInfoWindow.IsOpen = false; ParcelMap.Focus(); // Cause any non-committed cell in the popup window to lose its focus. This will commit the cell. } } if ((_srPoint == null) || !PDE_Tools.IsExpanded) { return; } ParcelData parcelData = ParcelGridContainer.DataContext as ParcelData; ESRI.ArcGIS.Client.Geometry.MapPoint currentPoint = ParcelMap.ScreenToMap(e.GetPosition(this)); if (RotationButton.IsChecked == true) { double rotation = GeometryUtil.Angle(_srPoint, currentPoint, _originPoint) + _oldRotation; while (rotation < -Math.PI) { rotation += Math.PI * 2; } while (rotation > Math.PI) { rotation -= Math.PI * 2; } parcelData.RotationValue = rotation; } else if (ScaleButton.IsChecked == true) { parcelData.ScaleValue = GeometryUtil.Scale(_srPoint, currentPoint, _originPoint) * _oldScale; } // If we have a snap point, adjust scale/rotation if we can snap point. if (_srSnapPointId != -1) { bool isRotating = RotationButton.IsChecked.GetValueOrDefault(false); bool isScaling = ScaleButton.IsChecked.GetValueOrDefault(false); double distanceToPoint = _srDistanceToPoint * parcelData.ScaleValue; double bearingToPoint = _srBearingToPoint - parcelData.RotationValue; if (bearingToPoint >= 2 * Math.PI) { bearingToPoint -= 2 * Math.PI; } ESRI.ArcGIS.Client.Geometry.MapPoint snapPointSR = GeometryUtil.ConstructPoint(_originPoint, bearingToPoint, distanceToPoint); if (snapPointSR != null) { ESRI.ArcGIS.Client.Geometry.Polyline snapLine; SnapPointToCacheObjects(snapPointSR, isScaling, out snapLine); // if scaling, skip zero distance so if (snapLine != null) // we don't snap to origin point. { bool ok = false; ESRI.ArcGIS.Client.Geometry.MapPoint intersectPoint = null; if (isRotating) { ok = GeometryUtil.ConstructPointLineCurveIntersection(snapLine, _originPoint, bearingToPoint, distanceToPoint, out intersectPoint); // distanceToPoint is radius here if (ok) // Only snap if the mouse location is within snap solution { ok = GeometryUtil.LineLength(intersectPoint, currentPoint) <= _xmlConfiguation.SnapTolerance; } if (ok) { parcelData.RotationValue = GeometryUtil.Angle(_srSnapPoint, intersectPoint, _originPoint); } } else if (isScaling) { ESRI.ArcGIS.Client.Geometry.MapPoint endPoint = GeometryUtil.ConstructPoint(_originPoint, bearingToPoint, distanceToPoint + _xmlConfiguation.SnapTolerance); ESRI.ArcGIS.Client.Geometry.Polyline sourceLine = GeometryUtil.Line(_originPoint, endPoint); ok = GeometryUtil.ConstructPointLineLineIntersection(snapLine, sourceLine, out intersectPoint); if (ok) // Only snap if the mouse location is within snap solution { ok = GeometryUtil.LineLength(intersectPoint, currentPoint) <= _xmlConfiguation.SnapTolerance; } if (ok) { double scale = GeometryUtil.Scale(_srSnapPoint, intersectPoint, _originPoint); if (scale > 0.0) { parcelData.ScaleValue = scale; } } } // Test code for debugging. // //GraphicsLayer testGraphicsLayer = ParcelMap.Layers["TestGraphicLayer"] as GraphicsLayer; //testGraphicsLayer.ClearGraphics(); //if (intersectPoint != null) //{ // ESRI.ArcGIS.Client.Graphic graphic = new ESRI.ArcGIS.Client.Graphic() // { // Geometry = intersectPoint, // Symbol = LayoutRoot.Resources["TestMarkerSymbol"] as ESRI.ArcGIS.Client.Symbols.Symbol // }; // testGraphicsLayer.Graphics.Add(graphic); //} } } } // Only redraw if there have been an update; // Otherwise runtime does not process mouse up and over flashes. if ((parcelData.ScaleValue != _moveScale) || (parcelData.RotationValue != _moveRotation)) { CalculateAndAddLineGraphics(); _moveScale = parcelData.ScaleValue; _moveRotation = parcelData.RotationValue; } }
private void ScaleRotate(Point srcPoint) { if (!PDE_Tools.IsExpanded) { return; } ParcelData parcelData = ParcelGridContainer.DataContext as ParcelData; _moveScale = _oldScale = parcelData.ScaleValue; _moveRotation = _oldRotation = parcelData.RotationValue; _srPoint = ParcelMap.ScreenToMap(srcPoint); _srSnapPoint = null; double spX = _srPoint.X; double spY = _srPoint.Y; // Find _startPoint in list of points. If "close" snap to that point. // Otherwise user can free form scale or rotate parcel lines. double shortestDistance = double.MaxValue; Int32 shortestId = -1; ESRI.ArcGIS.Client.Geometry.MapPoint foundPoint = null; foreach (KeyValuePair <Int32, ESRI.ArcGIS.Client.Geometry.MapPoint> kvp in _calculatedPoints) { double x = kvp.Value.X; double y = kvp.Value.Y; double distance = GeometryUtil.LineLength(spX, spY, x, y); if ((distance < shortestDistance) && (distance < _xmlConfiguation.SnapTolerance)) { shortestDistance = distance; shortestId = kvp.Key; foundPoint = new ESRI.ArcGIS.Client.Geometry.MapPoint(x, y); } } if (BearingDistanceToPoint(shortestId, out _srBearingToPoint, out _srDistanceToPoint, out _srSnapPoint)) { // BearingDistanceToPoint will fail if shortestId == -1 _srSnapPointId = shortestId; if (RotationButton.IsChecked == true) { double radialSearch = _srDistanceToPoint * parcelData.ScaleValue; // We seem to be getting some numerical precision error when rotating... this does not // really matter here; we only need to re-buffer if the changes are > 0.1. // if the user re-rotate with the same rotate point, try to avoid re-caching. if ((_originPoint == null) || (_lastGeometryCP == null) || (Math.Abs(_lastSearchDistance - radialSearch) > 0.1) || !_lastBufferBasedOnCurve || (_lastGeometryCP.X != _originPoint.X) || (_lastGeometryCP.Y != _originPoint.Y)) { ESRI.ArcGIS.Client.Geometry.MapPoint offsetOriginPoint = new ESRI.ArcGIS.Client.Geometry.MapPoint(_originPoint.X - radialSearch, _originPoint.Y); // Create a geometry circle from the anchor/rotating point to the snap point. // We will create create a cache of all these points within the buffer distance // of this circle. ESRI.ArcGIS.Client.Geometry.MapPoint endPoint; ESRI.ArcGIS.Client.Geometry.Polyline circle = GeometryUtil.ConstructArcSegment(offsetOriginPoint, 0.0, 0.001, radialSearch, false, SweepDirection.Counterclockwise, out endPoint); _lastGeometryCP = _originPoint; _lastSearchDistance = radialSearch; _lastBufferBasedOnCurve = true; CacheSnapObjects(circle, radialSearch); } } else if (ScaleButton.IsChecked == true) { double mapDistanceBuffer = _srDistanceToPoint * 1.5 * parcelData.ScaleValue; // if the user re-scales with the same scale point, try to avoid re-caching. if ((_originPoint == null) || (_lastGeometryCP == null) || (_lastSearchDistance < mapDistanceBuffer) || _lastBufferBasedOnCurve || (_lastGeometryCP.X != _originPoint.X) || (_lastGeometryCP.Y != _originPoint.Y)) { // Create a line from the anchor/rotating point to the snap point * 1.5 of the distance. // We will create create a cache of all these points within the buffer distance // of this line. ESRI.ArcGIS.Client.Geometry.MapPoint endPoint; ESRI.ArcGIS.Client.Geometry.Polyline snapLine = GeometryUtil.Line(_originPoint, _srBearingToPoint - parcelData.RotationValue, mapDistanceBuffer, out endPoint); if (snapLine != null) { _lastGeometryCP = _originPoint; _lastSearchDistance = mapDistanceBuffer; _lastBufferBasedOnCurve = false; CacheSnapObjects(snapLine, mapDistanceBuffer); } } } // else no snapping. CalculateAndAddLineGraphics(); // Redraw so we have snap graphic shown } else // BearingDistanceToPoint returns false if id = -1 { _srSnapPointId = -1; } }
/// <summary> /// Check rectangle intersects with geometry. /// </summary> /// <param name="frame">Rectangle.</param> /// <param name="geometry">Geometry to check.</param> /// <returns>True if intersects</returns> public static bool IsIntersects(ESRI.ArcGIS.Client.Geometry.Envelope frame, ESRI.ArcGIS.Client.Geometry.Geometry geometry) { bool isIntersects = false; if (geometry is ESRI.ArcGIS.Client.Geometry.MapPoint) { ESRI.ArcGIS.Client.Geometry.MapPoint point = (ESRI.ArcGIS.Client.Geometry.MapPoint)geometry; if (frame.Extent.Intersects(point.Extent)) { isIntersects = true; } } else if (geometry is ESRI.ArcGIS.Client.Geometry.Polyline) { ESRI.ArcGIS.Client.Geometry.Polyline polyline = (ESRI.ArcGIS.Client.Geometry.Polyline)geometry; if (frame.Extent.Intersects(polyline.Extent)) { foreach (ESRI.ArcGIS.Client.Geometry.PointCollection points in polyline.Paths) { ESRI.ArcGIS.Client.Geometry.MapPoint prevPoint = null; foreach (ESRI.ArcGIS.Client.Geometry.MapPoint point in points) { if (prevPoint != null) { if (_IsSegmentIntersectRectangle(frame.XMin, frame.YMin, frame.XMax, frame.YMax, point.X, point.Y, prevPoint.X, prevPoint.Y)) { isIntersects = true; break; } } prevPoint = point; } if (isIntersects) { break; } } } } else if (geometry is ESRI.ArcGIS.Client.Geometry.Polygon) { ESRI.ArcGIS.Client.Geometry.Polygon polygon = (ESRI.ArcGIS.Client.Geometry.Polygon)geometry; if (frame.Extent.Intersects(polygon.Extent)) { foreach (ESRI.ArcGIS.Client.Geometry.PointCollection points in polygon.Rings) { ESRI.ArcGIS.Client.Geometry.MapPoint prevPoint = null; foreach (ESRI.ArcGIS.Client.Geometry.MapPoint point in points) { if (prevPoint != null) { if (_IsSegmentIntersectRectangle(frame.XMin, frame.YMin, frame.XMax, frame.YMax, point.X, point.Y, prevPoint.X, prevPoint.Y)) { isIntersects = true; break; } } prevPoint = point; } if (isIntersects) { break; } } } } else { Debug.Assert(false); } return(isIntersects); }
// *********************************************************************************** // * Add a from location point on the map... closest facility will be found for this location // *********************************************************************************** void SolveClosestFacility_Completed(object sender, RouteEventArgs e) { _routesGraphicsLayer.Graphics.Clear(); _routeLabelsGraphicsLayer.Graphics.Clear(); if (e.RouteResults != null) { int i = 0; Random randomGen = new Random(); foreach (RouteResult route in e.RouteResults) { Graphic routeGraphic = route.Route; Color color = createRandomColor(randomGen); randomGen.Next(255); routeGraphic.Symbol = new SimpleLineSymbol() { Width = 5, Color = new SolidColorBrush(color) }; _routesGraphicsLayer.Graphics.Add(routeGraphic); //Route rank identification symbols... client.Geometry.Polyline pl = (client.Geometry.Polyline)routeGraphic.Geometry; int index = pl.Paths[0].Count / 4; Graphic squareGraphic = new Graphic(); client.Geometry.PointCollection ptColl = pl.Paths[pl.Paths.Count / 2]; squareGraphic.Geometry = ptColl[ptColl.Count / 2]; //this is the white outline... SimpleMarkerSymbol sms = new SimpleMarkerSymbol() { Style = SimpleMarkerSymbol.SimpleMarkerStyle.Square, Size = 24, Color = new SolidColorBrush(Color.FromRgb(255, 255, 255)), }; squareGraphic.Symbol = sms; _routeLabelsGraphicsLayer.Graphics.Add(squareGraphic); //purple rectangle behind the rank number Graphic squareGraphic2 = new Graphic(); SimpleMarkerSymbol sms2 = new SimpleMarkerSymbol() { Style = SimpleMarkerSymbol.SimpleMarkerStyle.Square, Size = 20, Color = new SolidColorBrush(Color.FromRgb(0, 0, 139)) }; squareGraphic2.Symbol = sms2; squareGraphic2.Geometry = ptColl[ptColl.Count / 2]; _routeLabelsGraphicsLayer.Graphics.Add(squareGraphic2); //rank number text symbol Graphic routeRankGraphic = new Graphic(); routeRankGraphic.Geometry = ptColl[ptColl.Count / 2]; TextSymbol routeRankSymbol = new TextSymbol(); routeRankSymbol.FontFamily = new FontFamily("Arial Black"); //Modified offsetx from -4 to 5 routeRankSymbol.OffsetX = 5; routeRankSymbol.OffsetY = 10; routeRankSymbol.Text = e.RouteResults[i].Directions.RouteID.ToString(); routeRankSymbol.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255)); routeRankSymbol.FontSize = 16; routeRankGraphic.Symbol = routeRankSymbol; _routeLabelsGraphicsLayer.Graphics.Add(routeRankGraphic); i++; } //zoom to the map if (chkZoomToMap.IsChecked ?? false) { _mapWidget.Map.Extent = _routesGraphicsLayer.FullExtent; } //Create and Display Closest Facilities List window... _result = new FindCloseFacilityResultView(this, e.RouteResults, _mapWidget); _mapWidget.SetToolbar(_result); } }
public static ESRI.ArcGIS.Client.Geometry.Polyline Line(ESRI.ArcGIS.Client.Geometry.MapPoint startPoint, double bearing, double distance, out ESRI.ArcGIS.Client.Geometry.MapPoint endPoint) { endPoint = null; if (distance == 0) return null; endPoint = ConstructPoint(startPoint, bearing, distance); ESRI.ArcGIS.Client.Geometry.PointCollection pointCollection = new ESRI.ArcGIS.Client.Geometry.PointCollection(); pointCollection.Add(startPoint); pointCollection.Add(endPoint); ESRI.ArcGIS.Client.Geometry.Polyline polyline = new ESRI.ArcGIS.Client.Geometry.Polyline(); polyline.Paths.Add(pointCollection); return polyline; }
public static ESRI.ArcGIS.Client.Geometry.Polyline Line(ESRI.ArcGIS.Client.Geometry.MapPoint startPoint, ESRI.ArcGIS.Client.Geometry.MapPoint endPoint) { ESRI.ArcGIS.Client.Geometry.PointCollection pointCollection = new ESRI.ArcGIS.Client.Geometry.PointCollection(); pointCollection.Add(startPoint); pointCollection.Add(endPoint); ESRI.ArcGIS.Client.Geometry.Polyline polyline = new ESRI.ArcGIS.Client.Geometry.Polyline(); polyline.Paths.Add(pointCollection); return polyline; }
// Create an ESRI polyline based on a densified representation of WPFs ArcSegment public static ESRI.ArcGIS.Client.Geometry.Polyline ConstructArcSegment(ESRI.ArcGIS.Client.Geometry.MapPoint startPoint, ESRI.ArcGIS.Client.Geometry.MapPoint endPoint, double radius, bool isMinor, SweepDirection direction) { if (endPoint == null) return null; // WPF ArcSegment has issue with high coordinates values. // Bring coordinates down to 0,0 and translate back to real world later. double startX = startPoint.X; double startY = startPoint.Y; double absRadius = Math.Abs(radius); // We need to switch the curve direction, b/c we are starting with the end point if (radius > 0) direction = direction == SweepDirection.Clockwise ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; Size radiusAspect = new Size(absRadius, absRadius); Point myEndPoint = new Point(endPoint.X - startX, endPoint.Y - startY); bool isLargeArc = !isMinor; ArcSegment wpfArcSegment = new ArcSegment(myEndPoint, radiusAspect, 0, isLargeArc, direction, false); // compose one or more segments into a collection var pathcoll = new PathSegmentCollection(); pathcoll.Add(wpfArcSegment); // create a figure based on the set of segments var pathFigure = new PathFigure(); pathFigure.Segments = pathcoll; pathFigure.IsClosed = false; // compose a collection of figures var figureCollection = new PathFigureCollection(); figureCollection.Add(pathFigure); // create a path-geometry using the figures collection var geometryPath = new PathGeometry(figureCollection); ESRI.ArcGIS.Client.Geometry.PointCollection pointCollection = new ESRI.ArcGIS.Client.Geometry.PointCollection(); double numSegments = 1.0 / 50; // Default 50 Point point, tangent; Point pointA, pointB; geometryPath.GetPointAtFractionLength(0, out pointA, out tangent); geometryPath.GetPointAtFractionLength(numSegments, out pointB, out tangent); double partDistance = LineLength(pointA.X, pointA.Y, pointB.X, pointB.Y); if (partDistance > 1.0) numSegments /= partDistance; if (1 / numSegments > 160) // cap it at 160 vertexes numSegments = 1.0 / 160; // Server is having issue with 185+ vertexes (180 seems ok) for (double fraction = 0.0; fraction < 1.0; fraction += numSegments) { geometryPath.GetPointAtFractionLength(fraction, out point, out tangent); pointCollection.Add(new ESRI.ArcGIS.Client.Geometry.MapPoint(point.X + startX, point.Y + startY)); } pointCollection.Add(endPoint); // faction 1 can be skipped, so add it here. ESRI.ArcGIS.Client.Geometry.Polyline polyline = new ESRI.ArcGIS.Client.Geometry.Polyline(); polyline.Paths.Add(pointCollection); return polyline; }
/// <summary> /// Convert from ArcLogistics polyline to ArcGIS polyline. /// </summary> /// <param name="sourcePolyline">ArcLogistics polyline</param> /// <param name="spatialReferenceID">Map spatial reference.</param> /// <returns>ArcGIS polyline.</returns> internal static ESRI.ArcGIS.Client.Geometry.Geometry ConvertToArcGISPolyline(Polyline sourcePolyline, int? spatialReferenceID) { ESRI.ArcGIS.Client.Geometry.Polyline resultPolyline = new ESRI.ArcGIS.Client.Geometry.Polyline(); // Project polyline from WGS84 to Web Mercator if spatial reference of map is Web Mercator. if (spatialReferenceID != null) // REV: comapre with specific Web Mercator WKID, instead of null. { sourcePolyline = WebMercatorUtil.ProjectPolylineToWebMercator(sourcePolyline, spatialReferenceID.Value); } int[] groups = sourcePolyline.Groups; for (int groupIndex = 0; groupIndex < groups.Length; ++groupIndex) { ESRI.ArcLogistics.Geometry.Point[] points = sourcePolyline.GetGroupPoints(groupIndex); ESRI.ArcGIS.Client.Geometry.PointCollection pointsCollection = new ESRI.ArcGIS.Client.Geometry.PointCollection(); for (int index = 0; index < points.Length; index++) { ESRI.ArcGIS.Client.Geometry.MapPoint mapPoint = new ESRI.ArcGIS.Client.Geometry.MapPoint( points[index].X, points[index].Y); pointsCollection.Add(mapPoint); } resultPolyline.Paths.Add(pointsCollection); } return resultPolyline; }
static public bool ConstructPointLineCurveIntersection(ESRI.ArcGIS.Client.Geometry.Polyline srcLine, ESRI.ArcGIS.Client.Geometry.MapPoint centerPoint, double bearing, double radius, out ESRI.ArcGIS.Client.Geometry.MapPoint intersectPoint) { // Given a straight line geometry and a point, find the intersection point. // If the line was purely in the x direction, this would be a trivial task: // i) If the x ordinate of the point is with the x range of the line a perpendicular can be drawn // ii) If i) is true, the distance is just the difference in the y values of the line and the point. // iii) Using a triangle (perpendicular distance, radius and angle) we can calculate point along line // For any general line orientation and point location, we can make it look like the simple case // above by: // i) Translating the point and line such that the 'from' end of the line is at the origin // ii) Rotating the point and line about the origin so that the line is indeed purely in the // x direction. // iii) Check the x ordinate of the point against the line's xMin and xMax. // iv) The magnitude of the point's y value is the distance. intersectPoint = null; if ((srcLine == null) || (centerPoint == null)) { return(false); } // Check if line is 2 point. if (srcLine.Paths.Count == 0) { return(false); } // For now we are only going to look at the first segment. ESRI.ArcGIS.Client.Geometry.PointCollection pathPoints = srcLine.Paths.First(); Int32 pointCount = pathPoints.Count; if (pointCount < 1) { return(false); } double srcAngle = Math.PI / 2 - bearing; ESRI.ArcGIS.Client.Geometry.MapPoint endPoint = ConstructPoint(centerPoint, bearing, radius); double endPointX = endPoint.X; double endPointY = endPoint.Y; double centerPointX = centerPoint.X; double centerPointY = centerPoint.Y; ESRI.ArcGIS.Client.Geometry.MapPoint fromPoint = pathPoints[0]; ESRI.ArcGIS.Client.Geometry.MapPoint toPoint = pathPoints[pointCount - 1]; if ((fromPoint == null) || (toPoint == null)) { return(false); } double fromX = fromPoint.X; double fromY = fromPoint.Y; double toX = toPoint.X; double toY = toPoint.Y; // Translate the coordinates to place the from point at the origin. endPointX -= fromX; endPointY -= fromY; centerPointX -= fromX; centerPointY -= fromY; toX -= fromX; toY -= fromY; if ((toX == 0.0) && (toY == 0.0)) { return(false); } double lineAngle = Math.Atan2(toY, toX); // Rotate the to point and the test point (clockwise) // (not require, since we have rotated the line flat) // x' = x.cos(angle) + y.sin(angle) // y' = y.cos(angle) - x.sin(angle) double cosAngle = Math.Cos(lineAngle); double sinAngle = Math.Sin(lineAngle); double rotToX = toX * cosAngle + toY * sinAngle; // No need to compute the to point rotated y position. It will just be zero. // double rotToY = toY * cosAngle - toX * sinAngle; double rotEndPointX = endPointX * cosAngle + endPointY * sinAngle; // Check whether the point is with the bounds of the line if ((rotEndPointX <= 0.0) || (rotEndPointX >= rotToX)) { return(false); } double rotEndPointY = endPointY * cosAngle - endPointX * sinAngle; double endPointPerpendicularDistance = Math.Abs(rotEndPointY); double rotCenterPointX = centerPointX * cosAngle + centerPointY * sinAngle; // Check whether the point is with the bounds of the line double rotCenterPointY = centerPointY * cosAngle - centerPointX * sinAngle; double centerPointPerpendicularDistance = Math.Abs(rotCenterPointY); // _____ // Get distance b/t rotCenterPointY and arc intersection point: k = √r²-d² double k = Math.Sqrt(Math.Pow(radius, 2) - Math.Pow(centerPointPerpendicularDistance, 2)); // For the first quadrant we have a good solution. The others we need to decide which // way to go on the line, and which origin point to use. The simplest solution is to // calculate both solutions and choose the closest. // // Use the following matrix to rotate solution point back counterclockwise. // x' = x.cos(angle) + y.sin(angle) // y' = -y.cos(angle) + x.sin(angle) // // y=0 since the line is horizontal. // rotBackIntersectionPointX = intersectionDistance * cosAngle + 0 * sinAngle; // rotBackIntersectionPointY = -0 * cosAngle + intersectionDistance * sinAngle; // // To complete the solution, add the original offset (fromX, fromY) // Intersection point (solution 1) double intersectionDistance = rotCenterPointX + k; ESRI.ArcGIS.Client.Geometry.MapPoint intersectPoint1 = null; if ((intersectionDistance >= 0) || (intersectionDistance <= rotToX)) { double rotBackIntersectionPointX = intersectionDistance * cosAngle + fromX; double rotBackIntersectionPointY = intersectionDistance * sinAngle + fromY; intersectPoint1 = new ESRI.ArcGIS.Client.Geometry.MapPoint(rotBackIntersectionPointX, rotBackIntersectionPointY); } // Intersection point (solution 2) intersectionDistance = rotCenterPointX - k; ESRI.ArcGIS.Client.Geometry.MapPoint intersectPoint2 = null; if ((intersectionDistance >= 0) || (intersectionDistance <= rotToX)) { double rotBackIntersectionPointX = intersectionDistance * cosAngle + fromX; double rotBackIntersectionPointY = intersectionDistance * sinAngle + fromY; intersectPoint2 = new ESRI.ArcGIS.Client.Geometry.MapPoint(rotBackIntersectionPointX, rotBackIntersectionPointY); } // Choose the solution that's closest to our source point. if ((intersectPoint1 != null) && (intersectPoint2 == null)) { intersectPoint = intersectPoint1; } else if ((intersectPoint1 == null) && (intersectPoint2 != null)) { intersectPoint = intersectPoint2; } else if ((intersectPoint1 != null) && (intersectPoint2 != null)) { double distance1 = LineLength(intersectPoint1, endPoint); double distance2 = LineLength(intersectPoint2, endPoint); if (distance1 <= distance2) { intersectPoint = intersectPoint1; // if equal, this will also be the solution (quadrant 1) } else { intersectPoint = intersectPoint2; } } else { return(false); } return(true); }
static public bool FindPerpendicularDistance(ESRI.ArcGIS.Client.Geometry.Polyline srcLine, ESRI.ArcGIS.Client.Geometry.MapPoint srcPoint, out double perpendicularDistance) { // Given a straight line geometry and a point, check whether a perpendicular can be drawn // from the line to the point and if so, calculate the distance. // If the line was purely in the x direction, this would be a trivial task: // i) If the x ordinate of the point is with the x range of the line a perpendicular can be drawn // ii) If i) is true, the distance is just the difference in the y values of the line and the point. // For any general line orientation and point location, we can make it look like the simple case // above by: // i) Translating the point and line such that the 'from' end of the line is at the origin // ii) Rotating the point and line about the origin so that the line is indeed purely in the // x direction. // iii) Check the x ordinate of the point against the line's xMin and xMax. // iv) The magnitude of the point's y value is the distance. perpendicularDistance = -1.0; if ((srcLine == null) || (srcPoint == null)) { return(false); } // Check if line is 2 point. if (srcLine.Paths.Count == 0) { return(false); } // For now we are only going to look at the first segment. ESRI.ArcGIS.Client.Geometry.PointCollection pathPoints = srcLine.Paths.First(); Int32 pointCount = pathPoints.Count; if (pointCount < 1) { return(false); } double pointX = srcPoint.X; double pointY = srcPoint.Y; ESRI.ArcGIS.Client.Geometry.MapPoint fromPoint = pathPoints[0]; ESRI.ArcGIS.Client.Geometry.MapPoint toPoint = pathPoints[pointCount - 1]; if ((fromPoint == null) || (toPoint == null)) { return(false); } double fromX = fromPoint.X; double fromY = fromPoint.Y; double toX = toPoint.X; double toY = toPoint.Y; // Translate the coordinates to place the from point at the origin. pointX -= fromX; pointY -= fromY; toX -= fromX; toY -= fromY; if ((toX == 0.0) && (toY == 0.0)) { return(false); } double angle = Math.Atan2(toY, toX); // Rotate the to point and the test point // (not require, since we have rotated the line flat) // // x' = x cos(angle) + y sin(angle) // y' = y cos(angle) - x sin(angle) double cosAngle = Math.Cos(angle); double sinAngle = Math.Sin(angle); double rotToX = toX * cosAngle + toY * sinAngle; // No need to compute the to point rotated y position // It will just be zero. // double rotToY = toY * cosAngle - toX * sinAngle; double rotPointX = pointX * cosAngle + pointY * sinAngle; // Check whether the point is with the bounds of the line if ((rotPointX < 0.0) || (rotPointX > rotToX)) { return(false); } double rotPointY = pointY * cosAngle - pointX * sinAngle; if (rotPointY < 0) { perpendicularDistance = -1.0 * rotPointY; } else { perpendicularDistance = rotPointY; } return(true); }
// Create an ESRI polyline based on a densified representation of WPFs ArcSegment static public ESRI.ArcGIS.Client.Geometry.Polyline ConstructArcSegment(ESRI.ArcGIS.Client.Geometry.MapPoint startPoint, ESRI.ArcGIS.Client.Geometry.MapPoint endPoint, double radius, bool isMinor, SweepDirection direction) { if (endPoint == null) { return(null); } // WPF ArcSegment has issue with high coordinates values. // Bring coordinates down to 0,0 and translate back to real world later. double startX = startPoint.X; double startY = startPoint.Y; double absRadius = Math.Abs(radius); // We need to switch the curve direction, b/c we are starting with the end point if (radius > 0) { direction = direction == SweepDirection.Clockwise ? SweepDirection.Counterclockwise : SweepDirection.Clockwise; } Size radiusAspect = new Size(absRadius, absRadius); Point myEndPoint = new Point(endPoint.X - startX, endPoint.Y - startY); bool isLargeArc = !isMinor; ArcSegment wpfArcSegment = new ArcSegment(myEndPoint, radiusAspect, 0, isLargeArc, direction, false); // compose one or more segments into a collection var pathcoll = new PathSegmentCollection(); pathcoll.Add(wpfArcSegment); // create a figure based on the set of segments var pathFigure = new PathFigure(); pathFigure.Segments = pathcoll; pathFigure.IsClosed = false; // compose a collection of figures var figureCollection = new PathFigureCollection(); figureCollection.Add(pathFigure); // create a path-geometry using the figures collection var geometryPath = new PathGeometry(figureCollection); ESRI.ArcGIS.Client.Geometry.PointCollection pointCollection = new ESRI.ArcGIS.Client.Geometry.PointCollection(); double numSegments = 1.0 / 50; // Default 50 Point point, tangent; Point pointA, pointB; geometryPath.GetPointAtFractionLength(0, out pointA, out tangent); geometryPath.GetPointAtFractionLength(numSegments, out pointB, out tangent); double partDistance = LineLength(pointA.X, pointA.Y, pointB.X, pointB.Y); if (partDistance > 1.0) { numSegments /= partDistance; } if (1 / numSegments > 160) // cap it at 160 vertexes { numSegments = 1.0 / 160; // Server is having issue with 185+ vertexes (180 seems ok) } for (double fraction = 0.0; fraction < 1.0; fraction += numSegments) { geometryPath.GetPointAtFractionLength(fraction, out point, out tangent); pointCollection.Add(new ESRI.ArcGIS.Client.Geometry.MapPoint(point.X + startX, point.Y + startY)); } pointCollection.Add(endPoint); // faction 1 can be skipped, so add it here. ESRI.ArcGIS.Client.Geometry.Polyline polyline = new ESRI.ArcGIS.Client.Geometry.Polyline(); polyline.Paths.Add(pointCollection); return(polyline); }