Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import mil.nga.giat.geowave.accumulo.IteratorConfig;
import mil.nga.giat.geowave.accumulo.ModelConvertingDataAdapter;
Expand Down Expand Up @@ -52,6 +51,7 @@
import mil.nga.giat.geowave.store.index.Index;
import mil.nga.giat.geowave.vector.adapter.merge.FeatureCollectionCombiner;
import mil.nga.giat.geowave.vector.plugin.GeoWaveGTDataStore;
import mil.nga.giat.geowave.vector.util.FeatureDataUtils;
import mil.nga.giat.geowave.vector.util.FitToIndexDefaultFeatureCollection;
import mil.nga.giat.geowave.vector.util.SimpleFeatureWrapper;

Expand All @@ -60,26 +60,18 @@
import org.apache.accumulo.core.iterators.Combiner;
import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
import org.apache.accumulo.core.iterators.user.TransformingIterator;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.geotools.data.DataUtilities;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.SchemaException;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;

import com.vividsolutions.jts.geom.Geometry;

/**
* This data adapter will handle all reading/writing concerns for storing and
Expand All @@ -93,7 +85,7 @@
* the term 'start' and the other contains either the term 'stop' or 'end' it
* will interpret the combination of these attributes as a time range to index
* on.
*
*
*/
public class FeatureCollectionDataAdapter extends
AbstractDataAdapter<DefaultFeatureCollection> implements
Expand Down Expand Up @@ -563,60 +555,27 @@ public DefaultFeatureCollection decode(
public Iterator<DefaultFeatureCollection> convertToIndex(
final Index index,
final DefaultFeatureCollection originalEntry ) {
// if the feature is in a different coordinate reference system than
// EPSG:4326, transform the geometry
final SimpleFeatureIterator itr = originalEntry.features();

while (itr.hasNext()) {
SimpleFeature feature = itr.next();
final CoordinateReferenceSystem crs = feature.getFeatureType().getCoordinateReferenceSystem();

if (!GeoWaveGTDataStore.DEFAULT_CRS.equals(crs)) {
MathTransform featureTransform = null;
if ((persistedType.getCoordinateReferenceSystem() != null) && persistedType.getCoordinateReferenceSystem().equals(
crs) && (transform != null)) {
// we can use the transform we have already calculated for
// this feature
featureTransform = transform;
}
else if (crs != null) {
// this feature differs from the persisted type in CRS,
// calculate the transform
try {
featureTransform = CRS.findMathTransform(
crs,
GeoWaveGTDataStore.DEFAULT_CRS,
true);
}
catch (final FactoryException e) {
LOGGER.warn(
"Unable to find transform to EPSG:4326, the feature geometry will remain in its original CRS",
e);
}
}
if (featureTransform != null) {
try {
final Object geom = feature.getDefaultGeometry();

// what should we do besides log a message when an entry
// can't be transformed to EPSG:4326 for some reason?
// this will clone the feature and retype it to
// EPSG:4326
feature = SimpleFeatureBuilder.retype(
feature,
reprojectedType);
// this will transform the geometry
feature.setDefaultGeometry(JTS.transform(
(Geometry) geom,
featureTransform));
}
catch (MismatchedDimensionException | TransformException e) {
LOGGER.warn(
"Unable to perform transform to EPSG:4326, the feature geometry will remain in its original CRS",
e);
}
}
final DefaultFeatureCollection defaultCRSEntry;

if (originalEntry instanceof FitToIndexDefaultFeatureCollection) {
defaultCRSEntry = originalEntry;
}
else {
defaultCRSEntry = new DefaultFeatureCollection(
originalEntry.getID());

final SimpleFeatureIterator itr = originalEntry.features();

while (itr.hasNext()) {
defaultCRSEntry.add(FeatureDataUtils.defaultCRSTransform(
itr.next(),
persistedType,
reprojectedType,
transform));
}

itr.close();
}

final SubStrategy[] subStrategies;
Expand All @@ -635,7 +594,6 @@ else if (index.getIndexStrategy() instanceof SingleTierSubStrategy) {
}
else {
LOGGER.warn("Could not determine index strategy type.");
IOUtils.closeQuietly(itr);
return Collections.<DefaultFeatureCollection> emptyList().iterator();
}

Expand All @@ -646,7 +604,7 @@ else if (index.getIndexStrategy() instanceof SingleTierSubStrategy) {
// next level in the hierarchy
final List<SimpleFeatureWrapper> reprocessQueue = new ArrayList<SimpleFeatureWrapper>();

final Iterator<SimpleFeature> featItr = originalEntry.iterator();
final Iterator<SimpleFeature> featItr = defaultCRSEntry.iterator();

// process each feature and continue processing until all features
// are placed
Expand All @@ -658,10 +616,10 @@ else if (index.getIndexStrategy() instanceof SingleTierSubStrategy) {
// reprocess data before inserting new features
if (featItr.hasNext() && (reprocessQueue.size() == 0)) {
// this is a special case used during global optimization
if (originalEntry instanceof FitToIndexDefaultFeatureCollection) {
if (defaultCRSEntry instanceof FitToIndexDefaultFeatureCollection) {
feature = featItr.next();
subStratIdx = ((FitToIndexDefaultFeatureCollection) originalEntry).getSubStratIdx() + 1;
prevId = ((FitToIndexDefaultFeatureCollection) originalEntry).getIndexId();
subStratIdx = ((FitToIndexDefaultFeatureCollection) defaultCRSEntry).getSubStratIdx() + 1;
prevId = ((FitToIndexDefaultFeatureCollection) defaultCRSEntry).getIndexId();
}
else {
feature = featItr.next();
Expand Down Expand Up @@ -798,7 +756,6 @@ else if ((entry.size() == featuresPerEntry) && ((subStratIdx + 1) < subStrategie
featureCollections.add(collection);
}
}
IOUtils.closeQuietly(itr);
return featureCollections.iterator();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,25 @@
import mil.nga.giat.geowave.vector.plugin.visibility.AdaptorProxyFieldLevelVisibilityHandler;
import mil.nga.giat.geowave.vector.plugin.visibility.JsonDefinitionColumnVisibilityManagement;
import mil.nga.giat.geowave.vector.stats.StatsManager;
import mil.nga.giat.geowave.vector.util.FeatureDataUtils;
import mil.nga.giat.geowave.vector.utils.TimeDescriptors;

import org.apache.log4j.Logger;
import org.geotools.data.DataUtilities;
import org.geotools.feature.SchemaException;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;

import com.vividsolutions.jts.geom.Geometry;

/**
* This data adapter will handle all reading/writing concerns for storing and
* retrieving GeoTools SimpleFeature objects to and from a GeoWave persistent
* store in Accumulo.
*
*
* If the implementor needs to write rows with particular visibility, this can
* be done by providing a FieldVisibilityHandler to a constructor or a
* VisibilityManagement to a constructor. When using VisibilityManagement, the
Expand All @@ -63,26 +57,26 @@
* attribute that contains the visibility meta-data.
* persistedType.getDescriptor("someAttributeName").getUserData().put(
* "visibility", Boolean.TRUE)
*
*
*
*
* The adapter will use the SimpleFeature's default geometry for spatial
* indexing.
*
*
* The adaptor will use the first temporal attribute (a Calendar or Date object)
* as the timestamp of a temporal index.
*
*
* If the feature type contains a UserData property 'time' for a specific time
* attribute with Boolean.TRUE, then the attribute is used as the timestamp of a
* temporal index.
*
*
* If the feature type contains UserData properties 'start' and 'end' for two
* different time attributes with value Boolean.TRUE, then the attributes are
* used for a range index.
*
*
* If the feature type contains a UserData property 'time' for *all* time
* attributes with Boolean.FALSE, then a temporal index is not used.
*
*
*
*
*/
@SuppressWarnings("unchecked")
public class FeatureDataAdapter extends
Expand Down Expand Up @@ -187,7 +181,9 @@ private void setFeatureType(
resetTimeDescriptors();
statsManager = new StatsManager(
this,
persistedType);
persistedType,
reprojectedType,
transform);
}

private static List<NativeFieldHandler<SimpleFeature, Object>> typeToFieldHandlers(
Expand Down Expand Up @@ -383,7 +379,7 @@ protected Object defaultTypeDataFromBinary(
typeName,
encodedType);

TimeDescriptors timeDescriptors = new TimeDescriptors();
final TimeDescriptors timeDescriptors = new TimeDescriptors();
timeDescriptors.fromBinary(
myType,
timeAndRangeBytes);
Expand Down Expand Up @@ -441,57 +437,13 @@ public SimpleFeatureType getType() {
public AdapterPersistenceEncoding encode(
final SimpleFeature entry,
final CommonIndexModel indexModel ) {
// if the feature is in a different coordinate reference system than
// EPSG:4326, transform the geometry
final CoordinateReferenceSystem crs = entry.getFeatureType().getCoordinateReferenceSystem();
SimpleFeature defaultCRSEntry = entry;

if (!GeoWaveGTDataStore.DEFAULT_CRS.equals(crs)) {
MathTransform featureTransform = null;
if ((persistedType.getCoordinateReferenceSystem() != null) && persistedType.getCoordinateReferenceSystem().equals(
crs) && (transform != null)) {
// we can use the transform we have already calculated for this
// feature
featureTransform = transform;
}
else if (crs != null) {
// this feature differs from the persisted type in CRS,
// calculate the transform
try {
featureTransform = CRS.findMathTransform(
crs,
GeoWaveGTDataStore.DEFAULT_CRS,
true);
}
catch (final FactoryException e) {
LOGGER.warn(
"Unable to find transform to EPSG:4326, the feature geometry will remain in its original CRS",
e);
}
}
if (featureTransform != null) {
try {
// what should we do besides log a message when an entry
// can't be transformed to EPSG:4326 for some reason?
// this will clone the feature and retype it to EPSG:4326
defaultCRSEntry = SimpleFeatureBuilder.retype(
entry,
reprojectedType);
// this will transform the geometry
defaultCRSEntry.setDefaultGeometry(JTS.transform(
(Geometry) entry.getDefaultGeometry(),
featureTransform));
}
catch (MismatchedDimensionException | TransformException e) {
LOGGER.warn(
"Unable to perform transform to EPSG:4326, the feature geometry will remain in its original CRS",
e);
}
}
}

return super.encode(
defaultCRSEntry,
FeatureDataUtils.defaultCRSTransform(
entry,
persistedType,
reprojectedType,
transform),
indexModel);
}

Expand Down Expand Up @@ -560,7 +512,7 @@ private void determineVisibilityAttribute() {
@Override
public HadoopWritableSerializer<SimpleFeature, FeatureWritable> createWritableSerializer() {
return new FeatureWritableSerializer(
this.reprojectedType);
reprojectedType);
}

private static class FeatureWritableSerializer implements
Expand All @@ -571,22 +523,22 @@ private static class FeatureWritableSerializer implements
private final FeatureWritable writable;

FeatureWritableSerializer(
SimpleFeatureType type ) {
final SimpleFeatureType type ) {
this.type = type;
writable = new FeatureWritable(
type);
}

@Override
public FeatureWritable toWritable(
SimpleFeature entry ) {
final SimpleFeature entry ) {
writable.setFeature(entry);
return writable;
}

@Override
public SimpleFeature fromWritable(
FeatureWritable writable ) {
final FeatureWritable writable ) {
return writable.getFeature();
}

Expand Down
Loading