use of org.locationtech.spatial4j.shape.Point in project elasticsearch by elastic.
the class RandomShapeGenerator method createShape.
/**
* Creates a random shape useful for randomized testing, NOTE: exercise caution when using this to build random GeometryCollections
* as creating a large random number of random shapes can result in massive resource consumption
* see: {@link GeoShapeQueryTests#testShapeFilterWithRandomGeoCollection}
*
* The following options are included
* @param nearPoint Create a shape near a provided point
* @param within Create a shape within the provided rectangle (note: if not null this will override the provided point)
* @param st Create a random shape of the provided type
* @return the ShapeBuilder for a random shape
*/
private static ShapeBuilder createShape(Random r, Point nearPoint, Rectangle within, ShapeType st, boolean validate) throws InvalidShapeException {
if (st == null) {
st = ShapeType.randomType(r);
}
if (within == null) {
within = xRandomRectangle(r, nearPoint);
}
// inside non overlapping bounding rectangles
switch(st) {
case POINT:
Point p = xRandomPointIn(r, within);
PointBuilder pb = new PointBuilder().coordinate(new Coordinate(p.getX(), p.getY(), Double.NaN));
return pb;
case MULTIPOINT:
case LINESTRING:
// for random testing having a maximum number of 10 points for a line string is more than sufficient
// if this number gets out of hand, the number of self intersections for a linestring can become
// (n^2-n)/2 and computing the relation intersection matrix will become NP-Hard
int numPoints = RandomNumbers.randomIntBetween(r, 3, 10);
CoordinatesBuilder coordinatesBuilder = new CoordinatesBuilder();
for (int i = 0; i < numPoints; ++i) {
p = xRandomPointIn(r, within);
coordinatesBuilder.coordinate(p.getX(), p.getY());
}
CoordinateCollection pcb = (st == ShapeType.MULTIPOINT) ? new MultiPointBuilder(coordinatesBuilder.build()) : new LineStringBuilder(coordinatesBuilder);
return pcb;
case MULTILINESTRING:
MultiLineStringBuilder mlsb = new MultiLineStringBuilder();
for (int i = 0; i < RandomNumbers.randomIntBetween(r, 1, 10); ++i) {
mlsb.linestring((LineStringBuilder) createShape(r, nearPoint, within, ShapeType.LINESTRING, false));
}
return mlsb;
case POLYGON:
numPoints = RandomNumbers.randomIntBetween(r, 5, 25);
Coordinate[] coordinates = new Coordinate[numPoints];
for (int i = 0; i < numPoints; ++i) {
p = (Point) createShape(r, nearPoint, within, ShapeType.POINT, false).build();
coordinates[i] = new Coordinate(p.getX(), p.getY());
}
// random point order or random linestrings can lead to invalid self-crossing polygons,
// compute the convex hull for a set of points to ensure polygon does not self cross
Geometry shell = new ConvexHull(coordinates, ctx.getGeometryFactory()).getConvexHull();
Coordinate[] shellCoords = shell.getCoordinates();
// when all else fails, use the bounding box as the polygon
if (shellCoords.length < 3) {
shellCoords = new Coordinate[4];
shellCoords[0] = new Coordinate(within.getMinX(), within.getMinY());
shellCoords[1] = new Coordinate(within.getMinX(), within.getMaxY());
shellCoords[2] = new Coordinate(within.getMaxX(), within.getMaxY());
shellCoords[3] = new Coordinate(within.getMaxX(), within.getMinY());
}
PolygonBuilder pgb = new PolygonBuilder(new CoordinatesBuilder().coordinates(shellCoords).close());
if (validate) {
// The validate flag will check for these possibilities and bail if an incorrect geometry is created
try {
pgb.build();
} catch (AssertionError | InvalidShapeException e) {
// or InvalidShapeException
return null;
}
}
return pgb;
default:
throw new ElasticsearchException("Unable to create shape of type [" + st + "]");
}
}
use of org.locationtech.spatial4j.shape.Point in project elasticsearch by elastic.
the class RandomShapeGenerator method createGeometryCollection.
protected static GeometryCollectionBuilder createGeometryCollection(Random r, Point nearPoint, Rectangle bounds, int numGeometries) throws InvalidShapeException {
if (numGeometries <= 0) {
// cap geometry collection at 4 shapes (to save test time)
numGeometries = RandomNumbers.randomIntBetween(r, 2, 4);
}
if (nearPoint == null) {
nearPoint = xRandomPoint(r);
}
if (bounds == null) {
bounds = xRandomRectangle(r, nearPoint);
}
GeometryCollectionBuilder gcb = new GeometryCollectionBuilder();
for (int i = 0; i < numGeometries; ) {
ShapeBuilder builder = createShapeWithin(r, bounds);
// Not the most efficient but its the lesser of the evil alternatives
if (builder != null) {
gcb.shape(builder);
++i;
}
}
return gcb;
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class SpatialExample method newSampleDocument.
private Document newSampleDocument(int id, Shape... shapes) {
Document doc = new Document();
doc.add(new StoredField("id", id));
doc.add(new NumericDocValuesField("id", id));
// strategies; see the javadocs of the SpatialStrategy impl to see.
for (Shape shape : shapes) {
for (Field f : strategy.createIndexableFields(shape)) {
doc.add(f);
}
//store it too; the format is up to you
// (assume point in this example)
Point pt = (Point) shape;
doc.add(new StoredField(strategy.getFieldName(), pt.getX() + " " + pt.getY()));
}
return doc;
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class DistanceToShapeValueSource method getValues.
@Override
public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
final FunctionValues shapeValues = shapeValueSource.getValues(context, readerContext);
return new DoubleDocValues(this) {
@Override
public double doubleVal(int doc) throws IOException {
Shape shape = (Shape) shapeValues.objectVal(doc);
if (shape == null || shape.isEmpty())
return nullValue;
Point pt = shape.getCenter();
return distCalc.distance(queryPoint, pt) * multiplier;
}
@Override
public Explanation explain(int doc) throws IOException {
Explanation exp = super.explain(doc);
List<Explanation> details = new ArrayList<>(Arrays.asList(exp.getDetails()));
details.add(shapeValues.explain(doc));
return Explanation.match(exp.getValue(), exp.getDescription(), details);
}
};
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class PointVectorStrategy method createIndexableFields.
/** @see #createIndexableFields(org.locationtech.spatial4j.shape.Shape) */
public Field[] createIndexableFields(Point point) {
Field[] fields = new Field[fieldsLen];
int idx = -1;
if (hasStored) {
fields[++idx] = new StoredField(fieldNameX, point.getX());
fields[++idx] = new StoredField(fieldNameY, point.getY());
}
if (hasDocVals) {
fields[++idx] = new DoubleDocValuesField(fieldNameX, point.getX());
fields[++idx] = new DoubleDocValuesField(fieldNameY, point.getY());
}
if (hasPointVals) {
fields[++idx] = new DoublePoint(fieldNameX, point.getX());
fields[++idx] = new DoublePoint(fieldNameY, point.getY());
}
assert idx == fields.length - 1;
return fields;
}
Aggregations