/* Copyright (c) 2012-2014 Boundless and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/edl-v10.html
*
* Contributors:
* Gabriel Roldan (Boundless) - initial implementation
*/
package org.locationtech.geogig.repository;
import javax.annotation.Nullable;
import org.geotools.geometry.jts.JTS;
import org.locationtech.geogig.api.Bucket;
import org.locationtech.geogig.api.Node;
import org.locationtech.geogig.api.RevFeature;
import org.locationtech.geogig.api.RevTree;
import org.opengis.geometry.BoundingBox;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
/**
* Utility methods to deal with various spatial operations
*
*/
public class SpatialOps {
private static final GeometryFactory gfac = new GeometryFactory();
/**
* @param oldObject
* @param newObject
* @return the aggregated bounding box
*/
public static com.vividsolutions.jts.geom.Envelope aggregatedBounds(Node oldObject,
Node newObject) {
Envelope env = new Envelope();
if (oldObject != null) {
oldObject.expand(env);
}
if (newObject != null) {
newObject.expand(env);
}
return env;
}
/**
* Creates and returns a geometry out of bounds (a point if bounds.getSpan(0) ==
* bounds.getSpan(1) == 0D, a polygon otherwise), setting the bounds
* {@link BoundingBox#getCoordinateReferenceSystem() CRS} as the geometry's
* {@link Geometry#getUserData() user data}.
*
* @param bounds the bounding box to build from
* @return the newly constructed geometry
*/
public static Geometry toGeometry(final BoundingBox bounds) {
if (bounds == null) {
return null;
}
Geometry geom;
if (bounds.getSpan(0) == 0D && bounds.getSpan(1) == 0D) {
geom = gfac.createPoint(new Coordinate(bounds.getMinX(), bounds.getMinY()));
} else {
geom = JTS.toGeometry(bounds, gfac);
}
geom.setUserData(bounds.getCoordinateReferenceSystem());
return geom;
}
public static Envelope boundsOf(RevTree tree) {
Envelope env = new Envelope();
if (tree.buckets().isPresent()) {
for (Bucket bucket : tree.buckets().get().values()) {
bucket.expand(env);
}
} else {
if (tree.trees().isPresent()) {
ImmutableList<Node> trees = tree.trees().get();
for (int i = 0; i < trees.size(); i++) {
trees.get(i).expand(env);
}
}
if (tree.features().isPresent()) {
ImmutableList<Node> trees = tree.features().get();
for (int i = 0; i < trees.size(); i++) {
trees.get(i).expand(env);
}
}
}
return env;
}
@Nullable
public static Envelope boundsOf(RevFeature feat) {
Envelope env = null;
for (Optional<Object> opt : feat.getValues()) {
if (opt.isPresent() && opt.get() instanceof Geometry) {
if (env == null) {
env = new Envelope();
}
env.expandToInclude(((Geometry) opt.get()).getEnvelopeInternal());
}
}
return env;
}
}