use of org.opengis.feature.IdentifiedType in project geotoolkit by Geomatys.
the class JAXBFeatureTypeReader method getType.
private Object getType(String namespaceURI, ComplexType type, BuildStack stack, boolean useCache) {
final GenericName name = extractFinalName(namespaceURI, type);
if (useCache && typesCache.containsKey(name)) {
return typesCache.get(name);
}
for (XSDMapping.Spi mapping : mappings) {
final XSDMapping map = mapping.create(name, this, type);
if (map != null) {
IdentifiedType mappedType = map.getType();
if (mappedType instanceof AttributeType) {
AttributeType at = (AttributeType) mappedType;
AttributeTypeBuilder atb = new FeatureTypeBuilder().addAttribute(at);
atb.addCharacteristic(XSDMapping.class).setName(GMLConvention.MAPPING).setDefaultValue(map);
mappedType = atb.build();
// AttributeType[] att = (AttributeType[]) at.characteristics().values().toArray(new AttributeType[0]);
// final Map properties = new HashMap();
// properties.put(AbstractIdentifiedType.NAME_KEY, at.getName());
// properties.put(AbstractIdentifiedType.DEFINITION_KEY, at.getDefinition());
// properties.put(AbstractIdentifiedType.DEPRECATED_KEY, ((Deprecable) at).isDeprecated());
// properties.put(AbstractIdentifiedType.DESCRIPTION_KEY, at.getDescription());
// properties.put(AbstractIdentifiedType.DESIGNATION_KEY, at.getDesignation());
// mappedType = new MappedAttributeType(
// properties,
// at.getValueClass(),
// at.getMinimumOccurs(),
// at.getMaximumOccurs(),
// at.getDefaultValue(),
// map,
// att);
}
typesCache.put(name, mappedType);
return mappedType;
}
}
// special case for gml:ReferenceType
final String namespace = NamesExt.getNamespace(name);
if ((GMLConvention.GML_311_NAMESPACE.equals(namespace) || GMLConvention.GML_321_NAMESPACE.equals(namespace)) && "ReferenceType".equals(name.tip().toString())) {
// note : can't use real AbstractGMLType, recursive object creation
final QName gml = new QName(namespace, "AbstractGMLType");
final Object abstractGmlType = getType(gml, stack);
if (abstractGmlType instanceof GenericName) {
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
FeatureAssociationRole far = ftb.addAssociation((GenericName) abstractGmlType).setName(name).build();
typesCache.put(name, far);
return far;
} else {
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
FeatureAssociationRole far = ftb.addAssociation((FeatureType) abstractGmlType).setName(name).build();
typesCache.put(name, far);
return far;
}
}
final boolean deprecated = GMLConvention.isDeprecated(type);
// read simple content type if defined
final SimpleContent simpleContent = type.getSimpleContent();
if (simpleContent != null) {
final ExtensionType sext = simpleContent.getExtension();
if (sext != null) {
// simple type base, it must be : this is the content of the tag <tag>XXX<tag>
// it is not named, so we call it value
final QName base = sext.getBase();
final AttributeType st = (AttributeType) resolveType(base, stack);
final AttributeTypeBuilder atb = new FeatureTypeBuilder().addAttribute(st);
atb.setName(name);
atb.setDeprecated(deprecated);
// read attributes
for (PropertyType property : getAnnotatedAttributes(namespaceURI, sext.getAttributeOrAttributeGroup(), stack)) {
CharacteristicTypeBuilder cb = atb.getCharacteristic(property.getName().toString());
if (cb == null) {
atb.addCharacteristic((AttributeType) property);
} else {
// characteristic already exist
}
}
final AttributeType att = atb.build();
typesCache.put(name, att);
return att;
}
final SimpleRestrictionType restriction = simpleContent.getRestriction();
if (restriction != null) {
final QName base = restriction.getBase();
if (base != null) {
final ComplexType sct = xsdContext.findComplexType(base);
if (sct != null) {
final AttributeType tct = (AttributeType) getType(namespaceURI, sct, stack, true);
final AttributeTypeBuilder atb = new FeatureTypeBuilder().addAttribute(tct);
atb.setName(name);
atb.setDeprecated(deprecated);
// read attributes
for (PropertyType property : getAnnotatedAttributes(namespaceURI, restriction.getAttributeOrAttributeGroup(), stack)) {
CharacteristicTypeBuilder cb = atb.getCharacteristic(property.getName().toString());
if (cb == null) {
atb.addCharacteristic((AttributeType) property);
} else {
// characteristic already exist
}
}
final AttributeType att = atb.build();
typesCache.put(name, att);
return att;
} else {
// final PropertyType restType = resolveType(base, stack);
// addOrReplace(finalType.builder, atb.create(restType, NamesExt.create(namespaceURI, Utils.VALUE_PROPERTY_NAME), 0, 1, false, null));
}
}
}
throw new MismatchedFeatureException("Undefined simple type : " + name);
}
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
ftb.setName(name);
ftb.setDeprecated(deprecated);
// read attributes
for (PropertyType property : getAnnotatedAttributes(namespaceURI, type.getAttributeOrAttributeGroup(), stack)) {
addProperty(ftb, property);
}
// read sequence properties
for (PropertyType property : getGroupAttributes(namespaceURI, type.getSequence(), stack)) {
addProperty(ftb, property);
}
// read complex content if defined
final ComplexContent content = type.getComplexContent();
if (content != null) {
final ExtensionType extension = content.getExtension();
if (extension != null) {
final QName base = extension.getBase();
if (base != null && !base.getLocalPart().equalsIgnoreCase("anytype")) {
final Object parent = getType(base, stack);
if (parent instanceof FeatureType) {
ftb.setSuperTypes((FeatureType) parent);
} else if (parent instanceof GenericName) {
// parent type is currently being resolved
return name;
}
}
// read attributes
for (PropertyType property : getAnnotatedAttributes(namespaceURI, extension.getAttributeOrAttributeGroup(), stack)) {
addProperty(ftb, property);
}
// read groups
for (PropertyType property : getGroupAttributes(namespaceURI, extension.getSequence(), stack)) {
addProperty(ftb, property);
}
}
/* BIG DIRTY HACK: Needed for GML 2.1.2 support.
* For geometry definition, GML 2 propose an association to some
* data-type defined by restiction over an abstract geometry type.
* But, we do not want it to an association, we want it to be an
* attribute, for god sake ! So, we cheat and if we find a structure
* like that, we transform it into attribute (oh god that's awful).
*/
final ComplexRestrictionType restriction = content.getRestriction();
if (restriction != null) {
final QName base = restriction.getBase();
if (base != null) {
Object restrictionType = getType(base, stack);
if (restrictionType instanceof FeatureType) {
ftb.setSuperTypes((FeatureType) restrictionType);
}
// final ComplexType sct = xsdContext.findComplexType(base);
// if (sct != null) {
// final Object obj = getType(base.getNamespaceURI(), sct, stack);
// if (obj instanceof FeatureType
// // && isGeometric((FeatureType)obj)
// ) {
// final ExplicitGroup sequence = sct.getSequence();
// if (sequence != null) {
// final List<Element> elements = sequence.getElements();
// if (elements != null && !elements.isEmpty()) {
// Element e = sequence.getElements().get(0);
// return ftb.addAttribute(Geometry.class)
// .setName(e.getRef().getLocalPart())
// .setMinimumOccurs(sequence.getMinOccurs())
// .build();
// }
// }
// } else if (obj instanceof PropertyType) {
// final PropertyTypeBuilder ptb = new FeatureTypeBuilder().addProperty((PropertyType) obj);
// if (ptb instanceof PropertyTypeBuilder) {
// final AttributeTypeBuilder atb = (AttributeTypeBuilder) ptb;
// // check characteristics
// for (PropertyType property : getAnnotatedAttributes(namespaceURI, restriction.getAttributeOrAttributeGroup(), stack)) {
// if (atb.getCharacteristic(property.getName().toString()) == null) {
// atb.addCharacteristic((AttributeType) property);
// }
// }
// }
// }
// }
}
}
}
// read choice if set
final ExplicitGroup choice = type.getChoice();
if (choice != null) {
// this is the case of gml:location
}
// // if (GMLConvention.isDecoratedProperty(featureType.getName().tip().toString())) {
// // //Used by geometry property types but also in some gml profils
// // final String decoratedName = NamesExt.toExpandedString(featureType.getName());
// //
// // //this is an encapsulated property, we unroll it
// // final Collection<? extends PropertyType> subProps = featureType.getProperties(true);
// // //we peek the first association, there should be only one
// // //but attributes are possible
// // for (PropertyType pt : subProps) {
// // if (pt.getName().tip().toString().startsWith("@")) {
// // //ignore xml attributes
// // continue;
// // }
// //
// // if (pt instanceof FeatureAssociationRole) {
// // /* HACK : GML 3.1.1 : Only way I've found to manage
// // * geometries as attributes. If we've found an association,
// // * and if it's feature type is a geometric property
// // * (derived from abstract geometric type), well, we
// // * return a geometric property.
// // */
// // final FeatureAssociationRole subFar = (FeatureAssociationRole) pt;
// // FeatureType valueType = subFar.getValueType();
// // FeatureAssociationRole ar = ftb
// // .addAssociation(subFar)
// // .setDescription(GMLConvention.DECORATED_DESCRIPTION+NamesExt.toExpandedString(subFar.getName()))
// // .build();
// //
// // typesCache.put(name, ar);
// // return featureType;
// // } else if (pt instanceof AttributeType) {
// // AttributeType at = (AttributeType) pt;
// //
// // ftb.clear();
// // at = ftb.addAttribute(at).setDescription(GMLConvention.DECORATED_DESCRIPTION+" "+NamesExt.toExpandedString(at.getName())).build();
// // typesCache.put(name, at);
// // return at;
// // }
// // }
// //
// // throw new UnsupportedOperationException("Decorated property without any property");
// //
// // }
// define the default geometry
PropertyTypeBuilder candidateDefaultGeom = null;
for (PropertyTypeBuilder ptb : ftb.properties()) {
if (ptb instanceof AttributeTypeBuilder) {
Class valueClass = ((AttributeTypeBuilder) ptb).getValueClass();
if (Geometry.class.isAssignableFrom(valueClass)) {
XSDMapping mapping = GMLConvention.getMapping(ptb.build());
if (mapping instanceof GeometryMapping) {
if (((GeometryMapping) mapping).isDecorated()) {
// keep it as a candidate, we prefere undecorated properties
candidateDefaultGeom = ptb;
} else {
candidateDefaultGeom = null;
((AttributeTypeBuilder) ptb).addRole(AttributeRole.DEFAULT_GEOMETRY);
break;
}
}
}
}
}
if (candidateDefaultGeom != null) {
((AttributeTypeBuilder) candidateDefaultGeom).addRole(AttributeRole.DEFAULT_GEOMETRY);
}
FeatureType featureType = ftb.build();
typesCache.put(name, featureType);
return featureType;
}
use of org.opengis.feature.IdentifiedType in project geotoolkit by Geomatys.
the class Query method reproject.
/**
* Create a simple query with columns which transform all geometric types to the given crs.
*/
public static FeatureQuery reproject(FeatureType type, final CoordinateReferenceSystem crs) {
final FilterFactory ff = FilterUtilities.FF;
final Literal crsLiteral = ff.literal(crs);
final FeatureQuery query = new FeatureQuery();
final List<FeatureQuery.NamedExpression> columns = new ArrayList<>();
for (PropertyType pt : type.getProperties(true)) {
final GenericName name = pt.getName();
Expression property = ff.property(name.toString());
// unroll operation
IdentifiedType result = pt;
while (result instanceof Operation) {
result = ((Operation) result).getResult();
}
if (result instanceof AttributeType) {
AttributeType at = (AttributeType) result;
if (Geometry.class.isAssignableFrom(at.getValueClass())) {
property = ff.function("ST_Transform", property, crsLiteral);
}
}
columns.add(new FeatureQuery.NamedExpression(property, name));
}
query.setProjection(columns.toArray(new FeatureQuery.NamedExpression[0]));
return query;
}
use of org.opengis.feature.IdentifiedType 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;
}
use of org.opengis.feature.IdentifiedType in project geotoolkit by Geomatys.
the class MIFUtils method identifyFeature.
/**
* Check the given FeatureType to know if its geometry property can be managed by MIF writer. Here we check feature
* type and not geometry because of style information which can be stored in the feature.
* @param toIdentify The feature type to check geometry.
* @return The MIF {@link GeometryType} corresponding to this feature.
*/
static Optional<GeometryType> identifyFeature(Feature toIdentify) {
GeometryType type = null;
/* We'll check for the exact featureType first, and if there's no matching, we'll refine our search by checking
* the geometry classes.
*/
final FeatureType inputType = toIdentify.getType();
final CoordinateReferenceSystem crsParam = FeatureExt.getCRS(inputType);
FeatureType superParam = null;
final Set<? extends FeatureType> superTypes = inputType.getSuperTypes();
if (!superTypes.isEmpty()) {
superParam = (FeatureType) superTypes.iterator().next();
}
for (GeometryType gType : GeometryType.values()) {
if (FeatureExt.sameProperties(gType.getBinding(crsParam, superParam), inputType, true)) {
type = gType;
break;
}
}
// for some types, we don't need to get the same featureType, only a matching geometry class will be sufficient.
final IdentifiedType geomType;
if (type != null) {
return Optional.of(type);
} else {
return FeatureExt.getDefaultGeometryValue(toIdentify).map(Object::getClass).map(MIFUtils::getGeometryType);
}
}
use of org.opengis.feature.IdentifiedType in project geotoolkit by Geomatys.
the class ComplexTypeBinding method get.
@Override
public <T> T get(FeatureType type, String xpath, Class<T> target) throws IllegalArgumentException {
if (type == null)
return null;
xpath = stripPrefix(xpath);
if (!xpath.isEmpty() && xpath.charAt(0) == '{') {
xpath = NamesExt.valueOf(xpath).toString();
}
String name = xpath;
PropertyType propertyType;
try {
// May throw IllegalArgumentException.
propertyType = type.getProperty(name);
final GenericName baseName = propertyType.getName();
while (propertyType instanceof Operation) {
final IdentifiedType it = ((Operation) propertyType).getResult();
if (it instanceof PropertyType) {
propertyType = (PropertyType) it;
} else if (it instanceof FeatureType) {
return (T) new DefaultAssociationRole(Collections.singletonMap(DefaultAssociationRole.NAME_KEY, baseName), type, 1, 1);
} else {
throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalPropertyValueClass_3, name, PropertyType.class, Classes.getStandardType(Classes.getClass(it))));
}
}
// preserve original name
if (!baseName.equals(propertyType.getName())) {
if (propertyType instanceof AttributeType) {
propertyType = new FeatureTypeBuilder().addAttribute((AttributeType) propertyType).setName(baseName).build();
}
}
} catch (PropertyNotFoundException ex) {
return null;
}
return (T) propertyType;
}
Aggregations