use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class TermQueryPrefixTreeStrategy method makeQuery.
@Override
public Query makeQuery(SpatialArgs args) {
final SpatialOperation op = args.getOperation();
if (op != SpatialOperation.Intersects)
throw new UnsupportedSpatialOperation(op);
Shape shape = args.getShape();
int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, distErrPct));
//--get a List of BytesRef for each term we want (no parents, no leaf bytes))
final int GUESS_NUM_TERMS;
if (shape instanceof Point)
//perfect guess
GUESS_NUM_TERMS = detailLevel;
else
//should this be a method on SpatialPrefixTree?
GUESS_NUM_TERMS = 4096;
//shared byte array for all terms
BytesRefBuilder masterBytes = new BytesRefBuilder();
List<BytesRef> terms = new ArrayList<>(GUESS_NUM_TERMS);
CellIterator cells = grid.getTreeCellIterator(shape, detailLevel);
while (cells.hasNext()) {
Cell cell = cells.next();
if (!cell.isLeaf())
continue;
//null because we want a new BytesRef
BytesRef term = cell.getTokenBytesNoLeaf(null);
//We copy out the bytes because it may be re-used across the iteration. This also gives us the opportunity
// to use one contiguous block of memory for the bytes of all terms we need.
masterBytes.grow(masterBytes.length() + term.length);
masterBytes.append(term);
//don't need; will reset later
term.bytes = null;
term.offset = masterBytes.length() - term.length;
terms.add(term);
}
//doing this now because if we did earlier, it's possible the bytes needed to grow()
for (BytesRef byteRef : terms) {
byteRef.bytes = masterBytes.bytes();
}
//TODO an automatonQuery might be faster?
return new TermInSetQuery(getFieldName(), terms);
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class CompositeStrategyTest method randomCircle.
//TODO move up
private Shape randomCircle() {
final Point point = randomPoint();
//TODO pick using gaussian
double radius;
if (ctx.isGeo()) {
radius = randomDouble() * 100;
} else {
//find distance to closest edge
final Rectangle worldBounds = ctx.getWorldBounds();
double maxRad = point.getX() - worldBounds.getMinX();
maxRad = Math.min(maxRad, worldBounds.getMaxX() - point.getX());
maxRad = Math.min(maxRad, point.getY() - worldBounds.getMinY());
maxRad = Math.min(maxRad, worldBounds.getMaxY() - point.getY());
radius = randomDouble() * maxRad;
}
return ctx.makeCircle(point, radius);
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class SpatialExample method search.
private void search() throws Exception {
IndexReader indexReader = DirectoryReader.open(directory);
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
Sort idSort = new Sort(new SortField("id", SortField.Type.INT));
//--Filter by circle (<= distance from a point)
{
//Search with circle
//note: SpatialArgs can be parsed from a string
SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, ctx.makeCircle(-80.0, 33.0, DistanceUtils.dist2Degrees(200, DistanceUtils.EARTH_MEAN_RADIUS_KM)));
Query query = strategy.makeQuery(args);
TopDocs docs = indexSearcher.search(query, 10, idSort);
assertDocMatchedIds(indexSearcher, docs, 2);
//Now, lets get the distance for the 1st doc via computing from stored point value:
// (this computation is usually not redundant)
Document doc1 = indexSearcher.doc(docs.scoreDocs[0].doc);
String doc1Str = doc1.getField(strategy.getFieldName()).stringValue();
//assume doc1Str is "x y" as written in newSampleDocument()
int spaceIdx = doc1Str.indexOf(' ');
double x = Double.parseDouble(doc1Str.substring(0, spaceIdx));
double y = Double.parseDouble(doc1Str.substring(spaceIdx + 1));
double doc1DistDEG = ctx.calcDistance(args.getShape().getCenter(), x, y);
assertEquals(121.6d, DistanceUtils.degrees2Dist(doc1DistDEG, DistanceUtils.EARTH_MEAN_RADIUS_KM), 0.1);
//or more simply:
assertEquals(121.6d, doc1DistDEG * DistanceUtils.DEG_TO_KM, 0.1);
}
//--Match all, order by distance ascending
{
Point pt = ctx.makePoint(60, -50);
//the distance (in km)
ValueSource valueSource = strategy.makeDistanceValueSource(pt, DistanceUtils.DEG_TO_KM);
//false=asc dist
Sort distSort = new Sort(valueSource.getSortField(false)).rewrite(indexSearcher);
TopDocs docs = indexSearcher.search(new MatchAllDocsQuery(), 10, distSort);
assertDocMatchedIds(indexSearcher, docs, 4, 20, 2);
//To get the distance, we could compute from stored values like earlier.
// However in this example we sorted on it, and the distance will get
// computed redundantly. If the distance is only needed for the top-X
// search results then that's not a big deal. Alternatively, try wrapping
// the ValueSource with CachingDoubleValueSource then retrieve the value
// from the ValueSource now. See LUCENE-4541 for an example.
}
//demo arg parsing
{
SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, ctx.makeCircle(-80.0, 33.0, 1));
SpatialArgs args2 = new SpatialArgsParser().parse("Intersects(BUFFER(POINT(-80 33),1))", ctx);
assertEquals(args.toString(), args2.toString());
}
indexReader.close();
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class DistanceValueSource method getValues.
/**
* Returns the FunctionValues used by the function query.
*/
@Override
public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
LeafReader reader = readerContext.reader();
final NumericDocValues ptX = DocValues.getNumeric(reader, strategy.getFieldNameX());
final NumericDocValues ptY = DocValues.getNumeric(reader, strategy.getFieldNameY());
return new FunctionValues() {
private int lastDocID = -1;
private final Point from = DistanceValueSource.this.from;
private final DistanceCalculator calculator = strategy.getSpatialContext().getDistCalc();
private final double nullValue = (strategy.getSpatialContext().isGeo() ? 180 * multiplier : Double.MAX_VALUE);
private double getDocValue(NumericDocValues values, int doc) throws IOException {
int curDocID = values.docID();
if (doc > curDocID) {
curDocID = values.advance(doc);
}
if (doc == curDocID) {
return Double.longBitsToDouble(values.longValue());
} else {
return 0.0;
}
}
@Override
public float floatVal(int doc) throws IOException {
return (float) doubleVal(doc);
}
@Override
public double doubleVal(int doc) throws IOException {
// make sure it has minX and area
double x = getDocValue(ptX, doc);
if (ptX.docID() == doc) {
double y = getDocValue(ptY, doc);
assert ptY.docID() == doc;
return calculator.distance(from, x, y) * multiplier;
}
return nullValue;
}
@Override
public String toString(int doc) throws IOException {
return description() + "=" + floatVal(doc);
}
};
}
use of org.locationtech.spatial4j.shape.Point in project lucene-solr by apache.
the class DistanceStrategyTest method checkDistValueSource.
void checkDistValueSource(Point pt, float... distances) throws IOException {
float multiplier = random().nextFloat() * 100f;
float[] dists2 = Arrays.copyOf(distances, distances.length);
for (int i = 0; i < dists2.length; i++) {
dists2[i] *= multiplier;
}
checkValueSource(strategy.makeDistanceValueSource(pt, multiplier), dists2, 1.0e-3f);
}
Aggregations