Search in sources :

Example 1 with Localizable

use of de.fhg.igd.geom.Localizable 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 2 with Localizable

use of de.fhg.igd.geom.Localizable 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)

Example 3 with Localizable

use of de.fhg.igd.geom.Localizable in project hale by halestudio.

the class Node method condenseTree.

/**
 * Eliminate l if it has too few entries. Propagate elimination upwards.
 * Adjust BoundingBoxes.
 *
 * @param l the Leaf from which an entry has been deleted
 */
@SuppressWarnings("unchecked")
private void condenseTree(Node<T> l) {
    // the list of deleted nodes
    List<Node<T>> q = new ArrayList<Node<T>>();
    Node<T> n = l;
    while (n._parent != null) {
        // eliminate under-full node
        int minSize = calculateMinSize();
        if (n._children.size() < minSize) {
            n._parent._children.remove(n);
            q.add(n);
        } else {
            // adjust BoundingBox of n (the element from which an
            // entry has been deleted)
            n._boundingBox = new BoundingBox();
            for (Localizable c : n._children) {
                n._boundingBox.add(c.getBoundingBox());
            }
        }
        n = n._parent;
    }
    // adjust the bounding box of the root
    n._boundingBox = new BoundingBox();
    for (Localizable c : n._children) {
        n._boundingBox.add(c.getBoundingBox());
    }
    // re-insert orphaned entries
    for (Node<T> no : q) {
        if (no.isLeaf()) {
            // re-insert the leaf's children as usual
            for (Localizable c : no.getChildren()) {
                _tree.insert((T) c);
            }
        } else {
            // insert the children of all leafs we can
            // find in "no"
            insertChildrenOfAllLeafs(no, _tree);
        }
    }
}
Also used : BoundingBox(de.fhg.igd.geom.BoundingBox) ArrayList(java.util.ArrayList) Localizable(de.fhg.igd.geom.Localizable)

Example 4 with Localizable

use of de.fhg.igd.geom.Localizable in project hale by halestudio.

the class Node method pickSeeds.

/**
 * Finds the first entries of two splitted groups (Quadratic Split)
 *
 * @return the two entries
 */
private Localizable[] pickSeeds() {
    Localizable[] result = new Localizable[2];
    int ii = -1, jj = -1;
    double min = Double.NEGATIVE_INFINITY;
    for (int i = 0; i < _children.size() - 1; ++i) {
        for (int j = i + 1; j < _children.size(); ++j) {
            Localizable e1 = _children.get(i);
            Localizable e2 = _children.get(j);
            // compose a new bounding box
            BoundingBox bb = new BoundingBox(e1.getBoundingBox());
            bb.add(e2.getBoundingBox());
            // calculate waste
            double d = calcPseudoVolume(bb) - calcPseudoVolume(e1) - calcPseudoVolume(e2);
            if (d > min) {
                result[0] = e1;
                ii = i;
                result[1] = e2;
                jj = j;
                min = d;
            }
        }
    }
    // result must not be empty
    assert result[0] != null;
    assert result[1] != null;
    // remove entries from the list of Localizables
    // make sure that we remove the correct element jj if
    // ii has been removed before
    _children.remove(ii);
    _children.remove(ii < jj ? jj - 1 : jj);
    return result;
}
Also used : BoundingBox(de.fhg.igd.geom.BoundingBox) Localizable(de.fhg.igd.geom.Localizable)

Example 5 with Localizable

use of de.fhg.igd.geom.Localizable in project hale by halestudio.

the class Node method find.

/**
 * Returns a list of all Localizables that have any relation to the given
 * Localizable loc.
 *
 * @param loc the Localizable to match
 * @param ignoreZ true if the z coordinate should be ignored during
 *            candidate search
 * @return a list of Localizables (containing only leafs of this tree and no
 *         nodes)
 */
@SuppressWarnings("unchecked")
private List<T> find(final Localizable loc, boolean ignoreZ) {
    List<T> result = new ArrayList<T>();
    BoundingBox theirs = loc.getBoundingBox();
    for (Localizable l : _children) {
        BoundingBox ours = l.getBoundingBox();
        if (relate(ours, theirs, ignoreZ)) {
            if (l instanceof Node) {
                // descend
                result.addAll(((Node<T>) l).find(loc, ignoreZ));
            } else {
                // add leaf
                result.add((T) l);
            }
        }
    }
    return result;
}
Also used : BoundingBox(de.fhg.igd.geom.BoundingBox) ArrayList(java.util.ArrayList) Localizable(de.fhg.igd.geom.Localizable)

Aggregations

Localizable (de.fhg.igd.geom.Localizable)7 BoundingBox (de.fhg.igd.geom.BoundingBox)6 ArrayList (java.util.ArrayList)3 Geometry (com.vividsolutions.jts.geom.Geometry)1 ServiceProvider (eu.esdihumboldt.hale.common.core.service.ServiceProvider)1 GeometryFinder (eu.esdihumboldt.hale.common.instance.geometry.GeometryFinder)1 DepthFirstInstanceTraverser (eu.esdihumboldt.hale.common.instance.helper.DepthFirstInstanceTraverser)1 InstanceTraverser (eu.esdihumboldt.hale.common.instance.helper.InstanceTraverser)1 LocalizableInstanceReference (eu.esdihumboldt.hale.common.instance.index.LocalizableInstanceReference)1 TypedInstanceReference (eu.esdihumboldt.hale.common.instance.index.TypedInstanceReference)1