use of org.opensearch.geometry.Line in project OpenSearch by opensearch-project.
the class GeoLineDecomposer method decompose.
/**
* Decompose a linestring given as array of coordinates by anti-meridian.
*/
private static void decompose(double[] lons, double[] lats, List<Line> collector) {
int offset = 0;
double shift = 0;
int i = 1;
while (i < lons.length) {
// Check where the line is going east (+1), west (-1) or directly north/south (0)
int direction = Double.compare(lons[i], lons[i - 1]);
double newShift = calculateShift(lons[i - 1], direction < 0);
// first point lon + shift is always between -180.0 and +180.0
if (i - offset > 1 && newShift != shift) {
// Jumping over anti-meridian - we need to start a new segment
double[] partLons = Arrays.copyOfRange(lons, offset, i);
double[] partLats = Arrays.copyOfRange(lats, offset, i);
performShift(shift, partLons);
shift = newShift;
offset = i - 1;
collector.add(new Line(partLons, partLats));
} else {
// Check if new point intersects with anti-meridian
shift = newShift;
double t = intersection(lons[i - 1] + shift, lons[i] + shift);
if (Double.isNaN(t) == false) {
// Found intersection, all previous segments are now part of the linestring
double[] partLons = Arrays.copyOfRange(lons, offset, i + 1);
double[] partLats = Arrays.copyOfRange(lats, offset, i + 1);
lons[i - 1] = partLons[partLons.length - 1] = (direction > 0 ? DATELINE : -DATELINE) - shift;
lats[i - 1] = partLats[partLats.length - 1] = lats[i - 1] + (lats[i] - lats[i - 1]) * t;
performShift(shift, partLons);
offset = i - 1;
collector.add(new Line(partLons, partLats));
} else {
// Didn't find intersection - just continue checking
i++;
}
}
}
if (offset == 0) {
performShift(shift, lons);
collector.add(new Line(lons, lats));
} else if (offset < lons.length - 1) {
double[] partLons = Arrays.copyOfRange(lons, offset, lons.length);
double[] partLats = Arrays.copyOfRange(lats, offset, lats.length);
performShift(shift, partLons);
collector.add(new Line(partLons, partLats));
}
}
use of org.opensearch.geometry.Line in project OpenSearch by opensearch-project.
the class MultiLineStringBuilder method buildGeometry.
@Override
public org.opensearch.geometry.Geometry buildGeometry() {
if (lines.isEmpty()) {
return MultiLine.EMPTY;
}
List<Line> linestrings = new ArrayList<>(lines.size());
for (int i = 0; i < lines.size(); ++i) {
LineStringBuilder lsb = lines.get(i);
linestrings.add(new Line(lsb.coordinates.stream().mapToDouble(c -> c.x).toArray(), lsb.coordinates.stream().mapToDouble(c -> c.y).toArray()));
}
return new MultiLine(linestrings);
}
use of org.opensearch.geometry.Line in project OpenSearch by opensearch-project.
the class GeometryParserTests method testWKTParsing.
public void testWKTParsing() throws Exception {
XContentBuilder pointGeoJson = XContentFactory.jsonBuilder().startObject().field("foo", "Point (100 0)").endObject();
try (XContentParser parser = createParser(pointGeoJson)) {
// Start object
parser.nextToken();
// Field Name
parser.nextToken();
// Field Value
parser.nextToken();
GeometryFormat format = new GeometryParser(true, randomBoolean(), randomBoolean()).geometryFormat(parser);
assertEquals(new Point(100, 0), format.fromXContent(parser));
XContentBuilder newGeoJson = XContentFactory.jsonBuilder().startObject().field("val");
format.toXContent(new Point(100, 10), newGeoJson, ToXContent.EMPTY_PARAMS);
newGeoJson.endObject();
assertEquals("{\"val\":\"POINT (100.0 10.0)\"}", Strings.toString(newGeoJson));
}
// Make sure we can parse values outside the normal lat lon boundaries
XContentBuilder lineGeoJson = XContentFactory.jsonBuilder().startObject().field("foo", "LINESTRING (100 0, 200 10)").endObject();
try (XContentParser parser = createParser(lineGeoJson)) {
// Start object
parser.nextToken();
// Field Name
parser.nextToken();
// Field Value
parser.nextToken();
assertEquals(new Line(new double[] { 100, 200 }, new double[] { 0, 10 }), new GeometryParser(true, randomBoolean(), randomBoolean()).parse(parser));
}
}
use of org.opensearch.geometry.Line in project OpenSearch by opensearch-project.
the class GeometryParserTests method testBasics.
public void testBasics() {
GeometryParser parser = new GeometryParser(true, randomBoolean(), randomBoolean());
// point
Point expectedPoint = new Point(-122.084110, 37.386637);
testBasics(parser, mapOf("lat", 37.386637, "lon", -122.084110), expectedPoint);
testBasics(parser, "37.386637, -122.084110", expectedPoint);
testBasics(parser, "POINT (-122.084110 37.386637)", expectedPoint);
testBasics(parser, Arrays.asList(-122.084110, 37.386637), expectedPoint);
testBasics(parser, mapOf("type", "Point", "coordinates", Arrays.asList(-122.084110, 37.386637)), expectedPoint);
// line
Line expectedLine = new Line(new double[] { 0, 1 }, new double[] { 0, 1 });
testBasics(parser, "LINESTRING(0 0, 1 1)", expectedLine);
testBasics(parser, mapOf("type", "LineString", "coordinates", Arrays.asList(Arrays.asList(0, 0), Arrays.asList(1, 1))), expectedLine);
// polygon
Polygon expectedPolygon = new Polygon(new LinearRing(new double[] { 0, 1, 1, 0, 0 }, new double[] { 0, 0, 1, 1, 0 }));
testBasics(parser, "POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))", expectedPolygon);
testBasics(parser, mapOf("type", "Polygon", "coordinates", Arrays.asList(Arrays.asList(Arrays.asList(0, 0), Arrays.asList(1, 0), Arrays.asList(1, 1), Arrays.asList(0, 1), Arrays.asList(0, 0)))), expectedPolygon);
// geometry collection
testBasics(parser, Arrays.asList(Arrays.asList(-122.084110, 37.386637), "37.386637, -122.084110", "POINT (-122.084110 37.386637)", mapOf("type", "Point", "coordinates", Arrays.asList(-122.084110, 37.386637)), mapOf("type", "LineString", "coordinates", Arrays.asList(Arrays.asList(0, 0), Arrays.asList(1, 1))), "POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))"), new GeometryCollection<>(Arrays.asList(expectedPoint, expectedPoint, expectedPoint, expectedPoint, expectedLine, expectedPolygon)));
expectThrows(OpenSearchParseException.class, () -> testBasics(parser, "not a geometry", null));
}
use of org.opensearch.geometry.Line in project OpenSearch by opensearch-project.
the class GeometryIndexerTests method testCollection.
public void testCollection() {
assertEquals(GeometryCollection.EMPTY, indexer.prepareForIndexing(GeometryCollection.EMPTY));
GeometryCollection<Geometry> collection = new GeometryCollection<>(Collections.singletonList(new Point(2, 1)));
Geometry indexed = new Point(2, 1);
assertEquals(indexed, indexer.prepareForIndexing(collection));
collection = new GeometryCollection<>(Arrays.asList(new Point(2, 1), new Point(4, 3), new Line(new double[] { 160, 200 }, new double[] { 10, 20 })));
indexed = new GeometryCollection<>(Arrays.asList(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 })))));
assertEquals(indexed, indexer.prepareForIndexing(collection));
}
Aggregations