@Override public boolean equals( Value other ) { if ( other instanceof PointValue ) { PointValue pv = (PointValue) other; return Arrays.equals( this.coordinate, pv.coordinate ) && this.getCoordinateReferenceSystem().equals( pv.getCoordinateReferenceSystem() ); } return false; }
@Override public <E extends Exception> void writeTo( ValueWriter<E> writer ) throws E { writer.writePoint( getCoordinateReferenceSystem(), coordinate ); }
@Override public String toString() { String coordString = coordinate.length == 2 ? format( "x: %s, y: %s", coordinate[0], coordinate[1] ) : format( "x: %s, y: %s, z: %s", coordinate[0], coordinate[1], coordinate[2] ); return format( "point({%s, crs: '%s'})", coordString, getCoordinateReferenceSystem().getName() ); //TODO: Use getTypeName -> Breaking change }
private static Value calculateDistance( PointValue p1, PointValue p2 ) { if ( p1.getCoordinateReferenceSystem().equals( p2.getCoordinateReferenceSystem() ) ) { return doubleValue( p1.getCoordinateReferenceSystem().getCalculator().distance( p1, p2 ) ); } else { return NO_VALUE; } }
public static PointValue minPointValue( PointValue reference ) { double[] coordinates = new double[reference.coordinate().length]; Arrays.fill( coordinates, -Double.MAX_VALUE ); return pointValue( reference.getCoordinateReferenceSystem(), coordinates ); }
public static PointValue maxPointValue( PointValue reference ) { double[] coordinates = new double[reference.coordinate().length]; Arrays.fill( coordinates, Double.MAX_VALUE ); return pointValue( reference.getCoordinateReferenceSystem(), coordinates ); }
@Override public void add( Collection<? extends IndexEntryUpdate<?>> updates ) throws IndexEntryConflictException { Map<CoordinateReferenceSystem,List<IndexEntryUpdate<?>>> batchMap = new HashMap<>(); for ( IndexEntryUpdate<?> update : updates ) { PointValue point = (PointValue) update.values()[0]; List<IndexEntryUpdate<?>> batch = batchMap.computeIfAbsent( point.getCoordinateReferenceSystem(), k -> new ArrayList<>() ); batch.add( update ); } for ( Map.Entry<CoordinateReferenceSystem,List<IndexEntryUpdate<?>>> entry : batchMap.entrySet() ) { IndexPopulator partPopulator = select( entry.getKey() ); partPopulator.add( entry.getValue() ); } }
/** * The string representation of this object when indexed in string-only indexes, like lucene, for equality search only. This should normally only * happen when points are part of composite indexes, because otherwise they are indexed in the spatial index. */ public String toIndexableString() { CoordinateReferenceSystem crs = getCoordinateReferenceSystem(); return format( "P:%d-%d%s", crs.getTable().getTableId(), crs.getCode(), Arrays.toString( coordinate ) ); }
@Override Value get( PointValue value ) { return Values.intValue( value.getCoordinateReferenceSystem().getCode() ); } };
@Override Value get( PointValue value ) { return Values.stringValue( value.getCoordinateReferenceSystem().toString() ); } },
@Override public long countIndexedNodes( long nodeId, int[] propertyKeyIds, Value... propertyValues ) { NativeIndexReader<SpatialIndexKey,NativeIndexValue> partReader = uncheckedSelect( ((PointValue) propertyValues[0]).getCoordinateReferenceSystem() ); return partReader == null ? 0L : partReader.countIndexedNodes( nodeId, propertyKeyIds, propertyValues ); }
private static PointArray readPointArray( ByteBuffer bb, int offset ) { final int len = bb.getInt( offset ); offset += Integer.BYTES; final PointValue[] array = new PointValue[len]; for ( int i = 0; i < len; i++ ) { final PointValue point = readPoint( bb, offset ); array[i] = point; offset += Integer.BYTES + point.getCoordinateReferenceSystem().getDimension() * Double.BYTES; } return pointArray( array ); }
@Override public double distance( PointValue p1, PointValue p2 ) { assert p1.getCoordinateReferenceSystem().getDimension() == dimension; assert p2.getCoordinateReferenceSystem().getDimension() == dimension; return pythagoras( p1.coordinate(), p2.coordinate() ); }
@Override public List<Pair<PointValue,PointValue>> boundingBox( PointValue center, double distance ) { assert center.getCoordinateReferenceSystem().getDimension() == dimension; double[] coordinates = center.coordinate(); double[] min = new double[dimension]; double[] max = new double[dimension]; for ( int i = 0; i < dimension; i++ ) { min[i] = coordinates[i] - distance; max[i] = coordinates[i] + distance; } CoordinateReferenceSystem crs = center.getCoordinateReferenceSystem(); return Collections.singletonList( Pair.of( Values.pointValue( crs, min ), Values.pointValue( crs, max ) ) ); } }
@Override public void includeSample( IndexEntryUpdate<?> update ) { Value[] values = update.values(); assert values.length == 1; uncheckedSelect( ((PointValue) values[0]).getCoordinateReferenceSystem() ).includeSample( update ); }
private CoordinateReferenceSystem getCrs( Value value ) { if ( Values.isGeometryValue( value ) ) { return ((PointValue) value).getCoordinateReferenceSystem(); } else if ( Values.isGeometryArray( value ) ) { PointArray array = (PointArray) value; return array.pointValue( 0 ).getCoordinateReferenceSystem(); } throw new IllegalArgumentException( "Expected some geometry value to get CRS from, but got " + value ); }
public static <E extends Exception> void writeTo( ValueWriter<E> writer, Point[] values ) throws E { writer.beginArray( values.length, ValueWriter.ArrayType.POINT ); for ( Point x : values ) { PointValue value = Values.point( x ); writer.writePoint( value.getCoordinateReferenceSystem(), value.coordinate() ); } writer.endArray(); } }
@Override public void write( Object value, FlushableChannel into ) throws IOException { PointValue pointValue = (PointValue) value; // using code is not a future-proof solution like the one we have in the PropertyStore. // But then again, this is not used from procution code. into.putInt( pointValue.getCoordinateReferenceSystem().getCode() ); double[] coordinate = pointValue.coordinate(); into.putInt( coordinate.length ); for ( double c : coordinate ) { into.putDouble( c ); } } } );
DoubleValue getNthCoordinate( int n, String fieldName, boolean onlyGeographic ) { if ( onlyGeographic && !this.getCoordinateReferenceSystem().isGeographic() ) { throw new InvalidValuesArgumentException( "Field: " + fieldName + " is not available on cartesian point: " + this ); } else if ( n >= this.coordinate().length ) { throw new InvalidValuesArgumentException( "Field: " + fieldName + " is not available on point: " + this ); } else { return Values.doubleValue( coordinate[n] ); } }
@Test void shouldBeAbleToParsePointThatOverridesHeaderInformation() { String headerInformation = "{crs:wgs-84}"; String data = "{latitude: 40.7128, longitude: -74.0060, height: 567.8, crs:wgs-84-3D}"; PointValue expected = PointValue.parse( data ); PointValue actual = PointValue.parse( data, PointValue.parseHeaderInformation( headerInformation ) ); assertEqual( expected, actual ); assertEquals( "wgs-84-3d", actual.getCoordinateReferenceSystem().getName().toLowerCase() ); }