use of com.vividsolutions.jts.geom.Envelope in project GeoGig by boundlessgeo.
the class WriteTree2 method handleRemainingDifferences.
private void handleRemainingDifferences(TreeDifference treeDifference, Set<String> ignoreList) {
// old/new refs to trees that have changed and apply to the pathFilters, deepest paths first
final SortedMap<NodeRef, NodeRef> changedTrees = treeDifference.findChanges();
// filterChanges(changedTrees);
final SortedMap<NodeRef, NodeRef> filteredChangedTrees = changedTrees;
for (Map.Entry<NodeRef, NodeRef> changedTreeRefs : filteredChangedTrees.entrySet()) {
NodeRef leftTreeRef = changedTreeRefs.getKey();
NodeRef rightTreeRef = changedTreeRefs.getValue();
String newPath = rightTreeRef.path();
if (ignoreList.contains(newPath)) {
continue;
}
if (!filterApplies(newPath, treeDifference.getRightTree())) {
continue;
}
ignoreList.add(newPath);
RevTree tree = applyChanges(leftTreeRef, rightTreeRef);
Envelope bounds = SpatialOps.boundsOf(tree);
Node newTreeNode = Node.create(rightTreeRef.name(), tree.getId(), rightTreeRef.getMetadataId(), TYPE.TREE, bounds);
MutableTree leftRoot = treeDifference.getLeftTree();
String parentPath = rightTreeRef.getParentPath();
leftRoot.setChild(parentPath, newTreeNode);
}
}
use of com.vividsolutions.jts.geom.Envelope in project GeoGig by boundlessgeo.
the class MutableTree method build.
public RevTree build(ObjectDatabase origin, ObjectDatabase target) {
final ObjectId nodeId = node.getObjectId();
final RevTree tree = origin.getTree(nodeId);
RevTreeBuilder builder = tree.builder(target).clearSubtrees();
for (MutableTree childTree : this.childTrees.values()) {
String name;
ObjectId newObjectId;
ObjectId metadataId;
Envelope bounds;
{
RevTree newChild = childTree.build(origin, target);
target.put(newChild);
Node oldNode = childTree.getNode();
name = oldNode.getName();
newObjectId = newChild.getId();
metadataId = oldNode.getMetadataId().or(ObjectId.NULL);
bounds = SpatialOps.boundsOf(newChild);
}
Node newNode = Node.create(name, newObjectId, metadataId, TYPE.TREE, bounds);
builder.put(newNode);
}
RevTree newTree = builder.build();
if (!this.node.getObjectId().equals(newTree.getId())) {
target.put(newTree);
Envelope bounds = SpatialOps.boundsOf(newTree);
this.node = Node.create(node.getName(), newTree.getId(), node.getMetadataId().or(ObjectId.NULL), TYPE.TREE, bounds);
}
return newTree;
}
use of com.vividsolutions.jts.geom.Envelope in project GeoGig by boundlessgeo.
the class ResolveConflict 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 (this.getTransactionId() == null) {
throw new CommandSpecException("No transaction was specified, add requires a transaction to preserve the stability of the repository.");
}
final Context geogig = this.getCommandLocator(context);
RevTree revTree = geogig.workingTree().getTree();
Optional<NodeRef> nodeRef = geogig.command(FindTreeChild.class).setParent(revTree).setChildPath(NodeRef.parentPath(path)).setIndex(true).call();
Preconditions.checkArgument(nodeRef.isPresent(), "Invalid reference: %s", NodeRef.parentPath(path));
RevFeatureType revFeatureType = geogig.command(RevObjectParse.class).setObjectId(nodeRef.get().getMetadataId()).call(RevFeatureType.class).get();
RevFeature revFeature = geogig.command(RevObjectParse.class).setObjectId(objectId).call(RevFeature.class).get();
CoordinateReferenceSystem crs = revFeatureType.type().getCoordinateReferenceSystem();
Envelope bounds = ReferencedEnvelope.create(crs);
Optional<Object> o;
for (int i = 0; i < revFeature.getValues().size(); i++) {
o = revFeature.getValues().get(i);
if (o.isPresent() && o.get() instanceof Geometry) {
Geometry g = (Geometry) o.get();
if (bounds.isNull()) {
bounds.init(JTS.bounds(g, crs));
} else {
bounds.expandToInclude(JTS.bounds(g, crs));
}
}
}
NodeRef node = new NodeRef(Node.create(NodeRef.nodeFromPath(path), objectId, ObjectId.NULL, TYPE.FEATURE, bounds), NodeRef.parentPath(path), ObjectId.NULL);
Optional<NodeRef> parentNode = geogig.command(FindTreeChild.class).setParent(geogig.workingTree().getTree()).setChildPath(node.getParentPath()).setIndex(true).call();
RevTreeBuilder treeBuilder = null;
ObjectId metadataId = ObjectId.NULL;
if (parentNode.isPresent()) {
metadataId = parentNode.get().getMetadataId();
Optional<RevTree> parsed = geogig.command(RevObjectParse.class).setObjectId(parentNode.get().getNode().getObjectId()).call(RevTree.class);
checkState(parsed.isPresent(), "Parent tree couldn't be found in the repository.");
treeBuilder = new RevTreeBuilder(geogig.objectDatabase(), parsed.get());
treeBuilder.remove(node.getNode().getName());
} else {
treeBuilder = new RevTreeBuilder(geogig.stagingDatabase());
}
treeBuilder.put(node.getNode());
ObjectId newTreeId = geogig.command(WriteBack.class).setAncestor(geogig.workingTree().getTree().builder(geogig.stagingDatabase())).setChildPath(node.getParentPath()).setToIndex(true).setTree(treeBuilder.build()).setMetadataId(metadataId).call();
geogig.workingTree().updateWorkHead(newTreeId);
AddOp command = geogig.command(AddOp.class);
command.addPattern(path);
command.call();
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
out.writeElement("Add", "Success");
out.finish();
}
});
}
use of com.vividsolutions.jts.geom.Envelope in project GeoGig by boundlessgeo.
the class RevTreeBuilder method normalizeToBuckets.
/**
* @return
*
*/
private RevTree normalizeToBuckets() {
// update all inner trees
final ImmutableSet<Integer> changedBucketIndexes;
// aggregate size delta for all changed buckets
long sizeDelta = 0L;
// aggregate number of trees delta for all changed buckets
int treesDelta = 0;
try {
Multimap<Integer, Node> changesByBucket = getChangesByBucket();
Preconditions.checkState(featureChanges.isEmpty());
Preconditions.checkState(treeChanges.isEmpty());
Preconditions.checkState(deletes.isEmpty());
changedBucketIndexes = ImmutableSet.copyOf(changesByBucket.keySet());
final Map<Integer, RevTree> bucketTrees = getBucketTrees(changedBucketIndexes);
List<RevTree> newLeafTreesToSave = Lists.newArrayList();
for (Integer bucketIndex : changedBucketIndexes) {
final RevTree currentBucketTree = bucketTrees.get(bucketIndex);
final int bucketDepth = this.depth + 1;
final RevTreeBuilder bucketTreeBuilder = new RevTreeBuilder(this.db, currentBucketTree, bucketDepth, this.pendingWritesCache);
{
final Collection<Node> bucketEntries = changesByBucket.removeAll(bucketIndex);
for (Node node : bucketEntries) {
if (node.getObjectId().isNull()) {
bucketTreeBuilder.remove(node.getName());
} else {
bucketTreeBuilder.put(node);
}
}
}
final RevTree modifiedBucketTree = bucketTreeBuilder.build();
final long bucketSizeDelta = modifiedBucketTree.size() - currentBucketTree.size();
final int bucketTreesDelta = modifiedBucketTree.numTrees() - currentBucketTree.numTrees();
sizeDelta += bucketSizeDelta;
treesDelta += bucketTreesDelta;
if (modifiedBucketTree.isEmpty()) {
bucketTreesByBucket.remove(bucketIndex);
} else {
final Bucket currBucket = this.bucketTreesByBucket.get(bucketIndex);
if (currBucket == null || !currBucket.id().equals(modifiedBucketTree.getId())) {
// trees may be too large and cause OOM
if (null != pendingWritesCache.remove(currentBucketTree.getId())) {
// System.err.printf(" ---> removed bucket %s from list\n",
// currentBucketTree.getId());
}
if (modifiedBucketTree.buckets().isPresent()) {
pendingWritesCache.put(modifiedBucketTree.getId(), modifiedBucketTree);
} else {
// db.put(modifiedBucketTree);
newLeafTreesToSave.add(modifiedBucketTree);
}
Envelope bucketBounds = SpatialOps.boundsOf(modifiedBucketTree);
Bucket bucket = Bucket.create(modifiedBucketTree.getId(), bucketBounds);
bucketTreesByBucket.put(bucketIndex, bucket);
}
}
}
if (!newLeafTreesToSave.isEmpty()) {
db.putAll(newLeafTreesToSave.iterator());
newLeafTreesToSave.clear();
newLeafTreesToSave = null;
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
// compute final size and number of trees out of the aggregate deltas
long accSize = sizeDelta;
if (initialSize > RevTree.NORMALIZED_SIZE_LIMIT) {
accSize += initialSize;
}
int accChildTreeCount = this.initialNumTrees + treesDelta;
RevTreeImpl unnamedTree;
unnamedTree = RevTreeImpl.createNodeTree(ObjectId.NULL, accSize, accChildTreeCount, this.bucketTreesByBucket);
return unnamedTree;
}
use of com.vividsolutions.jts.geom.Envelope in project GeoGig by boundlessgeo.
the class OSMHistoryImport method insertChanges.
/**
* @param cli
* @param changes
* @param featureFilter
* @throws IOException
*/
private long insertChanges(GeogigCLI cli, final Iterator<Change> changes, @Nullable Envelope featureFilter) throws IOException {
final GeoGIG geogig = cli.getGeogig();
final Repository repository = geogig.getRepository();
final WorkingTree workTree = repository.workingTree();
Map<Long, Coordinate> thisChangePointCache = new LinkedHashMap<Long, Coordinate>() {
/** serialVersionUID */
private static final long serialVersionUID = 1277795218777240552L;
@Override
protected boolean removeEldestEntry(Map.Entry<Long, Coordinate> eldest) {
return size() == 10000;
}
};
long cnt = 0;
Set<String> deletes = Sets.newHashSet();
Multimap<String, SimpleFeature> insertsByParent = HashMultimap.create();
while (changes.hasNext()) {
Change change = changes.next();
final String featurePath = featurePath(change);
if (featurePath == null) {
// ignores relations
continue;
}
final String parentPath = NodeRef.parentPath(featurePath);
if (Change.Type.delete.equals(change.getType())) {
cnt++;
deletes.add(featurePath);
} else {
final Primitive primitive = change.getNode().isPresent() ? change.getNode().get() : change.getWay().get();
final Geometry geom = parseGeometry(geogig, primitive, thisChangePointCache);
if (geom instanceof Point) {
thisChangePointCache.put(Long.valueOf(primitive.getId()), ((Point) geom).getCoordinate());
}
SimpleFeature feature = toFeature(primitive, geom);
if (featureFilter == null || featureFilter.intersects((Envelope) feature.getBounds())) {
insertsByParent.put(parentPath, feature);
cnt++;
}
}
}
for (String parentPath : insertsByParent.keySet()) {
Collection<SimpleFeature> features = insertsByParent.get(parentPath);
if (features.isEmpty()) {
continue;
}
Iterator<? extends Feature> iterator = features.iterator();
ProgressListener listener = new DefaultProgressListener();
List<org.locationtech.geogig.api.Node> insertedTarget = null;
Integer collectionSize = Integer.valueOf(features.size());
workTree.insert(parentPath, iterator, listener, insertedTarget, collectionSize);
}
if (!deletes.isEmpty()) {
workTree.delete(deletes.iterator());
}
return cnt;
}
Aggregations