Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
747 views
in Technique[技术] by (71.8m points)

sparql - get latitude and longitude of a place dbpedia

I want to get the latitude and longitude of a place whose name I already know by

PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT * WHERE {
  ?s a dbo:Place .
  ?s geo:lat ?lat .
  ?s geo:long ?long .
} 

where the name of the place (?s) is something like Graves Park. How would one go about implementing the same in Jena where the name of the place might vary?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use Jena's ARQ to execute queries against remote SPARQL endpoints. The process is described in ARQ?—?Querying Remote SPARQL Services.

Using ParameterizedSparqlStrings in SELECT queries

To do this for different places that you might not know until it is time to execute the query, you can use a ParameterizedSparqlString to hold the query and then inject the value(s) once you have them. Here's an example. The query is the one you provided. I put it into a ParameterizedSparqlString, and then used setIri to set ?s to http://dbpedia.org/resource/Mount_Monadnock.

import com.hp.hpl.jena.query.ParameterizedSparqlString;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFormatter;

public class DBPediaQuery {
    public static void main( String[] args ) {
        final String dbpedia = "http://dbpedia.org/sparql";
        final ParameterizedSparqlString queryString
          = new ParameterizedSparqlString(
                    "PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>"+
                    "PREFIX dbo: <http://dbpedia.org/ontology/>" +
                    "SELECT * WHERE {" +
                    "  ?s a dbo:Place ." +
                    "  ?s geo:lat ?lat ." +
                    "  ?s geo:long ?long ." +
                    "}" );
        queryString.setIri( "?s", "http://dbpedia.org/resource/Mount_Monadnock");
        QueryExecution exec = QueryExecutionFactory.sparqlService( dbpedia, queryString.toString() );
        ResultSet results = exec.execSelect();
        ResultSetFormatter.out( System.out, results );
    }
}

The results printed by this are:

--------------------------------------------------------------------------------------------------------------
| lat                                                 | long                                                 |
==============================================================================================================
| "42.8608"^^<http://www.w3.org/2001/XMLSchema#float> | "-72.1081"^^<http://www.w3.org/2001/XMLSchema#float> |
--------------------------------------------------------------------------------------------------------------

Once you have the ResultSet, you can iterate through the rows of the solution and extract the values. The values here are Literals, and from a Literal you can extract the lexical form (the string value), or the value as the corresponding Java type (in the case of numbers, strings, booleans, &c.). You could do the the following to print the latitude and longitude instead of using the ResultSetFormatter:

while ( results.hasNext() ) {
  QuerySolution solution = results.next();
  Literal latitude = solution.getLiteral( "?lat" );
  Literal longitude = solution.getLiteral( "?long" );

  String sLat = latitude.getLexicalForm();
  String sLon = longitude.getLexicalForm();

  float fLat = latitude.getFloat();
  float fLon = longitude.getFloat();

  System.out.println( "Strings: " + sLat + "," + sLon );
  System.out.println( "Floats: " + fLat + "," + fLon );
}

The output after this change is:

Strings: 42.8608,-72.1081
Floats: 42.8608,-72.1081

Using ParameterizedSparqlStrings in CONSTRUCT queries

Based some of the comments, it may also be useful to use CONSTRUCT queries to save the results from each query, and to aggregate them into a larger model. Here's code that uses a construct query to retrieve the latitude and longitude of Mount Monadnock and Mount Lafayette, and stores them in a single model. (Here we're just using CONSTRUCT WHERE {…}, so the model that is returned is exactly the same as the part of the graph that matched. You can get different results by using CONSTRUCT {…} WHERE {…}.)

import com.hp.hpl.jena.query.ParameterizedSparqlString;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;

public class DBPediaQuery {
  public static void main( String[] args ) {
    final String dbpedia = "http://dbpedia.org/sparql";
    final ParameterizedSparqlString queryString
      = new ParameterizedSparqlString(
            "PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>"+
            "PREFIX dbo: <http://dbpedia.org/ontology/>" +
            "CONSTRUCT WHERE {" +
            "  ?s a dbo:Place ." +
            "  ?s geo:lat ?lat ." +
            "  ?s geo:long ?long ." +
            "}" );
    Model allResults = ModelFactory.createDefaultModel();
    for ( String mountain : new String[] { "Mount_Monadnock", "Mount_Lafayette" } ) {
      queryString.setIri( "?s", "http://dbpedia.org/resource/" + mountain );
      QueryExecution exec = QueryExecutionFactory.sparqlService( dbpedia, queryString.toString() );
      Model results = exec.execConstruct();
      allResults.add( results );
    }
    allResults.setNsPrefix( "geo", "http://www.w3.org/2003/01/geo/wgs84_pos#" );
    allResults.setNsPrefix( "dbo", "http://dbpedia.org/ontology/" );
    allResults.setNsPrefix( "dbr", "http://dbpedia.org/resource/" );
    allResults.write( System.out, "N3" );
  }
}

The output shows triples from both queries:

@prefix dbr:     <http://dbpedia.org/resource/> .
@prefix geo:     <http://www.w3.org/2003/01/geo/wgs84_pos#> .
@prefix dbo:     <http://dbpedia.org/ontology/> .

dbr:Mount_Lafayette
      a       dbo:Place ;
      geo:lat "44.1607"^^<http://www.w3.org/2001/XMLSchema#float> ;
      geo:long "-71.6444"^^<http://www.w3.org/2001/XMLSchema#float> .

dbr:Mount_Monadnock
      a       dbo:Place ;
      geo:lat "42.8608"^^<http://www.w3.org/2001/XMLSchema#float> ;
      geo:long "-72.1081"^^<http://www.w3.org/2001/XMLSchema#float> .

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...