Skip to content

Commit

Permalink
Merge pull request #2147 from cecildelakers/master
Browse files Browse the repository at this point in the history
Add a new way for dragging: now supports to drag the whole feature on the map.
  • Loading branch information
inforithmics committed Aug 21, 2023
2 parents bc5090e + 2eddb62 commit fd6f21b
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 18 deletions.
1 change: 1 addition & 0 deletions Mapsui.Nts/Editing/DragInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ public class DragInfo
public GeometryFeature? Feature { get; set; }
public Coordinate? Vertex { get; set; }
public MPoint? StartOffsetToVertex { get; set; }
public Coordinate? VertexFeature { get; set; }
}
74 changes: 56 additions & 18 deletions Mapsui.Nts/Editing/EditManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,22 @@ public bool StartDragging(MapInfo mapInfo, double screenDistance)
if (mapInfo.Feature is GeometryFeature geometryFeature)
{
var vertexTouched = FindVertexTouched(mapInfo, geometryFeature.Geometry?.MainCoordinates() ?? new List<Coordinate>(), screenDistance);
if (vertexTouched != null)
_dragInfo.Feature = geometryFeature;
_dragInfo.Vertex = vertexTouched;
if (mapInfo.WorldPosition != null)
{
_dragInfo.Feature = geometryFeature;
_dragInfo.Vertex = vertexTouched;
if (mapInfo.WorldPosition != null && _dragInfo.Vertex != null)
if (_dragInfo.Vertex != null)
{
_dragInfo.StartOffsetToVertex = mapInfo.WorldPosition - _dragInfo.Vertex.ToMPoint();
}

return true; // to indicate start of drag
else if (_dragInfo.Feature != null && mapInfo.Feature.Extent != null)
{
_dragInfo.StartOffsetToVertex = mapInfo.WorldPosition - mapInfo.Feature.Extent.Centroid;
_dragInfo.VertexFeature = mapInfo.Feature.Extent.Centroid.ToCoordinate();
}
}

return true; // to indicate start of drag
}
}
}
Expand All @@ -190,21 +195,54 @@ public bool StartDragging(MapInfo mapInfo, double screenDistance)

public bool Dragging(Point? worldPosition)
{
if (EditMode != EditMode.Modify || _dragInfo.Feature == null || worldPosition == null || _dragInfo.StartOffsetToVertex == null) return false;
if (EditMode != EditMode.Modify || _dragInfo.Feature == null || worldPosition == null || (_dragInfo.StartOffsetToVertex == null)) return false;

_dragInfo.Vertex.SetXY(worldPosition.ToMPoint() - _dragInfo.StartOffsetToVertex);
// set the boundary value at 10 to decide the way of dragging
// try to modify vertex itself, if the worldPosition of mouse-clicking is close to the _draginfo.Vertex
if (_dragInfo.Vertex != null)
{
_dragInfo.Vertex.SetXY(worldPosition.ToMPoint() - _dragInfo.StartOffsetToVertex);

if (_dragInfo.Feature.Geometry is Polygon polygon) // Not this only works correctly it the feature is in the outer ring.
if (_dragInfo.Feature.Geometry is Polygon polygon) // Not this only works correctly it the feature is in the outer ring.
{
var count = polygon.ExteriorRing?.Coordinates.Length ?? 0;
var vertices = polygon.ExteriorRing?.Coordinates ?? Array.Empty<Coordinate>();
var index = vertices.ToList().IndexOf(_dragInfo.Vertex!);
if (index >= 0)
// It is a ring where the first should be the same as the last.
// So if the first was removed than set the last to the value of the new first
if (index == 0) vertices[count - 1].SetXY(vertices[0]);
// If the last was removed then set the first to the value of the new last
else if (index == vertices.Length) vertices[0].SetXY(vertices[count - 1]);
}
}
else if (_dragInfo.VertexFeature != null) // NEW: try to drag the whole feature when the position of dragging is inside the geometry
{
var count = polygon.ExteriorRing?.Coordinates.Length ?? 0;
var vertices = polygon.ExteriorRing?.Coordinates ?? Array.Empty<Coordinate>();
var index = vertices.ToList().IndexOf(_dragInfo.Vertex!);
if (index >= 0)
// It is a ring where the first should be the same as the last.
// So if the first was removed than set the last to the value of the new first
if (index == 0) vertices[count - 1].SetXY(vertices[0]);
// If the last was removed then set the first to the value of the new last
else if (index == vertices.Length) vertices[0].SetXY(vertices[count - 1]);
MPoint prevtx = _dragInfo.VertexFeature.ToMPoint(); // record the previous position
MPoint newvtx = worldPosition.ToMPoint() - _dragInfo.StartOffsetToVertex; // new position

if (_dragInfo.Feature.Geometry is Polygon polygon)
{
var vertices = polygon.ExteriorRing?.Coordinates ?? Array.Empty<Coordinate>();
foreach (Coordinate vtx in vertices) // modify every vertex on the ring
{
vtx.SetXY(vtx.ToMPoint() + (newvtx - prevtx)); // adding the offset
}
}
else if (_dragInfo.Feature.Geometry is LineString lineString)
{
var vertices = lineString.Coordinates ?? Array.Empty<Coordinate>();
foreach (Coordinate vtx in vertices) // modify every vertex on the line
{
vtx.SetXY(vtx.ToMPoint() + (newvtx - prevtx)); // adding the offset
}
}
else if (_dragInfo.Feature.Geometry is Point point)
{
var vertice = point.Coordinate;
vertice.SetXY(vertice.ToMPoint() + (newvtx - prevtx)); // adding the offset
}
_dragInfo.VertexFeature.SetXY(worldPosition.ToMPoint() - _dragInfo.StartOffsetToVertex);
}

_dragInfo.Feature.RenderedGeometry.Clear();
Expand Down

0 comments on commit fd6f21b

Please sign in to comment.