public override void OnMouseDown(ICoordinate worldPosition, MouseEventArgs e)
        {
            if (VectorLayer == null)
            {
                return;
            }

            if (e.Button != MouseButtons.Left)
            {
                return;
            }
            isBusy = true;
            StartDrawing();
            newNetworkFeature = GeometryFactory.CreatePoint(worldPosition);
            ((DataTableFeatureProvider)newNetworkFeatureLayer.DataSource).Clear();
            newNetworkFeatureLayer.DataSource.Add(newNetworkFeature);

            snapResult = MapControl.SnapTool.ExecuteLayerSnapRules(VectorLayer, null, newNetworkFeature, worldPosition, -1); //TODO check: why is this commented out in trunk?
            if (snapResult != null)
            {
                newNetworkFeature.Coordinates[0].X = snapResult.Location.X;
                newNetworkFeature.Coordinates[0].Y = snapResult.Location.Y;
            }

            newNetworkFeatureLayer.Style = MapControl.SnapTool.Failed ? errorNetworkFeatureStyle : networkFeatureStyle;
        }
Beispiel #2
0
        public virtual bool MoveTracker(TrackerFeature trackerFeature, double deltaX, double deltaY,
                                        SnapResult snapResult = null)
        {
            if (trackerFeature.Index == -1)
            {
                throw new ArgumentException("Can not find tracker; can not move.");
            }

            var handles = SelectedTrackerIndices.ToList();

            if (handles.Count == 0)
            {
                return false;
                    // Do not throw exception, can occur in special cases when moving with CTRL toggle selection
            }

            if (FallOffPolicy != null)
            {
                FallOffPolicy.Move(TargetFeature.Geometry, trackers.Select(t => t.Geometry).ToList(), handles,
                                   trackerFeature.Index, deltaX, deltaY);
            }
            else
            {
                GeometryHelper.MoveCoordinate(TargetFeature.Geometry, trackerFeature.Index, deltaX, deltaY);
                TargetFeature.Geometry = TargetFeature.Geometry; // fire event

                GeometryHelper.MoveCoordinate(trackerFeature.Geometry, 0, deltaX, deltaY);
                trackerFeature.Geometry = trackerFeature.Geometry; // fire event
            }

            foreach (var topologyRule in FeatureRelationEditors)
            {
                topologyRule.UpdateRelatedFeatures(SourceFeature, TargetFeature.Geometry, handles);
            }

            return true;
        }
Beispiel #3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sourceFeature"></param>
        /// <param name="sourceGeometry"></param>
        /// <param name="snapTargets"></param>
        /// <param name="worldPos"></param>
        /// <param name="envelope"></param>
        /// <param name="trackingIndex"></param>
        /// based of the selected tracker in the snapSource the rule can behave differently
        /// (only snap branches' first and last coordinate).
        /// <returns></returns>
        public virtual SnapResult Execute(IFeature sourceFeature, IFeature[] snapCandidates, ILayer[] snapLayers, IGeometry sourceGeometry, IList<IFeature> snapTargets, ICoordinate worldPos, IEnvelope envelope, int trackingIndex)
        {
            // hack preserve snapTargets functionality
            IList<IGeometry> snapTargetGeometries = new List<IGeometry>();
            if (null != snapTargets)
            {
                for (int i = 0; i < snapTargets.Count; i++)
                {
                    snapTargetGeometries.Add(snapTargets[i].Geometry);
                }
            }
            
            double minDistance = double.MaxValue; // TODO: incapsulate minDistance in ISnapResult
            SnapResult snapResult = null;

            if(snapCandidates == null || snapLayers == null)
            {
                return snapResult;
            }

            for (int i = 0; i < snapCandidates.Length; i++)
            {
                var feature = snapCandidates[i];
                var layer = snapLayers[i];

                if(Criteria != null && !Criteria(layer, feature))
                {
                    continue;
                };

                IGeometry geometry = feature.Geometry;
                if ((null != snapTargets) && (snapTargetGeometries.IndexOf(geometry) == -1))
                    continue;
                if (SnapRole == SnapRole.None) 
                    continue;
                if (geometry is IPolygon)
                {
                    IPolygon polygon = (IPolygon)geometry;
                    switch (SnapRole)
                    {
                        case SnapRole.Free:
                            PolygonSnapFree(ref minDistance, ref snapResult, polygon, worldPos);
                            break;
                        case SnapRole.AllTrackers:
                            GeometrySnapAllTrackers(ref minDistance, ref snapResult, polygon, worldPos);
                            break;
                        default:
                            //case SnapRole.FreeAtObject:
                            PolygonSnapFreeAtObject(ref minDistance, ref snapResult, polygon, worldPos);
                            break;
                    }
                }
                if (geometry is ILineString)
                {
                    ILineString lineString = (ILineString)geometry;

                    switch (SnapRole)
                    {
                        case SnapRole.Free:
                            LineStringSnapFree(ref minDistance, ref snapResult, lineString, worldPos);
                            break;
                        case SnapRole.FreeAtObject:
                            LineStringSnapFreeAtObject(ref minDistance, ref snapResult, feature, lineString, worldPos);
                            break;
                        case SnapRole.TrackersNoStartNoEnd:
                            break;
                        case SnapRole.AllTrackers:
                            LineStringSnapAllTrackers(ref minDistance, ref snapResult, lineString, worldPos);
                            break;
                        case SnapRole.Start:
                            LineStringSnapStart(ref snapResult, lineString);
                            break;
                        case SnapRole.End:
                            LineStringSnapEnd(ref snapResult, lineString);
                            break;
                        case SnapRole.StartEnd:
                            LineStringSnapStartEnd(ref minDistance, ref snapResult, lineString, worldPos);
                            break;
                    }
                }
                else if (geometry is IPoint)
                {
                    snapResult = new SnapResult(geometry.Coordinates[0], null, NewFeatureLayer, geometry, 0, 0) { Rule = this };
                }

                snapResult.NewFeatureLayer = NewFeatureLayer;
            } // foreach (IGeometry geometry in snapCandidates)


            return snapResult;
        }
Beispiel #4
0
 public void PolygonSnapFree(ref double minDistance, ref SnapResult snapResult, IPolygon polygon, ICoordinate worldPos)
 {
     for (int i = 1; i < polygon.Coordinates.Length; i++)
     {
         ICoordinate c1 = polygon.Coordinates[i - 1];
         ICoordinate c2 = polygon.Coordinates[i];
         double distance = GeometryHelper.LinePointDistance(c1.X, c1.Y, c2.X, c2.Y, worldPos.X, worldPos.Y);
         if (distance >= minDistance)
             continue;
         minDistance = distance;
         snapResult = new SnapResult(GeometryFactory.CreateCoordinate(worldPos.X, worldPos.Y), null, null, polygon,
                                     i - 1, i) { Rule = this };
     }
 }
Beispiel #5
0
        public void LineStringSnapFreeAtObject(ref double minDistance, ref SnapResult snapResult, IFeature feature, ILineString lineString, ICoordinate worldPos)
        {
            int vertexIndex;
            var nearestPoint = GeometryHelper.GetNearestPointAtLine(lineString, worldPos, minDistance, out vertexIndex);

            if (nearestPoint == null)
            {
                return;
            }

            minDistance = GeometryHelper.Distance(nearestPoint.X, nearestPoint.Y, worldPos.X, worldPos.Y);
            snapResult = new SnapResult(nearestPoint, feature, null, lineString, vertexIndex - 1, vertexIndex) { Rule = this };
        }
Beispiel #6
0
 private void GeometrySnapAllTrackers(ref double minDistance, ref SnapResult snapResult, IGeometry geometry,
                                         ICoordinate worldPos)
 {
     var coordinates = geometry.Coordinates;
     for (int i = 0; i < coordinates.Length; i++)
     {
         ICoordinate c1 = coordinates[i];
         double distance = GeometryHelper.Distance(c1.X, c1.Y, worldPos.X, worldPos.Y);
         if (distance >= minDistance)
             continue;
         minDistance = distance;
         snapResult = new SnapResult(coordinates[i], null, null, geometry, i, i) {Rule = this};
     }
 }
Beispiel #7
0
 public void LineStringSnapAllTrackers(ref double minDistance, ref SnapResult snapResult, ILineString lineString, ICoordinate worldPos)
 {
     GeometrySnapAllTrackers(ref minDistance, ref snapResult, lineString, worldPos);
 }
Beispiel #8
0
 public void LineStringSnapStart(ref SnapResult snapResult, ILineString lineString)
 {
     snapResult = new SnapResult(lineString.Coordinates[0], null, null, lineString, 0, 0) { Rule = this };
 }
Beispiel #9
0
 public void LineStringSnapEnd(ref SnapResult snapResult, ILineString lineString)
 {
     snapResult = new SnapResult(lineString.Coordinates[lineString.Coordinates.Length - 1], null, null, lineString,
                           lineString.Coordinates.Length - 1, lineString.Coordinates.Length - 1) { Rule = this };
 }
