use of org.locationtech.spatial4j.shape.Shape 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.Shape in project lucene-solr by apache.
the class StrategyTestCase method getDocuments.
protected List<Document> getDocuments(Iterator<SpatialTestData> sampleData) {
List<Document> documents = new ArrayList<>();
while (sampleData.hasNext()) {
SpatialTestData data = sampleData.next();
Document document = new Document();
document.add(new StringField("id", data.id, Field.Store.YES));
document.add(new StringField("name", data.name, Field.Store.YES));
Shape shape = data.shape;
shape = convertShapeFromGetDocuments(shape);
if (shape != null) {
for (Field f : strategy.createIndexableFields(shape)) {
document.add(f);
}
if (//just for diagnostics
storeShape)
document.add(new StoredField(strategy.getFieldName(), shape.toString()));
}
documents.add(document);
}
return documents;
}
use of org.locationtech.spatial4j.shape.Shape in project lucene-solr by apache.
the class SpatialArgsParser method parse.
/**
* Parses a string such as "Intersects(ENVELOPE(-10,-8,22,20)) distErrPct=0.025".
*
* @param v The string to parse. Mandatory.
* @param ctx The spatial context. Mandatory.
* @return Not null.
* @throws IllegalArgumentException if the parameters don't make sense or an add-on parameter is unknown
* @throws ParseException If there is a problem parsing the string
* @throws InvalidShapeException When the coordinates are invalid for the shape
*/
public SpatialArgs parse(String v, SpatialContext ctx) throws ParseException, InvalidShapeException {
int idx = v.indexOf('(');
int edx = v.lastIndexOf(')');
if (idx < 0 || idx > edx) {
throw new ParseException("missing parens: " + v, -1);
}
SpatialOperation op = SpatialOperation.get(v.substring(0, idx).trim());
String body = v.substring(idx + 1, edx).trim();
if (body.length() < 1) {
throw new ParseException("missing body : " + v, idx + 1);
}
Shape shape = parseShape(body, ctx);
SpatialArgs args = newSpatialArgs(op, shape);
if (v.length() > (edx + 1)) {
body = v.substring(edx + 1).trim();
if (body.length() > 0) {
Map<String, String> aa = parseMap(body);
readNameValuePairs(args, aa);
if (!aa.isEmpty()) {
throw new IllegalArgumentException("unused parameters: " + aa);
}
}
}
args.validate();
return args;
}
use of org.locationtech.spatial4j.shape.Shape in project lucene-solr by apache.
the class ShapeAreaValueSource method getValues.
@Override
public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
final FunctionValues shapeValues = shapeValueSource.getValues(context, readerContext);
return new DoubleDocValues(this) {
@Override
public double doubleVal(int doc) throws IOException {
Shape shape = (Shape) shapeValues.objectVal(doc);
if (shape == null || shape.isEmpty())
//or NaN?
return 0;
// assuming ctx.isGeo()
return shape.getArea(geoArea ? ctx : null) * multiplier;
}
@Override
public boolean exists(int doc) throws IOException {
return shapeValues.exists(doc);
}
@Override
public Explanation explain(int doc) throws IOException {
Explanation exp = super.explain(doc);
List<Explanation> details = new ArrayList<>(Arrays.asList(exp.getDetails()));
details.add(shapeValues.explain(doc));
return Explanation.match(exp.getValue(), exp.getDescription(), details);
}
};
}
use of org.locationtech.spatial4j.shape.Shape in project lucene-solr by apache.
the class PortedSolr3Test method _checkHits.
private void _checkHits(boolean bbox, Point pt, double distKM, int assertNumFound, int... assertIds) {
SpatialOperation op = SpatialOperation.Intersects;
double distDEG = DistanceUtils.dist2Degrees(distKM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
Shape shape = ctx.makeCircle(pt, distDEG);
if (bbox)
shape = shape.getBoundingBox();
SpatialArgs args = new SpatialArgs(op, shape);
//args.setDistPrecision(0.025);
Query query = strategy.makeQuery(args);
SearchResults results = executeQuery(query, 100);
assertEquals("" + shape, assertNumFound, results.numFound);
if (assertIds != null) {
Set<Integer> resultIds = new HashSet<>();
for (SearchResult result : results.results) {
resultIds.add(Integer.valueOf(result.document.get("id")));
}
for (int assertId : assertIds) {
assertTrue("has " + assertId, resultIds.contains(assertId));
}
}
}
Aggregations