【发布时间】:2017-01-24 23:46:48
【问题描述】:
我想对形状进行空间索引以支持基于多边形和点的查询。但是,我很难创建为此所需的 lucene 文档。想法是使用递归前缀树根据 geohash 对形状进行快速过滤,然后通过检查形状的序列化来查看查询的多边形是否确实匹配 (explained here)。
我遇到的第一个问题是无法创建要添加到空间文档的可索引字段:
Document doc = new Document();
Field[] fields = rptStrategy.createIndexableFields(spatial4jShape.getBoundingBox());
for (Field f : fields) {
doc.add(f);
}
我遇到的第二个问题是无法将 Jts 形状用于序列化部分:
fields = dvStrategy.createIndexableFields((Shape)spatial4jShape);
这会引发 IllegalArgumentException
java.lang.IllegalArgumentException: Unsupported shape class com.spatial4j.core.shape.jts.JtsGeometry
我现在的问题是
- 我在使用递归前缀树时做错了什么?
- 如何使用序列化策略来索引多边形本身?
完整代码:
import com.spatial4j.core.context.SpatialContext;
import com.spatial4j.core.context.jts.JtsSpatialContext;
import com.spatial4j.core.io.jts.JtsWKTReader;
import com.spatial4j.core.shape.Shape;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
import org.apache.lucene.spatial.serialized.SerializedDVStrategy;
import java.text.ParseException;
public class TestLuceneSpatial {
public static void main(String[] args) throws ParseException {
String wkt = "POLYGON((-122.4604 37.7818,-122.4707 37.7645,-122.4659 37.7509,-122.4337 37.7476,-122.4192 37.7856,-122.4604 37.7818))";
SpatialContext ctx = SpatialContext.GEO;
GeohashPrefixTree grid = new GeohashPrefixTree(ctx, 6);
RecursivePrefixTreeStrategy rptStrategy = new RecursivePrefixTreeStrategy(grid, "rptBBox");
rptStrategy.setPrefixGridScanLevel(grid.getMaxLevels() - 1);
SerializedDVStrategy dvStrategy = new SerializedDVStrategy(ctx, "polygon");
JtsWKTReader wktReader = new JtsWKTReader(JtsSpatialContext.GEO, null);
Shape spatial4jShape = wktReader.parse(wkt);
Document doc = new Document();
Field[] fields = rptStrategy.createIndexableFields(spatial4jShape.getBoundingBox());
for (Field f : fields) {
doc.add(f);
}
fields = dvStrategy.createIndexableFields((Shape)spatial4jShape);
for (Field f : fields) {
doc.add(f);
}
for (IndexableField f : doc.getFields()) {
System.out.printf("%s => %s\n", f.name(), f.binaryValue());
}
System.out.println(doc);
}
}
【问题讨论】: