Skip to content

Commit

Permalink
added first implementation of intersect function
Browse files Browse the repository at this point in the history
  • Loading branch information
wolf4ood committed Sep 30, 2015
1 parent 392c067 commit e051d09
Show file tree
Hide file tree
Showing 11 changed files with 272 additions and 11 deletions.
Expand Up @@ -48,6 +48,7 @@ public OLuceneGeoSpatialIndexEngine(String name, OShapeBuilder factory) {
@Override
protected SpatialStrategy createSpatialStrategy(OIndexDefinition indexDefinition, ODocument metadata) {
return new BBoxStrategy(ctx, "location");
// return new RecursivePrefixTreeStrategy(new PackedQuadPrefixTree(ctx, 11), "location");
}

@Override
Expand Down
Expand Up @@ -39,6 +39,7 @@ public class OSpatialFunctionsFactory implements OSQLFunctionFactory {
register(OSTBufferFunction.NAME, new OSTBufferFunction());
register(OSTDistanceFunction.NAME, new OSTDistanceFunction());
register(STDisjointFunction.NAME, new STDisjointFunction());
register(STIntersectsFunction.NAME, new STIntersectsFunction());

register(STSrid.NAME, new STSrid());
// register(STNearFunction.NAME, new STNearFunction());
Expand Down
@@ -0,0 +1,76 @@
/*
*
* * Copyright 2014 Orient Technologies.
* *
* * Licensed 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 com.orientechnologies.orient.spatial.functions;

import com.orientechnologies.orient.core.command.OCommandContext;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.sql.parser.OBinaryCompareOperator;
import com.orientechnologies.orient.core.sql.parser.OExpression;
import com.orientechnologies.orient.core.sql.parser.OFromClause;
import com.orientechnologies.orient.spatial.strategy.SpatialQueryBuilderIntersects;
import com.spatial4j.core.shape.Shape;

import java.util.Collection;

/**
* Created by Enrico Risa on 12/08/15.
*/
public class STIntersectsFunction extends OSpatialFunctionAbstract {

public static final String NAME = "st_intersects";

public STIntersectsFunction() {
super(NAME, 2, 2);
}

@Override
public Object execute(Object iThis, OIdentifiable iCurrentRecord, Object iCurrentResult, Object[] iParams,
OCommandContext iContext) {

Shape shape = factory.fromObject(iParams[0]);

Shape shape1 = factory.fromObject(iParams[1]);

return factory.operation().intersect(shape, shape1);
}

@Override
public String getSyntax() {
return null;
}

@Override
public Iterable<OIdentifiable> searchFromTarget(OFromClause target, OBinaryCompareOperator operator, Object rightValue,
OCommandContext ctx, OExpression... args) {
return results(target, args, ctx);
}

@Override
public long estimate(OFromClause target, OBinaryCompareOperator operator, Object rightValue, OCommandContext ctx,
OExpression... args) {

Collection resultSet = results(target, args, ctx);
return resultSet == null ? -1 : resultSet.size();
}

@Override
protected String operator() {
return SpatialQueryBuilderIntersects.NAME;
}
}
Expand Up @@ -26,4 +26,6 @@
public interface OShapeOperation {

public double distance(Shape s1, Shape s2);

public boolean intersect(Shape s1,Shape s2);
}
Expand Up @@ -26,16 +26,23 @@
*/
public class OShapeOperationImpl implements OShapeOperation {

private final OShapeFactory factory;
private final OShapeFactory factory;

public OShapeOperationImpl(OShapeFactory oShapeFactory) {
this.factory = oShapeFactory;
}
public OShapeOperationImpl(OShapeFactory oShapeFactory) {
this.factory = oShapeFactory;
}

@Override
public double distance(Shape s1, Shape s2) {
Geometry geometry = factory.toGeometry(s1);
Geometry geometry1 = factory.toGeometry(s2);
return geometry.distance(geometry1);
}
@Override
public double distance(Shape s1, Shape s2) {
Geometry geometry = factory.toGeometry(s1);
Geometry geometry1 = factory.toGeometry(s2);
return geometry.distance(geometry1);
}

@Override
public boolean intersect(Shape s1, Shape s2) {
Geometry geometry = factory.toGeometry(s1);
Geometry geometry1 = factory.toGeometry(s2);
return geometry.intersects(geometry1);
}
}
Expand Up @@ -42,6 +42,7 @@ private void initOperators(OLuceneSpatialIndexContainer manager, OShapeBuilder f
operators.put("within", new SpatialQueryBuilderWithin(manager, factory));
operators.put("contains", new SpatialQueryBuilderContains(manager, factory));
operators.put("near", new SpatialQueryBuilderNear(manager, factory));
operators.put("intersects", new SpatialQueryBuilderIntersects(manager, factory));
operators.put("&&", new SpatialQueryBuilderOverlap(manager, factory));
}

Expand Down
Expand Up @@ -23,6 +23,8 @@
import com.orientechnologies.orient.core.index.OIndexEngineException;
import com.orientechnologies.orient.spatial.shape.OShapeBuilder;
import com.spatial4j.core.shape.Shape;
import org.apache.lucene.spatial.SpatialStrategy;
import org.apache.lucene.spatial.bbox.BBoxStrategy;

import java.util.Map;

Expand Down Expand Up @@ -56,5 +58,9 @@ protected Shape parseShape(Map<String, Object> query) {
return factory.fromObject(geometry);
}

protected boolean isOnlyBB(SpatialStrategy spatialStrategy) {
return spatialStrategy instanceof BBoxStrategy;
}

public abstract String getName();
}
@@ -0,0 +1,61 @@
/*
*
* * Copyright 2014 Orient Technologies.
* *
* * Licensed 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 com.orientechnologies.orient.spatial.strategy;

import com.orientechnologies.lucene.engine.OLuceneSpatialIndexContainer;
import com.orientechnologies.lucene.query.SpatialQueryContext;
import com.orientechnologies.orient.spatial.shape.OShapeBuilder;
import com.spatial4j.core.shape.Shape;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.spatial.SpatialStrategy;
import org.apache.lucene.spatial.query.SpatialArgs;
import org.apache.lucene.spatial.query.SpatialOperation;

import java.util.Map;

/**
* Created by Enrico Risa on 11/08/15.
*/
public class SpatialQueryBuilderIntersects extends SpatialQueryBuilderAbstract {

public static final String NAME = "intersects";

public SpatialQueryBuilderIntersects(OLuceneSpatialIndexContainer manager, OShapeBuilder factory) {
super(manager, factory);
}

@Override
public SpatialQueryContext build(Map<String, Object> query) throws Exception {
Shape shape = parseShape(query);
SpatialStrategy strategy = manager.strategy();

if (isOnlyBB(strategy)) {
shape = shape.getBoundingBox();
}
SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, shape);
Filter filter = strategy.makeFilter(args);
return new SpatialQueryContext(null, manager.searcher(), new MatchAllDocsQuery(), filter);
}

@Override
public String getName() {
return NAME;
}
}
Expand Up @@ -44,6 +44,7 @@ public SpatialQueryBuilderWithin(OLuceneSpatialIndexContainer manager, OShapeBui
public SpatialQueryContext build(Map<String, Object> query) throws Exception {
Shape shape = parseShape(query);
SpatialArgs args = new SpatialArgs(SpatialOperation.IsWithin, shape);

Filter filter = manager.strategy().makeFilter(args);
return new SpatialQueryContext(null, manager.searcher(), new MatchAllDocsQuery(), filter);
}
Expand Down
@@ -0,0 +1,81 @@
/*
*
* * Copyright 2014 Orient Technologies.
* *
* * Licensed 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 com.orientechnologies.lucene.test.geo.functions;

import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.OCommandSQL;
import com.tinkerpop.blueprints.impls.orient.OrientGraphNoTx;
import org.testng.Assert;
import org.testng.annotations.Test;

import java.util.List;

/**
* Created by Enrico Risa on 28/09/15.
*/
public class LuceneSpatialIntersectsTest {

@Test
public void testIntersectsNoIndex() {

OrientGraphNoTx graph = new OrientGraphNoTx("memory:functionsTest");
try {
ODatabaseDocumentTx db = graph.getRawGraph();

List<ODocument> execute = db.command(new OCommandSQL("SELECT ST_Intersects('POINT(0 0)', 'LINESTRING ( 2 0, 0 2 )')"))
.execute();
ODocument next = execute.iterator().next();

Assert.assertEquals(next.field("ST_Intersects"), false);
execute = db.command(new OCommandSQL("SELECT ST_Intersects('POINT(0 0)', 'LINESTRING ( 0 0, 0 2 )')")).execute();
next = execute.iterator().next();

Assert.assertEquals(next.field("ST_Intersects"), true);

} finally {
graph.drop();
}
}

@Test
public void testIntersectsIndex() {

OrientGraphNoTx graph = new OrientGraphNoTx("memory:functionsTest");
try {
ODatabaseDocumentTx db = graph.getRawGraph();

db.command(new OCommandSQL("create class Lines extends v")).execute();
db.command(new OCommandSQL("create property Lines.geometry EMBEDDED OLINESTRING")).execute();

db.command(new OCommandSQL("insert into Lines set geometry = ST_GeomFromText('LINESTRING ( 2 0, 0 2 )')")).execute();
db.command(new OCommandSQL("insert into Lines set geometry = ST_GeomFromText('LINESTRING ( 0 0, 0 2 )')")).execute();

db.command(new OCommandSQL("create index L.g on Lines (geometry) SPATIAL engine lucene")).execute();
List<ODocument> execute = db.command(new OCommandSQL("SELECT from lines where ST_Intersects(geometry, 'POINT(0 0)') = true"))
.execute();

Assert.assertEquals(execute.size(), 1);

} finally {
graph.drop();
}
}

}
Expand Up @@ -16,7 +16,7 @@
*
*/

package com.orientechnologies.lucene.test.geo;
package com.orientechnologies.lucene.test.geo.functions;

import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.record.impl.ODocument;
Expand Down Expand Up @@ -164,4 +164,28 @@ public void testDisjoint() {
graph.drop();
}
}

@Test
public void testWithin() {

OrientGraphNoTx graph = new OrientGraphNoTx("memory:functionsTest");
try {
ODatabaseDocumentTx db = graph.getRawGraph();

List<ODocument> execute = db
.command(
new OCommandSQL(
"select ST_Within(smallc,smallc) as smallinsmall,ST_Within(smallc, bigc) As smallinbig, ST_Within(bigc,smallc) As biginsmall from (SELECT ST_Buffer(ST_GeomFromText('POINT(50 50)'), 20) As smallc,ST_Buffer(ST_GeomFromText('POINT(50 50)'), 40) As bigc)"))
.execute();
ODocument next = execute.iterator().next();

Assert.assertEquals(next.field("smallinsmall"), false);
Assert.assertEquals(next.field("smallinbig"), true);
Assert.assertEquals(next.field("biginsmall"), false);

} finally {
graph.drop();
}
}

}

0 comments on commit e051d09

Please sign in to comment.