/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * *************************************************************************************** */ package com.espertech.esper.spatial.quadtree.prqdrowindex; import com.espertech.esper.spatial.quadtree.core.*; import com.espertech.esper.spatial.quadtree.pointregion.PointRegionQuadTree; import com.espertech.esper.spatial.quadtree.pointregion.PointRegionQuadTreeNode; import com.espertech.esper.spatial.quadtree.pointregion.PointRegionQuadTreeNodeBranch; import com.espertech.esper.spatial.quadtree.pointregion.PointRegionQuadTreeNodeLeaf; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; public class PointRegionQuadTreeRowIndexRemove { /** * Remove value. * * @param x x * @param y y * @param value value to remove * @param tree quadtree */ public static void remove(double x, double y, Object value, PointRegionQuadTree<Object> tree) { PointRegionQuadTreeNode<Object> root = tree.getRoot(); PointRegionQuadTreeNode<Object> replacement = removeFromNode(x, y, value, root, tree); tree.setRoot(replacement); } private static PointRegionQuadTreeNode<Object> removeFromNode(double x, double y, Object value, PointRegionQuadTreeNode<Object> node, PointRegionQuadTree<Object> tree) { if (node instanceof PointRegionQuadTreeNodeLeaf) { PointRegionQuadTreeNodeLeaf<Object> leaf = (PointRegionQuadTreeNodeLeaf<Object>) node; boolean removed = removeFromPoints(x, y, value, leaf.getPoints()); if (removed) { leaf.decCount(); if (leaf.getCount() == 0) { leaf.setPoints(null); } } return leaf; } PointRegionQuadTreeNodeBranch<Object> branch = (PointRegionQuadTreeNodeBranch<Object>) node; QuadrantEnum quadrant = node.getBb().getQuadrant(x, y); if (quadrant == QuadrantEnum.NW) { branch.setNw(removeFromNode(x, y, value, branch.getNw(), tree)); } else if (quadrant == QuadrantEnum.NE) { branch.setNe(removeFromNode(x, y, value, branch.getNe(), tree)); } else if (quadrant == QuadrantEnum.SW) { branch.setSw(removeFromNode(x, y, value, branch.getSw(), tree)); } else { branch.setSe(removeFromNode(x, y, value, branch.getSe(), tree)); } if (!(branch.getNw() instanceof PointRegionQuadTreeNodeLeaf) || !(branch.getNe() instanceof PointRegionQuadTreeNodeLeaf) || !(branch.getSw() instanceof PointRegionQuadTreeNodeLeaf) || !(branch.getSe() instanceof PointRegionQuadTreeNodeLeaf)) { return branch; } PointRegionQuadTreeNodeLeaf<Object> nwLeaf = (PointRegionQuadTreeNodeLeaf<Object>) branch.getNw(); PointRegionQuadTreeNodeLeaf<Object> neLeaf = (PointRegionQuadTreeNodeLeaf<Object>) branch.getNe(); PointRegionQuadTreeNodeLeaf<Object> swLeaf = (PointRegionQuadTreeNodeLeaf<Object>) branch.getSw(); PointRegionQuadTreeNodeLeaf<Object> seLeaf = (PointRegionQuadTreeNodeLeaf<Object>) branch.getSe(); int total = nwLeaf.getCount() + neLeaf.getCount() + swLeaf.getCount() + seLeaf.getCount(); if (total >= tree.getLeafCapacity()) { return branch; } Collection<XYPointMultiType> collection = new LinkedList<>(); int count = mergeChildNodes(collection, nwLeaf.getPoints()); count += mergeChildNodes(collection, neLeaf.getPoints()); count += mergeChildNodes(collection, swLeaf.getPoints()); count += mergeChildNodes(collection, seLeaf.getPoints()); return new PointRegionQuadTreeNodeLeaf<>(branch.getBb(), branch.getLevel(), collection, count); } private static boolean removeFromPoints(double x, double y, Object value, Object points) { if (points == null) { return false; } if (!(points instanceof Collection)) { XYPointMultiType point = (XYPointMultiType) points; if (point.getX() == x && point.getY() == y) { boolean removed = point.remove(value); if (removed) { return true; } } return false; } Collection<XYPointMultiType> collection = (Collection<XYPointMultiType>) points; Iterator<XYPointMultiType> it = collection.iterator(); for (; it.hasNext(); ) { XYPointMultiType point = it.next(); if (point.getX() == x && point.getY() == y) { boolean removed = point.remove(value); if (removed) { if (point.isEmpty()) { it.remove(); } return true; } } } return false; } private static int mergeChildNodes(Collection<XYPointMultiType> target, Object points) { if (points == null) { return 0; } if (points instanceof XYPointMultiType) { XYPointMultiType p = (XYPointMultiType) points; target.add(p); return p.count(); } Collection<XYPointMultiType> coll = (Collection<XYPointMultiType>) points; int total = 0; for (XYPointMultiType p : coll) { target.add(p); total += p.count(); } return total; } }