use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class SpatialDistanceQuery method createFields.
@Override
public List<IndexableField> createFields(SchemaField field, Object value) {
String externalVal = value.toString();
//we could have 3 fields (two for the lat & lon, one for storage)
List<IndexableField> f = new ArrayList<>(3);
if (field.indexed()) {
Point point = SpatialUtils.parsePointSolrException(externalVal, SpatialContext.GEO);
//latitude
SchemaField subLatSF = subField(field, LAT, schema);
f.addAll(subLatSF.createFields(String.valueOf(point.getY())));
//longitude
SchemaField subLonSF = subField(field, LON, schema);
f.addAll(subLonSF.createFields(String.valueOf(point.getX())));
}
if (field.stored()) {
f.add(createField(field.getName(), externalVal, StoredField.TYPE));
}
return f;
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class SpatialDistanceQuery method createSpatialQuery.
@Override
public Query createSpatialQuery(QParser parser, SpatialOptions options) {
Point point = SpatialUtils.parsePointSolrException(options.pointStr, SpatialContext.GEO);
// lat & lon in degrees
double latCenter = point.getY();
double lonCenter = point.getX();
double distDeg = DistanceUtils.dist2Degrees(options.distance, options.radius);
Rectangle bbox = DistanceUtils.calcBoxByDistFromPtDEG(latCenter, lonCenter, distDeg, SpatialContext.GEO, null);
double latMin = bbox.getMinY();
double latMax = bbox.getMaxY();
double lonMin, lonMax, lon2Min, lon2Max;
if (bbox.getCrossesDateLine()) {
lonMin = -180;
lonMax = bbox.getMaxX();
lon2Min = bbox.getMinX();
lon2Max = 180;
} else {
lonMin = bbox.getMinX();
lonMax = bbox.getMaxX();
lon2Min = -180;
lon2Max = 180;
}
IndexSchema schema = parser.getReq().getSchema();
// Now that we've figured out the ranges, build them!
SchemaField latSF = subField(options.field, LAT, schema);
SchemaField lonSF = subField(options.field, LON, schema);
SpatialDistanceQuery spatial = new SpatialDistanceQuery();
if (options.bbox) {
BooleanQuery.Builder result = new BooleanQuery.Builder();
Query latRange = latSF.getType().getRangeQuery(parser, latSF, String.valueOf(latMin), String.valueOf(latMax), true, true);
result.add(latRange, BooleanClause.Occur.MUST);
if (lonMin != -180 || lonMax != 180) {
Query lonRange = lonSF.getType().getRangeQuery(parser, lonSF, String.valueOf(lonMin), String.valueOf(lonMax), true, true);
if (lon2Min != -180 || lon2Max != 180) {
// another valid longitude range
BooleanQuery.Builder bothLons = new BooleanQuery.Builder();
bothLons.add(lonRange, BooleanClause.Occur.SHOULD);
lonRange = lonSF.getType().getRangeQuery(parser, lonSF, String.valueOf(lon2Min), String.valueOf(lon2Max), true, true);
bothLons.add(lonRange, BooleanClause.Occur.SHOULD);
lonRange = bothLons.build();
}
result.add(lonRange, BooleanClause.Occur.MUST);
}
spatial.bboxQuery = result.build();
}
spatial.origField = options.field.getName();
spatial.latSource = latSF.getType().getValueSource(latSF, parser);
spatial.lonSource = lonSF.getType().getValueSource(lonSF, parser);
spatial.latMin = latMin;
spatial.latMax = latMax;
spatial.lonMin = lonMin;
spatial.lonMax = lonMax;
spatial.lon2Min = lon2Min;
spatial.lon2Max = lon2Max;
spatial.lon2 = lon2Min != -180 || lon2Max != 180;
spatial.latCenter = latCenter;
spatial.lonCenter = lonCenter;
spatial.dist = options.distance;
spatial.planetRadius = options.radius;
spatial.calcDist = !options.bbox;
return spatial;
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class AbstractSpatialFieldType method getRangeQuery.
@Override
public Query getRangeQuery(QParser parser, SchemaField field, String part1, String part2, boolean minInclusive, boolean maxInclusive) {
if (!minInclusive || !maxInclusive)
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Both sides of spatial range query must be inclusive: " + field.getName());
Point p1 = SpatialUtils.parsePointSolrException(part1, ctx);
Point p2 = SpatialUtils.parsePointSolrException(part2, ctx);
Rectangle bbox = ctx.makeRectangle(p1, p2);
SpatialArgs spatialArgs = new SpatialArgs(SpatialOperation.Intersects, bbox);
//won't score by default
return getQueryFromSpatialArgs(parser, field, spatialArgs);
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class GeoDistValueSourceParser method parsePoint.
private MultiValueSource parsePoint(FunctionQParser fp) throws SyntaxError {
String ptStr = fp.getParam(SpatialParams.POINT);
if (ptStr == null)
return null;
Point point = SpatialUtils.parsePointSolrException(ptStr, SpatialContext.GEO);
//assume Lat Lon order
return new VectorValueSource(Arrays.<ValueSource>asList(new DoubleConstValueSource(point.getY()), new DoubleConstValueSource(point.getX())));
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class GeohashHaversineFunction method distance.
protected double distance(int doc, FunctionValues gh1DV, FunctionValues gh2DV) throws IOException {
double result = 0;
String h1 = gh1DV.strVal(doc);
String h2 = gh2DV.strVal(doc);
if (h1 != null && h2 != null && h1.equals(h2) == false) {
//TODO: If one of the hashes is a literal value source, seems like we could cache it
//and avoid decoding every time
Point p1 = GeohashUtils.decode(h1, ctx);
Point p2 = GeohashUtils.decode(h2, ctx);
result = ctx.getDistCalc().distance(p1, p2) * degreesToDist;
} else if (h1 == null || h2 == null) {
result = Double.MAX_VALUE;
}
return result;
}
Aggregations