`
qxf567
  • 浏览: 21335 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

lucene4 spatial4j

阅读更多
    有次在一个项目中有人提出了一种基于LBS业务的搜索的技术,lucene spatial搜索。随后在网上进行了大搜索。只搜索出一些lucene3代的小例子。现在lucene已经发到4.6了,3代明显太落后了。所以,进行lucene4 spatial的例子搜索,很不幸:使用的人太少了,没有一个例子。就连官网上也没有太多的说明。
 
由于没有仔细观看官网关于spatial模块的说明,未发现有用东西。一次不经意找到一行。位于API_Javadocs中spatial search的index.html上“For some sample code showing how to use the API, see SpatialExample.java in the tests.
 
终于找到了入门的法宝。
SpatialExample 
 
下面对其中使用到的核心类作下说明:
SpatialContext:空间模块上下文,们于spatial4j包中,一个全局单例对象。它是spatial4j的入口。它提供读写Shape对象的通道。
Shape:形状接口。
SpatialStrategy:lucene spatial模块提供创建查询Shape对象索途径。
package com.spatial.client;


import java.io.File;
import java.io.IOException;


import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.spatial.SpatialStrategy;
import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
import org.apache.lucene.spatial.query.SpatialArgs;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;


import com.chenlb.mmseg4j.analysis.SimpleAnalyzer;
import com.spatial4j.core.context.SpatialContext;
import com.spatial4j.core.distance.DistanceUtils;
import com.spatial4j.core.shape.Shape;


public class LuceneSpatialExample {




  public static void main(String[] args) throws IOException {
    new LuceneSpatialExample().test();
  }


  public void test() throws IOException {
    init();
    createIndex();
    search();
  }


  private SpatialContext ctx;//"ctx" is the conventional variable name


  private SpatialStrategy strategy;


  private Directory directory;
  
  private String indexPath = "E:\\index\\spatial\\";
  
  protected void init() {
    //Typical geospatial context
    //  These can also be constructed from SpatialContextFactory
    this.ctx = SpatialContext.GEO;


    int maxLevels = 11;//results in sub-meter precision for geohash
    //TODO demo lookup by detail distance
    //  This can also be constructed from SpatialPrefixTreeFactory
    SpatialPrefixTree grid = new GeohashPrefixTree(ctx, maxLevels);


    this.strategy = new RecursivePrefixTreeStrategy(grid, "myGeoField");


    try {
this.directory = FSDirectory.open(new File(indexPath));
} catch (IOException e) {
e.printStackTrace();
}
  }


  private void createIndex() throws IOException {
    IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_40,new SimpleAnalyzer());
    IndexWriter indexWriter = new IndexWriter(directory, iwConfig);
    //Spatial4j is x-y order for arguments|对于参数的顺序是Longitude,Latitude
    indexWriter.addDocument(newSampleDocument(0, "一星大饭店",ctx.makePoint(116.430360,39.939686)));
    indexWriter.addDocument(newSampleDocument(1, "二星大饭店",ctx.makePoint( 116.430319,39.939702)));
    indexWriter.addDocument(newSampleDocument(2, "三星大饭店",ctx.makePoint(116.430459,39.939802)));
    indexWriter.addDocument(newSampleDocument(3, "四星大饭店", ctx.makePoint(116.430449,39.939902)));
    indexWriter.addDocument(newSampleDocument(4, "六星大饭店",ctx.makePoint(116.430439,39.93402)));
    indexWriter.addDocument(newSampleDocument(5, "七星大饭店",ctx.makePoint(116.430419,39.934102)));
    indexWriter.addDocument(newSampleDocument(6, "五星大饭店",ctx.makePoint(116.430429,39.934202)));
    indexWriter.addDocument(newSampleDocument(6, "五星大酒店",ctx.makePoint(115.430429,39.934202)));
    indexWriter.commit();
    indexWriter.close();
  }


  private Document newSampleDocument(int id,String keyword, Shape... shapes) {
    Document doc = new Document();
    doc.add(new IntField("id", id, Field.Store.YES));
    //Potentially more than one shape in this field is supported by some
    // strategies; see the javadocs of the SpatialStrategy impl to see.
    for (Shape shape : shapes) {
      for (IndexableField f : strategy.createIndexableFields(shape)) {
        doc.add(f);
      }
      //store it too; the format is up to you
      doc.add(new StoredField(strategy.getFieldName(), ctx.toString(shape)));
    }
    doc.add(new TextField("keyword",keyword, Field.Store.YES));
    return doc;
  }


  private void search() throws IOException {
    IndexReader indexReader = DirectoryReader.open(directory);
    IndexSearcher indexSearcher = new IndexSearcher(indexReader);
    {
     //16米范围内
     SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, ctx.makeCircle(116.430459,39.939802, DistanceUtils.dist2Degrees(0.016,DistanceUtils.EARTH_MEAN_RADIUS_KM)));
     Filter filter = strategy.makeFilter(args);
Term term = new Term("keyword","饭店");
Query query001 = new TermQuery(term);


TopDocs docs = indexSearcher.search(query001,filter,1000);
System.out.println(docs.totalHits);


     ScoreDoc[] scoreDoc = docs.scoreDocs;
     if(docs.totalHits>0)
     for (int i = 0; i < scoreDoc.length; i++) {
int doc = scoreDoc[i].doc;
Document mydoc = indexReader.document(doc);
System.out.println(mydoc.get("myGeoField"));
String value = mydoc.get("myGeoField");
String []lonlat = value.split(" ");
double eLat = Double.valueOf(lonlat[1]);
double eLon = Double.valueOf(lonlat[0]);
System.out.println(SpatialUtils.getDistance(39.939802, 116.430459, eLat, eLon, false)+"|keyword: "+mydoc.get("keyword"));
}
    }
    indexReader.close();
  }


}

 

 
 
 
lucene spatial 模块本身就是一个Filter的实现。核心还是lucene的全文检索。真正理解学习新框架或新开源的东西就得从TestCase看起。
 

 

分享到:
评论

相关推荐

    lucene3.3的全部jar包

    icu4j-4_8.jar jakarta-regexp-1.4.jar junit-4.7.jar lucene-analyzers-3.3.0.jar lucene-benchmark-3.3.0.jar lucene-core-3.3.0.jar lucene-demo-3.3.0.jar lucene-grouping-3.3.0.jar lucene-highlighter-3.3.0....

    基于Lucene4.8的空间检索

    这主要依赖于`Spatial4j`库来处理地理坐标,并结合Lucene的索引结构,实现了高效的空间查询。 2. **空间索引类型**:Lucene支持多种空间索引策略,如Grid-based(基于网格)和Tree-based(基于树)等,以优化不同...

    lucene地理位置搜索所用jar包

    1. **集成Lucene**:首先,将Lucene相关的jar包添加到Android项目的依赖中,这可能包括基础的Lucene核心库和其他扩展模块,如spatial4j和geohash库。 2. **构建索引**:创建一个索引,包含文档(如商店、餐馆等)的...

    elasticsearch-5.1.1客户端JAVA开发需要的52个jar包

    5.1.1.jar,log4j-api-2.7.jar,log4j-core-2.7.jar,lucene-analyzers-common-6.3.0.jar,lucene-backward-codecs-6.3.0.jar,lucene-core-6.3.0.jar,lucene-grouping-6.3.0.jar,lucene-highlighter-6.3.0.jar,lucene-...

    elasticsearch-5.2.2客户端JAVA开发需要的69个jar包

    5.1.1.jar,log4j-1.2-api-2.7.jar,log4j-api-2.7.jar,log4j-core-2.7.jar,lucene-analyzers-common-6.4.1.jar,lucene-backward-codecs-6.4.1.jar,lucene-core-6.4.1.jar,lucene-grouping-6.4.1.jar,lucene-...

    1_路径规划_地址编码_公交换乘_本地搜索_热点地图

    SSE4J(Spatial Search Engine for Java)是针对地理信息数据源构建的垂直搜索引擎应用接口,是基于Lucene+JTS Topology Suite开源库设计的框架。 规划的SSE4J包含: 1)SSE4J应用开发包 2)SSE4J Webservice应用...

    2_路径规划_地址编码_公交换乘_本地搜索_热点地图

    SSE4J(Spatial Search Engine for Java)是针对地理信息数据源构建的垂直搜索引擎应用接口,是基于Lucene+JTS Topology Suite开源库设计的框架。 规划的SSE4J包含: 1)SSE4J应用开发包 2)SSE4J Webservice应用...

    3_路径规划_地址编码_公交换乘_本地搜索_热点地图

    SSE4J(Spatial Search Engine for Java)是针对地理信息数据源构建的垂直搜索引擎应用接口,是基于Lucene+JTS Topology Suite开源库设计的框架。 规划的SSE4J包含: 1)SSE4J应用开发包 2)SSE4J Webservice应用...

    solr 需要的各种jar包

    6. **JVM和Java相关库**:Solr运行在Java虚拟机上,因此需要依赖一些Java标准库,如`log4j.jar`用于日志记录,`slf4j-api*.jar`和`slf4j-log4j*.jar`为SLF4J(Simple Logging Facade for Java)接口和适配器。...

    LBS_路径规划_地址编码_公交换乘_本地搜索_热点地图

    【SSE4J】全称为Spatial Search Engine for Java,是一个针对地理信息数据源的垂直搜索引擎应用接口。它基于Java Lucene(一个全文搜索引擎库)和JTS Topology Suite(一个用于地理空间分析的Java库)设计。SSE4J的...

Global site tag (gtag.js) - Google Analytics