/** Returns relation to the provided rectangle for this component */ protected Relation internalComponentRelate(double minLat, double maxLat, double minLon, double maxLon) { // if the bounding boxes are disjoint then the shape does not cross if (maxLon < this.minLon || minLon > this.maxLon || maxLat < this.minLat || minLat > this.maxLat) { return Relation.CELL_OUTSIDE_QUERY; } // if the rectangle fully encloses us, we cross. if (minLat <= this.minLat && maxLat >= this.maxLat && minLon <= this.minLon && maxLon >= this.maxLon) { return Relation.CELL_CROSSES_QUERY; } Relation shapeRelation = componentRelate(minLat, maxLat, minLon, maxLon); if (shapeRelation != null) { return shapeRelation; } // we cross if (tree.crosses(minLat, maxLat, minLon, maxLon)) { return Relation.CELL_CROSSES_QUERY; } return Relation.CELL_OUTSIDE_QUERY; }
protected EdgeTree(final double minLat, final double maxLat, final double minLon, final double maxLon, double[] lats, double[] lons) { this.minLat = minLat; this.maxLat = maxLat; this.minLon = minLon; this.maxLon = maxLon; this.maxY = maxLat; this.maxX = maxLon; // create interval tree of edges this.tree = createTree(lats, lons); }
/** Returns relation to the provided rectangle */ public Relation relate(double minLat, double maxLat, double minLon, double maxLon) { if (minLat <= maxY && minLon <= maxX) { Relation relation = internalComponentRelate(minLat, maxLat, minLon, maxLon); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } if (left != null) { relation = left.relate(minLat, maxLat, minLon, maxLon); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } } if (right != null && ((splitX == false && maxLat >= this.minLat) || (splitX && maxLon >= this.minLon))) { relation = right.relate(minLat, maxLat, minLon, maxLon); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } } } return Relation.CELL_OUTSIDE_QUERY; }
/** Returns relation to the provided triangle */ public Relation relateTriangle(double ax, double ay, double bx, double by, double cx, double cy) { // compute bounding box of triangle double minLat = StrictMath.min(StrictMath.min(ay, by), cy); double minLon = StrictMath.min(StrictMath.min(ax, bx), cx); double maxLat = StrictMath.max(StrictMath.max(ay, by), cy); double maxLon = StrictMath.max(StrictMath.max(ax, bx), cx); if (minLat <= maxY && minLon <= maxX) { Relation relation = internalComponentRelateTriangle(ax, ay, bx, by, cx, cy); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } if (left != null) { relation = left.relateTriangle(ax, ay, bx, by, cx, cy); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } } if (right != null && ((splitX == false && maxLat >= this.minLat) || (splitX && maxLon >= this.minLon))) { relation = right.relateTriangle(ax, ay, bx, by, cx, cy); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } } } return Relation.CELL_OUTSIDE_QUERY; }
private Relation internalComponentRelateTriangle(double ax, double ay, double bx, double by, double cx, double cy) { // compute bounding box of triangle double minLat = StrictMath.min(StrictMath.min(ay, by), cy); double minLon = StrictMath.min(StrictMath.min(ax, bx), cx); double maxLat = StrictMath.max(StrictMath.max(ay, by), cy); double maxLon = StrictMath.max(StrictMath.max(ax, bx), cx); if (maxLon < this.minLon || minLon > this.maxLon || maxLat < this.minLat || minLat > this.maxLat) { return Relation.CELL_OUTSIDE_QUERY; } Relation shapeRelation = componentRelateTriangle(ax, ay, bx, by, cx, cy); if (shapeRelation != null) { return shapeRelation; } // we cross if (tree.crossesTriangle(ax, ay, bx, by, cx, cy)) { return Relation.CELL_CROSSES_QUERY; } return Relation.CELL_OUTSIDE_QUERY; }
/** Returns relation to the provided triangle */ public Relation relateTriangle(double ax, double ay, double bx, double by, double cx, double cy) { // compute bounding box of triangle double minLat = StrictMath.min(StrictMath.min(ay, by), cy); double minLon = StrictMath.min(StrictMath.min(ax, bx), cx); double maxLat = StrictMath.max(StrictMath.max(ay, by), cy); double maxLon = StrictMath.max(StrictMath.max(ax, bx), cx); if (minLat <= maxY && minLon <= maxX) { Relation relation = internalComponentRelateTriangle(ax, ay, bx, by, cx, cy); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } if (left != null) { relation = left.relateTriangle(ax, ay, bx, by, cx, cy); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } } if (right != null && ((splitX == false && maxLat >= this.minLat) || (splitX && maxLon >= this.minLon))) { relation = right.relateTriangle(ax, ay, bx, by, cx, cy); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } } } return Relation.CELL_OUTSIDE_QUERY; }
private Relation internalComponentRelateTriangle(double ax, double ay, double bx, double by, double cx, double cy) { // compute bounding box of triangle double minLat = StrictMath.min(StrictMath.min(ay, by), cy); double minLon = StrictMath.min(StrictMath.min(ax, bx), cx); double maxLat = StrictMath.max(StrictMath.max(ay, by), cy); double maxLon = StrictMath.max(StrictMath.max(ax, bx), cx); if (maxLon < this.minLon || minLon > this.maxLon || maxLat < this.minLat || minLat > this.maxLat) { return Relation.CELL_OUTSIDE_QUERY; } Relation shapeRelation = componentRelateTriangle(ax, ay, bx, by, cx, cy); if (shapeRelation != null) { return shapeRelation; } // we cross if (tree.crossesTriangle(ax, ay, bx, by, cx, cy)) { return Relation.CELL_CROSSES_QUERY; } return Relation.CELL_OUTSIDE_QUERY; }
/** Creates tree from sorted edges (with range low and high inclusive) */ private static Edge createTree(Edge edges[], int low, int high) { if (low > high) { return null; } // add midpoint int mid = (low + high) >>> 1; Edge newNode = edges[mid]; // add children newNode.left = createTree(edges, low, mid - 1); newNode.right = createTree(edges, mid + 1, high); // pull up max values to this node if (newNode.left != null) { newNode.max = Math.max(newNode.max, newNode.left.max); } if (newNode.right != null) { newNode.max = Math.max(newNode.max, newNode.right.max); } return newNode; } }
/** Returns relation to the provided rectangle */ public Relation relate(double minLat, double maxLat, double minLon, double maxLon) { if (minLat <= maxY && minLon <= maxX) { Relation relation = internalComponentRelate(minLat, maxLat, minLon, maxLon); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } if (left != null) { relation = left.relate(minLat, maxLat, minLon, maxLon); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } } if (right != null && ((splitX == false && maxLat >= this.minLat) || (splitX && maxLon >= this.minLon))) { relation = right.relate(minLat, maxLat, minLon, maxLon); if (relation != Relation.CELL_OUTSIDE_QUERY) { return relation; } } } return Relation.CELL_OUTSIDE_QUERY; }
/** Returns relation to the provided rectangle for this component */ protected Relation internalComponentRelate(double minLat, double maxLat, double minLon, double maxLon) { // if the bounding boxes are disjoint then the shape does not cross if (maxLon < this.minLon || minLon > this.maxLon || maxLat < this.minLat || minLat > this.maxLat) { return Relation.CELL_OUTSIDE_QUERY; } // if the rectangle fully encloses us, we cross. if (minLat <= this.minLat && maxLat >= this.maxLat && minLon <= this.minLon && maxLon >= this.maxLon) { return Relation.CELL_CROSSES_QUERY; } Relation shapeRelation = componentRelate(minLat, maxLat, minLon, maxLon); if (shapeRelation != null) { return shapeRelation; } // we cross if (tree.crosses(minLat, maxLat, minLon, maxLon)) { return Relation.CELL_CROSSES_QUERY; } return Relation.CELL_OUTSIDE_QUERY; }
/** * Creates an edge interval tree from a set of geometry vertices. * @return root node of the tree. */ private static Edge createTree(double[] lats, double[] lons) { Edge edges[] = new Edge[lats.length - 1]; for (int i = 1; i < lats.length; i++) { double lat1 = lats[i-1]; double lon1 = lons[i-1]; double lat2 = lats[i]; double lon2 = lons[i]; edges[i - 1] = new Edge(lat1, lon1, lat2, lon2, Math.min(lat1, lat2), Math.max(lat1, lat2)); } // sort the edges then build a balanced tree from them Arrays.sort(edges, (left, right) -> { int ret = Double.compare(left.low, right.low); if (ret == 0) { ret = Double.compare(left.max, right.max); } return ret; }); return createTree(edges, 0, edges.length - 1); }
newNode.splitX = splitX; newNode.left = createTree(components, low, mid - 1, !splitX); newNode.right = createTree(components, mid + 1, high, !splitX);
protected EdgeTree(final double minLat, final double maxLat, final double minLon, final double maxLon, double[] lats, double[] lons) { this.minLat = minLat; this.maxLat = maxLat; this.minLon = minLon; this.maxLon = maxLon; this.maxY = maxLat; this.maxX = maxLon; // create interval tree of edges this.tree = createTree(lats, lons); }
/** Creates tree from sorted edges (with range low and high inclusive) */ private static Edge createTree(Edge edges[], int low, int high) { if (low > high) { return null; } // add midpoint int mid = (low + high) >>> 1; Edge newNode = edges[mid]; // add children newNode.left = createTree(edges, low, mid - 1); newNode.right = createTree(edges, mid + 1, high); // pull up max values to this node if (newNode.left != null) { newNode.max = Math.max(newNode.max, newNode.left.max); } if (newNode.right != null) { newNode.max = Math.max(newNode.max, newNode.right.max); } return newNode; } }
/** * Creates an edge interval tree from a set of geometry vertices. * @return root node of the tree. */ private static Edge createTree(double[] lats, double[] lons) { Edge edges[] = new Edge[lats.length - 1]; for (int i = 1; i < lats.length; i++) { double lat1 = lats[i-1]; double lon1 = lons[i-1]; double lat2 = lats[i]; double lon2 = lons[i]; edges[i - 1] = new Edge(lat1, lon1, lat2, lon2, Math.min(lat1, lat2), Math.max(lat1, lat2)); } // sort the edges then build a balanced tree from them Arrays.sort(edges, (left, right) -> { int ret = Double.compare(left.low, right.low); if (ret == 0) { ret = Double.compare(left.max, right.max); } return ret; }); return createTree(edges, 0, edges.length - 1); }
newNode.splitX = splitX; newNode.left = createTree(components, low, mid - 1, !splitX); newNode.right = createTree(components, mid + 1, high, !splitX);