Search in sources :

Example 1 with BoundingBox

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);
    }
}
Also used : InstanceWaypoint(eu.esdihumboldt.hale.ui.views.styledmap.painter.InstanceWaypoint) AbstractInstancePainter(eu.esdihumboldt.hale.ui.views.styledmap.painter.AbstractInstancePainter) InstanceReference(eu.esdihumboldt.hale.common.instance.model.InstanceReference) BoundingBox(de.fhg.igd.geom.BoundingBox) GeoPosition(org.jdesktop.swingx.mapviewer.GeoPosition) HashSet(java.util.HashSet)

Example 2 with BoundingBox

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);
    }
}
Also used : AbstractInstancePainter(eu.esdihumboldt.hale.ui.views.styledmap.painter.AbstractInstancePainter) BoundingBox(de.fhg.igd.geom.BoundingBox) GeoPosition(org.jdesktop.swingx.mapviewer.GeoPosition) HashSet(java.util.HashSet)

Example 3 with BoundingBox

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;
}
Also used : ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) Point(com.vividsolutions.jts.geom.Point) Point(com.vividsolutions.jts.geom.Point) SelectableWaypoint(de.fhg.igd.mapviewer.waypoints.SelectableWaypoint) GeometryCollection(com.vividsolutions.jts.geom.GeometryCollection) Geometry(com.vividsolutions.jts.geom.Geometry) Area(de.fhg.igd.mapviewer.marker.area.Area) PolygonArea(de.fhg.igd.mapviewer.marker.area.PolygonArea) MultiArea(de.fhg.igd.mapviewer.marker.area.MultiArea) CRSConverter(eu.esdihumboldt.hale.ui.views.styledmap.util.CRSConverter) Point2D(java.awt.geom.Point2D) LineString(com.vividsolutions.jts.geom.LineString) BoundingBox(de.fhg.igd.geom.BoundingBox) GeoPosition(org.jdesktop.swingx.mapviewer.GeoPosition) Polygon(com.vividsolutions.jts.geom.Polygon) MultiArea(de.fhg.igd.mapviewer.marker.area.MultiArea)

Example 4 with BoundingBox

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;
}
Also used : BoundingBox(de.fhg.igd.geom.BoundingBox) Localizable(de.fhg.igd.geom.Localizable)

Example 5 with BoundingBox

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);
}
Also used : BoundingBox(de.fhg.igd.geom.BoundingBox) Localizable(de.fhg.igd.geom.Localizable)

Aggregations

BoundingBox (de.fhg.igd.geom.BoundingBox)20 GeoPosition (org.jdesktop.swingx.mapviewer.GeoPosition)11 ArrayList (java.util.ArrayList)8 Localizable (de.fhg.igd.geom.Localizable)6 IllegalGeoPositionException (org.jdesktop.swingx.mapviewer.IllegalGeoPositionException)6 Point2D (java.awt.geom.Point2D)5 Area (de.fhg.igd.mapviewer.marker.area.Area)4 Point (java.awt.Point)4 HashSet (java.util.HashSet)4 Geometry (com.vividsolutions.jts.geom.Geometry)3 Rectangle (java.awt.Rectangle)3 SelectableWaypoint (de.fhg.igd.mapviewer.waypoints.SelectableWaypoint)2 InstanceReference (eu.esdihumboldt.hale.common.instance.model.InstanceReference)2 AbstractInstancePainter (eu.esdihumboldt.hale.ui.views.styledmap.painter.AbstractInstancePainter)2 CRSConverter (eu.esdihumboldt.hale.ui.views.styledmap.util.CRSConverter)2 Graphics2D (java.awt.Graphics2D)2 BufferedImage (java.awt.image.BufferedImage)2 PixelConverter (org.jdesktop.swingx.mapviewer.PixelConverter)2 GeometryCollection (com.vividsolutions.jts.geom.GeometryCollection)1 LineString (com.vividsolutions.jts.geom.LineString)1