Search in sources :

Example 1 with Shape

use of com.spatial4j.core.shape.Shape in project crate by crate.

the class IntersectsFunction method evaluate.

@Override
public Boolean evaluate(Input<Object>... args) {
    assert args.length == 2 : "Invalid number of Arguments";
    Object left = args[0].value();
    if (left == null) {
        return null;
    }
    Object right = args[1].value();
    if (right == null) {
        return null;
    }
    Shape leftShape = GeoJSONUtils.map2Shape(DataTypes.GEO_SHAPE.value(left));
    Shape rightShape = GeoJSONUtils.map2Shape(DataTypes.GEO_SHAPE.value(right));
    return leftShape.relate(rightShape).intersects();
}
Also used : Shape(com.spatial4j.core.shape.Shape)

Example 2 with Shape

use of com.spatial4j.core.shape.Shape in project crate by crate.

the class WithinFunction method parseLeftShape.

@SuppressWarnings("unchecked")
private Shape parseLeftShape(Object left) {
    Shape shape;
    if (left instanceof Double[]) {
        Double[] values = (Double[]) left;
        shape = SpatialContext.GEO.makePoint(values[0], values[1]);
    } else if (left instanceof List) {
        // ESSearchTask / ESGetTask returns it as list
        List values = (List) left;
        assert values.size() == 2 : "number of values must be 2";
        shape = SpatialContext.GEO.makePoint((Double) values.get(0), (Double) values.get(1));
    } else if (left instanceof BytesRef) {
        shape = GeoJSONUtils.wkt2Shape(BytesRefs.toString(left));
    } else {
        shape = GeoJSONUtils.map2Shape((Map<String, Object>) left);
    }
    return shape;
}
Also used : Shape(com.spatial4j.core.shape.Shape) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) BytesRef(org.apache.lucene.util.BytesRef)

Example 3 with Shape

use of com.spatial4j.core.shape.Shape in project titan by thinkaurelius.

the class LuceneIndex method addToDocument.

private void addToDocument(String store, String docID, Document doc, List<IndexEntry> content, Map<String, Shape> geofields, KeyInformation.IndexRetriever informations) {
    Preconditions.checkNotNull(doc);
    for (IndexEntry e : content) {
        Preconditions.checkArgument(!e.hasMetaData(), "Lucene index does not support indexing meta data: %s", e);
        if (log.isTraceEnabled())
            log.trace("Adding field [{}] on document [{}]", e.field, docID);
        if (doc.getField(e.field) != null)
            doc.removeFields(e.field);
        if (e.value instanceof Number) {
            Field field;
            if (AttributeUtil.isWholeNumber((Number) e.value)) {
                field = new LongField(e.field, ((Number) e.value).longValue(), Field.Store.YES);
            } else {
                //double or float
                field = new DoubleField(e.field, ((Number) e.value).doubleValue(), Field.Store.YES);
            }
            doc.add(field);
        } else if (AttributeUtil.isString(e.value)) {
            String str = (String) e.value;
            Mapping mapping = Mapping.getMapping(store, e.field, informations);
            Field field;
            switch(mapping) {
                case DEFAULT:
                case TEXT:
                    field = new TextField(e.field, str, Field.Store.YES);
                    break;
                case STRING:
                    field = new StringField(e.field, str, Field.Store.YES);
                    break;
                default:
                    throw new IllegalArgumentException("Illegal mapping specified: " + mapping);
            }
            doc.add(field);
        } else if (e.value instanceof Geoshape) {
            Shape shape = ((Geoshape) e.value).convert2Spatial4j();
            geofields.put(e.field, shape);
            doc.add(new StoredField(e.field, GEOID + toWkt(shape)));
        } else if (e.value instanceof Date) {
            doc.add(new LongField(e.field, (((Date) e.value).getTime()), Field.Store.YES));
        } else if (e.value instanceof Instant) {
            doc.add(new LongField(e.field, (((Instant) e.value).toEpochMilli()), Field.Store.YES));
        } else if (e.value instanceof Boolean) {
            doc.add(new IntField(e.field, ((Boolean) e.value) ? 1 : 0, Field.Store.YES));
        } else if (e.value instanceof UUID) {
            //Solr stores UUIDs as strings, we we do the same.
            Field field = new StringField(e.field, e.value.toString(), Field.Store.YES);
            doc.add(field);
        } else {
            throw new IllegalArgumentException("Unsupported type: " + e.value);
        }
    }
    for (Map.Entry<String, Shape> geo : geofields.entrySet()) {
        if (log.isTraceEnabled())
            log.trace("Updating geo-indexes for key {}", geo.getKey());
        for (IndexableField f : getSpatialStrategy(geo.getKey()).createIndexableFields(geo.getValue())) doc.add(f);
    }
}
Also used : Shape(com.spatial4j.core.shape.Shape) Instant(java.time.Instant) Mapping(com.thinkaurelius.titan.core.schema.Mapping) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 4 with Shape