Beispiel #10
0
 public void LineStringSnapStartEnd(ref double minDistance, ref SnapResult snapResult, ILineString lineString, ICoordinate worldPos)
 {
     ICoordinate c1 = lineString.Coordinates[0];
     ICoordinate location;
     int snapIndexPrevious;
     int snapIndexNext;
     double distance = GeometryHelper.Distance(c1.X, c1.Y, worldPos.X, worldPos.Y);
     if (distance < minDistance)
     {
         location = c1;
         snapIndexPrevious = 0;
         snapIndexNext = 0;
         minDistance = distance;
         snapResult = new SnapResult(location, null, null, lineString, snapIndexPrevious, snapIndexNext) { Rule = this };
     }
     ICoordinate c2 = lineString.Coordinates[lineString.Coordinates.Length - 1];
     distance = GeometryHelper.Distance(c2.X, c2.Y, worldPos.X, worldPos.Y);
     if (distance >= minDistance)
         return;
     location = c2;
     snapIndexPrevious = lineString.Coordinates.Length - 1;
     snapIndexNext = lineString.Coordinates.Length - 1;
     snapResult = new SnapResult(location, null, null, lineString, snapIndexPrevious, snapIndexNext) { Rule = this };
 }
        public override void OnMouseMove(ICoordinate worldPosition, MouseEventArgs e)
        {
            if (VectorLayer == null)
            {
                return;
            }

            //to avoid listening to the mousewheel in the mean time
            if (!(e.Button == MouseButtons.None || e.Button == MouseButtons.Left))
            {
                return;
            }
            StartDrawing();

            foreach (var layer in Layers)
            {
                if (!isBusy)
                {
                    // If the newNetworkFeatureTool is active but not actual dragging a new NetworkFeature show the snap position.
                    IPoint point = GeometryFactory.CreatePoint(worldPosition);

                    snapResult = MapControl.SnapTool.ExecuteLayerSnapRules(layer, null, point, worldPosition, -1);

                    if (snapResult != null)
                    {
                        break;
                    }
                }
                else 
                {
                    IPoint point = GeometryFactory.CreatePoint(worldPosition);
                    snapResult = MapControl.SnapTool.ExecuteLayerSnapRules(layer, null, point, worldPosition, -1);
                    if (snapResult != null)
                    {
                        newNetworkFeature.Coordinates[0].X = snapResult.Location.X;
                        newNetworkFeature.Coordinates[0].Y = snapResult.Location.Y;
                        newNetworkFeatureLayer.Style = networkFeatureStyle;
                        
                        break;
                    }
                    else
                    {
                        newNetworkFeature.Coordinates[0].X = worldPosition.X;
                        newNetworkFeature.Coordinates[0].Y = worldPosition.Y;
                        newNetworkFeatureLayer.Style = errorNetworkFeatureStyle;
                    }
                }
            }
            DoDrawing(true);
            StopDrawing();
        }
Beispiel #12
0
        private void ShowSnapResult(SnapResult snapResult)
        {
            ((DataTableFeatureProvider)snapLayer.DataSource).Clear();
            if (null == snapResult)
                return;
            IList<IGeometry> visibleSnaps = snapResult.VisibleSnaps;
            //if (null == visisbleSnaps)
            if (0 == visibleSnaps.Count)
            {
                List<ICoordinate> vertices = new List<ICoordinate>();
                if (-1 != snapResult.SnapIndexPrevious)
                {
                    vertices.Add(GeometryFactory.CreateCoordinate(snapResult.NearestTarget.Coordinates[snapResult.SnapIndexPrevious].X,
                        snapResult.NearestTarget.Coordinates[snapResult.SnapIndexPrevious].Y));
                }
                vertices.Add(GeometryFactory.CreateCoordinate(snapResult.Location.X, snapResult.Location.Y));
                IGeometry active = GeometryFactory.CreatePoint(snapResult.Location.X, snapResult.Location.Y);

                if (-1 != snapResult.SnapIndexNext)
                {
                    vertices.Add(GeometryFactory.CreateCoordinate(snapResult.NearestTarget.Coordinates[snapResult.SnapIndexNext].X,
                        snapResult.NearestTarget.Coordinates[snapResult.SnapIndexNext].Y));
                }

                if (vertices.Count > 1)
                {
                    ILineString snapLineString = GeometryFactory.CreateLineString(vertices.ToArray());
                    ((DataTableFeatureProvider)snapLayer.DataSource).Add(snapLineString);
                }
                ((DataTableFeatureProvider)snapLayer.DataSource).Add(active);
            }
            else
            {
                foreach (var snap in visibleSnaps)
                {
                    ((DataTableFeatureProvider)snapLayer.DataSource).Add(snap);
                }
            }
        }
