📄 extentindex.java
字号:
} /** * Called when you want to get the regions in the buckets, but you want * to further filter on objects that can intersect based on the bounding * circle provided. * * @param left left-most (west) bucket value. * @param right right-most (east) bucket value. * @param bc Bounding circle to do another filter check, if null, * everything in a bucket will be returned. * @return Iterator over regions in buckets that cover range provided * that intersect with the BoundingCircle (if one is provided). */ protected Iterator lookup(double left, double right, BoundingCircle bc) { Collection s = null; int lb = bucketFor(left); int rb = bucketFor(right); if (rb < lb) rb = rb + nbuckets; for (int i = lb; i <= rb; i++) { Collection b = buckets[i % nbuckets]; if (b != null) { if (bc == null) { if (s == null) { s = new HashSet(); } s.addAll(b); } else { for (Iterator it = b.iterator(); it.hasNext();) { GeoExtent region = (GeoExtent) it.next(); if (bc.intersects(region.getBoundingCircle())) { if (s == null) { s = new HashSet(); } s.add(region); } } } } } if (!polar.isEmpty()) { if (s == null) { s = new HashSet(); } s.addAll(polar); // add all the polar regions, just in case } if (s == null) { return Collections.EMPTY_SET.iterator(); } else { return s.iterator(); } } /** * Method to call to remove a region from the index. * * @return true if the region was found and removed. */ public boolean removeExtent(GeoExtent region) { boolean ret = false; BoundingCircle bc = region.getBoundingCircle(); if (bc == null) { return discarded.remove(region); } Geo center = bc.getCenter(); double clon = center.getLongitude(); double clat = center.getLatitude(); double rnm = Geo.nm(bc.getRadius()); if ((clat == 90.0 && clon == -180.0) || rnm >= 90 * 60) { discarded.remove(region); } else { all.remove(region); // remove from the everything list // we need to project the radius away from the // center at the latitude, NOT at the equator! double latfactor = Geo.npdAtLat(clat); if (latfactor == 0) { ret = ret || polar.remove(region); } else { double xd = (rnm + margin) / latfactor; /* * margin = xd "extra degrees" at the center's latitude */ if (xd >= 45) { ret = ret || polar.remove(region); } else { double[] lons = normalizeLons(new double[] { clon - xd, clon + xd }); int lb = bucketFor(lons[0]); int rb = bucketFor(lons[1]); if (rb < lb) rb = rb + nbuckets; for (int i = lb; i <= rb; i++) { int x = i % nbuckets; Collection b = buckets[x]; if (b != null) { ret = ret || b.remove(region); if (b.isEmpty()) { buckets[x] = null; } } } } } } return ret; } /** * Method to call to clear out the index. */ public void clear() { all.clear(); polar.clear(); discarded.clear(); for (int i = 0; i < buckets.length; i++) { if (buckets[i] != null) { buckets[i].clear(); } } } /** * RegionIndex parameter method. * * @return horizontal range in nautical miles for matches. */ public double indexHorizontalRange() { return margin; } public Iterator lookupBySegment(GeoSegment segment) { Geo[] pts = segment.getSeg(); double[] lons = normalizeLons(new double[] { pts[0].getLongitude(), pts[1].getLongitude() }); return lookup(lons[0], lons[1], segment.getBoundingCircle()); } public Iterator lookupByPath(GeoPath path) { Collection results = null; GeoPath.SegmentIterator pit = path.segmentIterator(); while (pit.hasNext()) { GeoSegment seg = pit.nextSegment(); for (Iterator it = lookupBySegment(seg); it.hasNext();) { if (results == null) { results = new HashSet(); } results.add(it.next()); } } if (results == null) { return Collections.EMPTY_SET.iterator(); } else { return results.iterator(); } } public Iterator lookupByBoundingCircle(BoundingCircle bc) { double cLon = bc.getCenter().getLongitude(); double rNM = Geo.nm(bc.getRadius()); // radius in nm at // equator double npd = Geo.npdAtLat(bc.getCenter().getLatitude()); if (npd == 0) { // avoid divide by zero - polar region return iterator(); } else { double rdeg = rNM / npd; if (rdeg >= 180) { return iterator(); // radius covers the whole world } else { return lookup(cLon - rdeg, cLon + rdeg, bc); } } } /** * @return an Iterator over BoundingCircle objects in the Collection * where the GExtent may be related to them. */ public Iterator iterator(GeoExtent o) { if (o instanceof GeoSegment) { return lookupBySegment((GeoSegment) o); } else if (o instanceof GeoRegion) { // It's important that GeoRegion be tested before GeoPath, // because the GeoPath will catch GeoRegions, and doing the // lookup by path for a region may cause the lookup to fail for // extents near the center of the region (outside of the // bounding circles of the region's segments). return lookupByBoundingCircle(o.getBoundingCircle()); } else if (o instanceof GeoPath) { return lookupByPath((GeoPath) o); } else if (o instanceof GeoPoint) { return lookupByBoundingCircle(new BoundingCircle.Impl(((GeoPoint) o).getPoint(), 0)); } else { return lookupByBoundingCircle(o.getBoundingCircle()); } } /** * @return Iterator over all entries in Collection. */ public Iterator iterator() { return all.iterator(); } /** * @return number of all entries in Collection. */ public int size() { return all.size(); } // // metrics // public String toString() { int entc = 0; int empties = 0; for (int i = 0; i < nbuckets; i++) { Collection l = buckets[i]; if (l != null) { entc += l.size(); } else { empties++; } } return this.getClass().getName() + "[" + size() + " -" + discarded.size() + " E" + (entc / ((float) nbuckets)) + "]"; } } class HashSetExtentIndexImpl extends AbstractExtentIndex { public HashSetExtentIndexImpl() { this(D_NBUCKETS, D_MARGIN); } public HashSetExtentIndexImpl(int nb) { this(nb, D_MARGIN); } public HashSetExtentIndexImpl(double m) { this(D_NBUCKETS, m); } public HashSetExtentIndexImpl(int nb, double m) { super(nb, m); } protected Collection makeBucket(int sizeHint) { if (sizeHint != 0) { return new HashSet(); } else { return new HashSet(sizeHint); } } } class ArrayListExtentIndexImpl extends AbstractExtentIndex { public ArrayListExtentIndexImpl() { this(D_NBUCKETS, D_MARGIN); } public ArrayListExtentIndexImpl(int nb) { this(nb, D_MARGIN); } public ArrayListExtentIndexImpl(double m) { this(D_NBUCKETS, m); } public ArrayListExtentIndexImpl(int nb, double m) { super(nb, m); } protected Collection makeBucket(int sizeHint) { if (sizeHint != 0) { return new ArrayList(); } else { return new ArrayList(sizeHint); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -