Lucene 5.5.3使用递归前缀树策略进行空间索引

时间:2016-09-16 17:01:43

标签: java lucene spatial

我想在空间上索引形状以支持基于多边形和点的查询。但是,我很难创建所需的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

我现在的问题是

  1. 我在使用递归前缀树做错了什么?
  2. 如何使用序列化策略索引多边形本身?
  3. 完整代码:

    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);
    
      }
    }
    

1 个答案:

答案 0 :(得分:0)

为时已晚,但可能会有所帮助

 private val ctx = new JtsSpatialContextFactory().newSpatialContext

并直接使用形状

Field[] fields = rptStrategy.createIndexableFields(spatial4jShape);