Skip to content

Commit

Permalink
Geo: fix indexing of west to east linestrings crossing the antimeridi…
Browse files Browse the repository at this point in the history
…an (#46601)

Fixes that way linestrings that are crossing the antimeridian are
indexed due to a normalization bug these lines were decomposed into
a line segment that was stretching entire globe.

Fixes #43775
  • Loading branch information
imotov authored Sep 11, 2019
1 parent 03116c0 commit 4ab7111
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ private List<Line> decomposeGeometry(Line line, List<Line> lines) {
double[] lons = new double[partMinus.length()];
for (int i = 0; i < partMinus.length(); i++) {
lats[i] = normalizeLat(partMinus.getY(i));
lons[i] = normalizeLon(partMinus.getX(i));
lons[i] = normalizeLonMinus180Inclusive(partMinus.getX(i));
}
lines.add(new Line(lons, lats));
}
Expand Down Expand Up @@ -274,7 +274,7 @@ private List<Line> decompose(double dateline, double[] lons, double[] lats) {
lons[offset + i - 1] = intersection.getX();
lats[offset + i - 1] = intersection.getY();

shift(shift, lons);
shift(shift, partLons);
offset = i - 1;
shift = lons[i] > DATELINE ? DATELINE : (lons[i] < -DATELINE ? -DATELINE : 0);
} else {
Expand Down Expand Up @@ -926,7 +926,7 @@ private static Polygon buildPolygon(List<Point[]> polygon) {
for (int i = 0; i < shell.length; ++i) {
//Lucene Tessellator treats different +180 and -180 and we should keep the sign.
//normalizeLon method excludes -180.
x[i] = Math.abs(shell[i].getX()) > 180 ? normalizeLon(shell[i].getX()) : shell[i].getX();
x[i] = normalizeLonMinus180Inclusive(shell[i].getX());
y[i] = normalizeLat(shell[i].getY());
}

Expand Down Expand Up @@ -1043,4 +1043,11 @@ public static org.apache.lucene.geo.Polygon toLucenePolygon(Polygon polygon) {
}
return new org.apache.lucene.geo.Polygon(polygon.getPolygon().getY(), polygon.getPolygon().getX(), holes);
}

/**
* Normalizes longitude while accepting -180 degrees as a valid value
*/
private static double normalizeLonMinus180Inclusive(double lon) {
return Math.abs(lon) > 180 ? normalizeLon(lon) : lon;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public void testCollection() {
new Point(2, 1), new Point(4, 3),
new MultiLine(Arrays.asList(
new Line(new double[]{160, 180}, new double[]{10, 15}),
new Line(new double[]{180, -160}, new double[]{15, 20}))
new Line(new double[]{-180, -160}, new double[]{15, 20}))
))
);
assertEquals(indexed, indexer.prepareForIndexing(collection));
Expand All @@ -87,7 +87,25 @@ public void testLine() {
line = new Line(new double[]{160, 200}, new double[]{10, 20});
indexed = new MultiLine(Arrays.asList(
new Line(new double[]{160, 180}, new double[]{10, 15}),
new Line(new double[]{180, -160}, new double[]{15, 20}))
new Line(new double[]{-180, -160}, new double[]{15, 20}))
);

assertEquals(indexed, indexer.prepareForIndexing(line));

line = new Line(new double[]{200, 160}, new double[]{10, 20});
indexed = new MultiLine(Arrays.asList(
new Line(new double[]{-160, -180}, new double[]{10, 15}),
new Line(new double[]{180, 160}, new double[]{15, 20}))
);

assertEquals(indexed, indexer.prepareForIndexing(line));

line = new Line(new double[]{160, 200, 160}, new double[]{0, 10, 20});
indexed = new MultiLine(Arrays.asList(
new Line(new double[]{160, 180}, new double[]{0, 5}),
new Line(new double[]{-180, -160, -180}, new double[]{5, 10, 15}),
new Line(new double[]{180, 160}, new double[]{15, 20})
)
);

assertEquals(indexed, indexer.prepareForIndexing(line));
Expand All @@ -106,7 +124,7 @@ line, new Line(new double[]{160, 200}, new double[]{10, 20})
indexed = new MultiLine(Arrays.asList(
line,
new Line(new double[]{160, 180}, new double[]{10, 15}),
new Line(new double[]{180, -160}, new double[]{15, 20}))
new Line(new double[]{-180, -160}, new double[]{15, 20}))
);

assertEquals(indexed, indexer.prepareForIndexing(multiLine));
Expand Down

0 comments on commit 4ab7111

Please sign in to comment.