use of org.opengis.feature.AttributeType in project geotoolkit by Geomatys.
the class MIFManager method deriveBaseTypes.
/**
* Try to compute {@link #midType} and {@link #mifBaseType} from input feature type.
* Implementation note : We'll try to remove reserved attributes (style rules), then we'll remove geometry to build mid type.
* Finally, if input type contained a geometry, we use it to build the mif base type.
*
* @param ft The data type to analyze and decompose.
*/
private void deriveBaseTypes(final FeatureType ft) {
FeatureTypeBuilder ftb = new FeatureTypeBuilder(ft);
ftb.setName(ft.getName().toString() + "_properties");
final Iterator<PropertyTypeBuilder> it = ftb.properties().iterator();
AttributeType geometry = null;
boolean sisGeometry = false;
while (it.hasNext()) {
final PropertyTypeBuilder next = it.next();
/* We have to determine if it's a geometry we should override (generify).
* We'll also check if it's a supported type.
*/
if (next instanceof AttributeTypeBuilder) {
final AttributeTypeBuilder builder = (AttributeTypeBuilder) next;
final Class valueClass = builder.getValueClass();
if (Geometry.class.isAssignableFrom(valueClass)) {
if (geometry != null) {
throw new IllegalArgumentException("Only one geometry is accepted for mif-mid, but given type contains multiple : " + System.lineSeparator() + ft);
} else if (!Geometry.class.equals(valueClass)) {
builder.setValueClass(Geometry.class);
}
geometry = builder.build();
// Geometry property is set aside, because we'll build mid type without geometry, then use it to build mif-type with geometry.
it.remove();
} else if (MIFUtils.getColumnMIFType(valueClass) == null) {
// not supported
throw new IllegalArgumentException("MIF-MID format cannot write elements of type " + valueClass);
}
} else if (AttributeConvention.GEOMETRY_PROPERTY.equals(next.getName())) {
sisGeometry = true;
it.remove();
}
}
if (ftb.properties().size() < 1 && ftb.getSuperTypes().length == 1) {
midType = ft.getSuperTypes().iterator().next();
mifBaseType = ft;
} else {
midType = ftb.build();
if (geometry != null || sisGeometry) {
ftb = new FeatureTypeBuilder();
ftb.setSuperTypes(midType);
ftb.setName(ft.getName());
if (geometry != null) {
final AttributeTypeBuilder geomBuilder = ftb.addAttribute(geometry);
if (sisGeometry) {
geomBuilder.addRole(AttributeRole.DEFAULT_GEOMETRY);
}
} else {
ftb.addProperty(ft.getProperty(AttributeConvention.GEOMETRY));
}
mifBaseType = ftb.build();
}
}
}
use of org.opengis.feature.AttributeType in project geotoolkit by Geomatys.
the class MIFStoreTest method testCreate.
/**
* Test store creation.
*
* @throws Exception
*/
@Test
public void testCreate() throws Exception {
final Path f = Files.createTempFile(tempDir, "test", ".mif");
final MIFProvider ff = (MIFProvider) DataStores.getProviderById("MIF-MID");
final Parameters params = Parameters.castOrWrap(ff.getOpenParameters().createValue());
params.getOrCreate(MIFProvider.PATH).setValue(f.toUri());
// create new store from scratch
try (final MIFStore store = (MIFStore) ff.open(params)) {
assertNotNull(store);
// create a feature type
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
ftb.setName("test");
ftb.addAttribute(Integer.class).setName("integerProp");
ftb.addAttribute(Double.class).setName("doubleProp");
ftb.addAttribute(String.class).setName("stringProp");
ftb.addAttribute(Point.class).setName("geometryProp").setCRS(CommonCRS.WGS84.normalizedGeographic());
final FeatureType featureType = ftb.build();
store.add(new DefiningFeatureSet(featureType, null));
assertEquals(1, store.components().size());
WritableFeatureSet resource = (WritableFeatureSet) store.components().iterator().next();
FeatureType ft = resource.getType();
for (PropertyType desc : featureType.getProperties(true)) {
if (!(desc instanceof AttributeType))
// ignore conventions and operations
continue;
PropertyType td = ft.getProperty(desc.getName().toString());
assertNotNull(td);
assertTrue(((AttributeType) td).getValueClass().isAssignableFrom(((AttributeType) desc).getValueClass()));
}
Feature feature1 = ft.newInstance();
feature1.setPropertyValue("integerProp", 8);
feature1.setPropertyValue("doubleProp", 3.12);
feature1.setPropertyValue("stringProp", "hello");
feature1.setPropertyValue("geometryProp", GF.createPoint(new Coordinate(10.3, 15.7)));
Feature feature2 = ft.newInstance();
feature2.setPropertyValue("integerProp", -15);
feature2.setPropertyValue("doubleProp", -7.1);
feature2.setPropertyValue("stringProp", "world");
feature2.setPropertyValue("geometryProp", GF.createPoint(new Coordinate(-1.6, -5.4)));
final List<Feature> expectedFeatures = new ArrayList<>(2);
expectedFeatures.add(feature1);
expectedFeatures.add(feature2);
resource.add(Arrays.asList(feature1, feature2).iterator());
checkFeatures(expectedFeatures, resource, new FeatureQuery());
}
}
use of org.opengis.feature.AttributeType in project geotoolkit by Geomatys.
the class FeatureExt method fill.
private static void fill(final ParameterValueGroup source, final Feature target) {
final ParameterDescriptorGroup paramdesc = source.getDescriptor();
for (final PropertyType desc : target.getType().getProperties(true)) {
if (desc instanceof FeatureAssociationRole) {
final FeatureAssociationRole assRole = (FeatureAssociationRole) desc;
try {
final List<ParameterValueGroup> groups = source.groups(desc.getName().tip().toString());
if (groups != null) {
for (ParameterValueGroup gr : groups) {
final FeatureAssociation att = assRole.newInstance();
final Feature val = assRole.getValueType().newInstance();
att.setValue(val);
fill(gr, val);
target.setProperty(att);
}
}
} catch (Exception ex) {
// parameter might not exist of might be a group
}
} else if (desc instanceof AttributeType) {
final AttributeType at = (AttributeType) desc;
final String code = desc.getName().tip().toString();
final GeneralParameterValue gpv = searchParameter(source, code);
if (gpv instanceof ParameterValue) {
target.setPropertyValue(code, ((ParameterValue) gpv).getValue());
}
}
}
}
use of org.opengis.feature.AttributeType in project geotoolkit by Geomatys.
the class FeatureExt method transform.
/**
* Create a transformed version of the feature type with the new CRS.
*
* @param type FeatureType
* @param crs , new crs for geometric attributes
* @return FeatureType
*/
public static FeatureType transform(FeatureType type, CoordinateReferenceSystem crs) {
final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
ftb.setName(type.getName());
ftb.setAbstract(type.isAbstract());
ftb.setSuperTypes(type.getSuperTypes().toArray(new FeatureType[0]));
for (PropertyType pt : type.getProperties(false)) {
if (pt instanceof AttributeType && Geometry.class.isAssignableFrom(((AttributeType) pt).getValueClass())) {
final AttributeType qualifier = new DefaultAttributeType(Collections.singletonMap(NAME_KEY, AttributeConvention.CRS_CHARACTERISTIC), CoordinateReferenceSystem.class, 1, 1, crs);
AttributeType at = (AttributeType) pt;
at = new DefaultAttributeType(extractIdentification(pt), at.getValueClass(), at.getMinimumOccurs(), at.getMaximumOccurs(), at.getDefaultValue(), qualifier);
ftb.addProperty(at);
} else {
ftb.addProperty(pt);
}
}
return ftb.build();
}
use of org.opengis.feature.AttributeType in project geotoolkit by Geomatys.
the class FeatureExt method prepareGeometryExtractor.
/**
* Try to create an operator to extract primary geometry from features of a specific type. This method offers the
* following advantages:
* <ul>
* <li>When read geometry does not define any CRS, we assign the one extracted from related property type.</li>
* <li>Property/characteristic analysis is done on assembly, to ensure minimal overhead on result function execution.</li>
* </ul>
*
* @param targetType Type of the features that will be passed as input to the resulting function. Cannot be null.
* @return A function for geometry extraction from features whose is or inherits from input type. Never null.
* If we cannot return a valid value, an error will be thrown as specified by {@link #getDefaultGeometry(FeatureType)}.
* @throws RuntimeException See {@link #getDefaultGeometry(FeatureType)}.
*/
public static Function<Feature, Geometry> prepareGeometryExtractor(final FeatureType targetType) {
ensureNonNull("Target type", targetType);
PropertyType geom = getDefaultGeometry(targetType);
// Minor optimisation : directly use geometry attribute in case a link convention has been set.
geom = Features.getLinkTarget(geom).map(name -> targetType.getProperty(name)).orElse(geom);
final AttributeType<?> attr = Features.toAttribute(geom).orElseThrow(() -> new IllegalStateException("Cannot extract geometries when associate type is not an attribute"));
final Class<?> vClass = attr.getValueClass();
if (!Geometry.class.isAssignableFrom(vClass)) {
throw new UnsupportedOperationException("Only JTS geometries are supported for now.");
}
// Name is built from geom, not attr, because attr can be a virtual result property, not present in source type.
// For example, if you've got two numeric attributes x and y, then add a concatenation operation, you've got no
// geometric attribute, but a geometric operation.
final String name = geom.getName().toString();
final CoordinateReferenceSystem crs = AttributeConvention.getCRSCharacteristic(targetType, attr);
if (crs == null) {
return f -> (Geometry) f.getPropertyValue(name);
} else {
return f -> {
final Object value = f.getPropertyValue(name);
if (value == null)
return null;
final Geometry geometry = (Geometry) value;
final CoordinateReferenceSystem currentCrs;
try {
currentCrs = JTS.findCoordinateReferenceSystem(geometry);
} catch (FactoryException e) {
throw new BackingStoreException(e);
}
if (currentCrs == null)
JTS.setCRS(geometry, crs);
return geometry;
};
}
}
Aggregations