Search in sources :

Example 1 with Polygon

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));
}
Also used : GeoPoint(org.elasticsearch.common.geo.GeoPoint) MatchNoDocsQuery(org.apache.lucene.search.MatchNoDocsQuery) MappedFieldType(org.elasticsearch.index.mapper.MappedFieldType) ArrayList(java.util.ArrayList) GeoPointFieldType(org.elasticsearch.index.mapper.GeoPointFieldMapper.GeoPointFieldType) Polygon(org.apache.lucene.geo.Polygon) LatLonPoint(org.apache.lucene.document.LatLonPoint) GeoPoint(org.elasticsearch.common.geo.GeoPoint)

Example 2 with Polygon

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"));
}
Also used : Query(org.apache.lucene.search.Query) GeoPolygon(org.apache.lucene.spatial3d.geom.GeoPolygon) Polygon(org.apache.lucene.geo.Polygon)

Example 3 with Polygon

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);
    }
}
Also used : GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint) ArrayList(java.util.ArrayList) GeoPolygon(org.apache.lucene.spatial3d.geom.GeoPolygon) Polygon(org.apache.lucene.geo.Polygon) GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint)

Example 4 with Polygon

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;
}
Also used : GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint) GeoPolygonFactory(org.apache.lucene.spatial3d.geom.GeoPolygonFactory) ArrayList(java.util.ArrayList) GeoCompositePolygon(org.apache.lucene.spatial3d.geom.GeoCompositePolygon) GeoPolygon(org.apache.lucene.spatial3d.geom.GeoPolygon) Polygon(org.apache.lucene.geo.Polygon) GeoPoint(org.apache.lucene.spatial3d.geom.GeoPoint)

Example 5 with Polygon

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);
}
Also used : Polygon(org.apache.lucene.geo.Polygon)

Aggregations

Polygon (org.apache.lucene.geo.Polygon)9 GeoPolygon (org.apache.lucene.spatial3d.geom.GeoPolygon)5 ArrayList (java.util.ArrayList)3 GeoPoint (org.apache.lucene.spatial3d.geom.GeoPoint)3 ParseException (java.text.ParseException)2 Line (org.apache.lucene.geo.Line)2 GeoCompositePolygon (org.apache.lucene.spatial3d.geom.GeoCompositePolygon)2 IOException (java.io.IOException)1 Path (java.nio.file.Path)1 Document (org.apache.lucene.document.Document)1 Field (org.apache.lucene.document.Field)1 LatLonPoint (org.apache.lucene.document.LatLonPoint)1 StringField (org.apache.lucene.document.StringField)1 IndexWriter (org.apache.lucene.index.IndexWriter)1 IndexWriterConfig (org.apache.lucene.index.IndexWriterConfig)1 MatchNoDocsQuery (org.apache.lucene.search.MatchNoDocsQuery)1 Query (org.apache.lucene.search.Query)1 GeoPolygonFactory (org.apache.lucene.spatial3d.geom.GeoPolygonFactory)1 PlanetModel (org.apache.lucene.spatial3d.geom.PlanetModel)1 Directory (org.apache.lucene.store.Directory)1