use of com.spatial4j.core.shape.Shape in project titan by thinkaurelius.

the class LuceneIndex method mutateStores.

private void mutateStores(Map.Entry<String, Map<String, IndexMutation>> stores, KeyInformation.IndexRetriever informations) throws StorageException, IOException {
    IndexReader reader = null;
    try {
        String storename = stores.getKey();
        IndexWriter writer = getWriter(storename);
        reader = DirectoryReader.open(writer, true);
        IndexSearcher searcher = new IndexSearcher(reader);
        for (Map.Entry<String, IndexMutation> entry : stores.getValue().entrySet()) {
            String docid = entry.getKey();
            IndexMutation mutation = entry.getValue();
            Term docTerm = new Term(DOCID, docid);
            if (mutation.isDeleted()) {
                log.trace("Deleted entire document [{}]", docid);
                writer.deleteDocuments(docTerm);
                continue;
            }
            Document doc = null;
            TopDocs hits = searcher.search(new TermQuery(docTerm), 10);
            Map<String, Shape> geofields = Maps.newHashMap();
            if (hits.scoreDocs.length == 0) {
                log.trace("Creating new document for [{}]", docid);
                doc = new Document();
                Field docidField = new StringField(DOCID, docid, Field.Store.YES);
                doc.add(docidField);
            } else if (hits.scoreDocs.length > 1) {
                throw new IllegalArgumentException("More than one document found for document id: " + docid);
            } else {
                log.trace("Updating existing document for [{}]", docid);
                int docId = hits.scoreDocs[0].doc;
                // retrieve the old document
                doc = searcher.doc(docId);
                for (IndexableField field : doc.getFields()) {
                    if (field.stringValue().startsWith(GEOID)) {
                        geofields.put(field.name(), ctx.readShape(field.stringValue().substring(GEOID.length())));
                    }
                }
            }
            Preconditions.checkNotNull(doc);
            for (String key : mutation.getDeletions()) {
                if (doc.getField(key) != null) {
                    log.trace("Removing field [{}] on document [{}]", key, docid);
                    doc.removeFields(key);
                    geofields.remove(key);
                }
            }
            for (IndexEntry add : mutation.getAdditions()) {
                log.trace("Adding field [{}] on document [{}]", add.key, docid);
                if (doc.getField(add.key) != null)
                    doc.removeFields(add.key);
                if (add.value instanceof Number) {
                    Field field = null;
                    if (AttributeUtil.isWholeNumber((Number) add.value)) {
                        field = new LongField(add.key, ((Number) add.value).longValue(), Field.Store.YES);
                    } else {
                        // double or float
                        field = new DoubleField(add.key, ((Number) add.value).doubleValue(), Field.Store.YES);
                    }
                    doc.add(field);
                } else if (AttributeUtil.isString(add.value)) {
                    String str = (String) add.value;
                    Mapping mapping = Mapping.getMapping(storename, add.key, informations);
                    Field field;
                    switch(mapping) {
                        case DEFAULT:
                        case TEXT:
                            field = new TextField(add.key, str, Field.Store.YES);
                            break;
                        case STRING:
                            field = new StringField(add.key, str, Field.Store.YES);
                            break;
                        default:
                            throw new IllegalArgumentException("Illegal mapping specified: " + mapping);
                    }
                    doc.add(field);
                } else if (add.value instanceof Geoshape) {
                    Shape shape = ((Geoshape) add.value).convert2Spatial4j();
                    geofields.put(add.key, shape);
                    doc.add(new StoredField(add.key, GEOID + ctx.toString(shape)));
                } else
                    throw new IllegalArgumentException("Unsupported type: " + add.value);
            }
            for (Map.Entry<String, Shape> geo : geofields.entrySet()) {
                log.trace("Updating geo-indexes for key {}", geo.getKey());
                for (IndexableField f : getSpatialStrategy(geo.getKey()).createIndexableFields(geo.getValue())) {
                    doc.add(f);
                }
            }
            // write the old document to the index with the modifications
            writer.updateDocument(new Term(DOCID, docid), doc);
        }
        writer.commit();
    } finally {
        IOUtils.closeQuietly(reader);
    }
}
Also used : Shape(com.spatial4j.core.shape.Shape) Mapping(com.thinkaurelius.titan.core.Mapping) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 5 with Shape

use of com.spatial4j.core.shape.Shape in project titan by thinkaurelius.

the class LuceneIndex method convertQuery.

