2017-02-12 1 views
0

Я пытаюсь использовать SPARQL с Jena 3.1.0. Я должен найти ресурсы, которые находятся в радиусе 20 км от каждого ресурса, полученного из списка ресурсов.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#>

+0

Непонятно, что такое 'Sparql.addService', но я думаю, что это как-то генерирует федеративный запрос? В противном случае вы будете запускать запрос SPARQL к пустой модели. Для цели отладки гораздо проще, если вы предоставите полный окончательный запрос, чтобы увидеть, что действительно выполнено. – AKSW

+2

Jena не поддерживает GeoSPARQL: он обеспечивает базовую функцию пространственного поиска. http://jena.apache.org/documentation/query/spatial-query.html 'bif: st_intersects' не является GeoSPARQL и не является Jena - это Virtuoso специфический. – AndyS

+0

@AndyS Я думаю, что он запускает федеративный запрос на конечной точке DBpedia, поэтому здесь это не имеет значения. По крайней мере, это то, что я предполагаю при просмотре кода, есть волшебная линия 'Sparql.addService (USING_GRAPH, serviceURI)'. В противном случае весь запрос будет запущен на пустой модели Jena. – AKSW

ответ

0

Я нашел решение моей проблемы.

По какой-то причине я не могу использовать префикс bif в bif:st_intersects(?location, ?sourcegeo, 20). Поэтому я положил полный URI FILTER (<http://www.openlinksw.com/schema/sparql/extensions#bif:st_intersects(?location,?sourcegeo,20)>)

EDIT: Следуя предложению @TallTed, я обновил свой метод Sparql.addPrefix() и положил на него PREFIX bif: <bif:>. Таким образом, мне не нужно использовать полный URI для моего запроса SPARQL.

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; 
+0

. Вы можете обнаружить, что использование '+ 'PREFIX bif: « "приносит вам успех с CURIe. – TallTed

+0

Спасибо за идею @TallTed. Оно работает! Но я не понял, как это работает без ссылки '

+0

'bif:' представляет собой встроенный префикс Virtuoso (и схему URI в SPARQL), стоящий для 'встроенной функции'. Вам нужен только оператор 'PREFIX' для инструментов, которые предварительно анализируют ваш SPARQL, прежде чем отправлять его в исходный код. Эти инструменты обычно не проверяют на достоверность расширенного CURIe; они просто проверяют, что есть расширение. – TallTed

Смежные вопросы