use of org.locationtech.geogig.api.plumbing.diff.GeometryAttributeDiff in project GeoGig by boundlessgeo.
the class MergeFeaturesOp method merge.
@SuppressWarnings("unchecked")
private Feature merge(RevFeature featureA, RevFeature featureB, RevFeature ancestor, RevFeatureType featureType) {
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder((SimpleFeatureType) featureType.type());
ImmutableList<Optional<Object>> valuesA = featureA.getValues();
ImmutableList<Optional<Object>> valuesB = featureB.getValues();
ImmutableList<Optional<Object>> valuesAncestor = ancestor.getValues();
ImmutableList<PropertyDescriptor> descriptors = featureType.sortedDescriptors();
for (int i = 0; i < descriptors.size(); i++) {
PropertyDescriptor descriptor = descriptors.get(i);
boolean isGeom = Geometry.class.isAssignableFrom(descriptor.getType().getBinding());
Name name = descriptor.getName();
Optional<Object> valueAncestor = valuesAncestor.get(i);
Optional<Object> valueA = valuesA.get(i);
Optional<Object> valueB = valuesB.get(i);
if (!valueA.equals(valueAncestor)) {
Optional<Object> merged = valueA;
if (isGeom && !valueB.equals(valueAncestor)) {
// true merge is only done with
// geometries
GeometryAttributeDiff diffB = new GeometryAttributeDiff(Optional.fromNullable((Geometry) valueAncestor.orNull()), Optional.fromNullable((Geometry) valueB.orNull()));
merged = (Optional<Object>) diffB.applyOn(valueA);
}
featureBuilder.set(name, merged.orNull());
} else {
featureBuilder.set(name, valueB.orNull());
}
}
return featureBuilder.buildFeature(nodeRefA.name());
}
use of org.locationtech.geogig.api.plumbing.diff.GeometryAttributeDiff in project GeoGig by boundlessgeo.
the class FeatureDiffWeb method run.
/**
* Runs the command and builds the appropriate response
*
* @param context - the context to use for this command
*
* @throws CommandSpecException
*/
@Override
public void run(CommandContext context) {
if (path == null || path.trim().isEmpty()) {
throw new CommandSpecException("No path for feature name specifed");
}
final Context geogig = this.getCommandLocator(context);
ObjectId newId = geogig.command(ResolveTreeish.class).setTreeish(newTreeish).call().get();
ObjectId oldId = geogig.command(ResolveTreeish.class).setTreeish(oldTreeish).call().get();
RevFeature newFeature = null;
RevFeatureType newFeatureType = null;
RevFeature oldFeature = null;
RevFeatureType oldFeatureType = null;
final Map<PropertyDescriptor, AttributeDiff> diffs;
Optional<NodeRef> ref = parseID(newId, geogig);
Optional<RevObject> object;
// need these to determine if the feature was added or removed so I can build the diffs
// myself until the FeatureDiff supports null values
boolean removed = false;
boolean added = false;
if (ref.isPresent()) {
object = geogig.command(RevObjectParse.class).setObjectId(ref.get().getMetadataId()).call();
if (object.isPresent() && object.get() instanceof RevFeatureType) {
newFeatureType = (RevFeatureType) object.get();
} else {
throw new CommandSpecException("Couldn't resolve newCommit's featureType");
}
object = geogig.command(RevObjectParse.class).setObjectId(ref.get().objectId()).call();
if (object.isPresent() && object.get() instanceof RevFeature) {
newFeature = (RevFeature) object.get();
} else {
throw new CommandSpecException("Couldn't resolve newCommit's feature");
}
} else {
removed = true;
}
if (!oldId.equals(ObjectId.NULL)) {
ref = parseID(oldId, geogig);
if (ref.isPresent()) {
object = geogig.command(RevObjectParse.class).setObjectId(ref.get().getMetadataId()).call();
if (object.isPresent() && object.get() instanceof RevFeatureType) {
oldFeatureType = (RevFeatureType) object.get();
} else {
throw new CommandSpecException("Couldn't resolve oldCommit's featureType");
}
object = geogig.command(RevObjectParse.class).setObjectId(ref.get().objectId()).call();
if (object.isPresent() && object.get() instanceof RevFeature) {
oldFeature = (RevFeature) object.get();
} else {
throw new CommandSpecException("Couldn't resolve oldCommit's feature");
}
} else {
added = true;
}
} else {
added = true;
}
if (removed) {
Map<PropertyDescriptor, AttributeDiff> tempDiffs = new HashMap<PropertyDescriptor, AttributeDiff>();
ImmutableList<PropertyDescriptor> attributes = oldFeatureType.sortedDescriptors();
ImmutableList<Optional<Object>> values = oldFeature.getValues();
for (int index = 0; index < attributes.size(); index++) {
Optional<Object> value = values.get(index);
if (Geometry.class.isAssignableFrom(attributes.get(index).getType().getBinding())) {
Optional<Geometry> temp = Optional.absent();
if (value.isPresent() || all) {
tempDiffs.put(attributes.get(index), new GeometryAttributeDiff(Optional.fromNullable((Geometry) value.orNull()), temp));
}
} else {
if (value.isPresent() || all) {
tempDiffs.put(attributes.get(index), new GenericAttributeDiffImpl(value, Optional.absent()));
}
}
}
diffs = tempDiffs;
} else if (added) {
Map<PropertyDescriptor, AttributeDiff> tempDiffs = new HashMap<PropertyDescriptor, AttributeDiff>();
ImmutableList<PropertyDescriptor> attributes = newFeatureType.sortedDescriptors();
ImmutableList<Optional<Object>> values = newFeature.getValues();
for (int index = 0; index < attributes.size(); index++) {
Optional<Object> value = values.get(index);
if (Geometry.class.isAssignableFrom(attributes.get(index).getType().getBinding())) {
Optional<Geometry> temp = Optional.absent();
if (value.isPresent() || all) {
tempDiffs.put(attributes.get(index), new GeometryAttributeDiff(temp, Optional.fromNullable((Geometry) value.orNull())));
}
} else {
if (value.isPresent() || all) {
tempDiffs.put(attributes.get(index), new GenericAttributeDiffImpl(Optional.absent(), value));
}
}
}
diffs = tempDiffs;
} else {
FeatureDiff diff = new FeatureDiff(path, newFeature, oldFeature, newFeatureType, oldFeatureType, all);
diffs = diff.getDiffs();
}
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
out.writeFeatureDiffResponse(diffs);
out.finish();
}
});
}
Aggregations