private final Filter convertQuery(Condition<?> condition, KeyInformation.StoreRetriever informations) {
    if (condition instanceof PredicateCondition) {
        PredicateCondition<String, ?> atom = (PredicateCondition) condition;
        Object value = atom.getValue();
        String key = atom.getKey();
        TitanPredicate titanPredicate = atom.getPredicate();
        if (value instanceof Number) {
            Preconditions.checkArgument(titanPredicate instanceof Cmp, "Relation not supported on numeric types: " + titanPredicate);
            Preconditions.checkArgument(value instanceof Number);
            return numericFilter(key, (Cmp) titanPredicate, (Number) value);
        } else if (value instanceof String) {
            Mapping map = Mapping.getMapping(informations.get(key));
            if ((map == Mapping.DEFAULT || map == Mapping.TEXT) && !titanPredicate.toString().startsWith("CONTAINS"))
                throw new IllegalArgumentException("Text mapped string values only support CONTAINS queries and not: " + titanPredicate);
            if (map == Mapping.STRING && titanPredicate.toString().startsWith("CONTAINS"))
                throw new IllegalArgumentException("String mapped string values do not support CONTAINS queries: " + titanPredicate);
            if (titanPredicate == Text.CONTAINS) {
                value = ((String) value).toLowerCase();
                return new TermsFilter(new Term(key, (String) value));
            } else if (titanPredicate == Text.CONTAINS_PREFIX) {
                value = ((String) value).toLowerCase();
                return new PrefixFilter(new Term(key, (String) value));
            } else if (titanPredicate == Text.PREFIX) {
                return new PrefixFilter(new Term(key, (String) value));
            // } else if (titanPredicate == Text.CONTAINS_REGEX) {
            // value = ((String) value).toLowerCase();
            // return new RegexpQuery(new Term(key,(String)value));
            } else if (titanPredicate == Cmp.EQUAL) {
                return new TermsFilter(new Term(key, (String) value));
            } else if (titanPredicate == Cmp.NOT_EQUAL) {
                BooleanFilter q = new BooleanFilter();
                q.add(new TermsFilter(new Term(key, (String) value)), BooleanClause.Occur.MUST_NOT);
                return q;
            } else
                throw new IllegalArgumentException("Relation is not supported for string value: " + titanPredicate);
        } else if (value instanceof Geoshape) {
            Preconditions.checkArgument(titanPredicate == Geo.WITHIN, "Relation is not supported for geo value: " + titanPredicate);
            Shape shape = ((Geoshape) value).convert2Spatial4j();
            SpatialArgs args = new SpatialArgs(SpatialOperation.IsWithin, shape);
            return getSpatialStrategy(key).makeFilter(args);
        } else
            throw new IllegalArgumentException("Unsupported type: " + value);
    } else if (condition instanceof Not) {
        BooleanFilter q = new BooleanFilter();
        q.add(convertQuery(((Not) condition).getChild(), informations), BooleanClause.Occur.MUST_NOT);
        return q;
    } else if (condition instanceof And) {
        BooleanFilter q = new BooleanFilter();
        for (Condition c : condition.getChildren()) {
            q.add(convertQuery(c, informations), BooleanClause.Occur.MUST);
        }
        return q;
    } else if (condition instanceof Or) {
        BooleanFilter q = new BooleanFilter();
        for (Condition c : condition.getChildren()) {
            q.add(convertQuery(c, informations), BooleanClause.Occur.SHOULD);
        }
        return q;
    } else
        throw new IllegalArgumentException("Invalid condition: " + condition);
}
Also used : BooleanFilter(org.apache.lucene.queries.BooleanFilter) SpatialArgs(org.apache.lucene.spatial.query.SpatialArgs) Shape(com.spatial4j.core.shape.Shape) TermsFilter(org.apache.lucene.queries.TermsFilter) Mapping(com.thinkaurelius.titan.core.Mapping) TitanPredicate(com.thinkaurelius.titan.graphdb.query.TitanPredicate)

Aggregations

Shape (com.spatial4j.core.shape.Shape)11 SpatialContext (com.spatial4j.core.context.SpatialContext)3 Map (java.util.Map)3 JtsSpatialContext (com.spatial4j.core.context.jts.JtsSpatialContext)2 Mapping (com.thinkaurelius.titan.core.Mapping)2 HashMap (java.util.HashMap)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 XContentBuilder (org.elasticsearch.common.xcontent.XContentBuilder)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 Point (com.spatial4j.core.shape.Point)1 Geoshape (com.thinkaurelius.titan.core.attribute.Geoshape)1 Mapping (com.thinkaurelius.titan.core.schema.Mapping)1 TitanPredicate (com.thinkaurelius.titan.graphdb.query.TitanPredicate)1 GeoJSONUtilsTest (io.crate.geo.GeoJSONUtilsTest)1 CrateUnitTest (io.crate.test.integration.CrateUnitTest)1 IOException (java.io.IOException)1 Instant (java.time.Instant)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1