package mil.nga.giat.geowave.core.geotime.store.dimension; import java.nio.ByteBuffer; import mil.nga.giat.geowave.core.index.ByteArrayId; import mil.nga.giat.geowave.core.index.PersistenceUtils; import mil.nga.giat.geowave.core.index.dimension.NumericDimensionDefinition; import mil.nga.giat.geowave.core.index.dimension.bin.BinRange; import mil.nga.giat.geowave.core.index.sfc.data.NumericData; import mil.nga.giat.geowave.core.index.sfc.data.NumericRange; import mil.nga.giat.geowave.core.store.data.field.FieldReader; import mil.nga.giat.geowave.core.store.data.field.FieldWriter; import mil.nga.giat.geowave.core.store.dimension.NumericDimensionField; /** * A base class for EPSG:4326 latitude/longitude fields that use JTS geometry * */ abstract public class SpatialField implements NumericDimensionField<GeometryWrapper> { private NumericDimensionDefinition baseDefinition; private final GeometryAdapter geometryAdapter; private ByteArrayId fieldId; protected SpatialField() { geometryAdapter = new GeometryAdapter(); } public SpatialField( final NumericDimensionDefinition baseDefinition ) { this( baseDefinition, GeometryAdapter.DEFAULT_GEOMETRY_FIELD_ID); } @Override public NumericData getFullRange() { return baseDefinition.getFullRange(); } public SpatialField( final NumericDimensionDefinition baseDefinition, final ByteArrayId fieldId ) { this.baseDefinition = baseDefinition; this.fieldId = fieldId; geometryAdapter = new GeometryAdapter(); } @Override public NumericRange getDenormalizedRange( final BinRange range ) { return new NumericRange( range.getNormalizedMin(), range.getNormalizedMax()); } @Override public double getRange() { return baseDefinition.getRange(); } @Override public int getFixedBinIdSize() { return 0; } @Override public NumericRange getBounds() { return baseDefinition.getBounds(); } @Override public double normalize( final double value ) { return baseDefinition.normalize(value); } @Override public double denormalize( final double value ) { return baseDefinition.denormalize(value); } @Override public BinRange[] getNormalizedRanges( final NumericData range ) { return baseDefinition.getNormalizedRanges(range); } @Override public ByteArrayId getFieldId() { return fieldId; } @Override public FieldWriter<?, GeometryWrapper> getWriter() { return geometryAdapter; } @Override public FieldReader<GeometryWrapper> getReader() { return geometryAdapter; } @Override public NumericDimensionDefinition getBaseDefinition() { return baseDefinition; } @Override public byte[] toBinary() { final byte[] dimensionBinary = PersistenceUtils.toBinary(baseDefinition); final ByteBuffer buf = ByteBuffer.allocate(dimensionBinary.length + fieldId.getBytes().length + 4); buf.putInt(fieldId.getBytes().length); buf.put(fieldId.getBytes()); buf.put(dimensionBinary); return buf.array(); } @Override public void fromBinary( final byte[] bytes ) { final ByteBuffer buf = ByteBuffer.wrap(bytes); final int fieldIdLength = buf.getInt(); final byte[] fieldIdBinary = new byte[fieldIdLength]; buf.get(fieldIdBinary); fieldId = new ByteArrayId( fieldIdBinary); final byte[] dimensionBinary = new byte[bytes.length - fieldIdLength - 4]; buf.get(dimensionBinary); baseDefinition = PersistenceUtils.fromBinary( dimensionBinary, NumericDimensionDefinition.class); } @Override public int hashCode() { final int prime = 31; int result = 1; final String className = getClass().getName(); result = (prime * result) + ((className == null) ? 0 : className.hashCode()); result = (prime * result) + ((baseDefinition == null) ? 0 : baseDefinition.hashCode()); result = (prime * result) + ((fieldId == null) ? 0 : fieldId.hashCode()); return result; } @Override public boolean equals( final Object obj ) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final SpatialField other = (SpatialField) obj; if (baseDefinition == null) { if (other.baseDefinition != null) { return false; } } else if (!baseDefinition.equals(other.baseDefinition)) { return false; } if (fieldId == null) { if (other.fieldId != null) { return false; } } else if (!fieldId.equals(other.fieldId)) { return false; } return true; } }