/** * Converts this shape into its equivalent Spatial4j {@link Shape}. * @return */ public Shape convert2Spatial4j() { switch(getType()) { case POINT: return getPoint().getSpatial4jPoint(); case CIRCLE: return CTX.makeCircle(getPoint(0).getSpatial4jPoint(), DistanceUtils.dist2Degrees(getRadius(), DistanceUtils.EARTH_MEAN_RADIUS_KM)); case BOX: return CTX.makeRectangle(getPoint(0).getSpatial4jPoint(),getPoint(1).getSpatial4jPoint()); case POLYGON: throw new UnsupportedOperationException("Not yet supported"); default: throw new IllegalStateException("Unrecognized type: " + getType()); } }
double[] arr = new double[len]; for (int i=0;i<len;i++) arr[i]=((Number)Array.get(value,i)).doubleValue(); if (len==2) shape= point(arr[0],arr[1]); else if (len==3) shape= circle(arr[0],arr[1],arr[2]); else if (len==4) shape= box(arr[0],arr[1],arr[2],arr[3]); else throw new IllegalArgumentException("Expected 2-4 coordinates to create Geoshape, but given: " + value); return shape;
private SpatialRelation getSpatialRelation(Geoshape other) { Preconditions.checkNotNull(other); return convert2Spatial4j().relate(other.convert2Spatial4j()); }
/** * {@link com.thinkaurelius.titan.core.attribute.Geoshape} stores Points in the String format: point[X.0,Y.0]. * Solr needs it to be in Well-Known Text format: POINT(X.0 Y.0) */ public static String convertToWktString(Geoshape fieldValue) throws BackendException { if (fieldValue.getType() == Geoshape.Type.POINT) { Geoshape.Point point = fieldValue.getPoint(); return "POINT(" + point.getLongitude() + " " + point.getLatitude() + ")"; } else { throw new PermanentBackendException("Cannot index " + fieldValue.getType()); } } }
@Override public String toString() { Type type = getType(); StringBuilder s = new StringBuilder(); s.append(type.toString().toLowerCase()); switch (type) { case POINT: s.append(getPoint().toString()); break; case CIRCLE: s.append(getPoint().toString()).append(":").append(getRadius()); break; default: s.append("["); for (int i=0;i<size();i++) { if (i>0) s.append(","); s.append(getPoint(i)); } s.append("]"); } return s.toString(); }
v.property(VertexProperty.Cardinality.single, "time", i); offset = (i % 2 == 0 ? 1 : -1) * (i * 50.0 / numV); v.property(VertexProperty.Cardinality.single, "location", Geoshape.point(0.0 + offset, 0.0 + offset)); e.property("category", i % numCategories); e.property("group", i % numGroups); e.property("location", Geoshape.point(0.0 + offset, 0.0 + offset)); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertCount(i + 1, tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).vertices()); assertCount(i + 1, tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).edges()); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertCount(5, tx.query().has("location", Geo.INTERSECT, Geoshape.circle(0.0, 0.0, distance)).has("text", Text.CONTAINS, words[0]).vertices()); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertCount(i + 1, tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).vertices()); assertCount(i + 1, tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).edges()); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertCount(5, tx.query().has("location", Geo.INTERSECT, Geoshape.circle(0.0, 0.0, distance)).has("text", Text.CONTAINS, words[0]).vertices()); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertCount(i + 1, tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).vertices()); assertCount(i + 1, tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).edges()); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertCount(5, tx.query().has("location", Geo.INTERSECT, Geoshape.circle(0.0, 0.0, distance)).has("text", Text.CONTAINS, words[0]).vertices());
jgen.writeFieldName(FIELD_TYPE); switch(value.getType()) { case POLYGON: throw new UnsupportedOperationException("Polygons are not supported"); jgen.writeString(Type.CIRCLE.toString()); jgen.writeFieldName(FIELD_RADIUS); jgen.writeNumber(value.getRadius()); jgen.writeFieldName(FIELD_COORDINATES); jgen.writeStartArray();
/** * Constructs a point from its latitude and longitude information * @param latitude * @param longitude * @return */ public static final Geoshape point(final double latitude, final double longitude) { return point((float)latitude,(float)longitude); }
/** * Returns the radius in kilometers of this circle. Only applicable to circle shapes. * @return */ public float getRadius() { Preconditions.checkArgument(getType()==Type.CIRCLE,"This shape is not a circle"); return coordinates[1][1]; }
private List<Geoshape.Point> getPolygonPoints(Geoshape polygon) { List<Geoshape.Point> locations = new ArrayList<Geoshape.Point>(); int index = 0; boolean hasCoordinates = true; while (hasCoordinates) { try { locations.add(polygon.getPoint(index)); } catch (ArrayIndexOutOfBoundsException ignore) { //just means we asked for a point past the size of the list //of known coordinates hasCoordinates = false; } } return locations; }
private void storeTest(String... stores) throws Exception { Map<String, Object> doc1 = getDocument("Hello world", 1001, 5.2, Geoshape.point(48.0, 0.0)); Map<String, Object> doc2 = getDocument("Tomorrow is the world", 1010, 8.5, Geoshape.point(49.0, 1.0)); Map<String, Object> doc3 = getDocument("Hello Bob, are you there?", -500, 10.1, Geoshape.point(47.0, 10.0)); result = tx.query(new IndexQuery(store, PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 200.00)))); assertEquals(2, result.size()); assertEquals(ImmutableSet.of("doc1", "doc2"), ImmutableSet.copyOf(result)); result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TEXT, Text.CONTAINS, "tomorrow"), PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 200.00))))); assertEquals(ImmutableSet.of("doc2"), ImmutableSet.copyOf(result)); result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TIME, Cmp.GREATER_THAN_EQUAL, -1000), PredicateCondition.of(TIME, Cmp.LESS_THAN, 1010), PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 1000.00))))); assertEquals(ImmutableSet.of("doc1", "doc3"), ImmutableSet.copyOf(result)); add(store, "doc4", getDocument("I'ts all a big Bob", -100, 11.2, Geoshape.point(48.0, 8.0)), true); remove(store, "doc2", doc2, true); remove(store, "doc3", ImmutableMap.of(WEIGHT, (Object) 10.1), false); result = tx.query(new IndexQuery(store, PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 200.00)))); assertEquals(ImmutableSet.of("doc1"), ImmutableSet.copyOf(result)); result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TEXT, Text.CONTAINS, "tomorrow"), PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 200.00))))); assertEquals(ImmutableSet.of(), ImmutableSet.copyOf(result)); result = tx.query(new IndexQuery(store, And.of(PredicateCondition.of(TIME, Cmp.GREATER_THAN_EQUAL, -1000), PredicateCondition.of(TIME, Cmp.LESS_THAN, 1010), PredicateCondition.of(LOCATION, Geo.WITHIN, Geoshape.circle(48.5, 0.5, 1000.00))))); assertEquals(ImmutableSet.of("doc1", "doc4"), ImmutableSet.copyOf(result));
/** * Constructs a circle from a given center point and a radius in kilometer * @param latitude * @param longitude * @param radiusInKM * @return */ public static final Geoshape circle(final double latitude, final double longitude, final double radiusInKM) { return circle((float)latitude,(float)longitude,(float)radiusInKM); }
/** * Constructs a new box shape which is identified by its south-west and north-east corner points * @param southWestLatitude * @param southWestLongitude * @param northEastLatitude * @param northEastLongitude * @return */ public static final Geoshape box(final double southWestLatitude, final double southWestLongitude, final double northEastLatitude, final double northEastLongitude) { return box((float)southWestLatitude,(float)southWestLongitude,(float)northEastLatitude,(float)northEastLongitude); }
@Override public String toString() { Type type = getType(); StringBuilder s = new StringBuilder(); s.append(type.toString().toLowerCase()); switch (type) { case POINT: s.append(getPoint().toString()); break; case CIRCLE: s.append(getPoint().toString()).append(":").append(getRadius()); break; default: s.append("["); for (int i=0;i<size();i++) { if (i>0) s.append(","); s.append(getPoint(i)); } s.append("]"); } return s.toString(); }
private static Object convertToEsType(Object value) { if (value instanceof Number) { if (AttributeUtil.isWholeNumber((Number) value)) { return ((Number) value).longValue(); } else { //double or float return ((Number) value).doubleValue(); } } else if (AttributeUtil.isString(value)) { return value; } else if (value instanceof Geoshape) { Geoshape shape = (Geoshape) value; if (shape.getType() == Geoshape.Type.POINT) { Geoshape.Point p = shape.getPoint(); return new double[]{p.getLongitude(), p.getLatitude()}; } else throw new UnsupportedOperationException("Geo type is not supported: " + shape.getType()); } else if (value instanceof Date || value instanceof Instant) { return value; } else if (value instanceof Boolean) { return value; } else if (value instanceof UUID) { return value.toString(); } else throw new IllegalArgumentException("Unsupported type: " + value.getClass() + " (value: " + value + ")"); }
v.setProperty("time", i); offset = (i % 2 == 0 ? 1 : -1) * (i * 50.0 / numV); v.setProperty("location", Geoshape.point(0.0 + offset, 0.0 + offset)); e.setProperty("category", i % numCategories); e.setProperty("group", i % numGroups); e.setProperty("location", Geoshape.point(0.0 + offset, 0.0 + offset)); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertEquals(i + 1, Iterables.size(tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).vertices())); assertEquals(i + 1, Iterables.size(tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).edges())); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertEquals(5, Iterables.size(tx.query().has("location", Geo.INTERSECT, Geoshape.circle(0.0, 0.0, distance)).has("text", Text.CONTAINS, words[0]).vertices())); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertEquals(i + 1, Iterables.size(tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).vertices())); assertEquals(i + 1, Iterables.size(tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).edges())); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertEquals(5, Iterables.size(tx.query().has("location", Geo.INTERSECT, Geoshape.circle(0.0, 0.0, distance)).has("text", Text.CONTAINS, words[0]).vertices())); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertEquals(i + 1, Iterables.size(tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).vertices())); assertEquals(i + 1, Iterables.size(tx.query().has("location", Geo.WITHIN, Geoshape.circle(0.0, 0.0, distance)).edges())); distance = Geoshape.point(0.0, 0.0).getPoint().distance(Geoshape.point(offset, offset).getPoint()) + 20; assertEquals(5, Iterables.size(tx.query().has("location", Geo.INTERSECT, Geoshape.circle(0.0, 0.0, distance)).has("text", Text.CONTAINS, words[0]).vertices()));
public static Multimap<String, Object> getRandomDocument() { final StringBuilder s = new StringBuilder(); for (int i = 0; i < 3; i++) s.append(RandomGenerator.randomString(5, 8)).append(" "); Multimap values = HashMultimap.create(); values.put(TEXT, s.toString()); values.put(NAME, s.toString()); values.put(TIME, Math.abs(random.nextLong())); values.put(WEIGHT, random.nextDouble()); values.put(LOCATION, Geoshape.point(random.nextDouble() * 180 - 90, random.nextDouble() * 360 - 180)); return values; }