epoz / shmarql

SPARQL endpoint explorer
The Unlicense
15 stars 3 forks source link

Add support for GeoSPARQL #12

Open ch-sander opened 3 months ago

ch-sander commented 3 months ago

A boolean for falls within and contains based in the specifications (e.g. http://www.opengis.net/def/function/geosparql/sfWithin). Either done within sqlite or with GeoPandas/Shapely/Fiona

ch-sander commented 1 month ago

Will come with the latest oxigraph built

ch-sander commented 1 month ago

using custom_functions in query params {px.NamedNode("http://shmarql.com/geo/distance"): distance_function_wkt}

def distance_function_wkt(t1, t2):
    try:
        point1 = wkt.loads(t1.value)
        point2 = wkt.loads(t2.value)
        coords1 = (point1.y, point1.x)
        coords2 = (point2.y, point2.x)
        distance_km = geodesic(coords1, coords2).kilometers
        return Literal(str(distance_km))
    except Exception as e:
        return Literal("-1")

@Tpt thanks for the suggestions. I wonder how to return a numerical literal. Moreover, the Exception handling probably is idiotic...

Yet, this%0A%20%20%0A%0A%7D%0ALIMIT%2010000%0A&endpoint=https%3A%2F%2Fg17dev.dhi-roma.it%2Fsparql&requestMethod=POST&tabTitle=Query%207&headers=%7B%7D&contentTypeConstruct=application%2Fn-triples%2C%2F%3Bq%3D0.9&contentTypeSelect=application%2Fsparql-results%2Bjson%2C%2F%3Bq%3D0.9&outputFormat=table&outputSettings=%7B%22compact%22%3Atrue%7D) works as a start:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX geo: <http://shmarql.com/geo/>

SELECT DISTINCT 
  ?event_1 
  ?event_1_label 
  ?map_8 
  ?map_6 
  ?distance
WHERE {
  ?event_1 rdf:type <http://www.graceful17.org/ontology/event>;
           <http://www.graceful17.org/ontology/called> ?event_1_label;
           <http://www.graceful17.org/ontology/place_of_event> ?place_2.

  ?place_2 rdf:type <http://www.graceful17.org/ontology/place>;
           <http://www.graceful17.org/ontology/wkt> ?map_6.

  ?event_1 (<http://www.graceful17.org/ontology/event_related_to_object>/<http://www.graceful17.org/ontology/in_diocese>/<http://www.graceful17.org/ontology/primary_place>) ?place_4.

  ?place_4 rdf:type <http://www.graceful17.org/ontology/place>;
           <http://www.graceful17.org/ontology/wkt> ?map_8.
         BIND(geo:distance(?map_6, ?map_8) AS ?distance)

}
LIMIT 10000

It shows job applications for new positions, and the distance between the place of the job and the place where the application is decided on...

Tpt commented 1 month ago

@Tpt thanks for the suggestions. I wonder how to return a numerical literal.

Just set a datatype:

return Literal(str(distance_km), datatype=NamedNode('http://www.w3.org/2001/XMLSchema#integer'))

It would be great that I update Literal constructor to allow various Python types as input (int, float, bool, datetime...)

Moreover, the Exception handling probably is idiotic...

You can return None to make the function fail and the result row ignored. Or just not catch the exception. In this case, the exception will be catched by oxigraph and the row ignored too.

ch-sander commented 1 month ago

Great, thanks @Tpt

It would be great that I update Literal constructor to allow various Python types as input (int, float, bool, datetime...)

yes, that would be even better. Even without aggregation, there are still quite useful applications, I have implemented geo/area as well as logarithm (#26 ) and Levenshtein distance. I will think of more, like making a convex hull of geometries, getting centroids, etc.