/** * 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); }
if (left.crossesTriangle(ax, ay, bx, by, cx, cy)) { return true; if (right.crossesTriangle(ax, ay, bx, by, cx, cy)) { return true;
/** Returns relation to the provided rectangle for this component */ @Override protected Relation componentRelate(double minLat, double maxLat, double minLon, double maxLon) { // check any holes if (holes != null) { Relation holeRelation = holes.relate(minLat, maxLat, minLon, maxLon); if (holeRelation == Relation.CELL_CROSSES_QUERY) { return Relation.CELL_CROSSES_QUERY; } else if (holeRelation == Relation.CELL_INSIDE_QUERY) { return Relation.CELL_OUTSIDE_QUERY; } } // check each corner: if < 4 are present, its cheaper than crossesSlowly int numCorners = numberOfCorners(minLat, maxLat, minLon, maxLon); if (numCorners == 4) { if (tree.crosses(minLat, maxLat, minLon, maxLon)) { return Relation.CELL_CROSSES_QUERY; } return Relation.CELL_INSIDE_QUERY; } else if (numCorners > 0) { return Relation.CELL_CROSSES_QUERY; } return null; }
/** * 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); }
@Override protected Relation componentRelateTriangle(double ax, double ay, double bx, double by, double cx, double cy) { // check any holes if (holes != null) { Relation holeRelation = holes.relateTriangle(ax, ay, bx, by, cx, cy); if (holeRelation == Relation.CELL_CROSSES_QUERY) { return Relation.CELL_CROSSES_QUERY; } else if (holeRelation == Relation.CELL_INSIDE_QUERY) { return Relation.CELL_OUTSIDE_QUERY; } } // check each corner: if < 3 are present, its cheaper than crossesSlowly int numCorners = numberOfTriangleCorners(ax, ay, bx, by, cx, cy); if (numCorners == 3) { if (tree.crossesTriangle(ax, ay, bx, by, cx, cy)) { return Relation.CELL_CROSSES_QUERY; } return Relation.CELL_INSIDE_QUERY; } else if (numCorners > 0) { return Relation.CELL_CROSSES_QUERY; } return null; }
/** 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; }
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; }
if (left.crossesTriangle(ax, ay, bx, by, cx, cy)) { return true; if (right.crossesTriangle(ax, ay, bx, by, cx, cy)) { return true;
@Override protected Relation componentRelateTriangle(double ax, double ay, double bx, double by, double cx, double cy) { // check any holes if (holes != null) { Relation holeRelation = holes.relateTriangle(ax, ay, bx, by, cx, cy); if (holeRelation == Relation.CELL_CROSSES_QUERY) { return Relation.CELL_CROSSES_QUERY; } else if (holeRelation == Relation.CELL_INSIDE_QUERY) { return Relation.CELL_OUTSIDE_QUERY; } } // check each corner: if < 3 are present, its cheaper than crossesSlowly int numCorners = numberOfTriangleCorners(ax, ay, bx, by, cx, cy); if (numCorners == 3) { if (tree.crossesTriangle(ax, ay, bx, by, cx, cy)) { return Relation.CELL_CROSSES_QUERY; } return Relation.CELL_INSIDE_QUERY; } else if (numCorners > 0) { return Relation.CELL_CROSSES_QUERY; } return null; }
/** Returns relation to the provided rectangle for this component */ @Override protected Relation componentRelate(double minLat, double maxLat, double minLon, double maxLon) { // check any holes if (holes != null) { Relation holeRelation = holes.relate(minLat, maxLat, minLon, maxLon); if (holeRelation == Relation.CELL_CROSSES_QUERY) { return Relation.CELL_CROSSES_QUERY; } else if (holeRelation == Relation.CELL_INSIDE_QUERY) { return Relation.CELL_OUTSIDE_QUERY; } } // check each corner: if < 4 are present, its cheaper than crossesSlowly int numCorners = numberOfCorners(minLat, maxLat, minLon, maxLon); if (numCorners == 4) { if (tree.crosses(minLat, maxLat, minLon, maxLon)) { return Relation.CELL_CROSSES_QUERY; } return Relation.CELL_INSIDE_QUERY; } else if (numCorners > 0) { return Relation.CELL_CROSSES_QUERY; } return null; }
/** 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; }
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; }