SPARQL用于查找资源20公里范围内的内容

时间:2017-02-12 15:51:42

标签: java sparql jena

我正在尝试使用Jena 3.1.0进行SPARQL。我必须找到从资源列表中获得的每个资源半径20公里范围内的资源。

我做了这个SPARQL查询:click me。它适用于DBpedia端点,但它在Java中不起作用。

这是我的代码。

public class SKPQSearch {

    static Model model = getTestModel();
    public static char quotes = '"';
    public static boolean USING_GRAPH = false;

    public static void main(String[] args) {

        List<Resource> interestObject = new ArrayList<Resource>();
        List<Resource> features = new ArrayList<Resource>();

        interestObject = searchObjectofInterest("Hotel");
        features = findFeatures(interestObject);

        Iterator<Resource> it = features.iterator();

        System.out.println("Features.....\n\n");

        while (it.hasNext()) {
            System.out.println(it.next().getURI());
        }                   }

    public static Model getTestModel() {

        Model model = ModelFactory.createDefaultModel();
        return model;

    }

    public static List<Resource> findFeatures(List<Resource> interestSet) {

        List<Resource> featureSet = new ArrayList<>();

        String serviceURI = "http://dbpedia.org/sparql";

        for (int a = 0; a < interestSet.size(); a++) {

            String queryString = "" + Sparql.addService(USING_GRAPH, serviceURI)
                    + "SELECT DISTINCT ?resource WHERE { <" + interestSet.get(a).getURI()
                    + "> geo:geometry ?sourcegeo." + " ?resource geo:geometry ?location ;" + "rdfs:label ?label ."
                    + "FILTER( bif:st_intersects( ?location, ?sourcegeo, 20 ) )." + "FILTER( lang( ?label ) =" + quotes
                    + "en" + quotes + ")}" + Sparql.addServiceClosing(USING_GRAPH);

            Query query = QueryFactory.create(Sparql.addPrefix().concat(queryString));

            try (QueryExecution qexec = QueryExecutionFactory.create(query, model)) {

                Map<String, Map<String, List<String>>> serviceParams = new HashMap<String, Map<String, List<String>>>();
                Map<String, List<String>> params = new HashMap<String, List<String>>();
                List<String> values = new ArrayList<String>();
                values.add("20000");
                params.put("timeout", values);
                serviceParams.put(serviceURI, params);
                qexec.getContext().set(ARQ.serviceParams, serviceParams);
                try {
                    ResultSet rs = qexec.execSelect();
                    System.out.println(rs.hasNext());
                    for (; rs.hasNext();) {
                        QuerySolution rb = rs.nextSolution();

                        RDFNode x = rb.get("resource");
                        if (x.isResource()) {
                            featureSet.add((Resource) x);
                        }
                    }
                } finally {
                    qexec.close();
                }
            }
        }
        return featureSet;
    }

    public static List<Resource> searchObjectofInterest(String object) {

        List<Resource> resources = new ArrayList<Resource>();

        String serviceURI = "http://dbpedia.org/sparql";

        String queryString = "" + Sparql.addService(USING_GRAPH, serviceURI) + "SELECT distinct ?hotel " + "WHERE {  "
                + " ?hotel a <http://dbpedia.org/ontology/" + object + ">. }" + " LIMIT 1"
                + Sparql.addServiceClosing(USING_GRAPH);

        Query query = QueryFactory.create(Sparql.addPrefix().concat(queryString));

        try (QueryExecution qexec = QueryExecutionFactory.create(query, model)) {

            Map<String, Map<String, List<String>>> serviceParams = new HashMap<String, Map<String, List<String>>>();
            Map<String, List<String>> params = new HashMap<String, List<String>>();
            List<String> values = new ArrayList<String>();
            values.add("20000");
            params.put("timeout", values);
            serviceParams.put(serviceURI, params);
            qexec.getContext().set(ARQ.serviceParams, serviceParams);
            try {
                ResultSet rs = qexec.execSelect();

                for (; rs.hasNext();) {
                    QuerySolution rb = rs.nextSolution();

                    RDFNode x = rb.get("hotel");
                    if (x.isResource()) {
                        resources.add((Resource) x);
                    }
                }
            } finally {
                qexec.close();
            }
            return resources;
        }       }    }

Sparql.addService方法

public static String addService(boolean usingGraph, String serviceURI) {
    if (!usingGraph) {
        return "SELECT DISTINCT * WHERE { SERVICE <" + serviceURI + ">{";
    } else {
        return " ";
    }
}

查询示例:click me

PS:我使用的是前缀:PREFIX geo: <http://www.opengis.net/ont/geosparql#>

1 个答案:

答案 0 :(得分:0)

我找到了解决问题的方法。

出于某种原因,我无法在bif中使用bif:st_intersects( ?location, ?sourcegeo, 20 )前缀。所以我把完整的URI FILTER ( <http://www.openlinksw.com/schema/sparql/extensions#bif:st_intersects(?location,?sourcegeo,20)> )

编辑:在@TallTed建议之后,我更新了我的Sparql.addPrefix()方法并将PREFIX bif: <bif:>放在上面。这样我就不必在我的SPARQL查询中使用完整的URI。

 public static String addPrefix() {
        String prefix = "" + "PREFIX owl: <http://www.w3.org/2002/07/owl#>"                 
                + "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> "
                + "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> "
                + "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
                + "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " 
                + "PREFIX dc: <http://purl.org/dc/elements/1.1/> "
                + "PREFIX bif: <bif:>"
                + "PREFIX : <http://dbpedia.org/resource/> " 
                + "PREFIX dbpedia2: <http://dbpedia.org/property/> "
                + "PREFIX dbpedia: <http://dbpedia.org/> " 
                + "PREFIX skos: <http://www.w3.org/2004/02/skos/core#> "
                + "PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>"
                + "PREFIX e: <http://learningsparql.com/ns/expenses#> "
                + "PREFIX d: <http://learningsparql.com/ns/data#> ";
        return prefix;