use of org.geotoolkit.storage.memory.GenericMappingFeatureCollection in project geotoolkit by Geomatys.
the class FeatureStoreUtilities method decomposeByGeometryType.
/**
* Split the collection by geometry types.
* Multiple feature store can only support a limited number of geometry types.
* This method will split the content of the given collection in collections with a
* simple geometry type.
*
* Collection datas are not copied, result collections are filtered collections
*
* @param col
* @param adaptType : ry to map types even if they do not match exactly.
* list of adapt operations :
* LineString -> MultiLineString
* Polygon -> MultiPolygon
* Point -> MultiPoint
* @param geomClasses
* @return splitted collections
* @throws org.apache.sis.storage.DataStoreException
*/
public static FeatureCollection[] decomposeByGeometryType(FeatureCollection col, GenericName geomPropName, boolean adaptType, Class... geomClasses) throws DataStoreException {
final FilterFactory FF = FilterUtilities.FF;
final FeatureType baseType = col.getType();
final GenericName name = baseType.getName();
final PropertyType geomDesc = baseType.getProperty(geomPropName.toString());
boolean setDefaultGeometryRole = false;
try {
IdentifiedType defaultGeometry = baseType.getProperty(AttributeConvention.GEOMETRY);
setDefaultGeometryRole = defaultGeometry.equals(geomDesc);
while (setDefaultGeometryRole == false && defaultGeometry instanceof Operation) {
defaultGeometry = ((Operation) defaultGeometry).getResult();
setDefaultGeometryRole = defaultGeometry.equals(geomDesc);
}
} catch (PropertyNotFoundException e) {
LOGGER.log(Level.FINEST, "No SIS convention found in given data type", e);
}
final CoordinateReferenceSystem crs = FeatureExt.getCRS(geomDesc);
final List<Class> lstClasses = Arrays.asList(geomClasses);
final FeatureCollection[] cols = new FeatureCollection[geomClasses.length];
for (int i = 0; i < geomClasses.length; i++) {
final Class geomClass = geomClasses[i];
Filter filter = FF.equal(FF.function("geometryType", FF.property(geomPropName.tip().toString())), FF.literal(geomClass.getSimpleName()));
// check if we need to map another type
if (adaptType) {
if (geomClass == MultiPolygon.class && !lstClasses.contains(Polygon.class)) {
filter = FF.or(filter, FF.equal(FF.function("geometryType", FF.property(geomPropName.tip().toString())), FF.literal(Polygon.class.getSimpleName())));
} else if (geomClass == MultiLineString.class && !lstClasses.contains(LineString.class)) {
filter = FF.or(filter, FF.equal(FF.function("geometryType", FF.property(geomPropName.tip().toString())), FF.literal(LineString.class.getSimpleName())));
} else if (geomClass == MultiPoint.class && !lstClasses.contains(Point.class)) {
filter = FF.or(filter, FF.equal(FF.function("geometryType", FF.property(geomPropName.tip().toString())), FF.literal(Point.class.getSimpleName())));
}
}
cols[i] = col.subset(Query.filtered(name.toString(), filter));
// retype the collection
final FeatureTypeBuilder ftb = new FeatureTypeBuilder(baseType);
ftb.setName(NamesExt.create(NamesExt.getNamespace(name), name.tip().toString() + '_' + geomClass.getSimpleName()));
PropertyTypeBuilder geometryBuilder = null;
final Iterator<PropertyTypeBuilder> it = ftb.properties().iterator();
while (geometryBuilder == null && it.hasNext()) {
final PropertyTypeBuilder next = it.next();
if (next.getName().equals(geomPropName)) {
geometryBuilder = next;
it.remove();
}
}
final AttributeTypeBuilder geomAttr = ftb.addAttribute(geomClasses[i]).setCRS(crs);
if (setDefaultGeometryRole) {
geomAttr.addRole(AttributeRole.DEFAULT_GEOMETRY);
}
cols[i] = new GenericMappingFeatureCollection(cols[i], new DefaultFeatureMapper(baseType, ftb.build()));
}
return cols;
}
Aggregations