Example #1
0
        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);
        }
Example #2
0
        /// <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);
        }
Example #3
0
        //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);
        }
Example #5
0
        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
        }
Example #7
0
        //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);
        }
Example #11
0
        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);
        }
Example #13
0
        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;
        }
Example #15
0
 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;
 }
Example #16
0
        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);
        }
Example #17
0
        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);
        }
Example #18
0
        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;
            }
        }
Example #19
0
        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;
            }
        }
Example #20
0
        /// <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);
            }
        }
Example #22
0
        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;
        }
Example #23
0
        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;
        }
Example #24
0
        // 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;
        }
Example #25
0
        /// <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;
        }
Example #26
0
        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);
        }
Example #27
0
        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);
        }
Example #28
0
        // 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);
        }