Esempio n. 1
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;
            }
        }