/* * 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.operator; import com.orientechnologies.lucene.collections.OSpatialCompositeKey; import com.orientechnologies.lucene.shape.OShapeFactoryImpl; import com.orientechnologies.orient.core.command.OCommandContext; import com.orientechnologies.orient.core.db.ODatabase; import com.orientechnologies.orient.core.db.record.OIdentifiable; import com.orientechnologies.orient.core.id.ORID; import com.orientechnologies.orient.core.index.*; import com.orientechnologies.orient.core.metadata.schema.OClass; import com.orientechnologies.orient.core.record.impl.ODocument; import com.orientechnologies.orient.core.sql.OIndexSearchResult; import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition; import com.orientechnologies.orient.core.sql.operator.OIndexReuseType; import com.orientechnologies.orient.core.sql.operator.OQueryTargetOperator; import com.spatial4j.core.context.SpatialContext; import com.spatial4j.core.shape.Shape; import com.spatial4j.core.shape.SpatialRelation; import org.apache.lucene.spatial.query.SpatialOperation; import java.util.Collection; import java.util.List; public class OLuceneWithinOperator extends OQueryTargetOperator { OShapeFactoryImpl shapeFactory = OShapeFactoryImpl.INSTANCE; public OLuceneWithinOperator() { super("WITHIN", 5, false); } @Override public Collection<OIdentifiable> filterRecords(ODatabase<?> iRecord, List<String> iTargetClasses, OSQLFilterCondition iCondition, Object iLeft, Object iRight) { return null; } @Override public Object evaluateRecord(OIdentifiable iRecord, ODocument iCurrentResult, OSQLFilterCondition iCondition, Object iLeft, Object iRight, OCommandContext iContext) { List<Number> left = (List<Number>) iLeft; double lat = left.get(0).doubleValue(); double lon = left.get(1).doubleValue(); Shape shape = SpatialContext.GEO.makePoint(lon, lat); Shape shape1 = shapeFactory.makeShape(new OSpatialCompositeKey((List<?>) iRight), SpatialContext.GEO); return shape.relate(shape1) == SpatialRelation.WITHIN; } @Override public OIndexReuseType getIndexReuseType(Object iLeft, Object iRight) { return OIndexReuseType.INDEX_OPERATOR; } @Override public OIndexCursor executeIndexQuery(OCommandContext iContext, OIndex<?> index, List<Object> keyParams, boolean ascSortOrder) { OIndexDefinition definition = index.getDefinition(); int idxSize = definition.getFields().size(); int paramsSize = keyParams.size(); OIndexCursor cursor; Object indexResult = index.get(new OSpatialCompositeKey(keyParams).setOperation(SpatialOperation.IsWithin)); if (indexResult == null || indexResult instanceof OIdentifiable) cursor = new OIndexCursorSingleValue((OIdentifiable) indexResult, new OSpatialCompositeKey(keyParams)); else cursor = new OIndexCursorCollectionValue(((Collection<OIdentifiable>) indexResult).iterator(), new OSpatialCompositeKey( keyParams)); iContext.setVariable("$luceneIndex", true); return cursor; } @Override public ORID getBeginRidRange(Object iLeft, Object iRight) { return null; } @Override public ORID getEndRidRange(Object iLeft, Object iRight) { return null; } @Override public OIndexSearchResult getOIndexSearchResult(OClass iSchemaClass, OSQLFilterCondition iCondition, List<OIndexSearchResult> iIndexSearchResults, OCommandContext context) { return OLuceneOperatorUtil.buildOIndexSearchResult(iSchemaClass, iCondition, iIndexSearchResults, context); } }