GeoAroundService.java
package org.wikidata.query.rdf.blazegraph.geo;
import org.openrdf.model.URI;
import org.openrdf.model.impl.URIImpl;
import org.wikidata.query.rdf.common.uri.GeoSparql;
import org.wikidata.query.rdf.common.uri.Ontology;
import com.bigdata.rdf.model.BigdataValueFactory;
import com.bigdata.rdf.sparql.ast.ConstantNode;
import com.bigdata.rdf.sparql.ast.DummyConstantNode;
import com.bigdata.rdf.sparql.ast.JoinGroupNode;
import com.bigdata.rdf.sparql.ast.StatementPatternNode;
import com.bigdata.rdf.sparql.ast.TermNode;
import com.bigdata.rdf.sparql.ast.eval.ServiceParams;
import com.bigdata.rdf.sparql.ast.service.ServiceCallCreateParams;
import com.bigdata.rdf.store.AbstractTripleStore;
import com.bigdata.rdf.vocab.Vocabulary;
import com.bigdata.service.geospatial.GeoSpatial;
import com.bigdata.service.geospatial.GeoSpatial.GeoFunction;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
/**
* Implements a service to do geospatial search.
*
* This class searches for items around certain point.
*
* Example:
*
* SELECT * WHERE {
* wd:Q90 wdt:P625 ?parisLoc .
*
* SERVICE wikibase:around {
* ?place wdt:P625 ?location .
* bd:serviceParam wikibase:center ?parisLoc .
* bd:serviceParam wikibase:radius "1" .
* bd:serviceParam wikibase:distance ?distance .
* }
* }
*/
@SuppressFBWarnings(value = "FCCD_FIND_CLASS_CIRCULAR_DEPENDENCY", justification = "This should probably be fixed at some point")
public class GeoAroundService extends GeoService {
/**
* The URI service key.
*/
public static final URI SERVICE_KEY = new URIImpl(
Ontology.NAMESPACE + "around");
/**
* wikibase:center parameter name.
*/
public static final URIImpl CENTER_PARAM = new URIImpl(
Ontology.NAMESPACE + "center");
/**
* wikibase:radius parameter name.
*/
public static final URIImpl RADIUS_PARAM = new URIImpl(
Ontology.NAMESPACE + "radius");
/**
* wikibase:distance parameter name.
*/
public static final URIImpl DISTANCE_PARAM = new URIImpl(
Ontology.NAMESPACE + "distance");
@Override
protected JoinGroupNode buildServiceNode(ServiceCallCreateParams params,
ServiceParams serviceParams) {
final AbstractTripleStore store = params.getTripleStore();
final Vocabulary voc = store.getVocabulary();
BigdataValueFactory vf = store.getValueFactory();
final StatementPatternNode pattern = getPatternNode(params);
final TermNode searchVar = pattern.s();
final TermNode predicate = pattern.p();
final TermNode locationVar = pattern.o();
final JoinGroupNode newGroup = new JoinGroupNode();
// ?var geo:search "inCircle" .
newGroup.addArg(new StatementPatternNode(
searchVar,
new DummyConstantNode(vf.asValue(GeoSpatial.SEARCH)),
new DummyConstantNode(vf.createLiteral(GeoFunction.IN_CIRCLE.toString()))
));
// ?var geo:predicate wdt:P625 .
newGroup.addArg(new StatementPatternNode(
searchVar,
new DummyConstantNode(vf.asValue(GeoSpatial.PREDICATE)),
predicate
));
// ?var geo:searchDatatype ogc:wktLiteral .
newGroup.addArg(new StatementPatternNode(
searchVar,
new DummyConstantNode(vf.asValue(GeoSpatial.SEARCH_DATATYPE)),
new ConstantNode(
voc.getConstant(new URIImpl(GeoSparql.WKT_LITERAL)))));
// ?var geo:spatialCircleCenter ?parisLoc .
newGroup.addArg(new StatementPatternNode(
searchVar,
new DummyConstantNode(vf.asValue(GeoSpatial.SPATIAL_CIRCLE_CENTER)),
getParam(serviceParams, CENTER_PARAM)
));
// ?var geo:spatialCircleRadius "1" .
newGroup.addArg(new StatementPatternNode(
searchVar,
new DummyConstantNode(vf.asValue(GeoSpatial.SPATIAL_CIRCLE_RADIUS)),
getParam(serviceParams, RADIUS_PARAM)
));
// ?var geo:locationValue ?location .
newGroup.addArg(new StatementPatternNode(
searchVar,
new DummyConstantNode(vf.asValue(GeoSpatial.LOCATION_VALUE)),
locationVar));
// ?var geo:coordSystem "0" .
newGroup.addArg(new StatementPatternNode(
searchVar,
new DummyConstantNode(vf.asValue(GeoSpatial.COORD_SYSTEM)),
getGlobeNode(vf, serviceParams)
));
final TermNode distance = serviceParams.get(DISTANCE_PARAM, null);
if (distance != null) {
// ?var geo:distanceValue ?distance .
newGroup.addArg(new StatementPatternNode(
searchVar,
new DummyConstantNode(vf.asValue(GeoSpatial.DISTANCE_VALUE)),
distance
));
}
return newGroup;
}
}