All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.stratio.cassandra.lucene.schema.mapping.GeoShapeMapper Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2014 Stratio (http://stratio.com)
 *
 * 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.stratio.cassandra.lucene.schema.mapping;

import com.google.common.base.MoreObjects;
import com.spatial4j.core.shape.jts.JtsGeometry;
import com.stratio.cassandra.lucene.IndexException;
import com.stratio.cassandra.lucene.common.GeoTransformation;
import com.stratio.cassandra.lucene.common.GeospatialUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.search.SortField;
import org.apache.lucene.spatial.composite.CompositeSpatialStrategy;
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.serialized.SerializedDVStrategy;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static com.stratio.cassandra.lucene.common.GeospatialUtilsJTS.CONTEXT;
import static com.stratio.cassandra.lucene.common.GeospatialUtilsJTS.geometry;

/**
 * A {@link Mapper} to map geographical shapes represented according to the 
 * Well Known Text (WKT) format. 

This class depends on Java Topology * Suite (JTS). This library can't be distributed together with this project due to license compatibility problems, * but you can add it by putting jts-core-1.14.0.jar * into Cassandra lib directory.

Pole wrapping is not supported. * * The indexing is based on a {@link CompositeSpatialStrategy} combining a geohash search tree in front of doc values. * The search tree is used to quickly filtering according to a precision level, and the stored BinaryDocValues are used * to achieve precision discarding false positives. * * @author Andres de la Pena {@literal } */ public class GeoShapeMapper extends SingleColumnMapper { /** The default max number of levels for geohash search trees. */ public static final int DEFAULT_MAX_LEVELS = 5; // ±2.4 Km /** The name of the mapped column. */ public final String column; /** The max number of levels in the tree. */ public final int maxLevels; /** The spatial strategy for radial distance searches. */ public final CompositeSpatialStrategy strategy; /** The sequence of transformations to be applied to the shape before indexing. */ public final List transformations; /** * Builds a new {@link GeoShapeMapper}. * * @param field the name of the field * @param column the name of the column * @param validated if the field must be validated * @param maxLevels the maximum number of precision levels in the search tree. False positives will be discarded * using stored doc values, so a low value doesn't mean precision lost. High values will produce few false positives * to be post-filtered, at the expense of creating many terms in the search index, specially with large polygons. * @param transformations the sequence of operations to be applied to the indexed shapes */ public GeoShapeMapper(String field, String column, Boolean validated, Integer maxLevels, List transformations) { super(field, column, false, validated, null, String.class, TEXT_TYPES); this.column = column == null ? field : column; if (StringUtils.isWhitespace(column)) { throw new IndexException("Column must not be whitespace, but found '{}'", column); } this.maxLevels = GeospatialUtils.validateGeohashMaxLevels(maxLevels, DEFAULT_MAX_LEVELS); SpatialPrefixTree grid = new GeohashPrefixTree(CONTEXT, this.maxLevels); RecursivePrefixTreeStrategy indexStrategy = new RecursivePrefixTreeStrategy(grid, field); SerializedDVStrategy geometryStrategy = new SerializedDVStrategy(CONTEXT, field); strategy = new CompositeSpatialStrategy(field, indexStrategy, geometryStrategy); this.transformations = transformations == null ? Collections.emptyList() : transformations; } /** {@inheritDoc} */ @Override public List indexableFields(String name, String value) { JtsGeometry shape = geometry(value); for (GeoTransformation transformation : transformations) { shape = transformation.apply(shape); } return Arrays.asList(strategy.createIndexableFields(shape)); } /** {@inheritDoc} */ @Override public SortField sortField(String name, boolean reverse) { throw new IndexException("GeoShape mapper '{}' does not support simple sorting", name); } /** {@inheritDoc} */ @Override protected String doBase(String field, Object value) { return value.toString(); } /** {@inheritDoc} */ @Override public String toString() { return MoreObjects.toStringHelper(this) .add("field", field) .add("column", column) .add("validated", validated) .add("maxLevels", maxLevels) .add("transformations", transformations) .toString(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy