@SqlNullable @Description("Returns the first point of a LINESTRING geometry as a Point") @ScalarFunction("ST_StartPoint") @SqlType(GEOMETRY_TYPE_NAME) public static Slice stStartPoint(@SqlType(GEOMETRY_TYPE_NAME) Slice input) { OGCGeometry geometry = deserialize(input); validateType("ST_StartPoint", geometry, EnumSet.of(LINE_STRING)); if (geometry.isEmpty()) { return null; } MultiPath lines = (MultiPath) geometry.getEsriGeometry(); SpatialReference reference = geometry.getEsriSpatialReference(); return serialize(createFromEsriGeometry(lines.getPoint(0), reference)); }
case ST_CONTAINS: if (probeFirst) { return (buildGeometry, probeGeometry, radius) -> probeGeometry.contains(buildGeometry); return (buildGeometry, probeGeometry, radius) -> buildGeometry.contains(probeGeometry); return (buildGeometry, probeGeometry, radius) -> probeGeometry.within(buildGeometry); return (buildGeometry, probeGeometry, radius) -> buildGeometry.within(probeGeometry); return (buildGeometry, probeGeometry, radius) -> buildGeometry.intersects(probeGeometry); case ST_DISTANCE: if (comparisonOperator.get() == LESS_THAN) { return (buildGeometry, probeGeometry, radius) -> buildGeometry.distance(probeGeometry) < radius.getAsDouble(); return (buildGeometry, probeGeometry, radius) -> buildGeometry.distance(probeGeometry) <= radius.getAsDouble();
protected void assertAggregatedGeometries(String testDescription, String expectedWkt, String... wkts) { List<Slice> geometrySlices = Arrays.stream(wkts) .map(text -> text == null ? null : OGCGeometry.fromText(text)) .map(input -> input == null ? null : GeometrySerde.serialize(input)) .collect(Collectors.toList()); // Add a custom equality assertion because the resulting geometry may have // its constituent points in a different order BiFunction<Object, Object, Boolean> equalityFunction = (left, right) -> { if (left == null && right == null) { return true; } if (left == null || right == null) { return false; } OGCGeometry leftGeometry = OGCGeometry.fromText(left.toString()); OGCGeometry rightGeometry = OGCGeometry.fromText(right.toString()); // Check for equality by getting the difference return leftGeometry.difference(rightGeometry).isEmpty() && rightGeometry.difference(leftGeometry).isEmpty(); }; // Test in forward and reverse order to verify that ordering doesn't affect the output assertAggregation(function, equalityFunction, testDescription, new Page(BlockAssertions.createSlicesBlock(geometrySlices)), expectedWkt); Collections.reverse(geometrySlices); assertAggregation(function, equalityFunction, testDescription, new Page(BlockAssertions.createSlicesBlock(geometrySlices)), expectedWkt); }
public void eval() { com.esri.core.geometry.ogc.OGCGeometry geom1; com.esri.core.geometry.ogc.OGCGeometry geom2; geom1 = com.esri.core.geometry.ogc.OGCGeometry .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); geom2 = com.esri.core.geometry.ogc.OGCGeometry .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); out.value = geom1.intersects(geom2) ? 1 : 0; } }
public void eval() { com.esri.core.geometry.ogc.OGCGeometry geom1; com.esri.core.geometry.ogc.OGCGeometry geom2; geom1 = com.esri.core.geometry.ogc.OGCGeometry .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); geom2 = com.esri.core.geometry.ogc.OGCGeometry .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); out.value = geom1.distance(geom2); } }
public void eval() { com.esri.core.geometry.ogc.OGCGeometry geom1; com.esri.core.geometry.ogc.OGCGeometry geom2; geom1 = com.esri.core.geometry.ogc.OGCGeometry .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); geom2 = com.esri.core.geometry.ogc.OGCGeometry .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); out.value = geom1.contains(geom2) ? 1 : 0; } }
public double distance(OGCGeometry another) { if (this == another) { return isEmpty() ? Double.NaN : 0; } if (another.geometryType() == OGCConcreteGeometryCollection.TYPE) { return another.distance(this); } com.esri.core.geometry.Geometry geom1 = getEsriGeometry(); com.esri.core.geometry.Geometry geom2 = another.getEsriGeometry(); return com.esri.core.geometry.GeometryEngine.distance(geom1, geom2, getEsriSpatialReference()); }
public void eval() { com.esri.core.geometry.ogc.OGCGeometry geomSrc = com.esri.core.geometry.ogc.OGCGeometry .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); java.nio.ByteBuffer geomBytes; if (geomSrc.geometryType().equals("Point")) { com.esri.core.geometry.ogc.OGCPoint pointGeom = (com.esri.core.geometry.ogc.OGCPoint) geomSrc; result = transform.transform(new org.osgeo.proj4j.ProjCoordinate(pointGeom.X(), pointGeom.Y()), result); new com.esri.core.geometry.Point(result.x, result.y), sr).asBinary(); } else { com.esri.core.geometry.Geometry esriGeom = geomSrc.getEsriGeometry(); com.esri.core.geometry.MultiVertexGeometry vertexGeom = com.esri.core.geometry.VertexGeomAccessor.getVertexGeometry(esriGeom); com.esri.core.geometry.ogc.OGCGeometry.createFromEsriGeometry(esriGeom, sr); geomBytes = tGeom.asBinary();
@SqlNullable @Description("Returns the 2-dimensional cartesian minimum distance (based on spatial ref) between two geometries in projected units") @ScalarFunction("ST_Distance") @SqlType(DOUBLE) public static Double stDistance(@SqlType(GEOMETRY_TYPE_NAME) Slice left, @SqlType(GEOMETRY_TYPE_NAME) Slice right) { OGCGeometry leftGeometry = deserialize(left); OGCGeometry rightGeometry = deserialize(right); verifySameSpatialReference(leftGeometry, rightGeometry); return leftGeometry.isEmpty() || rightGeometry.isEmpty() ? null : leftGeometry.distance(rightGeometry); }
private static void writeSimpleGeometry(DynamicSliceOutput output, GeometrySerializationType type, OGCGeometry geometry) { output.appendByte(type.code()); Geometry esriGeometry = requireNonNull(geometry.getEsriGeometry(), "esriGeometry is null"); byte[] shape = geometryToEsriShape(esriGeometry); output.appendBytes(shape); }
public void eval() { com.esri.core.geometry.ogc.OGCGeometry geom1; geom1 = com.esri.core.geometry.ogc.OGCGeometry .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); com.esri.core.geometry.ogc.OGCGeometry envelopeGeom; if (geom1.geometryType().equals("Point")) { envelopeGeom = geom1; } else { envelopeGeom = geom1.envelope(); } java.nio.ByteBuffer envelopeGeomBytes = envelopeGeom.asBinary(); int outputSize = envelopeGeomBytes.remaining(); buffer = out.buffer = buffer.reallocIfNeeded(outputSize); out.start = 0; out.end = outputSize; buffer.setBytes(0, envelopeGeomBytes); } }
@Description("Returns the 2D Euclidean area of a geometry") @ScalarFunction("ST_Area") @SqlType(DOUBLE) public static double stArea(@SqlType(GEOMETRY_TYPE_NAME) Slice input) { OGCGeometry geometry = deserialize(input); // The Esri geometry library does not support area for geometry collections. We compute the area // of collections by summing the area of the individual components. GeometryType type = GeometryType.getForEsriGeometryType(geometry.geometryType()); if (type == GeometryType.GEOMETRY_COLLECTION) { double area = 0.0; GeometryCursor cursor = geometry.getEsriGeometryCursor(); while (true) { com.esri.core.geometry.Geometry esriGeometry = cursor.next(); if (esriGeometry == null) { return area; } area += esriGeometry.calculateArea2D(); } } return geometry.getEsriGeometry().calculateArea2D(); }
@Description("Returns the cardinality of the geometry collection") @ScalarFunction("ST_NumGeometries") @SqlType(INTEGER) public static long stNumGeometries(@SqlType(GEOMETRY_TYPE_NAME) Slice input) { OGCGeometry geometry = deserialize(input); if (geometry.isEmpty()) { return 0; } GeometryType type = GeometryType.getForEsriGeometryType(geometry.geometryType()); if (!type.isMultitype()) { return 1; } return ((OGCGeometryCollection) geometry).numGeometries(); }
public void eval() { int srid = sridParam.value; String wktText = org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(input.start, input.end, input.buffer); com.esri.core.geometry.ogc.OGCGeometry geom; geom = com.esri.core.geometry.ogc.OGCGeometry.fromText(wktText); geom.setSpatialReference(com.esri.core.geometry.SpatialReference.create(srid)); java.nio.ByteBuffer pointBytes = geom.asBinary(); int outputSize = pointBytes.remaining(); buffer = out.buffer = buffer.reallocIfNeeded(outputSize); out.start = 0; out.end = outputSize; buffer.setBytes(0, pointBytes); } }
@Description("Returns the closure of the combinatorial boundary of this Geometry") @ScalarFunction("ST_Boundary") @SqlType(GEOMETRY_TYPE_NAME) public static Slice stBoundary(@SqlType(GEOMETRY_TYPE_NAME) Slice input) { OGCGeometry geometry = deserialize(input); if (geometry.isEmpty() && GeometryType.getForEsriGeometryType(geometry.geometryType()) == LINE_STRING) { // OCGGeometry#boundary crashes with NPE for LINESTRING EMPTY return EMPTY_MULTIPOINT; } return serialize(geometry.boundary()); }
public void eval() { com.esri.core.geometry.ogc.OGCGeometry geom1; com.esri.core.geometry.ogc.OGCGeometry geom2; geom1 = com.esri.core.geometry.ogc.OGCGeometry .fromBinary(geom1Param.buffer.nioBuffer(geom1Param.start, geom1Param.end - geom1Param.start)); geom2 = com.esri.core.geometry.ogc.OGCGeometry .fromBinary(geom2Param.buffer.nioBuffer(geom2Param.start, geom2Param.end - geom2Param.start)); com.esri.core.geometry.ogc.OGCGeometry diffGeom = geom1.difference(geom2); java.nio.ByteBuffer bufferedGeomBytes = diffGeom.asBinary(); int outputSize = bufferedGeomBytes.remaining(); buffer = out.buffer = buffer.reallocIfNeeded(outputSize); out.start = 0; out.end = outputSize; buffer.setBytes(0, bufferedGeomBytes); } }
@SqlNullable @Description("Returns the great-circle distance in meters between two SphericalGeography points.") @ScalarFunction("ST_Distance") @SqlType(DOUBLE) public static Double stSphericalDistance(@SqlType(SPHERICAL_GEOGRAPHY_TYPE_NAME) Slice left, @SqlType(SPHERICAL_GEOGRAPHY_TYPE_NAME) Slice right) { OGCGeometry leftGeometry = deserialize(left); OGCGeometry rightGeometry = deserialize(right); if (leftGeometry.isEmpty() || rightGeometry.isEmpty()) { return null; } // TODO: support more SphericalGeography types. validateSphericalType("ST_Distance", leftGeometry, EnumSet.of(POINT)); validateSphericalType("ST_Distance", rightGeometry, EnumSet.of(POINT)); Point leftPoint = (Point) leftGeometry.getEsriGeometry(); Point rightPoint = (Point) rightGeometry.getEsriGeometry(); // greatCircleDistance returns distance in KM. return greatCircleDistance(leftPoint.getY(), leftPoint.getX(), rightPoint.getY(), rightPoint.getX()) * 1000; }
@Description("Returns the minimum convex geometry that encloses all input geometries") @ScalarFunction("ST_ConvexHull") @SqlType(GEOMETRY_TYPE_NAME) public static Slice stConvexHull(@SqlType(GEOMETRY_TYPE_NAME) Slice input) { OGCGeometry geometry = deserialize(input); if (geometry.isEmpty()) { return input; } if (GeometryType.getForEsriGeometryType(geometry.geometryType()) == POINT) { return input; } return serialize(geometry.convexHull()); }
@Benchmark public Object stContainsInnerPointDeserialized(BenchmarkData data) { return data.ogcGeometry.contains(data.innerOgcPoint); }
@Override public boolean contains(OGCGeometry another) { if (isEmpty() || another.isEmpty()) return false; if (this == another) return true; return another.difference(this).isEmpty(); }