基于Lucene4.8的空间检索

  • L3_344933
    了解作者
  • 15.7MB
    文件大小
  • zip
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-04-28 02:46
    上传日期
针对已知坐标search一定范围内的其他point,根据分类或名称进行search,源文件为类似"PVID","ELPVID","POINAME" 的UTF-8的csv文件
LuceneSpatialDemo.zip
内容介绍
package com.nnn.m.service; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.StoredField; import org.apache.lucene.document.StringField; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; 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.nnn.m.dao.LuceneSearchDao; import com.nnn.m.dao.impl.LuceneSearchDaoImpl; import com.nnn.m.pojo.LuceuePOI; import com.nnn.m.pojo.ResultPojo; import com.nnn.m.pojo.SearchPojo; import com.nnn.tools.SearchUtils; import com.spatial4j.core.context.SpatialContext; import com.spatial4j.core.distance.DistanceUtils; import com.spatial4j.core.shape.Shape; public class LuceneSearchService { private static Log log = LogFactory.getLog(LuceneSearchDaoImpl.class); private static boolean logOperation = false; private LuceneSearchDao dao = new LuceneSearchDaoImpl(); // Spatial private SpatialContext ctx = SpatialContext.GEO; private SpatialStrategy strategy; private Directory directory; public LuceneSearchService(String fieldName, String indexPath) { SpatialPrefixTree grid = new GeohashPrefixTree(ctx, SearchUtils.MAX_LEVELS); this.strategy = new RecursivePrefixTreeStrategy(grid, fieldName); try { File file = new File(indexPath); if (file.exists() && file.isDirectory()) { } else { file.mkdir(); } this.directory = FSDirectory.open(new File(indexPath)); } catch (IOException e) { if (logOperation) { log.debug(e.getMessage()); } e.printStackTrace(); } } // 初始化并创建 // 创建索引 public void writeIndex(String filePath) throws IOException { Properties prop = new Properties(); BufferedReader reader = null; Analyzer analyzer = new SmartChineseAnalyzer(Version.LUCENE_48); try { // 读取配置文件并对document对象赋值 prop.load(LuceneSearchService.class.getResourceAsStream("file_init.properties")); reader = new BufferedReader(new FileReader(filePath)); List<Document> documents = new ArrayList<Document>(); while (reader.ready()) { Document document = new Document(); String line = reader.readLine(); if (line != null && line.length() > 1 && !line.contains("PVID")) { String[] tempLine = line.substring(1).split("\",\""); String pvid = tempLine[Integer.parseInt(prop.getProperty("pvid"))]; String name = tempLine[Integer.parseInt(prop.getProperty("name"))]; String tag1 = tempLine[Integer.parseInt(prop.getProperty("tag1"))]; String tag2 = tempLine[Integer.parseInt(prop.getProperty("tag2"))]; String tel = tempLine[Integer.parseInt(prop.getProperty("tel"))]; String address = tempLine[Integer.parseInt(prop.getProperty("address"))]; String nav_x = tempLine[Integer.parseInt(prop.getProperty("nav_x"))]; String nav_y = tempLine[Integer.parseInt(prop.getProperty("nav_y"))]; Field f_pvid = new StringField(LuceuePOI.PVID, pvid, Field.Store.YES); Field f_name = new StringField(LuceuePOI.NAME, name, Field.Store.YES); Field f_tag1 = new StringField(LuceuePOI.TAG1, tag1, Field.Store.YES); Field f_tag2 = new StringField(LuceuePOI.TAG2, tag2, Field.Store.YES); Field f_address = new StringField(LuceuePOI.ADDRESS, address, Field.Store.YES); Field f_tel = new StringField(LuceuePOI.TEL, tel, Field.Store.YES); // Field f_nav_x = new LongField(LuceuePOI.NAV_X, // NumericUtils.doubleToSortableLong(Double.parseDouble(nav_x)), // Field.Store.YES); // Field f_nav_y = new LongField(LuceuePOI.NAV_X, // NumericUtils.doubleToSortableLong(Double.parseDouble(nav_y)), // Field.Store.YES); document.add(f_pvid); document.add(f_name); document.add(f_tag1); document.add(f_tag2); document.add(f_address); document.add(f_tel); buildDocument(document, ctx.makePoint(Double.parseDouble(nav_x), Double.parseDouble(nav_y))); documents.add(document); if (documents.size() > 102400) { dao.createIndex(documents, directory, analyzer); documents.clear(); } } } if (documents.size() > 0) { dao.createIndex(documents, directory, analyzer); documents.clear(); } } catch (IOException e) { if (logOperation) { log.debug(e.getMessage()); } e.printStackTrace(); } finally { reader.close(); } } private Document buildDocument(Document doc, Shape... shapes) { for (Shape shape : shapes) { for (IndexableField f : strategy.createIndexableFields(shape)) { doc.add(f); } doc.add(new StoredField(strategy.getFieldName(), ctx.toString(shape))); } return doc; } public List<ResultPojo> search(SearchPojo searchPojo) throws IOException { List<ResultPojo> resultList = new ArrayList<ResultPojo>(); IndexReader indexReader = DirectoryReader.open(directory); SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, ctx.makeCircle(searchPojo.getLat(), searchPojo.getLon(), DistanceUtils.dist2Degrees(searchPojo.getRange(), DistanceUtils.EARTH_MEAN_RADIUS_KM))); Filter filter = strategy.makeFilter(args); Term term = new Term(searchPojo.getKeyWord(), searchPojo.getKeyValue()); Query query = new TermQuery(term); TopDocs docs = dao.search(indexReader, query, filter, searchPojo.getNeedToSearchCount()); 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); String value = mydoc.get("poiSearch"); String[] lonlat = value.split(" "); double eLat = Double.valueOf(lonlat[0]); double eLon = Double.valueOf(lonlat[1]); LuceuePOI lp = new LuceuePOI(); lp.setName(mydoc.get("name")); lp.setPvid(mydoc.get("pvid")); lp.setTag1(mydoc.get("tag1")); lp.setTag2(mydoc.get("tag2")); lp.setAddress(mydoc.get("address")); lp.setTel(mydoc.get("tel")); lp.setNav_x(lonlat[0]); lp.setNav_y(lonlat[1]); ResultPojo rp = new ResultPojo(); rp.setDistance(SpatialUtils.getDistance(Double.valueOf(searchPojo.getLat()), Double.valueOf(searchPojo.getLon()), eLat, eLon) + ""); rp.setLucenePoi(lp); resultList.add(rp); } } Collections.sort(resultList, new SearchSort()); indexReader.close(); return resultList; } } class SearchSort implements Comparator<ResultPojo> { public int compare(ResultPojo r1, ResultPojo r2) { int sort = r1.getDistance().compareTo(r2.getDistance()); if (sort == 0) { sort = r1.getLucenePoi().getName().compareToIgnoreCase(r2.
评论
    相关推荐