Example usage for org.apache.lucene.spatial SpatialStrategy makeDistanceValueSource

List of usage examples for org.apache.lucene.spatial SpatialStrategy makeDistanceValueSource

Introduction

In this page you can find the example usage for org.apache.lucene.spatial SpatialStrategy makeDistanceValueSource.

Prototype

public abstract DoubleValuesSource makeDistanceValueSource(Point queryPoint, double multiplier);

Source Link

Document

Make a ValueSource returning the distance between the center of the indexed shape and queryPoint .

Usage

From source file:com.gogobot.DistanceParser.java

License:Apache License

@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
    // TODO: dispatch through SpatialQueryable in the future?

    //note: parseValueSourceList can't handle a field reference to an AbstractSpatialFieldType,
    // so those fields are expressly handled via sfield=
    List<ValueSource> sources = fp.parseValueSourceList();

    // "m" is a multi-value source, "x" is a single-value source
    // allow (m,m) (m,x,x) (x,x,m) (x,x,x,x)
    // if not enough points are present, "pt" will be checked first, followed by "sfield".

    MultiValueSource mv1 = null;/*from  ww w .j a v  a  2s  .c  o  m*/
    MultiValueSource mv2 = null;

    if (sources.size() == 0) {
        // nothing to do now
    } else if (sources.size() == 1) {
        ValueSource vs = sources.get(0);
        if (!(vs instanceof MultiValueSource)) {
            throw new SyntaxError("geodist - invalid parameters:" + sources);
        }
        mv1 = (MultiValueSource) vs;
    } else if (sources.size() == 2) {
        ValueSource vs1 = sources.get(0);
        ValueSource vs2 = sources.get(1);

        if (vs1 instanceof MultiValueSource && vs2 instanceof MultiValueSource) {
            mv1 = (MultiValueSource) vs1;
            mv2 = (MultiValueSource) vs2;
        } else {
            mv1 = makeMV(sources, sources);
        }
    } else if (sources.size() == 3) {
        ValueSource vs1 = sources.get(0);
        ValueSource vs2 = sources.get(1);
        if (vs1 instanceof MultiValueSource) { // (m,x,x)
            mv1 = (MultiValueSource) vs1;
            mv2 = makeMV(sources.subList(1, 3), sources);
        } else { // (x,x,m)
            mv1 = makeMV(sources.subList(0, 2), sources);
            vs1 = sources.get(2);
            if (!(vs1 instanceof MultiValueSource)) {
                throw new SyntaxError("geodist - invalid parameters:" + sources);
            }
            mv2 = (MultiValueSource) vs1;
        }
    } else if (sources.size() == 4) {
        mv1 = makeMV(sources.subList(0, 2), sources);
        mv2 = makeMV(sources.subList(2, 4), sources);
    } else if (sources.size() > 4) {
        throw new SyntaxError("geodist - invalid parameters:" + sources);
    }

    if (mv1 == null) {
        mv1 = parsePoint(fp);
        mv2 = parseSfield(fp);
    } else if (mv2 == null) {
        mv2 = parsePoint(fp);
        if (mv2 == null)
            mv2 = parseSfield(fp);
    }

    if (mv1 == null || mv2 == null) {
        throw new SyntaxError("geodist - not enough parameters:" + sources);
    }

    // We have all the parameters at this point, now check if one of the points is constant
    double[] constants;//latLon
    constants = getConstants(mv1);
    MultiValueSource other = mv2;
    if (constants == null) {
        constants = getConstants(mv2);
        other = mv1;
    }

    // At this point we dispatch to one of:
    // * SpatialStrategy.makeDistanceValueSource
    // * HaversineConstFunction
    // * HaversineFunction

    // sfield can only be in mv2, according to the logic above
    if (mv2 instanceof SpatialStrategyMultiValueSource) {
        if (constants == null)
            throw new SyntaxError("When using AbstractSpatialFieldType (e.g. RPT not LatLonType),"
                    + " the point must be supplied as constants");
        // note: uses Haversine by default but can be changed via distCalc=...
        SpatialStrategy strategy = ((SpatialStrategyMultiValueSource) mv2).strategy;
        Point queryPoint = strategy.getSpatialContext().makePoint(constants[1], constants[0]);
        //TODO Spatial4j 0.4 will have a direct constant
        double multiplier = DistanceUtils.degrees2Dist(1, DistanceUtils.EARTH_MEAN_RADIUS_KM);
        return strategy.makeDistanceValueSource(queryPoint, multiplier);
    }

    if (constants != null && other instanceof VectorValueSource) {
        return new GogobotHaversineConstFunction(constants[0], constants[1], (VectorValueSource) other);
    }

    return new HaversineFunction(mv1, mv2, DistanceUtils.EARTH_MEAN_RADIUS_KM, true);
}

From source file:com.stratio.cassandra.lucene.search.sort.GeoDistanceSortField.java

License:Apache License