Beispiel #13
0
        /// <summary>
        /// Update snapping 
        /// </summary>
        /// <param name="sourceLayer"></param>
        /// The layer of feature. 
        /// <param name="feature"></param>
        /// Feature that is snapped. Feature is not always available. 
        /// <param name="geometry"></param>
        /// actual geometry of the feature that is snapped. 
        /// <param name="worldPosition"></param>
        /// <param name="trackerIndex"></param>
        public SnapResult ExecuteLayerSnapRules(ILayer sourceLayer, IFeature feature, IGeometry geometry, 
                                                ICoordinate worldPosition, int trackerIndex)
        {
            var snapRules = sourceLayer.FeatureEditor.SnapRules;

            SnapResult = null;
            for (int i = 0; i < snapRules.Count; i++)
            {
                ISnapRule rule = snapRules[i];
                ExecuteSnapRule(rule, feature, geometry, null, worldPosition, trackerIndex);
                if (null != SnapResult)
                    break;
                // If snapping failed for the last rule and snapping is obligatory 
                // any position is valid
                // todo add rule with SnapRole.Free?
                if ((!rule.Obligatory) && (i == snapRules.Count - 1))
                {
                    SnapResult = new SnapResult(worldPosition, null, sourceLayer, null, -1, -1) { Rule = rule };
                }
            }
            if (0 == snapRules.Count)
            {
                SnapResult = new SnapResult(worldPosition, null, sourceLayer, null, -1, -1);
            }
            return SnapResult;
        }
Beispiel #14
0
 public virtual void Stop(SnapResult snapResult)
 {
     Stop();
 }
        public override bool MoveTracker(TrackerFeature trackerFeature, double deltaX, double deltaY,
                                         SnapResult snapResult = null)
        {
            if (trackerFeature == AllTracker)
            {
                if (FallOffPolicy == null)
                {
                    FallOffPolicy = new NoFallOffPolicy();
                }

                var handles = TrackerIndices.ToList();

                FallOffPolicy.Move(TargetFeature.Geometry, Trackers.Select(t => t.Geometry).ToList(),
                                   handles, -1, deltaX, deltaY);

                foreach (var topologyRule in FeatureRelationEditors)
                {
                    topologyRule.UpdateRelatedFeatures(SourceFeature, TargetFeature.Geometry, handles);
                }

                return true;
            }
            return base.MoveTracker(trackerFeature, deltaX, deltaY, snapResult);
        }
Beispiel #16
0
        public override void OnMouseUp(ICoordinate worldPosition, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
                return;
            if (newLineGeometry.Count == 0)
            {
                return;
            }

            SnapResult snapResult = MapControl.SnapTool.ExecuteLayerSnapRules(VectorLayer, null, adding ? newLineGeometry[0] : null,
                                                            worldPosition,
                                                            adding ? newLineGeometry[0].Coordinates.Length - 1 : -1);

            ILineString lineString = (ILineString)newLineGeometry[0];
            if (null == lineString)
            {
                isBusy = false;
                return;
            }
            if (ActualAutoCurve)
            {
                snapResult = Snap(worldPosition);
                if (null == snapResult)
                {
                    // hack if obligatory snapping failed mimic result. This is not valid for NewNetworkFeatureTool
                    // Think of solution within snaprule
                    snapResult = new SnapResult(worldPosition, null, null, null, -1, -1);
                }
                    
                if (TemporalEnd)
                    lineString = (ILineString)GeometryHelper.SetCoordinate(lineString, lineString.Coordinates.Length - 1, snapResult.Location);
                else
                    lineString = AppendCurvePoint(lineString, snapResult.Location);
                    
                if (!KeepDuplicates)
                {
                    lineString = RemoveDuplicatePoints(lineString);
                }
                adding = false;
                newLineGeometry[0] = lineString;
                //Flush();
                SelectTool selectTool = MapControl.SelectTool;

                if (null != lineString && snapResult != null)
                {
                    // TODO: call interactor here instead of feature provider
                    IFeature newFeature;
                    try
                    {
                        if (CloseLine)
                        {
                            lineString = CloseLineString(lineString);
                        }

                        newFeature = VectorLayer.DataSource.Add(lineString); // will add Cross Section and call ConnectCrossSectionToBranch

                        // was adding succesfull?
                        if (null != newFeature)
                        {
                            //Layer.RenderRequired = true;
                            MapControl.SelectTool.Select(VectorLayer, newFeature);
                        }
                    }
                    catch (Exception exception)
                    {
                        // an exception during add operation can fail; for example when adding a branch feature
                        log.Warn(exception.Message);
                    }
                }
                else
                {
                    // do not add a linestring with zero length
                    selectTool.Clear();
                }
                adding = false;
                StopDrawing();
                newLineGeometry.Clear();
                isBusy = false;
            }
            else
            {
                isBusy = true;
            }
            
            VectorLayer.RenderRequired = true;
            
            MapControl.Refresh();
        }