private void setupPrefixTrees() { GeoShapeFieldType ft = fieldType(); SpatialPrefixTree prefixTree; if (ft.tree().equals(DeprecatedParameters.PrefixTrees.GEOHASH)) { prefixTree = new GeohashPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(ft.treeLevels(), ft.precisionInMeters(), DeprecatedParameters.Defaults.GEOHASH_TREE_LEVELS, true)); } else if (ft.tree().equals(DeprecatedParameters.PrefixTrees.LEGACY_QUADTREE)) { prefixTree = new QuadPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(ft.treeLevels(), ft.precisionInMeters(), DeprecatedParameters.Defaults.QUADTREE_LEVELS, false)); } else if (ft.tree().equals(DeprecatedParameters.PrefixTrees.QUADTREE)) { prefixTree = new PackedQuadPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(ft.treeLevels(), ft.precisionInMeters(), DeprecatedParameters.Defaults.QUADTREE_LEVELS, false)); } else { throw new IllegalArgumentException("Unknown prefix tree type [" + ft.tree() + "]"); } // setup prefix trees regardless of strategy (this is used for the QueryBuilder) // recursive: RecursivePrefixTreeStrategy rpts = new RecursivePrefixTreeStrategy(prefixTree, ft.name()); rpts.setDistErrPct(ft.distanceErrorPct()); rpts.setPruneLeafyBranches(false); ft.recursiveStrategy = rpts; // term: TermQueryPrefixTreeStrategy termStrategy = new TermQueryPrefixTreeStrategy(prefixTree, ft.name()); termStrategy.setDistErrPct(ft.distanceErrorPct()); ft.termStrategy = termStrategy; // set default (based on strategy): ft.defaultPrefixTreeStrategy = ft.resolvePrefixTreeStrategy(ft.strategy()); ft.defaultPrefixTreeStrategy.setPointsOnly(ft.pointsOnly()); }
@Override public Field[] createIndexableFields(Shape shape) { List<Field> fields = new ArrayList<>(); Collections.addAll(fields, indexStrategy.createIndexableFields(shape)); Collections.addAll(fields, geometryStrategy.createIndexableFields(shape)); return fields.toArray(new Field[fields.size()]); }
@Override public NumberRangePrefixTree getGrid() { return (NumberRangePrefixTree) super.getGrid(); }
public GeoProperty(Property prop) { this.prop = prop; this.spatialctx = SpatialContext.GEO; int maxlevels = 11; // FIXME: how to compute? GeohashPrefixTree grid = new GeohashPrefixTree(spatialctx, maxlevels); this.strategy = new RecursivePrefixTreeStrategy(grid, prop.getName()); }
protected RecursivePrefixTreeStrategy makeRPTStrategy(String spatialField, Config config, Map<String, String> configMap, SpatialContext ctx) { //A factory for the prefix tree grid SpatialPrefixTree grid = SpatialPrefixTreeFactory.makeSPT(configMap, null, ctx); RecursivePrefixTreeStrategy strategy = new RecursivePrefixTreeStrategy(grid, spatialField); strategy.setPointsOnly(config.get("spatial.docPointsOnly", false)); final boolean pruneLeafyBranches = config.get("spatial.pruneLeafyBranches", true); if (grid instanceof PackedQuadPrefixTree) { ((PackedQuadPrefixTree) grid).setPruneLeafyBranches(pruneLeafyBranches); strategy.setPruneLeafyBranches(false);//always leave it to packed grid, even though it isn't the same } else { strategy.setPruneLeafyBranches(pruneLeafyBranches); } int prefixGridScanLevel = config.get("query.spatial.prefixGridScanLevel", -4); if (prefixGridScanLevel < 0) prefixGridScanLevel = grid.getMaxLevels() + prefixGridScanLevel; strategy.setPrefixGridScanLevel(prefixGridScanLevel); double distErrPct = config.get("spatial.distErrPct", .025);//doc & query; a default strategy.setDistErrPct(distErrPct); return strategy; }
public SpatialStrategy createStrategy(SpatialContext ctx, ODatabaseDocumentInternal db, OIndexDefinition indexDefinition, ODocument metadata) { OClass aClass = db.getMetadata().getSchema().getClass(indexDefinition.getClassName()); OProperty property = aClass.getProperty(indexDefinition.getFields().get(0)); OClass linkedClass = property.getLinkedClass(); if ("OPoint".equalsIgnoreCase(linkedClass.getName())) { RecursivePrefixTreeStrategy strategy = new RecursivePrefixTreeStrategy(new GeohashPrefixTree(ctx, 11), "location"); strategy.setDistErrPct(0); return strategy; } return BBoxStrategy.newInstance(ctx, "location"); } }
final SpatialPrefixTree grid = indexStrategy.getGrid(); final int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, 0.0));//default to max precision return new IntersectsRPTVerifyQuery(args.getShape(), indexStrategy.getFieldName(), grid, detailLevel, indexStrategy.getPrefixGridScanLevel(), predicateValueSource); } else { final Query indexQuery = indexStrategy.makeQuery(indexArgs); return new CompositeVerifyQuery(indexQuery, predicateValueSource);
/** {@link #makeQuery(SpatialArgs)} specialized for the query being a grid square. */ protected Query makeGridShapeIntersectsQuery(Shape gridShape) { assert isGridAlignedShape(gridShape); if (isPointsOnly()) { // Awesome; this will be equivalent to a TermQuery. Iterator<Cell> cellIterator = grid.getTreeCellIterator(gridShape, grid.getMaxLevels()); // get last cell Cell cell = cellIterator.next(); while (cellIterator.hasNext()) { int prevLevel = cell.getLevel(); cell = cellIterator.next(); assert prevLevel < cell.getLevel(); } assert cell.isLeaf(); return new TermQuery(new Term(getFieldName(), cell.getTokenBytesWithLeaf(null))); } else { // Well there could be parent cells. But we can reduce the "scan level" which will be slower for a point query. // TODO: AVPTQ will still scan the bottom nonetheless; file an issue to eliminate that return new IntersectsPrefixTreeQuery( gridShape, getFieldName(), grid, getGrid().getMaxLevels(), getGrid().getMaxLevels() + 1); } } }
@Override public Query makeQuery(SpatialArgs args) { final SpatialOperation op = args.getOperation(); Shape shape = args.getShape(); int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, distErrPct)); if (op == SpatialOperation.Intersects) { if (isGridAlignedShape(args.getShape())) { return makeGridShapeIntersectsQuery(args.getShape()); } return new IntersectsPrefixTreeQuery( shape, getFieldName(), grid, detailLevel, prefixGridScanLevel); } else if (op == SpatialOperation.IsWithin) { return new WithinPrefixTreeQuery( shape, getFieldName(), grid, detailLevel, prefixGridScanLevel, -1);//-1 flag is slower but ensures correct results } else if (op == SpatialOperation.Contains) { return new ContainsPrefixTreeQuery(shape, getFieldName(), grid, detailLevel, multiOverlappingIndexedShapes); } throw new UnsupportedSpatialOperation(op); }
@Override public Query makeQuery(SpatialArgs args) { final SpatialOperation op = args.getOperation(); Shape shape = args.getShape(); int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, distErrPct)); if (op == SpatialOperation.Intersects) { return new IntersectsPrefixTreeQuery( shape, getFieldName(), grid, detailLevel, prefixGridScanLevel); } else if (op == SpatialOperation.IsWithin) { return new WithinPrefixTreeQuery( shape, getFieldName(), grid, detailLevel, prefixGridScanLevel, -1);//-1 flag is slower but ensures correct results } else if (op == SpatialOperation.Contains) { return new ContainsPrefixTreeQuery(shape, getFieldName(), grid, detailLevel, multiOverlappingIndexedShapes); } throw new UnsupportedSpatialOperation(op); } }
@Override public SpatialStrategy apply(String field) { return new RecursivePrefixTreeStrategy(spt, GEO_FIELD_PREFIX + field); }
final SpatialPrefixTree grid = indexStrategy.getGrid(); final int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, 0.0));//default to max precision return new IntersectsRPTVerifyQuery(args.getShape(), indexStrategy.getFieldName(), grid, detailLevel, indexStrategy.getPrefixGridScanLevel(), predicateValueSource); } else { final Query indexQuery = indexStrategy.makeQuery(indexArgs); return new CompositeVerifyQuery(indexQuery, predicateValueSource);
@Override public void freeze() { super.freeze(); // This is a bit hackish: we need to setup the spatial tree and strategies once the field name is set, which // must be by the time freeze is called. SpatialPrefixTree prefixTree; if ("geohash".equals(tree)) { prefixTree = new GeohashPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(treeLevels, precisionInMeters, Defaults.GEOHASH_LEVELS, true)); } else if ("legacyquadtree".equals(tree)) { prefixTree = new QuadPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(treeLevels, precisionInMeters, Defaults.QUADTREE_LEVELS, false)); } else if ("quadtree".equals(tree)) { prefixTree = new PackedQuadPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(treeLevels, precisionInMeters, Defaults.QUADTREE_LEVELS, false)); } else { throw new IllegalArgumentException("Unknown prefix tree type [" + tree + "]"); } recursiveStrategy = new RecursivePrefixTreeStrategy(prefixTree, name()); recursiveStrategy.setDistErrPct(distanceErrorPct()); recursiveStrategy.setPruneLeafyBranches(false); termStrategy = new TermQueryPrefixTreeStrategy(prefixTree, name()); termStrategy.setDistErrPct(distanceErrorPct()); defaultStrategy = resolveStrategy(strategyName); defaultStrategy.setPointsOnly(pointsOnly); }
public SpatialFacetHandler(String name, String lonFieldName, String latFieldName, String geoFieldName, int geoHashPrefixTreeMaxLevels) { super(name); longitude = lonFieldName; latitude = latFieldName; SpatialPrefixTree grid = new GeohashPrefixTree(SpatialContext.GEO, geoHashPrefixTreeMaxLevels); spatialStrategy = new RecursivePrefixTreeStrategy(grid, geoFieldName); }
@Override public Field[] createIndexableFields(Shape shape) { List<Field> fields = new ArrayList<>(); Collections.addAll(fields, indexStrategy.createIndexableFields(shape)); Collections.addAll(fields, geometryStrategy.createIndexableFields(shape)); return fields.toArray(new Field[fields.size()]); }
@Override public NumberRangePrefixTree getGrid() { return (NumberRangePrefixTree) super.getGrid(); }
@Override public void freeze() { super.freeze(); // This is a bit hackish: we need to setup the spatial tree and strategies once the field name is set, which // must be by the time freeze is called. SpatialPrefixTree prefixTree; if ("geohash".equals(tree)) { prefixTree = new GeohashPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(treeLevels, precisionInMeters, Defaults.GEOHASH_LEVELS, true)); } else if ("legacyquadtree".equals(tree)) { prefixTree = new QuadPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(treeLevels, precisionInMeters, Defaults.QUADTREE_LEVELS, false)); } else if ("quadtree".equals(tree)) { prefixTree = new PackedQuadPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(treeLevels, precisionInMeters, Defaults.QUADTREE_LEVELS, false)); } else { throw new IllegalArgumentException("Unknown prefix tree type [" + tree + "]"); } recursiveStrategy = new RecursivePrefixTreeStrategy(prefixTree, name()); recursiveStrategy.setDistErrPct(distanceErrorPct()); recursiveStrategy.setPruneLeafyBranches(false); termStrategy = new TermQueryPrefixTreeStrategy(prefixTree, name()); termStrategy.setDistErrPct(distanceErrorPct()); defaultStrategy = resolveStrategy(strategyName); defaultStrategy.setPointsOnly(pointsOnly); }
public OLuceneSpatialIndexManager(OShapeFactory factory) { super(); this.ctx = SpatialContext.GEO; this.factory = factory; SpatialPrefixTree grid = new GeohashPrefixTree(ctx, 11); this.strategy = new RecursivePrefixTreeStrategy(grid, "location"); }
@Override public void freeze() { super.freeze(); // This is a bit hackish: we need to setup the spatial tree and strategies once the field name is set, which // must be by the time freeze is called. SpatialPrefixTree prefixTree; if ("geohash".equals(tree)) { prefixTree = new GeohashPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(treeLevels, precisionInMeters, Defaults.GEOHASH_LEVELS, true)); } else if ("legacyquadtree".equals(tree)) { prefixTree = new QuadPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(treeLevels, precisionInMeters, Defaults.QUADTREE_LEVELS, false)); } else if ("quadtree".equals(tree)) { prefixTree = new PackedQuadPrefixTree(ShapeBuilder.SPATIAL_CONTEXT, getLevels(treeLevels, precisionInMeters, Defaults.QUADTREE_LEVELS, false)); } else { throw new IllegalArgumentException("Unknown prefix tree type [" + tree + "]"); } recursiveStrategy = new RecursivePrefixTreeStrategy(prefixTree, name()); recursiveStrategy.setDistErrPct(distanceErrorPct()); recursiveStrategy.setPruneLeafyBranches(false); termStrategy = new TermQueryPrefixTreeStrategy(prefixTree, name()); termStrategy.setDistErrPct(distanceErrorPct()); defaultStrategy = resolveStrategy(strategyName); defaultStrategy.setPointsOnly(pointsOnly); }
public GeoProperty(Property prop) { this.prop = prop; this.spatialctx = SpatialContext.GEO; int maxlevels = 11; // FIXME: how to compute? GeohashPrefixTree grid = new GeohashPrefixTree(spatialctx, maxlevels); this.strategy = new RecursivePrefixTreeStrategy(grid, prop.getName()); }