use of org.apache.lucene.geo.Polygon in project elasticsearch by elastic.
the class GeoPolygonQueryBuilder method doToQuery.
@Override
protected Query doToQuery(QueryShardContext context) throws IOException {
MappedFieldType fieldType = context.fieldMapper(fieldName);
if (fieldType == null) {
if (ignoreUnmapped) {
return new MatchNoDocsQuery();
} else {
throw new QueryShardException(context, "failed to find geo_point field [" + fieldName + "]");
}
}
if (!(fieldType instanceof GeoPointFieldType)) {
throw new QueryShardException(context, "field [" + fieldName + "] is not a geo_point field");
}
List<GeoPoint> shell = new ArrayList<GeoPoint>();
for (GeoPoint geoPoint : this.shell) {
shell.add(new GeoPoint(geoPoint));
}
final int shellSize = shell.size();
// percolation queries we only ignore_malformed on 2.x created indexes
if (!GeoValidationMethod.isIgnoreMalformed(validationMethod)) {
for (GeoPoint point : shell) {
if (!GeoUtils.isValidLatitude(point.lat())) {
throw new QueryShardException(context, "illegal latitude value [{}] for [{}]", point.lat(), GeoPolygonQueryBuilder.NAME);
}
if (!GeoUtils.isValidLongitude(point.lat())) {
throw new QueryShardException(context, "illegal longitude value [{}] for [{}]", point.lon(), GeoPolygonQueryBuilder.NAME);
}
}
}
if (GeoValidationMethod.isCoerce(validationMethod)) {
for (GeoPoint point : shell) {
GeoUtils.normalizePoint(point, true, true);
}
}
double[] lats = new double[shellSize];
double[] lons = new double[shellSize];
GeoPoint p;
for (int i = 0; i < shellSize; ++i) {
p = shell.get(i);
lats[i] = p.lat();
lons[i] = p.lon();
}
return LatLonPoint.newPolygonQuery(fieldType.name(), new Polygon(lats, lons));
}
use of org.apache.lucene.geo.Polygon in project lucene-solr by apache.
the class TestGeo3DPoint method testPolygonOrdering.
public void testPolygonOrdering() {
final double[] lats = new double[] { 51.204382859999996, 50.89947531437482, 50.8093624806861, 50.8093624806861, 50.89947531437482, 51.204382859999996, 51.51015366140113, 51.59953838204167, 51.59953838204167, 51.51015366140113, 51.204382859999996 };
final double[] lons = new double[] { 0.8747711978759765, 0.6509219832137298, 0.35960265165247807, 0.10290284834752167, -0.18841648321373008, -0.41226569787597667, -0.18960465285650027, 0.10285893781346236, 0.35964656218653757, 0.6521101528565002, 0.8747711978759765 };
final Query q = Geo3DPoint.newPolygonQuery("point", new Polygon(lats, lons));
//System.out.println(q);
assertTrue(!q.toString().contains("GeoConcavePolygon"));
}
use of org.apache.lucene.geo.Polygon in project lucene-solr by apache.
the class TestGeo3DPoint method makePoly.
/** Cook up a random Polygon that makes sense, with possible nested polygon within.
* This is part of testing more complex polygons with nested holes. Picking random points
* doesn't do it because it's almost impossible to come up with nested ones of the proper
* clockwise/counterclockwise rotation that way.
*/
protected static Polygon makePoly(final PlanetModel pm, final GeoPoint pole, final boolean clockwiseDesired, final boolean createHoles) {
// Polygon edges will be arranged around the provided pole, and holes will each have a pole selected within the parent
// polygon.
final int pointCount = TestUtil.nextInt(random(), 3, 10);
// The point angles we pick next. The only requirement is that they are not all on one side of the pole.
// We arrange that by picking the next point within what's left of the remaining angle, but never more than 180 degrees,
// and never less than what is needed to insure that the remaining point choices are less than 180 degrees always.
// These are all picked in the context of the pole,
final double[] angles = new double[pointCount];
final double[] arcDistance = new double[pointCount];
// Pick a set of points
while (true) {
double accumulatedAngle = 0.0;
for (int i = 0; i < pointCount; i++) {
final int remainingEdgeCount = pointCount - i;
final double remainingAngle = 2.0 * Math.PI - accumulatedAngle;
if (remainingEdgeCount == 1) {
angles[i] = remainingAngle;
} else {
// The maximum angle is 180 degrees, or what's left when you give a minimal amount to each edge.
double maximumAngle = remainingAngle - (remainingEdgeCount - 1) * MINIMUM_EDGE_ANGLE;
if (maximumAngle > Math.PI) {
maximumAngle = Math.PI;
}
// The minimum angle is MINIMUM_EDGE_ANGLE, or enough to be sure nobody afterwards needs more than
// 180 degrees. And since we have three points to start with, we already know that.
final double minimumAngle = MINIMUM_EDGE_ANGLE;
// Pick the angle
final double angle = random().nextDouble() * (maximumAngle - minimumAngle) + minimumAngle;
angles[i] = angle;
accumulatedAngle += angle;
}
// Pick the arc distance randomly; not quite the full range though
arcDistance[i] = random().nextDouble() * (Math.PI * 0.5 - MINIMUM_ARC_ANGLE) + MINIMUM_ARC_ANGLE;
}
if (clockwiseDesired) {
// Reverse the signs
for (int i = 0; i < pointCount; i++) {
angles[i] = -angles[i];
}
}
// Now, use the pole's information plus angles and arcs to create GeoPoints in the right order.
final List<GeoPoint> polyPoints = convertToPoints(pm, pole, angles, arcDistance);
// Next, do some holes. No more than 2 of these. The poles for holes must always be within the polygon, so we're
// going to use Geo3D to help us select those given the points we just made.
final int holeCount = createHoles ? TestUtil.nextInt(random(), 0, 2) : 0;
final List<Polygon> holeList = new ArrayList<>();
/* Hole logic is broken and needs rethinking
// Create the geo3d polygon, so we can test out our poles.
final GeoPolygon poly;
try {
poly = GeoPolygonFactory.makeGeoPolygon(pm, polyPoints, null);
} catch (IllegalArgumentException e) {
// This is what happens when three adjacent points are colinear, so try again.
continue;
}
for (int i = 0; i < holeCount; i++) {
// Choose a pole. The poly has to be within the polygon, but it also cannot be on the polygon edge.
// If we can't find a good pole we have to give it up and not do the hole.
for (int k = 0; k < 500; k++) {
final GeoPoint poleChoice = new GeoPoint(pm, toRadians(GeoTestUtil.nextLatitude()), toRadians(GeoTestUtil.nextLongitude()));
if (!poly.isWithin(poleChoice)) {
continue;
}
// We have a pole within the polygon. Now try 100 times to build a polygon that does not intersect the outside ring.
// After that we give up and pick a new pole.
boolean foundOne = false;
for (int j = 0; j < 100; j++) {
final Polygon insidePoly = makePoly(pm, poleChoice, !clockwiseDesired, false);
// Verify that the inside polygon is OK. If not, discard and repeat.
if (!verifyPolygon(pm, insidePoly, poly)) {
continue;
}
holeList.add(insidePoly);
foundOne = true;
}
if (foundOne) {
break;
}
}
}
*/
final Polygon[] holes = holeList.toArray(new Polygon[0]);
// Finally, build the polygon and return it
final double[] lats = new double[polyPoints.size() + 1];
final double[] lons = new double[polyPoints.size() + 1];
for (int i = 0; i < polyPoints.size(); i++) {
lats[i] = polyPoints.get(i).getLatitude() * 180.0 / Math.PI;
lons[i] = polyPoints.get(i).getLongitude() * 180.0 / Math.PI;
}
lats[polyPoints.size()] = lats[0];
lons[polyPoints.size()] = lons[0];
return new Polygon(lats, lons, holes);
}
}
use of org.apache.lucene.geo.Polygon in project lucene-solr by apache.
the class Geo3DUtil method convertToDescription.
/**
* Convert a list of polygons to a list of polygon descriptions.
* @param polygons is the list of polygons to convert.
* @return the list of polygon descriptions.
*/
private static List<GeoPolygonFactory.PolygonDescription> convertToDescription(final Polygon... polygons) {
final List<GeoPolygonFactory.PolygonDescription> descriptions = new ArrayList<>(polygons.length);
for (final Polygon polygon : polygons) {
final Polygon[] theHoles = polygon.getHoles();
final List<GeoPolygonFactory.PolygonDescription> holes = convertToDescription(theHoles);
// Now do the polygon itself
final double[] polyLats = polygon.getPolyLats();
final double[] polyLons = polygon.getPolyLons();
// I presume the arguments have already been checked
final List<GeoPoint> points = new ArrayList<>(polyLats.length - 1);
// We skip the last point anyway because the API requires it to be repeated, and geo3d doesn't repeat it.
for (int i = 0; i < polyLats.length - 1; i++) {
final int index = polyLats.length - 2 - i;
points.add(new GeoPoint(PlanetModel.WGS84, fromDegrees(polyLats[index]), fromDegrees(polyLons[index])));
}
descriptions.add(new GeoPolygonFactory.PolygonDescription(points, holes));
}
return descriptions;
}
use of org.apache.lucene.geo.Polygon in project lucene-solr by apache.
the class Polygon2D method create.
/** Builds a Polygon2D from multipolygon */
public static Polygon2D create(Polygon... polygons) {
Polygon2D[] components = new Polygon2D[polygons.length];
for (int i = 0; i < components.length; i++) {
Polygon gon = polygons[i];
Polygon[] gonHoles = gon.getHoles();
Polygon2D holes = null;
if (gonHoles.length > 0) {
holes = create(gonHoles);
}
components[i] = new Polygon2D(gon, holes);
}
return createTree(components, 0, components.length - 1, false);
}
Aggregations