/** {@inheritDoc} */
@Override//from  ww  w  .ja  v  a2s. c om
public org.apache.lucene.search.SortField sortField(Schema schema) {
    final Mapper mapper = schema.getMapper(this.mapper);
    if (mapper == null) {
        throw new IndexException("No mapper found for sortFields mapper '%s'", this.mapper);
    } else if (!mapper.sorted) {
        throw new IndexException("Mapper '%s' is not sorted", mapper.field);
    } else if (!(mapper instanceof GeoPointMapper)) {
        throw new IndexException("Only Geo Point Mapper is allowed but Mapper '%s' is not", mapper.field);
    }
    GeoPointMapper geoPointMapper = (GeoPointMapper) mapper;

    SpatialStrategy strategy = geoPointMapper.getDistanceStrategy();
    Point pt = GeoPointMapper.SPATIAL_CONTEXT.makePoint(longitude, latitude);

    // The distance (in km)
    ValueSource valueSource = strategy.makeDistanceValueSource(pt, DistanceUtils.DEG_TO_KM);
    return valueSource.getSortField(this.reverse);
}

From source file:org.apache.solr.search.function.distance.GeoDistValueSourceParser.java

License:Apache License

@Override
public ValueSource parse(FunctionQParser fp) throws SyntaxError {
    // TODO: dispatch through SpatialQueryable in the future?

    //note: parseValueSourceList can't handle a field reference to an AbstractSpatialFieldType,
    // so those fields are expressly handled via sfield=
    List<ValueSource> sources = fp.parseValueSourceList();

    // "m" is a multi-value source, "x" is a single-value source
    // allow (m,m) (m,x,x) (x,x,m) (x,x,x,x)
    // if not enough points are present, "pt" will be checked first, followed by "sfield".

    MultiValueSource mv1 = null;//from   www  . j  a v  a2s. c om
    MultiValueSource mv2 = null;

    if (sources.size() == 0) {
        // nothing to do now
    } else if (sources.size() == 1) {
        ValueSource vs = sources.get(0);
        if (!(vs instanceof MultiValueSource)) {
            throw new SyntaxError("geodist - invalid parameters:" + sources);
        }
        mv1 = (MultiValueSource) vs;
    } else if (sources.size() == 2) {
        ValueSource vs1 = sources.get(0);
        ValueSource vs2 = sources.get(1);

        if (vs1 instanceof MultiValueSource && vs2 instanceof MultiValueSource) {
            mv1 = (MultiValueSource) vs1;
            mv2 = (MultiValueSource) vs2;
        } else {
            mv1 = makeMV(sources, sources);
        }
    } else if (sources.size() == 3) {
        ValueSource vs1 = sources.get(0);
        ValueSource vs2 = sources.get(1);
        if (vs1 instanceof MultiValueSource) { // (m,x,x)
            mv1 = (MultiValueSource) vs1;
            mv2 = makeMV(sources.subList(1, 3), sources);
        } else { // (x,x,m)
            mv1 = makeMV(sources.subList(0, 2), sources);
            vs1 = sources.get(2);
            if (!(vs1 instanceof MultiValueSource)) {
                throw new SyntaxError("geodist - invalid parameters:" + sources);
            }
            mv2 = (MultiValueSource) vs1;
        }
    } else if (sources.size() == 4) {
        mv1 = makeMV(sources.subList(0, 2), sources);
        mv2 = makeMV(sources.subList(2, 4), sources);
    } else if (sources.size() > 4) {
        throw new SyntaxError("geodist - invalid parameters:" + sources);
    }

    if (mv1 == null) {
        mv1 = parsePoint(fp);
        mv2 = parseSfield(fp);
    } else if (mv2 == null) {
        mv2 = parsePoint(fp);
        if (mv2 == null)
            mv2 = parseSfield(fp);
    }

    if (mv1 == null || mv2 == null) {
        throw new SyntaxError("geodist - not enough parameters:" + sources);
    }

    // We have all the parameters at this point, now check if one of the points is constant
    double[] constants;//latLon
    constants = getConstants(mv1);
    MultiValueSource other = mv2;
    if (constants == null) {
        constants = getConstants(mv2);
        other = mv1;
    }

    // At this point we dispatch to one of:
    // * SpatialStrategy.makeDistanceValueSource
    // * HaversineConstFunction
    // * HaversineFunction

    // sfield can only be in mv2, according to the logic above
    if (mv2 instanceof SpatialStrategyMultiValueSource) {
        if (constants == null)
            throw new SyntaxError("When using AbstractSpatialFieldType (e.g. RPT not LatLonType),"
                    + " the point must be supplied as constants");
        // note: uses Haversine by default but can be changed via distCalc=...
        SpatialStrategy strategy = ((SpatialStrategyMultiValueSource) mv2).strategy;
        Point queryPoint = strategy.getSpatialContext().makePoint(constants[1], constants[0]);
        //TODO Spatial4j 0.4 will have a direct constant
        double multiplier = DistanceUtils.degrees2Dist(1, DistanceUtils.EARTH_MEAN_RADIUS_KM);
        return strategy.makeDistanceValueSource(queryPoint, multiplier);
    }

    if (constants != null && other instanceof VectorValueSource) {
        return new HaversineConstFunction(constants[0], constants[1], (VectorValueSource) other);
    }

    return new HaversineFunction(mv1, mv2, DistanceUtils.EARTH_MEAN_RADIUS_KM, true);
}