openlink / virtuoso-opensource

Virtuoso is a high-performance and scalable Multi-Model RDBMS, Data Integration Middleware, Linked Data Deployment, and HTTP Application Server Platform
https://vos.openlinksw.com
Other
870 stars 210 forks source link

GeoSPARQL geof:envelope() returns BOX() non standard geometry #807

Open tioannid opened 6 years ago

tioannid commented 6 years ago

Hi, I am running the following GeoSPARQL query:

PREFIX geof: <http://www.opengis.net/def/function/geosparql/> 
select ?o1 (geof:envelope(?o1) as ?ret) where { 
    GRAPH <http://geographica.di.uoa.gr/dataset/clc> {?s1 <http://geo.linkedopendata.gr/corine/ontology#asWKT> ?o1} 
} limit 1

The result is the following:

POLYGON((21.21482082946 38.604241103633,21.214753050773 38.603677052906,21.214631008421 38.603357774756,21.214286547149 38.602998047923,21.213984128286 38.602709625545,21.213550162213 38.602347764386,21.21321930177 38.601636834862,21.212676466485 38.60128873497,21.212108525495 38.600080513702,21.211724012013 38.599626799668,21.211135920631 38.599289635488,21.210373112725 38.599042731735,21.209583739706 38.599001856303,21.207523580033 38.599497296202,21.206758004654 38.599819434757,21.206552433384 38.600282606399,21.206709654127 38.600848797052,21.207144936549 38.6011755634,21.207993905529 38.601230986309,21.209245164799 38.601282760606,21.210127803879 38.601468115764,21.210595063649 38.602115597762,21.210880595701 38.602738005376,21.211263444472 38.603558739944,21.211644489645 38.604130263358,21.212172047372 38.604388906305,21.212847471891 38.604299548417,21.213093740124 38.604280096127,21.213247453444 38.604365906947,21.213397195907 38.604554309274,21.213431899997 38.605140594601,21.213444674144 38.605356387987,21.213412172655 38.605519911055,21.21329408045 38.60586622804,21.213072978203 38.606169016338,21.213130777129 38.606704358044,21.213506336808 38.607144586823,21.214148159246 38.607467934968,21.214595079162 38.607416968552,21.215080846557 38.607038332108,21.215333645569 38.606592534989,21.215533352273 38.606166011172,21.215521485425 38.605796060256,21.215301222943 38.605400610097,21.214897130051 38.605021318846,21.214882537911 38.604970386337,21.214763848384 38.604556116524,21.21482082946 38.604241103633))"^^<http://www.openlinksw.com/schemas/virtrdf#Geometry>

BOX(21.206549905366 38.598997254943,21.215535881361 38.607472537337)

Apart from the #803 error which shows up again as the the ?o1 value should have been geo:wktLiteral, the other problem is that according to GeoSPARQL standard which is based on the Simple Feature Access Specification the return value on the "envelope" function should be a POLYGON which is the minimum bounding box. The list of acceptable WKT representations does not include any BOX specification.

Regards

tioannid commented 6 years ago

Hi @HughWilliams Below you can see the 3 triples that represent the portion of the corresponding N-Triples file loaded to the database:

<http://geo.linkedopendata.gr/corine/Geometry_4095> <http://geo.linkedopendata.gr/corine/ontology#asWKT> "POLYGON ((21.214820829460276 38.60424110363288,21.214753050772799 38.603677052906008,21.214631008420852 38.603357774756354,21.214286547149054 38.602998047922902,21.213984128286 38.602709625544591,21.213550162212737 38.602347764386039,21.213219301770042 38.601636834861623,21.212676466484698 38.601288734969572,21.212108525494795 38.600080513702068,21.211724012013466 38.599626799668115,21.211135920630767 38.599289635488105,21.21037311272508 38.599042731734613,21.209583739705501 38.599001856302877,21.207523580032682 38.599497296202038,21.206758004654407 38.599819434757244,21.20655243338387 38.60028260639934,21.206709654126705 38.600848797051853,21.20714493654852 38.601175563399863,21.207993905529463 38.601230986308757,21.209245164799309 38.601282760606381,21.210127803878947 38.601468115764412,21.210595063648867 38.602115597761504,21.21088059570107 38.602738005376445,21.21126344447195 38.603558739944226,21.211644489645284 38.604130263357725,21.21217204737216 38.604388906305161,21.212847471891205 38.604299548417309,21.213093740124123 38.604280096127461,21.213247453444477 38.604365906947386,21.213397195906754 38.604554309273801,21.213431899997378 38.605140594601089,21.213444674144458 38.605356387986831,21.213412172655119 38.605519911054699,21.213294080450275 38.605866228039879,21.213072978203247 38.606169016338455,21.213130777129443 38.606704358044375,21.213506336807665 38.607144586822542,21.214148159246228 38.607467934968469,21.21459507916164 38.607416968552478,21.215080846556795 38.607038332108118,21.215333645568773 38.606592534989083,21.215533352272523 38.606166011172121,21.215521485424738 38.605796060256132,21.21530122294315 38.60540061009678,21.214897130050595 38.605021318846269,21.21488253791119 38.604970386336596,21.214763848384084 38.604556116524066,21.214820829460276 38.60424110363288))"^^<http://www.opengis.net/ont/geosparql#wktLiteral> .
<http://geo.linkedopendata.gr/corine/Geometry_4095> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.opengis.net/ont/sf#Polygon> .
<http://geo.linkedopendata.gr/corine/Area_4095> <http://geo.linkedopendata.gr/corine/ontology#hasGeometry> <http://geo.linkedopendata.gr/corine/Geometry_4095> .

In order to verify this again I modified the initial query to show the ?s1 field.

PREFIX geof: <http://www.opengis.net/def/function/geosparql/> 
select ?s1 ?o1 (geof:envelope(?o1) as ?ret) where { 
    GRAPH <http://geographica.di.uoa.gr/dataset/clc> {?s1 <http://geo.linkedopendata.gr/corine/ontology#asWKT> ?o1} 
} limit 1

and the result is the following:

 s1     o1  ret
http://geo.linkedopendata.gr/corine/Geometry_4095   

"POLYGON((21.21482082946 38.604241103633,21.214753050773 38.603677052906,21.214631008421 38.603357774756,21.214286547149 38.602998047923,21.213984128286 38.602709625545,21.213550162213 38.602347764386,21.21321930177 38.601636834862,21.212676466485 38.60128873497,21.212108525495 38.600080513702,21.211724012013 38.599626799668,21.211135920631 38.599289635488,21.210373112725 38.599042731735,21.209583739706 38.599001856303,21.207523580033 38.599497296202,21.206758004654 38.599819434757,21.206552433384 38.600282606399,21.206709654127 38.600848797052,21.207144936549 38.6011755634,21.207993905529 38.601230986309,21.209245164799 38.601282760606,21.210127803879 38.601468115764,21.210595063649 38.602115597762,21.210880595701 38.602738005376,21.211263444472 38.603558739944,21.211644489645 38.604130263358,21.212172047372 38.604388906305,21.212847471891 38.604299548417,21.213093740124 38.604280096127,21.213247453444 38.604365906947,21.213397195907 38.604554309274,21.213431899997 38.605140594601,21.213444674144 38.605356387987,21.213412172655 38.605519911055,21.21329408045 38.60586622804,21.213072978203 38.606169016338,21.213130777129 38.606704358044,21.213506336808 38.607144586823,21.214148159246 38.607467934968,21.214595079162 38.607416968552,21.215080846557 38.607038332108,21.215333645569 38.606592534989,21.215533352273 38.606166011172,21.215521485425 38.605796060256,21.215301222943 38.605400610097,21.214897130051 38.605021318846,21.214882537911 38.604970386337,21.214763848384 38.604556116524,21.21482082946 38.604241103633))"^^<http://www.openlinksw.com/schemas/virtrdf#Geometry>

BOX(21.206549905366 38.598997254943,21.215535881361 38.607472537337)

I hope this helps.

HughWilliams commented 6 years ago

@tioannid: I loaded the triples into Virtuoso 7 open source database but the query returns no results:

SQL> SPARQL INSERT INTO GRAPH <http://example.org> { <http://geo.linkedopendata.gr/corine/Geometry_4095> <http://geo.linkedopendata.gr/corine/ontology#asWKT> "POLYGON ((21.214820829460276 38.60424110363288,21.214753050772799 38.603677052906008,21.214631008420852 38.603357774756354,21.214286547149054 38.602998047922902,21.213984128286 38.602709625544591,21.213550162212737 38.602347764386039,21.213219301770042 38.601636834861623,21.212676466484698 38.601288734969572,21.212108525494795 38.600080513702068,21.211724012013466 38.599626799668115,21.211135920630767 38.599289635488105,21.21037311272508 38.599042731734613,21.209583739705501 38.599001856302877,21.207523580032682 38.599497296202038,21.206758004654407 38.599819434757244,21.20655243338387 38.60028260639934,21.206709654126705 38.600848797051853,21.20714493654852 38.601175563399863,21.207993905529463 38.601230986308757,21.209245164799309 38.601282760606381,21.210127803878947 38.601468115764412,21.210595063648867 38.602115597761504,21.21088059570107 38.602738005376445,21.21126344447195 38.603558739944226,21.211644489645284 38.604130263357725,21.21217204737216 38.604388906305161,21.212847471891205 38.604299548417309,21.213093740124123 38.604280096127461,21.213247453444477 38.604365906947386,21.213397195906754 38.604554309273801,21.213431899997378 38.605140594601089,21.213444674144458 38.605356387986831,21.213412172655119 38.605519911054699,21.213294080450275 38.605866228039879,21.213072978203247 38.606169016338455,21.213130777129443 38.606704358044375,21.213506336807665 38.607144586822542,21.214148159246228 38.607467934968469,21.21459507916164 38.607416968552478,21.215080846556795 38.607038332108118,21.215333645568773 38.606592534989083,21.215533352272523 38.606166011172121,21.215521485424738 38.605796060256132,21.21530122294315 38.60540061009678,21.214897130050595 38.605021318846269,21.21488253791119 38.604970386336596,21.214763848384084 38.604556116524066,21.214820829460276 38.60424110363288))"^^<http://www.opengis.net/ont/geosparql#wktLiteral> .
Type the rest of statement, end with a semicolon (;)> <http://geo.linkedopendata.gr/corine/Geometry_4095> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.opengis.net/ont/sf#Polygon> .
Type the rest of statement, end with a semicolon (;)> <http://geo.linkedopendata.gr/corine/Area_4095> <http://geo.linkedopendata.gr/corine/ontology#hasGeometry> <http://geo.linkedopendata.gr/corine/Geometry_4095> . };

Done. -- 15 msec.
SQL> SPARQL PREFIX geof: <http://www.opengis.net/def/function/geosparql/>  select ?s1 ?o1 (geof:envelope(?o1) as ?ret) where {  GRAPH <http://geographica.di.uoa.gr/dataset/clc> {?s1 <http://geo.linkedopendata.gr/corine/ontology#asWKT> ?o1}  } limit 1;                                                                                                                                       s1                                                                                o1                                                                                ret
LONG VARCHAR                                                                      LONG VARCHAR                                                                      LONG VARCHAR
_______________________________________________________________________________

0 Rows. -- 5 msec.
SQL> status('');
REPORT
VARCHAR
_______________________________________________________________________________

OpenLink Virtuoso  Server
Version 07.20.3230-pthreads for Linux as of Nov  2 2018 

Is there any other data that needs to be in place ?

tioannid commented 6 years ago

Hi @HughWilliams I think that you have loaded the data into a different graph that's why the query does not return any rows.

HughWilliams commented 6 years ago

@tioannid: Ah, I have loaded the data into the <http://geographica.di.uoa.gr/dataset/clc> and now the query returns data:

SQL> SPARQL INSERT INTO GRAPH <http://geographica.di.uoa.gr/dataset/clc> { <http://geo.linkedopendata.gr/corine/Geometry_4095> <http://geo.linkedopendata.gr/corine/ontology#asWKT> "POLYGON ((21.214820829460276 38.60424110363288,21.214753050772799 38.603677052906008,21.214631008420852 38.603357774756354,21.214286547149054 38.602998047922902,21.213984128286 38.602709625544591,21.213550162212737 38.602347764386039,21.213219301770042 38.601636834861623,21.212676466484698 38.601288734969572,21.212108525494795 38.600080513702068,21.211724012013466 38.599626799668115,21.211135920630767 38.599289635488105,21.21037311272508 38.599042731734613,21.209583739705501 38.599001856302877,21.207523580032682 38.599497296202038,21.206758004654407 38.599819434757244,21.20655243338387 38.60028260639934,21.206709654126705 38.600848797051853,21.20714493654852 38.601175563399863,21.207993905529463 38.601230986308757,21.209245164799309 38.601282760606381,21.210127803878947 38.601468115764412,21.210595063648867 38.602115597761504,21.21088059570107 38.602738005376445,21.21126344447195 38.603558739944226,21.211644489645284 38.604130263357725,21.21217204737216 38.604388906305161,21.212847471891205 38.604299548417309,21.213093740124123 38.604280096127461,21.213247453444477 38.604365906947386,21.213397195906754 38.604554309273801,21.213431899997378 38.605140594601089,21.213444674144458 38.605356387986831,21.213412172655119 38.605519911054699,21.213294080450275 38.605866228039879,21.213072978203247 38.606169016338455,21.213130777129443 38.606704358044375,21.213506336807665 38.607144586822542,21.214148159246228 38.607467934968469,21.21459507916164 38.607416968552478,21.215080846556795 38.607038332108118,21.215333645568773 38.606592534989083,21.215533352272523 38.606166011172121,21.215521485424738 38.605796060256132,21.21530122294315 38.60540061009678,21.214897130050595 38.605021318846269,21.21488253791119 38.604970386336596,21.214763848384084 38.604556116524066,21.214820829460276 38.60424110363288))"^^<http://www.opengis.net/ont/geosparql#wktLiteral> .
Type the rest of statement, end with a semicolon (;)> <http://geo.linkedopendata.gr/corine/Geometry_4095> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.opengis.net/ont/sf#Polygon> .
Type the rest of statement, end with a semicolon (;)> <http://geo.linkedopendata.gr/corine/Area_4095> <http://geo.linkedopendata.gr/corine/ontology#hasGeometry> <http://geo.linkedopendata.gr/corine/Geometry_4095> . };

Done. -- 2 msec.
SQL>
SQL> SPARQL PREFIX geof: <http://www.opengis.net/def/function/geosparql/>  select ?s1 ?o1 (geof:envelope(?o1) as ?ret) where {  GRAPH <http://geographica.di.uoa.gr/dataset/clc> {?s1 <http://geo.linkedopendata.gr/corine/ontology#asWKT> ?o1}  } limit 1;
s1                                                                                o1                                                                                ret
LONG VARCHAR                                                                      LONG VARCHAR                                                                      LONG VARCHAR
_______________________________________________________________________________

http://geo.linkedopendata.gr/corine/Geometry_4095                                                                                  POLYGON((21.21482082946 38.604241103633,21.214753050773 38.603677052906,21.214631008421 38.603357774756,21.214286547149 38.602998047923,21.213984128286 38.602709625545,21.213550162213 38.602347764386,21.21321930177 38.601636834862,21.212676466485 38.60128873497,21.212108525495 38.600080513702,21.211724012013 38.599626799668,21.211135920631 38.599289635488,21.210373112725 38.599042731735,21.209583739706 38.599001856303,21.207523580033 38.599497296202,21.206758004654 38.599819434757,21.206552433384 38.600282606399,21.206709654127 38.600848797052,21.207144936549 38.6011755634,21.207993905529 38.601230986309,21.209245164799 38.601282760606,21.210127803879 38.601468115764,21.210595063649 38.602115597762,21.210880595701 38.602738005376,21.211263444472 38.603558739944,21.211644489645 38.604130263358,21.212172047372 38.604388906305,21.212847471891 38.604299548417,21.213093740124 38.604280096127,21.213247453444 38.604365906947,21.213397195907 38.604554309274,21.213431899997 38.605140594601,21.213444674144 38.605356387987,21.213412172655 38.605519911055,21.21329408045 38.60586622804,21.213072978203 38.606169016338,21.213130777129 38.606704358044,21.213506336808 38.607144586823,21.214148159246 38.607467934968,21.214595079162 38.607416968552,21.215080846557 38.607038332108,21.215333645569 38.606592534989,21.215533352273 38.606166011172,21.215521485425 38.605796060256,21.215301222943 38.605400610097,21.214897130051 38.605021318846,21.214882537911 38.604970386337,21.214763848384 38.604556116524,21.21482082946 38.604241103633))                                                                                  BOX(21.206549905366 38.598997254943,21.215535881361 38.607472537337)

1 Rows. -- 2 msec.
SQL>

Where in the GeoSPARQL Simple Feature Access Specification document does it state that the envelope() function should return a polygon? As the definition I see is:

Envelope ( ): Geometry — The minimum bounding box for this Geometry, returned as a Geometry. The polygon is defined by the corner points of the bounding box [(MINX, MINY), (MAXX, MINY), (MAXX, MAXY), (MINX, MAXY), (MINX, MINY)]. Minimums for Z and M may be added. The simplest representation of an Envelope is as two direct positions, one containing all the minimums, and another all the maximums. In some cases, this coordinate will be outside the range of validity for the Spatial Reference System.

which seems rather vague ...

tioannid commented 6 years ago

Hi @HughWilliams Below I provide the trace of evidence which according to my opinion leads to the conclusions I had asserted earlier.

From the GeoSPARQL standard we have the following evidence:

1) Definition of geof:envelope() Paragraph "8.7.8 Function: geof:envelope", defines input and output values are of type ogc:geomLiteral:

geof:envelope (geom1: ogc:geomLiteral): ogc:geomLiteral 2) Definition of ogc:geomLiteral Paragraph "5.3 Placeholder URIs", defines that: The URI ogc:geomLiteral is used in requirement specifications as a placeholder for the geometry literal serialization used in a fully-qualified conformance class, e.g. <http://www.opengis.net/ont/geosparql#wktLiteral> .

3) Further explanation of geo:wktLiteral Paragraph "8.5 Requirements for WKT Serialization (serialization=WKT)"

All RDFS Literals of type geo:wktLiteral shall consist of an optional URI identifying the coordinate reference system followed by Simple Features Well Known Text (WKT) describing a geometric value. Valid geo:wktLiterals are formed by concatenating a valid, absolute URI as defined in [RFC 2396], one or more spaces (Unicode U+0020 character) as a separator, and a WKT string as defined in Simple Features [ISO 19125-1]

From the Simple Feature Access standard

1) BNF Productions for WKT geometries

Paragraph "7.2.2 BNF Productions for Two-Dimension Geometry WKT" does not specify BOX as a valid geometry, therefore as with most other systems that implement the GeoSPARQL standard, the most obvious alternative is a POLYGON which represents the minimum bounding box

Regards