use of org.locationtech.geowave.core.store.dimension.NumericDimensionField in project geowave by locationtech.
the class NumericAttributeIndexProvider method buildIndex.
@Override
public AttributeIndex buildIndex(final String indexName, final DataTypeAdapter<?> adapter, final FieldDescriptor<?> fieldDescriptor) {
final Class<?> bindingClass = fieldDescriptor.bindingClass();
final String fieldName = fieldDescriptor.fieldName();
final NumericIndexStrategy indexStrategy;
final CommonIndexModel indexModel;
if (Byte.class.isAssignableFrom(bindingClass)) {
indexStrategy = new SimpleByteIndexStrategy();
indexModel = new BasicIndexModel(new NumericDimensionField[] { new BasicNumericDimensionField<>(fieldName, Byte.class) });
} else if (Short.class.isAssignableFrom(bindingClass)) {
indexStrategy = new SimpleShortIndexStrategy();
indexModel = new BasicIndexModel(new NumericDimensionField[] { new BasicNumericDimensionField<>(fieldName, Short.class) });
} else if (Integer.class.isAssignableFrom(bindingClass)) {
indexStrategy = new SimpleIntegerIndexStrategy();
indexModel = new BasicIndexModel(new NumericDimensionField[] { new BasicNumericDimensionField<>(fieldName, Integer.class) });
} else if (Long.class.isAssignableFrom(bindingClass)) {
indexStrategy = new SimpleLongIndexStrategy();
indexModel = new BasicIndexModel(new NumericDimensionField[] { new BasicNumericDimensionField<>(fieldName, Long.class) });
} else if (Float.class.isAssignableFrom(bindingClass)) {
indexStrategy = new SimpleFloatIndexStrategy();
indexModel = new BasicIndexModel(new NumericDimensionField[] { new BasicNumericDimensionField<>(fieldName, Float.class) });
} else if (Double.class.isAssignableFrom(bindingClass)) {
indexStrategy = new SimpleDoubleIndexStrategy();
indexModel = new BasicIndexModel(new NumericDimensionField[] { new BasicNumericDimensionField<>(fieldName, Double.class) });
} else {
throw new ParameterException("Unsupported numeric attribute index class: " + bindingClass.getName());
}
return new AttributeIndexImpl(indexStrategy, indexModel, indexName, fieldName);
}
use of org.locationtech.geowave.core.store.dimension.NumericDimensionField in project geowave by locationtech.
the class AbstractPartitioner method initIndex.
protected void initIndex(final CommonIndexModel indexModel, final double[] distancePerDimensionForIndex) {
// truncating to lower precision
final NumericDimensionField<?>[] dimensions = indexModel.getDimensions();
int totalRequestedPrecision = 0;
final int[] dimensionPrecision = new int[indexModel.getDimensions().length];
for (int i = 0; i < dimensionPrecision.length; i++) {
// total
final double distance = distancePerDimensionForIndex[i] * 2.0;
// width...(radius)
// adjust by precision factory (0 to 1.0)
dimensionPrecision[i] = (int) (precisionFactor * Math.abs((int) (Math.log(dimensions[i].getRange() / distance) / Math.log(2))));
totalRequestedPrecision += dimensionPrecision[i];
}
if (totalRequestedPrecision > 63) {
final double rescale = 63.0 / totalRequestedPrecision;
for (int i = 0; i < dimensionPrecision.length; i++) {
dimensionPrecision[i] = (int) (rescale * dimensionPrecision[i]);
}
}
final TieredSFCIndexStrategy indexStrategy = TieredSFCIndexFactory.createSingleTierStrategy(indexModel.getDimensions(), dimensionPrecision, SFCType.HILBERT);
// Not relevant since this is a single tier strategy.
// For now, just setting to a non-zero reasonable value
indexStrategy.setMaxEstimatedDuplicateIdsPerDimension(2);
index = new IndexImpl(indexStrategy, indexModel);
}
use of org.locationtech.geowave.core.store.dimension.NumericDimensionField in project geowave by locationtech.
the class SpatialDimensionalityTypeProvider method createIndexFromOptions.
public static Index createIndexFromOptions(final SpatialOptions options) {
NumericDimensionDefinition[] dimensions;
boolean isDefaultCRS;
String crsCode = null;
NumericDimensionField<?>[] fields = null;
NumericDimensionField<?>[] fields_temporal = null;
final Integer geometryPrecision = options.getGeometryPrecision();
if ((options.crs == null) || options.crs.isEmpty() || options.crs.equalsIgnoreCase(GeometryUtils.DEFAULT_CRS_STR)) {
dimensions = SPATIAL_DIMENSIONS;
fields = getSpatialFields(geometryPrecision);
isDefaultCRS = true;
crsCode = "EPSG:4326";
} else {
final CoordinateReferenceSystem crs = GeometryUtils.decodeCRS(options.crs);
final CoordinateSystem cs = crs.getCoordinateSystem();
isDefaultCRS = false;
crsCode = options.crs;
dimensions = new NumericDimensionDefinition[cs.getDimension()];
if (options.storeTime) {
fields_temporal = new NumericDimensionField[dimensions.length + 1];
for (int d = 0; d < dimensions.length; d++) {
final CoordinateSystemAxis csa = cs.getAxis(d);
if (!isUnbounded(csa)) {
dimensions[d] = new CustomCRSBoundedSpatialDimension((byte) d, csa.getMinimumValue(), csa.getMaximumValue());
fields_temporal[d] = new CustomCRSSpatialField((CustomCRSBoundedSpatialDimension) dimensions[d], geometryPrecision, crs);
} else {
dimensions[d] = new CustomCRSUnboundedSpatialDimension(DEFAULT_UNBOUNDED_CRS_INTERVAL, (byte) d);
fields_temporal[d] = new CustomCRSSpatialField((CustomCRSUnboundedSpatialDimension) dimensions[d], geometryPrecision, crs);
}
}
fields_temporal[dimensions.length] = new TimeField(Unit.YEAR);
} else {
fields = new NumericDimensionField[dimensions.length];
for (int d = 0; d < dimensions.length; d++) {
final CoordinateSystemAxis csa = cs.getAxis(d);
if (!isUnbounded(csa)) {
if (d == 0) {
dimensions[d] = new CustomCRSBoundedSpatialDimensionX(csa.getMinimumValue(), csa.getMaximumValue());
fields[d] = new CustomCRSSpatialField((CustomCRSBoundedSpatialDimensionX) dimensions[d], geometryPrecision, crs);
}
if (d == 1) {
dimensions[d] = new CustomCRSBoundedSpatialDimensionY(csa.getMinimumValue(), csa.getMaximumValue());
fields[d] = new CustomCRSSpatialField((CustomCRSBoundedSpatialDimensionY) dimensions[d], geometryPrecision, crs);
}
} else {
if (d == 0) {
dimensions[d] = new CustomCRSUnboundedSpatialDimensionX(DEFAULT_UNBOUNDED_CRS_INTERVAL, (byte) d);
fields[d] = new CustomCRSSpatialField((CustomCRSUnboundedSpatialDimensionX) dimensions[d], geometryPrecision, crs);
}
if (d == 1) {
dimensions[d] = new CustomCRSUnboundedSpatialDimensionY(DEFAULT_UNBOUNDED_CRS_INTERVAL, (byte) d);
fields[d] = new CustomCRSSpatialField((CustomCRSUnboundedSpatialDimensionY) dimensions[d], geometryPrecision, crs);
}
}
}
}
}
BasicIndexModel indexModel = null;
if (isDefaultCRS) {
indexModel = new BasicIndexModel(options.storeTime ? getSpatialTemporalFields(geometryPrecision) : getSpatialFields(geometryPrecision));
} else {
indexModel = new CustomCrsIndexModel(options.storeTime ? fields_temporal : fields, crsCode);
}
return new CustomNameIndex(XZHierarchicalIndexFactory.createFullIncrementalTieredStrategy(dimensions, new int[] { // flexible enough to handle n-dimensions
LONGITUDE_BITS, LATITUDE_BITS }, SFCType.HILBERT), indexModel, // TODO append CRS code to ID if its overridden
isDefaultCRS ? (options.storeTime ? DEFAULT_SPATIAL_ID + "_TIME" : DEFAULT_SPATIAL_ID) : (options.storeTime ? DEFAULT_SPATIAL_ID + "_TIME" : DEFAULT_SPATIAL_ID) + "_" + crsCode.substring(crsCode.indexOf(":") + 1));
}
use of org.locationtech.geowave.core.store.dimension.NumericDimensionField in project geowave by locationtech.
the class FilterConstraints method getIndexData.
/**
* Get the multi-dimensional index data from these constraints.
*
* @return the multi-dimensional index data
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public List<MultiDimensionalIndexData<V>> getIndexData() {
if (cachedIndexData == null) {
if ((adapter == null) || (index == null) || (indexMapping == null)) {
return Lists.newArrayList();
}
if (index instanceof CustomIndex) {
final TextIndexStrategy indexStrategy = (TextIndexStrategy) ((CustomIndex) index).getCustomIndexStrategy();
if (!(indexStrategy.getEntryConverter() instanceof AdapterFieldTextIndexEntryConverter)) {
throw new RuntimeException("Unable to determine adapter field used by text index.");
}
final String fieldName = ((AdapterFieldTextIndexEntryConverter) indexStrategy.getEntryConverter()).getFieldName();
final IndexFieldConstraints<?> fieldConstraint = fieldConstraints.get(fieldName);
final List<DimensionConstraints<String>> dimensionConstraints = Lists.newArrayList();
if (fieldConstraint == null) {
dimensionConstraints.add(DimensionConstraints.of(Lists.newArrayList(FilterRange.of((String) null, (String) null, true, true, true))));
} else if (fieldConstraint instanceof TextFieldConstraints) {
final DimensionConstraints<String> dimensionConstraint = ((TextFieldConstraints) fieldConstraint).getDimensionRanges(0);
if (dimensionConstraint == null) {
dimensionConstraints.add(DimensionConstraints.of(Lists.newArrayList(FilterRange.of((String) null, (String) null, true, true, true))));
} else {
dimensionConstraints.add(dimensionConstraint);
}
} else {
throw new RuntimeException("Non-text field constraints cannot be used for a text index.");
}
cachedIndexData = (List) TextFieldConstraints.toIndexData(dimensionConstraints);
} else {
// Right now all index strategies that aren't custom are numeric
final CommonIndexModel indexModel = index.getIndexModel();
final int numStrategyDimensions = index.getIndexStrategy().getOrderedDimensionDefinitions().length;
final List<DimensionConstraints<Double>> dimensionConstraints = Lists.newArrayListWithCapacity(numStrategyDimensions);
final Map<String, Integer> indexFieldDimensions = Maps.newHashMap();
final NumericDimensionField<?>[] dimensions = indexModel.getDimensions();
int dimensionIndex = 0;
for (final NumericDimensionField<?> indexField : dimensions) {
if (dimensionIndex >= numStrategyDimensions) {
// Only build constraints for dimensions used by the index strategy.
break;
}
dimensionIndex++;
final String indexFieldName = indexField.getFieldName();
if (!indexFieldDimensions.containsKey(indexFieldName)) {
indexFieldDimensions.put(indexFieldName, 0);
}
final int indexFieldDimension = indexFieldDimensions.get(indexFieldName);
final IndexFieldMapper<?, ?> mapper = indexMapping.getMapperForIndexField(indexFieldName);
final String[] adapterFields = mapper.getIndexOrderedAdapterFields();
IndexFieldConstraints<?> fieldConstraint = null;
if (adapterFields.length > 1 && isSingleDimension(indexFieldName, dimensions)) {
// constraints
for (int i = 0; i < adapterFields.length; i++) {
final IndexFieldConstraints<?> constraint = fieldConstraints.get(adapterFields[i]);
if (fieldConstraint == null) {
fieldConstraint = constraint;
} else {
fieldConstraint.and((IndexFieldConstraints) constraint);
}
}
} else {
fieldConstraint = fieldConstraints.get(adapterFields[indexFieldDimension % adapterFields.length]);
}
if (fieldConstraint == null) {
dimensionConstraints.add(DimensionConstraints.of(Lists.newArrayList(FilterRange.of((Double) null, (Double) null, true, true, true))));
} else if (fieldConstraint instanceof NumericFieldConstraints) {
final DimensionConstraints<Double> dimensionConstraint = ((NumericFieldConstraints) fieldConstraint).getDimensionRanges(indexFieldDimension % fieldConstraint.getDimensionCount());
if (dimensionConstraint == null) {
dimensionConstraints.add(DimensionConstraints.of(Lists.newArrayList(FilterRange.of((Double) null, (Double) null, true, true, true))));
} else {
dimensionConstraints.add(dimensionConstraint);
}
indexFieldDimensions.put(indexFieldName, indexFieldDimension + 1);
} else {
throw new RuntimeException("Non-numeric field constraints cannot be used for a numeric index.");
}
}
cachedIndexData = (List) NumericFieldConstraints.toIndexData(dimensionConstraints);
}
}
return cachedIndexData;
}
use of org.locationtech.geowave.core.store.dimension.NumericDimensionField in project geowave by locationtech.
the class GeoWaveGTDataStore method getPreferredIndices.
public Index[] getPreferredIndices(final GeotoolsFeatureDataAdapter adapter) {
final List<Index> currentSelectionsList = new ArrayList<>(2);
final List<String> indexNames = SimpleFeaturePrimaryIndexConfiguration.getIndexNames(adapter.getFeatureType());
final boolean canUseTime = adapter.hasTemporalConstraints();
/**
* Requires the indices to EXIST prior to set up of the adapter. Otherwise, only Geospatial is
* chosen and the index Names are ignored.
*/
CoordinateReferenceSystem selectedCRS = null;
try (CloseableIterator<Index> indices = indexStore.getIndices()) {
while (indices.hasNext()) {
final Index index = indices.next();
final CoordinateReferenceSystem indexCRS = GeometryUtils.getIndexCrs(index);
if ((selectedCRS != null) && !selectedCRS.equals(indexCRS)) {
continue;
}
if (!indexNames.isEmpty()) {
// Only used selected preferred indices
if (indexNames.contains(index.getName())) {
selectedCRS = indexCRS;
currentSelectionsList.add(index);
}
}
final NumericDimensionField<?>[] dims = index.getIndexModel().getDimensions();
boolean hasLat = false;
boolean hasLong = false;
boolean hasTime = false;
for (final NumericDimensionField<?> dim : dims) {
hasLat |= SpatialIndexUtils.isLatitudeDimension(dim);
hasLong |= SpatialIndexUtils.isLongitudeDimension(dim);
hasTime |= dim instanceof TimeField;
}
if (hasLat && hasLong) {
// constraints)
if (!hasTime || canUseTime) {
selectedCRS = indexCRS;
currentSelectionsList.add(index);
}
}
}
}
if (currentSelectionsList.isEmpty()) {
currentSelectionsList.add(SpatialDimensionalityTypeProvider.createIndexFromOptions(new SpatialOptions()));
}
return currentSelectionsList.toArray(new Index[currentSelectionsList.size()]);
}
Aggregations