use of de.fhg.igd.geom.BoundingBox in project hale by halestudio.
the class StyledMapUtil method zoomToSelection.
/**
* Zoom to the selected instances. Does nothing if the selection is empty or
* contains no {@link Instance}s or {@link InstanceReference}s.
*
* @param mapKit the map kit
* @param selection the selection
*/
public static void zoomToSelection(BasicMapKit mapKit, IStructuredSelection selection) {
BoundingBox bb = null;
// determine bounding box for each reference and accumulate it
for (AbstractInstancePainter painter : mapKit.getTilePainters(AbstractInstancePainter.class)) {
for (Object element : selection.toList()) {
InstanceReference ref = getReference(element);
if (ref != null) {
InstanceWaypoint wp = painter.findWaypoint(ref);
if (wp != null) {
BoundingBox wpBB = wp.getBoundingBox();
if (wpBB.checkIntegrity() && !wpBB.isEmpty()) {
if (bb == null) {
bb = new BoundingBox(wpBB);
} else {
bb.add(wpBB);
}
}
}
}
}
}
if (bb != null) {
Set<GeoPosition> positions = new HashSet<GeoPosition>();
positions.add(new GeoPosition(bb.getMinX(), bb.getMinY(), SelectableWaypoint.COMMON_EPSG));
positions.add(new GeoPosition(bb.getMaxX(), bb.getMaxY(), SelectableWaypoint.COMMON_EPSG));
mapKit.zoomToPositions(positions);
}
}
use of de.fhg.igd.geom.BoundingBox in project hale by halestudio.
the class StyledMapUtil method zoomToAll.
/**
* Zoom to all instances available in the map. Does nothing if there are no
* instances displayed.
*
* @param mapKit the map kit
*/
public static void zoomToAll(BasicMapKit mapKit) {
BoundingBox bb = null;
// determine bounding box
for (AbstractInstancePainter painter : mapKit.getTilePainters(AbstractInstancePainter.class)) {
BoundingBox painterBB = painter.getBoundingBox();
if (painterBB.checkIntegrity() && !painterBB.isEmpty()) {
if (bb == null) {
bb = new BoundingBox(painterBB);
} else {
bb.add(painterBB);
}
}
}
if (bb != null) {
Set<GeoPosition> positions = new HashSet<GeoPosition>();
positions.add(new GeoPosition(bb.getMinX(), bb.getMinY(), SelectableWaypoint.COMMON_EPSG));
positions.add(new GeoPosition(bb.getMaxX(), bb.getMaxY(), SelectableWaypoint.COMMON_EPSG));
mapKit.zoomToPositions(positions);
}
}
use of de.fhg.igd.geom.BoundingBox in project hale by halestudio.
the class InstanceMarker method paintGeometry.
/**
* Paint a geometry.
*
* @param g the graphics to paint on
* @param crsDefinition the CRS definition associated with the geometry
* @param geometry the geometry
* @param context the context
* @param converter the pixel converter
* @param zoom the zoom level
* @param singleGeometry if this is the only geometry associated to the
* marker
* @param gBounds the graphics bounds
* @param mapCRS the map coordinate reference system
* @param calculateArea if the area representing the marker should be
* calculated, if <code>false</code> is given here the return
* value is ignored and should be <code>null</code>
* @return the area the geometry occupies (in pixel coordinates), or
* <code>null</code> if nothing has been painted
*/
protected Area paintGeometry(Graphics2D g, CRSDefinition crsDefinition, Geometry geometry, InstanceWaypoint context, PixelConverter converter, int zoom, boolean singleGeometry, Rectangle gBounds, CoordinateReferenceSystem mapCRS, boolean calculateArea) {
if (geometry instanceof GeometryCollection) {
// paint each geometry in a geometry collection
List<Area> areas = (calculateArea) ? (new ArrayList<Area>()) : (null);
GeometryCollection collection = (GeometryCollection) geometry;
for (int i = 0; i < collection.getNumGeometries(); i++) {
Geometry geom = collection.getGeometryN(i);
Area geomArea = paintGeometry(g, crsDefinition, geom, context, converter, zoom, singleGeometry && collection.getNumGeometries() == 1, gBounds, mapCRS, calculateArea);
if (areas != null && geomArea != null) {
areas.add(geomArea);
}
}
if (areas == null || areas.isEmpty()) {
return null;
} else {
return new MultiArea(areas);
}
}
// if it is the only geometry the check that was already made is OK
if (!calculateArea && !singleGeometry) {
// we can safely return null inside this method, as no area has to
// be calculated
// determine bounding box
BoundingBox geometryBB;
synchronized (geometryMapBBs) {
// retrieve cached bounding box
geometryBB = geometryMapBBs.get(geometry);
if (geometryBB == null) {
// if none available, try to calculate BB
BoundingBox calcBB = BoundingBox.compute(geometry);
if (calcBB != null && calcBB.checkIntegrity()) {
try {
// get CRS converter
CRSConverter conv = CRSConverter.getConverter(crsDefinition.getCRS(), mapCRS);
// manually convert to map CRS
geometryBB = conv.convert(calcBB);
// put BB in cache
geometryMapBBs.put(geometry, geometryBB);
} catch (Throwable e) {
log.error("Error checking geometry bounding box", e);
return null;
}
}
}
}
if (geometryBB != null) {
try {
GeoPosition minCorner = new GeoPosition(geometryBB.getMinX(), geometryBB.getMinY(), converter.getMapEpsg());
GeoPosition maxCorner = new GeoPosition(geometryBB.getMaxX(), geometryBB.getMaxY(), converter.getMapEpsg());
// determine pixel coordinates
Point2D minPixels = converter.geoToPixel(minCorner, zoom);
Point2D maxPixels = converter.geoToPixel(maxCorner, zoom);
// geometry pixel bounding box
int minX = Math.min((int) minPixels.getX(), (int) maxPixels.getX());
int minY = Math.min((int) minPixels.getY(), (int) maxPixels.getY());
int maxX = Math.max((int) minPixels.getX(), (int) maxPixels.getX());
int maxY = Math.max((int) minPixels.getY(), (int) maxPixels.getY());
// add overlap
minX -= GEOMETRY_PIXEL_BB_OVERLAP;
minY -= GEOMETRY_PIXEL_BB_OVERLAP;
maxX += GEOMETRY_PIXEL_BB_OVERLAP;
maxY += GEOMETRY_PIXEL_BB_OVERLAP;
// create bounding box
Rectangle geometryPixelBB = new Rectangle(minX, minY, maxX - minX, maxY - minY);
if (!gBounds.intersects(geometryPixelBB) && !gBounds.contains(geometryPixelBB)) {
// geometry does not lie in tile
return null;
}
} catch (Throwable e) {
log.error("Error checking geometry bounding box", e);
return null;
}
} else {
// empty or invalid bounding box
return null;
}
}
if (geometry instanceof Point) {
return paintPoint((Point) geometry, g, crsDefinition, context, converter, zoom, mapCRS, calculateArea);
}
if (geometry instanceof Polygon) {
return paintPolygon((Polygon) geometry, g, crsDefinition, context, converter, zoom, mapCRS, calculateArea);
}
if (geometry instanceof LineString) {
return paintLine((LineString) geometry, g, crsDefinition, context, converter, zoom, mapCRS, calculateArea);
}
return null;
}
use of de.fhg.igd.geom.BoundingBox in project hale by halestudio.
the class Node method split.
/**
* Splits this node into two nodes and adds them to the parent node.
* (Quadratic Split)
*
* @return the new second Node
*/
private Node<T> split() {
// choose two entries to be the first
// elements of the groups
Localizable[] seeds = pickSeeds();
// calculate minimum fill factor
int minSize = calculateMinSize();
// save this._children
List<Localizable> children = _children;
// assign each entry to a new Node
// this node will be group 0
Node<T> group0 = this;
_boundingBox = new BoundingBox();
_children = new ArrayList<Localizable>(_pageSize);
group0.plainAdd(seeds[0]);
Node<T> group1 = new Node<T>(_pageSize, this, _tree);
group1._isLeaf = this.isLeaf();
group1.plainAdd(seeds[1]);
// add next entries until nothing is left
while (children.size() > 0) {
// add all remaining entries to it
if (minSize - group0._children.size() == children.size()) {
for (Localizable c : children) {
group0.plainAdd(c);
}
break;
} else if (minSize - group1._children.size() == children.size()) {
for (Localizable c : children) {
group1.plainAdd(c);
}
break;
}
Localizable next = null;
double min = Double.NEGATIVE_INFINITY;
double dd0 = 0.0, dd1 = 0.0;
int ii = -1;
// the least cost
for (int i = 0; i < children.size(); ++i) {
Localizable l = children.get(i);
BoundingBox eb = l.getBoundingBox();
// calculate how much group 0 had to be extended if
// we would add the child to it
BoundingBox bb = new BoundingBox(group0.getBoundingBox());
bb.add(eb);
double d0 = calcPseudoVolume(bb) - calcPseudoVolume(group0);
// calculate the same for group 2
bb = new BoundingBox(group1.getBoundingBox());
bb.add(eb);
double d1 = calcPseudoVolume(bb) - calcPseudoVolume(group1);
// calculate the least cost
double diff = Math.abs(d1 - d0);
if (diff > min) {
next = l;
ii = i;
min = diff;
// remember the cost
dd0 = d0;
dd1 = d1;
}
}
// we must have a next entity now
assert next != null;
// remove entry from the list of Localizables
children.remove(ii);
// add result to one of the groups
if (dd0 < dd1) {
group0.plainAdd(next);
} else if (dd1 < dd0) {
group1.plainAdd(next);
} else {
double a0 = calcPseudoVolume(group0);
double a1 = calcPseudoVolume(group1);
if (a0 < a1) {
group0.plainAdd(next);
} else if (a1 < a0) {
group1.plainAdd(next);
} else {
if (group1._children.size() < group0._children.size()) {
group1.plainAdd(next);
} else {
group0.plainAdd(next);
}
}
}
}
return group1;
}
use of de.fhg.igd.geom.BoundingBox in project hale by halestudio.
the class Node method chooseLeaf.
/**
* Select a leaf node in which to place a new index entry.
*
* @param loc the localizable to find a leaf for
* @return the leaf node
*/
@SuppressWarnings({ "unchecked", "null" })
private Node<T> chooseLeaf(final Localizable loc) {
// if this is a leaf, return this
if (this.isLeaf()) {
return this;
}
// we're a node, so there must be children
assert _children != null;
// Guttman: find the smallest enlargement and find the
// bounding box with the smallest volume
double max = Double.POSITIVE_INFINITY;
Node<T> child = null;
for (Localizable l : _children) {
// l must be a Node, because this is no leaf (see above)
assert l instanceof Node;
Node<T> n = (Node<T>) l;
// calculate enlargement
BoundingBox larger = new BoundingBox(n.getBoundingBox());
larger.add(loc.getBoundingBox());
double nvolume = calcPseudoVolume(n);
double enlargement = calcPseudoVolume(larger) - nvolume;
if (enlargement < max) {
// use the one with the smallest enlargement
max = enlargement;
child = n;
} else if (enlargement < max + 0.000001) {
// always be set to n
assert child != null;
// use the one with the smallest volume
if (nvolume < calcPseudoVolume(child)) {
child = n;
}
}
}
// because there's always at least one child
assert child != null;
// descend
return child.chooseLeaf(loc);
}
Aggregations