Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jena.query.spatial;
import java.io.IOException ;
import java.util.ArrayList ;
import java.util.List ;
import org.apache.jena.graph.Node ;
import org.apache.lucene.analysis.Analyzer ;
import org.apache.lucene.analysis.standard.StandardAnalyzer ;
import org.apache.lucene.document.Document ;
import org.apache.lucene.document.Field ;
import org.apache.lucene.document.FieldType ;
import org.apache.lucene.index.* ;
import org.apache.lucene.queries.function.ValueSource ;
import org.apache.lucene.search.* ;
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.util.Version ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import com.spatial4j.core.shape.Point ;
import com.spatial4j.core.shape.Shape ;
public class SpatialIndexLucene implements SpatialIndex {
private static Logger log = LoggerFactory
.getLogger(SpatialIndexLucene.class);
private static int MAX_N = 10000;
public static final Version VER = Version.LUCENE_4_9;
public static final FieldType ftIRI;
static {
ftIRI = new FieldType();
ftIRI.setTokenized(false);
ftIRI.setStored(true);
ftIRI.setIndexed(true);
ftIRI.freeze();
}
// public static final FieldType ftText = TextField.TYPE_NOT_STORED ;
// Bigger index, easier to debug!
// public static final FieldType ftText = TextField.TYPE_STORED ;
private final EntityDefinition docDef;
private final Directory directory;
private IndexWriter indexWriter;
private Analyzer analyzer = new StandardAnalyzer(VER);
/**
* The Lucene spatial {@link SpatialStrategy} encapsulates an approach to
* indexing and searching shapes, and providing distance values for them.
* It's a simple API to unify different approaches. You might use more than
* one strategy for a shape as each strategy has its strengths and
* weaknesses.
*
* Note that these are initialized with a field name.
*/
private SpatialStrategy strategy;
public SpatialIndexLucene(Directory directory, EntityDefinition def) {
this.directory = directory;
this.docDef = def;
int maxLevels = 11;// results in sub-meter precision for geohash
// This can also be constructed from SpatialPrefixTreeFactory
SpatialPrefixTree grid = new GeohashPrefixTree(SpatialQuery.ctx, maxLevels);
this.strategy = new RecursivePrefixTreeStrategy(grid, def.getGeoField());
//this.strategy = new PointVectorStrategy(ctx, def.getGeoField());
// force creation of the index if it don't exist
// otherwise if we get a search before data is written we get an
// exception
startIndexing();
finishIndexing();
}
public Directory getDirectory() {
return directory;
}
public Analyzer getAnalyzer() {
return analyzer;
}
@Override
public void startIndexing() {
try {
IndexWriterConfig wConfig = new IndexWriterConfig(VER, analyzer);
indexWriter = new IndexWriter(directory, wConfig);
} catch (IOException e) {
exception(e);
}
}
@Override
public void finishIndexing() {
try {
indexWriter.commit();
indexWriter.close();
indexWriter = null;
} catch (IOException e) {
exception(e);
}
}
@Override
public void abortIndexing() {
try {
indexWriter.rollback();
} catch (IOException ex) {
exception(ex);
}
}
@Override
public void close() {
if (indexWriter != null)
try {
indexWriter.close();
} catch (IOException ex) {
exception(ex);
}
}
@Override
public void add(String entityURI, Shape... shapes) {
try {
boolean autoBatch = (indexWriter == null);
Document doc = doc(entityURI, shapes);
if (autoBatch)
startIndexing();
indexWriter.addDocument(doc);
if (autoBatch)
finishIndexing();
} catch (IOException e) {
exception(e);
}
}
private Document doc(String entityURI, Shape... shapes) {
Document doc = new Document();
Field entField = new Field(docDef.getEntityField(), entityURI, ftIRI);
doc.add(entField);
for (Shape shape : shapes) {
for (IndexableField f : strategy.createIndexableFields(shape)) {
doc.add(f);
}
}
return doc;
}
@Override
public List query(Shape shape, int limit, SpatialOperation operation) {
// Upgrade at Java7 ...
try (IndexReader indexReader = DirectoryReader.open(directory)) {
return query$(indexReader, shape, limit, operation) ;
}
catch (Exception ex) {
exception(ex) ;
return null ;
}
}
private List query$(IndexReader indexReader, Shape shape, int limit, SpatialOperation operation) throws IOException {
if (limit <= 0)
limit = MAX_N;
IndexSearcher indexSearcher = new IndexSearcher(indexReader);
Point pt = shape.getCenter();
ValueSource valueSource = strategy.makeDistanceValueSource(pt);// the
// distance
// (in
// degrees)
Sort distSort = new Sort(valueSource.getSortField(false))
.rewrite(indexSearcher);
SpatialArgs args = new SpatialArgs(operation, shape);
args.setDistErr(0.0);
Filter filter = strategy.makeFilter(args);
TopDocs docs = indexSearcher.search(new MatchAllDocsQuery(), filter,
limit, distSort);
List results = new ArrayList<>();
// Align and DRY with Solr.
for (ScoreDoc sd : docs.scoreDocs) {
Document doc = indexSearcher.doc(sd.doc);
String[] values = doc.getValues(docDef.getEntityField());
for (String v : values) {
Node n = SpatialQueryFuncs.stringToNode(v) ;
results.add(n);
}
}
return results;
}
@Override
public EntityDefinition getDocDef() {
return docDef;
}
private static void exception(Exception ex) {
throw new SpatialIndexException(ex);
}
}