GeoSearch::GeoSearch(Collection* collection, TwoDAccessMethod* accessMethod, const Point& startPt, int numWanted, MatchExpression* filter, double maxDistance, GeoDistType type) : GeoHopper(collection, accessMethod, numWanted, startPt, filter, maxDistance, type), _start(accessMethod->getParams().geoHashConverter->hash(startPt.x, startPt.y)), _numWanted(numWanted), _type(type), _params(accessMethod->getParams()) { _nscanned = 0; _found = 0; if(_maxDistance < 0){ _scanDistance = numeric_limits<double>::max(); } else if (type == GEO_PLANE) { _scanDistance = maxDistance + _params.geoHashConverter->getError(); } else if (type == GEO_SPHERE) { checkEarthBounds(startPt); // TODO: consider splitting into x and y scan distances _scanDistance = computeXScanDistance(startPt.y, rad2deg(_maxDistance) + _params.geoHashConverter->getError()); } verify(_scanDistance > 0); }
bool GeoCircleBrowse::exactDocCheck(const Point& p, double& d){ switch (_type) { case GEO_PLANE: { if(distanceWithin(_startPt, p, _maxDistance)) return true; break; } case GEO_SPHERE: checkEarthBounds(p); if(spheredist_deg(_startPt, p) <= _maxDistance) return true; break; default: verify(false); } return false; }
bool GeoHopper::exactDocCheck(const Point& p, double& d){ bool within = false; // Get the appropriate distance for the type switch (_type) { case GEO_PLANE: d = distance(_near, p); within = distanceWithin(_near, p, _maxDistance); break; case GEO_SPHERE: checkEarthBounds(p); d = spheredist_deg(_near, p); within = (d <= _maxDistance); break; default: verify(false); } return within; }
GeoAccumulator:: KeyResult GeoHopper::approxKeyCheck(const Point& p, double& d) { // Always check approximate distance, since it lets us avoid doing // checks of the rest of the object if it succeeds switch (_type) { case GEO_PLANE: d = distance(_near, p); break; case GEO_SPHERE: checkEarthBounds(p); d = spheredist_deg(_near, p); break; default: verify(false); } verify(d >= 0); // If we need more points double borderDist = (_points.size() < _max ? _maxDistance : farthest()); if (d >= borderDist - 2 * _distError && d <= borderDist + 2 * _distError) return BORDER; else return d < borderDist ? GOOD : BAD; }
GeoAccumulator::KeyResult GeoCircleBrowse::approxKeyCheck(const Point& p, double& d) { // Inexact hash distance checks. double error = 0; switch (_type) { case GEO_PLANE: d = distance(_startPt, p); error = _converter->getError(); break; case GEO_SPHERE: { checkEarthBounds(p); d = spheredist_deg(_startPt, p); error = _converter->getErrorSphere(); break; } default: verify(false); } // If our distance is in the error bounds... if(d >= _maxDistance - error && d <= _maxDistance + error) return BORDER; return d > _maxDistance ? BAD : GOOD; }