Hi Andy,
Thank you very much for your response, it works as a charm!
For the general interest, I put my solution (using "east" function to
simplify it)
[...]
SpatialQuery.init(); // it registers all the property functions related to
spatial, you'll need the Jena-Spatial jar in your classpath
// nodes for the literal values (float)
NodeValue nodeLatitud = NodeValue.makeDecimal(this.position.getLatitude() );
NodeValue nodeLongitud = NodeValue.makeDecimal(this.position.getLongitude()
);
// anonymous variables used as auxiliary
Var varAnon1 = Var.alloc("anon1");
Var varAnon2 = Var.alloc("anon2");
// main block is an ElementTriplesBlock created previously
Triple tripleListLatitude = Triple.create(varAnon1, RDF.first.asNode(),
nodeLatitud.asNode() );
mainBlock.addTriple(tripleListLatitude);
Triple tripleListLatitudeFollows = Triple.create(varAnon1,
RDF.rest.asNode(), varAnon2);
mainBlock.addTriple(tripleListLatitudeFollows);
Triple tripleListLongitude = Triple.create(varAnon2, RDF.first.asNode(),
nodeLongitud.asNode() );
mainBlock.addTriple(tripleListLongitude);
Triple tripleListLongitudeFollows = Triple.create(varAnon2,
RDF.rest.asNode(), RDF.nil.asNode() );
mainBlock.addTriple(tripleListLongitudeFollows);
Triple tripleEast = Triple.create(Var.alloc(varResult),
NodeFactory.createURI("http://jena.apache.org/spatial#east"), varAnon1);
mainBlock.addTriple(tripleEast);
[...]
After compiling it...
Op op = Algebra.compile(query);
I get this Algebra:
(project (?result ?lat ?long)
(bgp
(triple ?result <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <
http://www.w3.org/2003/01/geo/wgs84_pos#SpatialThing>)
(triple ?result <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat)
(triple ?result <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?long)
(triple ?anon1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first>
39.2085)
(triple ?anon1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> ?anon2)
(triple ?anon2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first>
-2.713)
(triple ?anon2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <
http://www.w3.org/1999/02/22-rdf-syntax-ns#nil>)
(triple ?result <http://jena.apache.org/spatial#east> ?anon1)
))
After optimizing it...
Op op2 = Algebra.optimize(op);
(project (?result ?lat ?long)
(propfunc <http://jena.apache.org/spatial#east>
?result (39.2085 -2.713)
(bgp
(triple ?result <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <
http://www.w3.org/2003/01/geo/wgs84_pos#SpatialThing>)
(triple ?result <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat)
(triple ?result <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?long)
)))
Therefore, the translation seems to work properly.
I still have two questions:
1) After optimizing the algebra, when I return it to a query using:
Query queryOptimized = OpAsQuery.asQuery(op2);
If I serialize "queryOptimized" I get the long form (using the RDF list).
Indeed, in my fuseki service I receive this long query instead of the
optimized form.
SELECT ?result ?lat ?long
WHERE
{ _:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b1 .
_:b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> 39.2085 .
_:b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> _:b2 .
_:b2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> -2.713 .
_:b2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <
http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
?result <http://jena.apache.org/spatial#east> _:b0 .
}
I suppose there are no differences in performance, but...
Is it normal? Could I improve my code?
2) How do you answer the questions so quickly??? Thank you very much for
your useful tips ;-)
David
2014-07-16 15:16 GMT+02:00 Andy Seaborne <[email protected]>:
> On 16/07/14 09:08, David Torres wrote:
>
>> Hello,
>>
>> I'm trying to implement this using ARQ API:
>>
>> SELECT ?placeName{
>> ?place spatial:nearby (51.46 2.6 10 'km') .
>> ?place rdfs:label ?placeName}
>>
>> I'm able to create the function as follows:
>>
>> ExprList args = new ExprList();
>>
>> NodeValue nodeLatitud = NodeValue.makeDecimal(51.46);
>> NodeValue nodeLongitud = NodeValue.makeDecimal(2.6);
>> NodeValue nodeRadius = NodeValue.makeDecimal(10);
>> NodeValue nodeUnit = NodeValue.makeString("km");
>>
>> args.add(nodeLatitud);
>> args.add(nodeLongitud);
>> args.add(nodeRadius);
>> args.add(nodeUnit);
>>
>> Expr function = new E_Function("http://jena.apache.org/spatial#nearby",
>> args);
>>
>> But now, I don't know how to insert this function in the main query.
>>
>> For example, this would include as filter clause, but of course it hasn't
>> the same effects:
>>
>> ElementGroup body = new ElementGroup();
>>
>> ElementFilter emfilter = new ElementFilter(function);
>> body.addElement(emfilter) ;
>>
>> Any help would be appreciated!
>>
>> David
>>
>>
> (brief reply)
>
> ElementFilter and E_* are all about FILTER expressions.
>
> Property Functions like spatial:nearby are completely different :
>
> 1/ Build the query using basic graph patterns - no mention of "property
> functions"
>
> Basic graph pattern of
>
> ?place spatial:nearby bnode .
>
> and bnode is head of the RDF list (more triples).
>
> 2/ register the property function with the property function registry.
>
> then when a query is compiled (first stage of execution) the registered
> property triggers code to convert the triples to the algebra for calling a
> property function.
>
> Try using "arq.qparse" on a query you know works with a property function
> and a list as object argument. e.g.
>
> ---------------
> prefix list: <http://jena.hpl.hp.com/ARQ/list#>
>
> SELECT * {
> ?x list:index (?idx ?m)
> }
> ----------------
>
> then try:
> arq.qparse --print=op (outputs the raw algebra as per the SPARQL spec)
>
> arq.qparse --print=opt (outputs the algebra after the optimizer)
>
> The optimizer includes the property function translation.
>
> Andy
>
>
>