Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 36 additions & 42 deletions src/main/java/com/esri/core/geometry/TopologicalOperations.java
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ int selectVertex_(int cluster, EditShape shape) {
}

private double prevailingDirection_(EditShape shape, int half_edge) {
int current_parentage = getCombinedHalfEdgeParentage_(half_edge);
int cluster = m_topo_graph.getHalfEdgeOrigin(half_edge);
int clusterTo = m_topo_graph.getHalfEdgeTo(half_edge);
int signTotal = 0;
Expand All @@ -555,26 +556,28 @@ private double prevailingDirection_(EditShape shape, int half_edge) {
int path = shape.getPathFromVertex(vertex);
int geometry = shape.getGeometryFromPath(path);
int geomID = m_topo_graph.getGeometryID(geometry);
final boolean goodPar = (current_parentage & geomID) != 0;
int nextVert = shape.getNextVertex(vertex);
int prevVert = shape.getPrevVertex(vertex);

int firstVert = shape.getFirstVertex(path);
if (firstVert == vertex) {// remember the first half edge of the
// path. We use it to produce correct
// startpath for closed polyline loops
if (firstVert == vertex && goodPar) {
// remember the first vertex of the path.
// We use it to produce correct startpath for closed polyline loops
m_from_edge_for_polylines = half_edge;
}

if (nextVert != -1
&& m_topo_graph.getClusterFromVertex(nextVert) == clusterTo) {
signTotal++;
if (isGoodParentage(geomID)) {
if (firstVert == nextVert) {// remember the first vertex of
// the path. We use it to
// produce correct startpath for
// closed polyline loops
m_from_edge_for_polylines = m_topo_graph
.getHalfEdgeNext(half_edge);
if (goodPar) {
if (m_from_edge_for_polylines == -1 && firstVert == nextVert) {
// remember the first vertex of the path.
// We use it to produce correct startpath for closed polyline loops
int next = m_topo_graph.getHalfEdgeNext(half_edge);
if (isGoodParentage(getCombinedHalfEdgeParentage_(next))) {
m_from_edge_for_polylines = next;
}
}

// update the sign
Expand All @@ -583,13 +586,14 @@ private double prevailingDirection_(EditShape shape, int half_edge) {
} else if (prevVert != -1
&& m_topo_graph.getClusterFromVertex(prevVert) == clusterTo) {
signTotal--;
if (isGoodParentage(geomID)) {
if (firstVert == prevVert) {// remember the first vertex of
// the path. We use it to
// produce correct startpath for
// closed polyline loops
m_from_edge_for_polylines = m_topo_graph
.getHalfEdgeNext(half_edge);
if (goodPar) {
if (m_from_edge_for_polylines != -1 && firstVert == prevVert) {
// remember the first vertex of the path.
// We use it to produce correct startpath for closed polyline loops
int next = m_topo_graph.getHalfEdgeNext(half_edge);
if (isGoodParentage(getCombinedHalfEdgeParentage_(next))) {
m_from_edge_for_polylines = next;
}
}

// update the sign
Expand Down Expand Up @@ -657,23 +661,17 @@ private void restorePolylineParts_(int first_edge, int newGeometry,
int halfEdgeTwin = m_topo_graph.getHalfEdgeTwin(half_edge);
m_topo_graph.setHalfEdgeUserIndex(half_edge, visitedEdges, 1);
m_topo_graph.setHalfEdgeUserIndex(halfEdgeTwin, visitedEdges, 1);
double prevailingLength = prevailingDirection_(shape, half_edge);// prevailing
// direction
// is
// used
// to
// figure
// out
// the
// polyline
// direction.
//set by the prevailingDirection_()
m_from_edge_for_polylines = -1;

//prevailing direction is used to figure out the polyline direction.
double prevailingLength = prevailingDirection_(shape, half_edge);
// Prevailing length is the sum of the length of vectors that constitute
// the polyline.
// Vector length is positive, if the halfedge direction coincides with
// the direction of the original geometry
// and negative otherwise.

m_from_edge_for_polylines = -1;
int fromEdge = half_edge;
int toEdge = -1;
boolean b_found_impassable_crossroad = false;
Expand All @@ -689,21 +687,21 @@ private void restorePolylineParts_(int first_edge, int newGeometry,
// there is only a single way to pass through.
//When doing planar_simplify we'll never go through the crossroad.
half_edge = tryMoveThroughCrossroadBackwards_(half_edge);
if (half_edge == -1)
if (half_edge == -1) {
b_found_impassable_crossroad = true;
break;
}
else {
b_found_impassable_crossroad = true;
halfEdgeTwin = m_topo_graph.getHalfEdgeTwin(half_edge);
}
} else {
half_edge = halfEdgePrev;
halfEdgeTwin = halfEdgeTwinNext;
}

if (half_edge == first_edge) {// we are in a loop. No need to search
// for the toEdge. Just remember the
// toEdge and skip the next while
// loop.
if (half_edge == first_edge) {
// we are in a loop. No need to search for the toEdge.
//Just remember the toEdge and skip the next while loop.
toEdge = first_edge;
break;
}
Expand Down Expand Up @@ -763,11 +761,9 @@ private void restorePolylineParts_(int first_edge, int newGeometry,

if (m_from_edge_for_polylines != -1) {
fromEdge = m_from_edge_for_polylines;
//try simply getting prev
toEdge = m_topo_graph
.getHalfEdgePrev(m_from_edge_for_polylines);// try
// simply
// getting
// prev
.getHalfEdgePrev(m_from_edge_for_polylines);
int fromEdgeTwin = m_topo_graph.getHalfEdgeTwin(fromEdge);
int fromEdgeTwinNext = m_topo_graph
.getHalfEdgeNext(fromEdgeTwin);
Expand All @@ -788,10 +784,8 @@ private void restorePolylineParts_(int first_edge, int newGeometry,
int e = toEdge;
toEdge = fromEdge;
fromEdge = e;
toEdge = m_topo_graph.getHalfEdgeTwin(toEdge);// switch to twin so
// that we can use
// next instead of
// Prev
//switch to twin so that we can use next instead of Prev
toEdge = m_topo_graph.getHalfEdgeTwin(toEdge);
assert (isGoodParentage(getCombinedHalfEdgeParentage_(toEdge)));
fromEdge = m_topo_graph.getHalfEdgeTwin(fromEdge);
assert (isGoodParentage(getCombinedHalfEdgeParentage_(fromEdge)));
Expand Down
16 changes: 16 additions & 0 deletions src/test/java/com/esri/core/geometry/TestDifference.java
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,22 @@ public static void testDifferencePolylineAlongPolygonBoundary() {
assertEquals(GeometryEngine.geometryToJson(null, result), "{\"paths\":[[[0,5],[-2,5]]]}");
}

@Test
public static void testIssue328() {
//https://github.com/Esri/geometry-api-java/issues/328
Geometry g1 = OperatorImportFromWkt.local().execute(0,Geometry.Type.Polyline,"MULTILINESTRING ( ( 117422 -64366,119336 -64652,119218 -65440,114999 -64810,115034 -64578,115117 -64022,117422 -64366),(111611 -62617,111365 -64268,110476 -64135,110722 -62484,110975 -62522,111611 -62617))",null);
Geometry g2 = OperatorImportFromWkt.local().execute(0,Geometry.Type.Polyline,"MULTILINESTRING ( (117422 -64366, 117911 -61089))",null);
Geometry g2Backwards = OperatorImportFromWkt.local().execute(0,Geometry.Type.Polyline,"MULTILINESTRING ( (117911 -61089, 117422 -64366))",null);
Geometry res_geom = OperatorDifference.local().execute(g1, g2,null,null);
Geometry resGeomBackwards = OperatorDifference.local().execute(g1, g2Backwards,null,null);
String str = GeometryEngine.geometryToJson(0, res_geom);
String strBackwards = GeometryEngine.geometryToJson(0, resGeomBackwards);
String expectedResult = "{\"paths\":[[[117422,-64366],[119336,-64652],[119218,-65440],[114999,-64810],[115034,-64578],[115117,-64022],[117422,-64366]],[[111611,-62617],[111365,-64268],[110476,-64135],[110722,-62484],[110975,-62522],[111611,-62617]]]}";
assertEquals(str, expectedResult);
assertEquals(strBackwards, expectedResult);
}


public static Polygon makePolygon1() {
Polygon poly = new Polygon();
poly.startPath(0, 0);
Expand Down