use of org.opengis.feature.Operation in project geotoolkit by Geomatys.
the class GeoJSONWriter method writeProperties.
/**
* Write ComplexAttribute.
*
* @param edited
* @param fieldName
* @param writeFieldName
* @throws IOException
* @throws IllegalArgumentException
*/
private void writeProperties(Feature edited, String fieldName, boolean writeFieldName, Set<Feature> alreadyWritten) throws IOException, IllegalArgumentException {
if (writeFieldName) {
writer.writeObjectFieldStart(fieldName);
} else {
writer.writeStartObject();
}
FeatureType type = edited.getType();
PropertyType defGeom = FeatureExt.getDefaultGeometrySafe(type).flatMap(Features::toAttribute).orElse(null);
Collection<? extends PropertyType> descriptors = type.getProperties(true).stream().filter(GeoJSONUtils.IS_NOT_CONVENTION).filter(it -> !Objects.equals(defGeom, it)).collect(Collectors.toList());
for (PropertyType propType : descriptors) {
final String name = propType.getName().tip().toString();
final Object value = edited.getPropertyValue(propType.getName().toString());
if (propType instanceof AttributeType) {
final AttributeType attType = (AttributeType) propType;
if (attType.getMaximumOccurs() > 1) {
writer.writeArrayFieldStart(name);
for (Object v : (Collection) value) {
writeProperty(name, v, false, alreadyWritten);
}
writer.writeEndArray();
} else {
writeProperty(name, value, true, alreadyWritten);
}
} else if (propType instanceof FeatureAssociationRole) {
final FeatureAssociationRole asso = (FeatureAssociationRole) propType;
if (asso.getMaximumOccurs() > 1) {
writer.writeFieldName(name);
writeFeatureCollection((List<Feature>) value, asso.getValueType());
} else {
writeProperty(name, value, true, alreadyWritten);
}
} else if (propType instanceof Operation) {
writeProperty(name, value, true, alreadyWritten);
}
}
writer.writeEndObject();
}
use of org.opengis.feature.Operation in project geotoolkit by Geomatys.
the class AbstractReadingTests method testReaders.
/**
* test different readers.
*/
private void testReaders(final FeatureSet featureSet, final ExpectedResult candidate) throws Exception {
final FeatureType type = featureSet.getType();
final Collection<? extends PropertyType> properties = type.getProperties(true);
try (Stream<Feature> stream = featureSet.features(true)) {
stream.forEach((Feature t) -> {
// do nothing
});
throw new Exception("Asking for a reader without any query whould raise an error.");
} catch (Exception ex) {
// ok
}
// property -------------------------------------------------------------
{
// check only id query
final FeatureQuery query = new FeatureQuery();
query.setProjection(new FeatureQuery.NamedExpression(FF.property(AttributeConvention.IDENTIFIER)));
FeatureSet subset = featureSet.subset(query);
FeatureType limited = subset.getType();
assertNotNull(limited);
assertTrue(limited.getProperties(true).size() == 1);
try (Stream<Feature> stream = subset.features(false)) {
final Iterator<Feature> ite = stream.iterator();
while (ite.hasNext()) {
final Feature f = ite.next();
assertNotNull(FeatureExt.getId(f));
}
}
for (final PropertyType desc : properties) {
if (desc instanceof Operation)
continue;
final FeatureQuery sq = new FeatureQuery();
sq.setProjection(new FeatureQuery.NamedExpression(FF.property(desc.getName().tip().toString())));
subset = featureSet.subset(sq);
limited = subset.getType();
assertNotNull(limited);
assertTrue(limited.getProperties(true).size() == 1);
assertNotNull(limited.getProperty(desc.getName().toString()));
try (Stream<Feature> stream = subset.features(false)) {
final Iterator<Feature> ite = stream.iterator();
while (ite.hasNext()) {
final Feature f = ite.next();
assertNotNull(f.getProperty(desc.getName().toString()));
}
}
}
}
// sort by --------------------------------------------------------------
for (final PropertyType desc : properties) {
if (!(desc instanceof AttributeType)) {
continue;
}
final AttributeType att = (AttributeType) desc;
if (att.getMaximumOccurs() > 1) {
// do not test sort by on multi occurence properties
continue;
}
final Class clazz = att.getValueClass();
if (!Comparable.class.isAssignableFrom(clazz) || Geometry.class.isAssignableFrom(clazz)) {
// can not make a sort by on this attribut.
continue;
}
final FeatureQuery query = new FeatureQuery();
query.setSortBy(FF.sort(FF.property(desc.getName().tip().toString()), SortOrder.ASCENDING));
FeatureSet subset = featureSet.subset(query);
// count should not change with a sort by
assertEquals(candidate.size, FeatureStoreUtilities.getCount(subset, true).intValue());
try (Stream<Feature> stream = subset.features(false)) {
final Iterator<Feature> reader = stream.iterator();
Comparable last = null;
while (reader.hasNext()) {
final Feature f = reader.next();
Object obj = f.getProperty(desc.getName().toString()).getValue();
if (obj instanceof Identifier)
obj = ((Identifier) obj).getCode();
final Comparable current = (Comparable) obj;
if (current != null) {
if (last != null) {
// check we have the correct order.
assertTrue(current.compareTo(last) >= 0);
}
last = current;
} else {
// any restriction about where should be placed the feature with null values ? before ? after ?
}
}
}
query.setSortBy(FF.sort(FF.property(desc.getName().tip().toString()), SortOrder.DESCENDING));
subset = featureSet.subset(query);
// count should not change with a sort by
assertEquals(candidate.size, FeatureStoreUtilities.getCount(subset, true).intValue());
try (Stream<Feature> stream = subset.features(false)) {
final Iterator<Feature> reader = stream.iterator();
Comparable last = null;
while (reader.hasNext()) {
final Feature f = reader.next();
Object obj = f.getProperty(desc.getName().toString()).getValue();
if (obj instanceof Identifier)
obj = ((Identifier) obj).getCode();
final Comparable current = (Comparable) obj;
if (current != null) {
if (last != null) {
// check we have the correct order.
assertTrue(current.compareTo(last) <= 0);
}
last = current;
} else {
// any restriction about where should be placed the feature with null values ? before ? after ?
}
}
}
}
// start ----------------------------------------------------------------
if (candidate.size > 1) {
List<ResourceId> ids = new ArrayList<>();
try (Stream<Feature> stream = featureSet.features(false)) {
final Iterator<Feature> ite = stream.iterator();
while (ite.hasNext()) {
ids.add(FeatureExt.getId(ite.next()));
}
}
// skip the first element
final FeatureQuery query = new FeatureQuery();
query.setOffset(1);
try (Stream<Feature> stream = featureSet.subset(query).features(false)) {
final Iterator<Feature> ite = stream.iterator();
int i = 1;
while (ite.hasNext()) {
assertEquals(FeatureExt.getId(ite.next()), ids.get(i));
i++;
}
}
}
// max ------------------------------------------------------------------
if (candidate.size > 1) {
final FeatureQuery query = new FeatureQuery();
query.setLimit(1);
int i = 0;
try (Stream<Feature> stream = featureSet.subset(query).features(false)) {
final Iterator<Feature> ite = stream.iterator();
while (ite.hasNext()) {
ite.next();
i++;
}
}
assertEquals(1, i);
}
// filter ---------------------------------------------------------------
// filters are tested more deeply in the filter module
// we just make a few tests here for sanity check
// todo should we make more deep tests ?
Set<ResourceId> ids = new HashSet<>();
try (Stream<Feature> stream = featureSet.features(false)) {
final Iterator<Feature> ite = stream.iterator();
// peek only one on two ids
boolean oneOnTwo = true;
while (ite.hasNext()) {
final Feature feature = ite.next();
if (oneOnTwo) {
ids.add(FeatureExt.getId(feature));
}
oneOnTwo = !oneOnTwo;
}
}
Set<ResourceId> remaining = new HashSet<>(ids);
final FeatureQuery query = new FeatureQuery();
final Filter f;
switch(ids.size()) {
case 0:
f = Filter.exclude();
break;
case 1:
f = ids.iterator().next();
break;
default:
f = FF.or(ids);
break;
}
query.setSelection(f);
try (Stream<Feature> stream = featureSet.subset(query).features(false)) {
final Iterator<Feature> ite = stream.iterator();
while (ite.hasNext()) {
remaining.remove(FeatureExt.getId(ite.next()));
}
}
assertTrue(remaining.isEmpty());
}
use of org.opengis.feature.Operation in project geotoolkit by Geomatys.
the class JAXPStreamFeatureReader method readFeature.
private Feature readFeature(final FeatureType featureType, final GenericName tagName) throws XMLStreamException {
final Feature feature = featureType.newInstance();
/*
* We create a map and a collection because we can encounter two cases :
* - The case featureType defines a property with max occur > 1.
* - The case featureType defines a property with max occur = 1, and its
* value instance of collection or map.
* We store all encountered name with its linked property in the map, so
* at each value parsed, we can add it in the existing property if its
* value is a list or map. The collection is the final property store,
* we add the all the created properties in it (so we can put multiple
* properties with the same name).
*/
final List<Entry<Operation, Object>> ops = new ArrayList<>();
// read attributes
final int nbAtts = reader.getAttributeCount();
for (int i = 0; i < nbAtts; i++) {
final QName attName = reader.getAttributeName(i);
if ("href".equals(attName.getLocalPart())) {
// or if can't be resolved we will still have the id
try {
final String attVal = reader.getAttributeValue(i);
feature.setPropertyValue(AttributeConvention.IDENTIFIER, attVal);
} catch (IllegalArgumentException ex) {
// do nothing
}
} else {
try {
final AttributeType pd = (AttributeType) featureType.getProperty("@" + attName.getLocalPart());
final String attVal = reader.getAttributeValue(i);
final Object val = ObjectConverters.convert(attVal, pd.getValueClass());
feature.setPropertyValue(pd.getName().toString(), val);
} catch (PropertyNotFoundException ex) {
// do nothing
}
}
}
boolean doNext = true;
// read a real complex type
while (!doNext || reader.hasNext()) {
if (doNext) {
reader.next();
}
doNext = true;
int event = reader.getEventType();
if (event == START_ELEMENT) {
GenericName propName = nameCache.get(reader.getName());
// we skip the boundedby attribute if it's present
if ("boundedBy".equals(propName.tip().toString())) {
toTagEnd("boundedBy");
continue;
}
final String nameAttribute = reader.getAttributeValue(null, "name");
// search property
PropertyType propertyType = null;
FeatureType associationSubType = null;
// search direct name
try {
propertyType = featureType.getProperty(propName.toString());
} catch (PropertyNotFoundException e) {
/*can happen*/
}
// search using only local part
if (propertyType == null) {
try {
propertyType = featureType.getProperty(propName.tip().toString());
} catch (PropertyNotFoundException e) {
/*can happen*/
}
}
// search if we are dealing with a subtype of a feature association role value type
if (propertyType == null) {
try {
final FeatureType candidate = featureTypes.get(propName.toString());
if (candidate != null) {
// search for a FeatureAssociationRole
for (PropertyType pt : featureType.getProperties(true)) {
if (pt instanceof FeatureAssociationRole) {
final FeatureAssociationRole far = (FeatureAssociationRole) pt;
final FeatureType vt = far.getValueType();
if (vt.isAssignableFrom(candidate)) {
propertyType = far;
associationSubType = candidate;
// change property name where data will be stored
propName = far.getName();
break;
}
}
}
}
} catch (IllegalNameException ex) {
Logger.getLogger(JAXPStreamFeatureReader.class.getName()).log(Level.SEVERE, null, ex);
}
}
// skip property if we couldn't find it and user requested it
if (propertyType == null && Boolean.TRUE.equals(this.properties.get(SKIP_UNEXPECTED_PROPERTY_TAGS))) {
toTagEnd(propName.tip().toString());
continue;
}
// search if we have an _any attribute available
if (propertyType == null) {
try {
final AttributeType pd = (AttributeType) featureType.getProperty("_any");
// convert the content as a dom node
final Document doc = readAsDom(propName.tip().toString());
feature.setPropertyValue(pd.getName().toString(), doc);
doNext = false;
continue;
} catch (PropertyNotFoundException e) {
throw new XMLStreamException("Could not find any property fitting named tag " + propName);
}
}
if (propertyType instanceof Operation) {
final Operation opType = (Operation) propertyType;
final PropertyType resultType = (PropertyType) opType.getResult();
final Object value = readPropertyValue(resultType, null, null);
ops.add(new AbstractMap.SimpleImmutableEntry<>((Operation) propertyType, value));
if (resultType.getName().equals(propertyType.getName())) {
// we are already on the next element here, jaxb ate one
doNext = false;
}
continue;
}
// read attributes
if (propertyType instanceof AttributeType) {
final AttributeType<?> attType = (AttributeType) propertyType;
final int nbPropAtts = reader.getAttributeCount();
if (nbPropAtts > 0) {
final Attribute att = (Attribute) feature.getProperty(propName.toString());
for (int i = 0; i < nbPropAtts; i++) {
final QName qname = reader.getAttributeName(i);
final GenericName attName = nameCache.get(new QName(qname.getNamespaceURI(), "@" + qname.getLocalPart()));
final AttributeType<?> charType = attType.characteristics().get(attName.toString());
if (charType != null) {
final String attVal = reader.getAttributeValue(i);
final Object val = ObjectConverters.convert(attVal, charType.getValueClass());
final Attribute chara = charType.newInstance();
chara.setValue(val);
att.characteristics().put(attName.toString(), chara);
}
}
}
}
// check if attribute has it's own mapping
final XSDMapping mapping = GMLConvention.getMapping(propertyType);
if (mapping != null) {
mapping.readValue(reader, propName, feature);
} else {
// parse the value
final Object value = readPropertyValue(propertyType, associationSubType, feature);
setValue(feature, propertyType, propName, nameAttribute, value);
}
} else if (event == END_ELEMENT) {
final QName q = reader.getName();
if (q.getLocalPart().equals("featureMember") || nameCache.get(q).equals(tagName)) {
break;
}
}
}
return feature;
}
use of org.opengis.feature.Operation in project geotoolkit by Geomatys.
the class Utils method propertyValueAsList.
public static Collection<?> propertyValueAsList(Feature feature, String propertyName) {
final Object val = feature.getPropertyValue(propertyName);
final PropertyType type = feature.getType().getProperty(propertyName);
if (type instanceof AttributeType) {
if (((AttributeType) type).getMinimumOccurs() > 1) {
return (Collection<?>) val;
} else {
return Collections.singleton(val);
}
} else if (type instanceof FeatureAssociationRole) {
if (((FeatureAssociationRole) type).getMinimumOccurs() > 1) {
return (Collection<?>) val;
} else {
return Collections.singleton(val);
}
} else if (type instanceof Operation) {
return Collections.singleton(val);
} else {
throw new IllegalArgumentException("Unknown propert type : " + type);
}
}
use of org.opengis.feature.Operation 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;
}
Aggregations