2017-02-12 53 views
0

我正在用Jena 3.1.0試用SPARQL。我必須從資源列表中獲得每個資源20公里範圍內的資源。SPARQL用於查找距離資源20km以內的東西

我做了這個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,也不是耶拿 - 它是Virtuoso特有的。 – AndyS

+0

@AndyS我認爲他在DBpedia端點上運行一個聯邦查詢,因此這裏沒關係。至少這就是我在看代碼時所假設的,有一些神奇的行'Sparql.addService(USING_GRAPH,serviceURI)'。否則,整個查詢將在一個空的Jena模型上運行。 – AKSW

回答

0

我已經找到了解決我的問題。

由於某種原因,我不能在bif:st_intersects(?location, ?sourcegeo, 20)中使用bif前綴。所以我把完整的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; 
+0

您可能會發現使用'+「PREFIX bif:」'爲您帶來CURIe的成功。 – TallTed

+0

感謝@TallTed這個創意。有用!但是我不明白它是如何在沒有<

+0

'bif:'是一個內置的Virtuoso前綴(和SPARQL中的URI方案),代表'built-in function'。在提交給後端之前,您只需要用於預解析SPARQL的工具的'PREFIX'語句。這些工具通常不檢查擴展CURIe的有效性;他們只是檢查是否有擴張。 – TallTed