Closed azaroth42 closed 4 years ago
Technically, there's E47 Spatial Coordinates, which is what you're looking for. A Subclass of Appellation for this kind of thing. Personally, I'd rather try and get GeoJsonLD working, and defer to that.
See https://en.wikipedia.org/wiki/GeoSPARQL in which you can use the so-called "Well Known Text" data types that are very commonly used in the GIS community. Probably that kind of compatibility is not so important for LinkedArt. That said, I believe WKT is supported in OpenLayers, so there's something of practical utility. These are just literal datatypes in RDF land: https://docs.oracle.com/database/121/RDFRM/GUID-4E342E2A-73EF-42D4-80BD-AE8BEF5C6910.htm
I also have a project which uses the Basic Geo ontology, described here: https://www.w3.org/2003/01/geo/ and I think this is probably a lot more widely used than the WKT datatypes, though the ontology only includes points (that's literally all it is). How crucial are polygons?
The only coordinate use case I know of right now is if we were to map TGN to CIDOC-CRM. Which would be a step up from where it is today, but only a very small one. I expect that Ethan has thousands of coordinates in his data though. Asked him in slack at the above comment's link.
My concern (perhaps misplaced?) with GeoJSON is about how it maps to the RDF model. As far as I can see (and this is where maybe I've just missed something) GeoJSON is not defined with regard to JSON-LD, and there is no standard mechanism to represent a GeoJSON object as triples.
The GeoSPARQL standard provides two RDF literal data types for geospatial geometry:
GML (a point example):
<gml:Point
srsName=\"http://www.opengis.net/def/crs/OGC/1.3/CRS84\"
xmlns:gml=\"http://www.opengis.net/ont/gml\">
<gml:pos>-83.38 33.95</gml:pos>
</gml:Point>"^^<http://www.opengis.net/ont/geosparql#gmlLiteral>
WKT:
"Point(-83.38 33.95)"^^<http://www.opengis.net/ont/geosparql#wktLiteral>
NB the GeoSPARQL standard also defines spatial semantics for these data types and spatial functions for extending the SPARQL language to support spatial querying. There are even implementations of this.
One could record a GeoJSON object in the same way, as an RDF object literal. But it would be awkward to query in SPARQL; you could do it with regexes, but without index support it would be inefficient.
I suppose one could define a JSON-LD frame and context which a LOD service could use to map between GeoJSON and an RDF graph. Has anyone done that? I'm not aware of any such mapping, myself.
This is where, IMHO, the Basic Geo ontology is a much simpler and more accessible low-level model for a public LOD interface to offer; its principal drawback is that the ontology is limited to describing individual points, rather than polygons, but I think the 80/20 rules applies.
I agree with @workergnome that it's best to use a Coordinates/Geometry node (crm:E47_Spatial_Coordinates). If we use crm:P168_place_is_defined_by (a recent addition!) then we must use a literal (and then I agree with @Conal-Tuohy that WKT is best) but we can't use simple (separate) props for lat/long:
<place> crm:P168_place_is_defined_by "Point(-83.38 33.95)"^^geo:wktLiteral.
BTW, GeoSPARQL also says WKT literals should be applied on separate Geometry nodes:
geo:asWKT rdfs:domain geo:Geometry; rdfs:range geo:wktLiteral.
If we adopt a geometry node, we could represent coordinates in many different ways (Note: I haven't checked the proper order of lat,long vs WKT):
<place> crm:P87_is_identified_by geo:-83.38,33.95. #1
<place> crm:P87_is_identified_by <place/geo>.
<place/geo> a crm:E47_Spatial_Coordinates, geo:Geometry;
geo:asWKT "Point(-83.38 33.95)"^^geo:wktLiteral. #2
<place/geo> a crm:E47_Spatial_Coordinates, wgs:SpatialThing;
wgs:lat -83.38; wgs:long 33.95. #3
<place/geo> a crm:E47_Spatial_Coordinates, schema:GeoCoordinates;
schema:latitude -83.38; schema:longitude 33.95.
I think linked.art should recommend 2 but say that a redundant representation could also be useful (belt-and-suspenders, eg in TGN we used 3&4)
GeoJSON-LD is defined here: http://geojson.org/geojson-ld/
As @sgillies notes in the description, the array of arrays pattern used in GeoJSON is not supported, but everything else works okay.
Implementation wise, GeoJSON is the preferred format in Arches (see https://www.archesproject.org/standards-and-interoperability/) and I believe it's the only representation that is implemented.
Which doesn't mean we shouldn't use WKT ... but I think there's further discussion as to whether we need to decide on example one, or whether GeoJSON-LD should be used as well.
I'm curious as to what geometries are actually in use. Apart from points, what other geometric data types are needed? Do we have an actual requirement for arbitrary polygons, for instance? It would be good to have this discussion in the context provided by some concrete examples.
I'm rather wary of relying on complex literal datatypes; for instance, a sequence of points that represent a touring exhibition, or the provenance of an object, would be better represented as a graph of CRM events, etc, than with a complex GeoJSON literal. It is easy enough to generate representations that use GeoJSON or KML or geo:
URIs, or whatever, from such an RDF graph, but relatively hard to spatially query RDF which uses such data types and URI schemes for storage.
So that sways me in favour of using the "basic GEO" and/or GeoJSON-LD vocabularies for the modelling.
It seems to me that the incompatibility between JSON-LD and GeoJSON's use of nested arrays would not be a problem for representing RDF as GeoJSON, but only for parsing GeoJSON (which might use these nested arrays) as RDF. Is that right? If so, it's probably nothing to worry about, right?
The Getty's main use case is that TGN has lat/long points and we would need to at least represent them if we're to move away from the current ontology soup.
Without committing to anything, it would be nice to reconcile TGN with other gazetteers, some of which have polygons like Who's On First. For example: https://whosonfirst.mapzen.com/spelunker/id/102533795/
Once we then reconcile our places in other datasets against TGN (e.g. Museum collection, provenance, photo archive, etc etc), being able to plot polygons on a map is a nicer UI, and polygon overlap search is better than point-plus-radius search.
For the GeoJSON-LD limitation, note the polygon in the LAX example is represented by a geometry with a list of coordinates, each of which is a list of two floats ... that wouldn't survive the RDF <--> JSON round trip :(
OK after consulting the GeoJSON and JSON-LD specs I think I see the problem now; that effectively only "point" geometries can be represented in a way that's compatible with JSON-LD. I had assumed that non-point geometries could be represented in GeoJSON in multiple ways, some of them (nested arrays) incompatible, and others (I was imagining intermediate object nodes containing the arrays, that could map to RDF nodes) compatible. But it seems to me now that JSON-LD processing of JSON arrays generates RDF lists, and would simply flatten a recursive structure, and that there's no mechanism for serializing JSON-LD that can generate nested lists, and that GeoJSON-LD doesn't provide a vocabulary that would model such things. So from a modelling point of view, GeoJSON-LD is actually not helpful.
TGN has points and bounding boxes (represented with schema:box). Many triple-stores (including ONTO GraphDB) support GeoSPARQL: it's a standard. Because it's based on established OGC standards, there are open source implementations to use. These include efficient geospatial indexes, so querying is fast. No triple-store supports GeoJSON.
Unfortunately, I don't know any web mapping libraries that implement support for GeoSPARQL—they're almost entirely GeoJSON. At least at this point, it's the standard format for communicating web geometry data. (I've never seen a mapping tool online that supports anything but it, Shapefiles, and MAYBE KML.) It looks like there's some work at converting between them see here, but I don't know how robust that is.
If I were choosing, I'd continue to use the schema and was lat/lng for representing points, perhaps with types for various centers (label center, geographical center, etc).
Is there a way to treat a GeoJSON file a document, much like we treat image files?
@workergnome If you plan to query that data, then you must use GeoSPARQL.
I don't know many mapping libraries, but I know openlayers. Google "openlayers wkt" and you'll see that it is supported. Which mapping library do you want to use?
I'm interesting in using Leaflet, or D3.js, or Tableau, or Google Maps, or Carto,as a couple of examples. All of them either use geoJSON natively, or have well-supported converters for it (see:google). OpenLayers is uncommon outside of the GIS space—I've never seen a project that uses it. That's probably as much because of my background—I'm not a GIS person, but I've done many, many mapping projects at different scales.
And I guess the question is HOW you're planning on querying that data. ElasticSearch uses GeoJSON to do search queries, for instance. If you're planning on using SPARQL to do geo-work, GeoSPARQL is probably the way to do it. But, coming from the perspective of people doing online mapping, I'm not familiar with people doing that.
As another data point, Pelagios's recommendation is:
# Optional: a representative point coordinate
geo:location [ geo:lat 5.16 ; geo:long 52.05 ] ;
# Optional: detail geometry as WKT string
# (alternatively, use osgeo:asGeoJSON for a GeoJSON string)
geosparql:hasGeometry [
geosparql:asWKT "LINESTRING (5.16 52.05, 5.17 52.05, 5.16 52.06)" ;
] ;
Where they treat the geometry as a string-dump, which works well for me, though it does mean there'd have to be some form of non-JSON-LD expansion to use it as JSON.
Eg here's for Leaflet: http://leafletjs.com/plugins.html
I think you should store them in WKT so you can use them for geospatial querying, and convert them to GeoJSON for output. There are convertors both ways:
Because GeoSPARQL is based on established OGC standards, there are open source implementations to use
I mean PostGIS. Most GeoSPARQL implementations use the same libraries that PostGIS uses to implement "region algebra" as defined by the standard. This includes
Fantastic. OK—If there are easy, well-written converters between WKT and geoJSON, I become ambivalent as to which we embed, and I may actually learn more strongly towards WKT because it's explicitly a text representation, and we don't get the "JSON in JSON" problem that geoJSON presents.
And geoSPARQL as a side benefit is OK with me, too.
@workergnome I'm surprised you treat GeoSPARQL so lightly.
+1 to WKT. The specifications should be implementable on as simple a platform as possible with the maximum possible benefit. If there's a translator from WKT into the data that geoSPARQL uses, that's all we need to be concerned about.
I'm in agreement. WKT in the data definition, geoJSON as an API-level enhancement as needed.
https://koopjs.github.io/ doesn't support WKT (?) but does support a bunch of other formats.
Never heard of Koop—what's it do?
KoopJS recommends using PostGIS for caching: https://koopjs.github.io/docs/caches/, https://github.com/koopjs/koop-pgcache.
And PostGIS supports WKT input and output (eg http://www.postgis.net/docs/ST_AsEWKT.html, https://postgis.net/docs/ST_AsText.html)
{
"id": "tgn:paris",
"type": "Place",
"identified_by":[ { "type": "Name", "value": "Paris", "language": "fr" } ],
"label": "Paris, France",
"part_of": [ { ... France goes here ... } ],
"part": [ { ... Arrondisements go here ... } ],
"defined_by": "POLYGON( ... WKT goes here ... )"
}
As discussed in Slack, this doesn't allow for associating a format with the definition without data-typing it.
Current, unlovely but better, approach is:
{
"id": "tgn:paris",
"type": "Place",
"dimension": [
{
"value": "POLYGON( ... WKT goes here ... )",
"unit": "some-uri-for-wkt"
}
]
}
On the grounds that Dimensions can be used to describe regions in a conceptual space, which WKT does.
For the record, what's the problem with using a datatype?
For the record, apparently the perceived problem was that JSON-LD consumers might be confused by JSON-LD's syntax for representing literal datatypes.
But in any case, the data type can be subsumed in an JSON-LD term
which effectively combines an RDF predicate and a literal datatype into a single unit with a simple syntax. See example%22%7D%5D%7D&context=%7B%22geosparql%22%3A%22http%3A%2F%2Fwww.opengis.net%2Font%2Fgeosparql%23%22%2C%22crm%22%3A%22http%3A%2F%2Fwww.cidoc-crm.org%2Fcidoc-crm%2F%22%2C%22defined_by_wkt%22%3A%7B%22%40id%22%3A%22crm%3AP168_place_is_defined_by%22%2C%22%40type%22%3A%22geosparql%3AwktLiteral%22%7D%2C%22defined_by_handwaving%22%3A%7B%22%40id%22%3A%22crm%3AP168_place_is_defined_by%22%2C%22%40type%22%3A%22http%3A%2F%2Fexample.com%2Fgeospatial-handwaving%22%7D%7D).
I see what you guys mean by incompatibility.
http://geojson.org/geojson-ld/ says "Outstanding issues: Nested GeoJSON coordinate arrays are incompatible with the processing model of JSON-LD 1.0. There are no current best practices for addressing this issue."
And I tried the geojson
RFC example https://tools.ietf.org/html/rfc7946#section-1.5 with the geojson-ld
context http://geojson.org/geojson-ld/geojson-context.jsonld at json-ld playground:
http://tinyurl.com/ydyjfw6d
and got this jsonld.SyntaxError: Invalid JSON-LD syntax; lists of lists are not permitted.
I think the best practice for geojson-ld would be to adopt the WKT principle that complex geometries are expressed as opaque literals. RDF is not appropriate for representing long lists of coordinates: put them in a special opaque literal. @azaroth42 should we extend geojson-ld with such specification about an opaque datatype? It would make sense for such literals to be JSON.
Maybe a difficulty is to distinguish which is simple and which is complex, expose the simple as coordinates in RDF but the complex as opaque literals. Or maybe we adopt the WKT approach and put all geometries in opaque literals.
@Conal-Tuohy I agree with you that the best is to use special datatypes, as specified for GML and WKT in the GeoSPARQL spec. For specific application profiles, a JSON-LD context can bind such datatype to a term, to simplify it for consumers.
I disagree with this worry
I'm rather wary of relying on complex literal datatypes; for instance, a sequence of points that represent a touring exhibition, or the provenance of an object, would be better represented as a graph of CRM events
Of course if you have exhibition or provenance events, you should represent them as events with simple geometries. But that's not always the case, in many cases you have complex geometries without separate events that happened at those points.
Cheers!
My comment about "complex" literals was poorly worded; it was meant to refer to ontological complexity rather than syntactical or spatial complexity; specifically my wariness was about the inclusion of non-spatial attributes in geoJSON.
So, do you like the idea of fixing geojson-ld by adding opaque complex literals like GeoSPARQL has (WKT and GML)? It won't be possible to round-trip geojson <-> geojson-ld using standard JSON-LD tools. But it will be possible with a small piece of extra code.
Note:
Embedding JSON literals in JSON-LD without mapping them into RDF will be a feature of the next version of the specification: https://github.com/json-ld/json-ld.org/issues/333 As such, we can allow GeoJSON as a literal directly.
I think we need further discussion around consistency for the term-based approach demonstrated by Conal. We don't do that anywhere else ... but this is quite a confined need, unlike features such as language or type.
Proposal coming from Getty discussion with Farallon Geographics, Historic England and a representative of the CRM-SIG:
Use CRMGeo extension that has two valuable classes, SP4 Spatial Coordinate Reference System and SP5 Geometric Place Expression.
SP5 is a subClass of geo:Geometry, Information Object, Space Primitive and Spatial Coordinates. This can thus be the object of the P168 is defined by relationship from Place. SP5 then will be classified_as Types and might have a label. It uses geo:hasSerialization, mapped in the JSON-LD context to value for surface level consistency to a literal (e.g. WKT or GeoJSON). The SP5 is also Q9 expressed in terms of an SP4, which is the reference system similar in scope to the units of a dimension.
It's recognized that there's a need for the format of the resource (currently we use dc:format) and other standards that the resource conforms to (we use dcterms:conformsTo).
Thus something like ...
{
"type": "Place",
"defined_by": [
{
"type": "Geometry",
"classified_as": [ aat:coastline ],
"label": "GeoJSON coastline",
"value": "{ ... data goes here ... }",
"expressed_in_terms_of": {
"id": "...",
"type": "ReferenceSystem",
"label": "EPSG 3241"
}
}
]
}
See image from Integration of CIDOC CRM with OGC Standards to model spatial information, Gerald Hiebel, Martin Doerr, Øyvind Eide, CAA Mar 2013
There are a few mismatches in the above proposal
^^geo:wktLiteral
). We can similarly define a custom datatype for GeoJSON.I would use crm:P168_place_is_defined_by rather than the round-about path, and point to a geo:Geometry with an geo:asWKT literal.
value
via a scoped context.crm:P168_place_is_defined_by rdfs:range rdfs:Literal
. You can't have a subclass of Literal, so it's not legit to point P168 to SP5.^^geo:wktLiteral
, repos won't index that geo literal, and it becomes pointless to involve geosparql classes and properties.
<geometry1> geo:hasSerialization "Point(-83.38 33.95)"^^geo:wktLiteral.
<geometry2> geo:hasSerialization """<http://www.opengis.net/def/crs/OGC/1.3/CRS84>
Point(-83.38 33.95)"""^^geo:wktLiteral. # same as previous
<geometry3> geo:hasSerialization """<http://www.opengis.net/def/crs/EPSG/0/4326>
Point(33.95 -83.38)"""^^geo:wktLiteral . # different CRS with a different axis order
geo:crs
(eg see https://github.com/openlink/virtuoso-opensource/issues/455), but such is not mentioned in the standardAny argument from a logical inconsistency is invalid. As the conceptual reference model and the RDFS implementation of it are inconsistent, we're choosing to resolve that inconsistency by making SP4 a resource rather than a Literal. Otherwise CRMGeo is impossible to implement and all of the rest of your arguments are equally invalid. This resolves the SP5/SP6 issue, as there is a direct reference from Place to SP5 via P168.
Feel free to take up the inconsistency with the SIG.
Why do you choose to use an inconsistent ontology?
On my second point (about geo:wktLiteral
), sadly Pleiades also uses a non-standard approach: http://atlantides.org/capgrids/2.ttl uses props osgeo:asGeoJSON, osgeo:asWKT
where osgeo:
is http://data.ordnancesurvey.co.uk/ontology/geometry and defines neither of these.
See https://github.com/isawnyu/pleiades-rdf/issues/11
Err, don't tempt me to throw out CRM due to being inconsistent ;) As I said:
... we're choosing to resolve that inconsistency by making SP4 a resource rather than a Literal.
Until the SIG resolves the inconsistency in the RDFS mapping, we're no more wrong than anyone else, and a lot more usable.
Martin's response to my question (http://lists.ics.forth.gr/pipermail/crm-sig/2018-July/003403.html) doesn't instill confidence in the literal vs resource inconsistency being resolved.
However, the chain of SP5 -> E47 -> E44 -> E41, does give us P1_is_identified_by as another possible predicate between E53 Place and SP5.
Thus:
{
"type": "Place",
"identified_by": [
{
"type": "Geometry",
"classified_as": [ aat:coastline ],
"label": "GeoJSON coastline",
"value": "{ ... data goes here ... }",
"format": "application/vnd.geo+json",
"expressed_in_terms_of": {
"id": "...",
"type": "ReferenceSystem",
"label": "EPSG 3241"
}
}
]
}
It seems to me the definition of E59_Primitive_Value as an RDF literal is simply a corrigible error, and we should ask for that statement to be removed.
These "primitive" values in the CRM should really only be considered "primitive" relative to the CRM, not RDF itself. In fact the ontologies we need to use are layered; a geospatial ontology exist as a layer above RDF, while still being a "primitive" from the point of view of the CRM.
I suspect the CIDOC group are not really invested in insisting that these "primitive" values be modeled as RDF literals (i.e. RDF primitives). It seems to me their intent was essentially to kick these items out of the CRM into an "infrastructural" layer (which is a very sound idea in itself). It's just that they have mis-directed their kick and scored an own goal. I think this comes from not being sufficiently invested in the RDF stack to have comprehended the mistake,
Oh dear, Martin's latest is here: http://lists.ics.forth.gr/pipermail/crm-sig/2018-August/003453.html
Notably:
we define in the CRM RDFS the range of properties that use E94 Space Primitive in the definition of the CRM as rdfs:Literal, and recommend the user to instantiate it with adequate XML datatypes. These are for the surface of Earth “ogc:gmlLiteral” or “geo:wktLiteral”.
Since any instance of E94 Space Primitive identifies unambiguously an instance of E53 Place by a symbolic expression, E94 Space Primitive must logically be regarded as a subclass of E41 Appellation, regardless whether this can be expressed in RDFS or OWL.
The concepts E47 Spatial Coordinates, crmgeo: SP5 Geometric Place Expression, crmgeo:Q10 defines place and P168 place is defined by (defines place) need to be revised soon. E94 Space Primitive should replace E47 Spatial Coordinates and SP5 Geometric Place Expression. P168 place is defined by (defines place) should replace crmgeo:Q10 defines place. It may be useful in the CRM RDFS to specify two subproperties of P168, one having as range “geo:wktLiteral” and another “ogc:gmlLiteral”.
I have responded on list.
Tagging as blocked, as the current solution is documented on the site, but what happens with crmgeo would affect it.
Would you mind posting this for me (I'm persona non grata on that mlist ;-) “geo:wktLiteral” and “geo:gmlLiteral” use the same namespace, so they should use the same prefix. Defining sub-properties is unnecessary, because the values can be distinguished by datatype. If you do that, then you should also define 3 sub-props of P82a_begin_of_the_begin etc: for year, yearMonth and date. And similar for Measurement Value: for integer, int, short, decimal, float, etc etc.
On Thu, Aug 2, 2018 at 11:05 PM, Rob Sanderson notifications@github.com wrote:
Tagging as blocked, as the current solution is documented on the site, but what happens with crmgeo would affect it.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/linked-art/linked.art/issues/69#issuecomment-410051082, or mute the thread https://github.com/notifications/unsubscribe-auth/AAguutGjYTdw5W8VMfgF5xmPYHPjHnAKks5uM1t2gaJpZM4OK40g .
-- Vladimir Alexiev, PhD, PMP Lead, Data and Ontology Management Ontotext Corp, www.ontotext.com Email: vladimir.alexiev@ontotext.com, skype:valexiev1 Mobile: +359 888 568 132, SMS: 359888568132@sms.mtel.net Calendar: https://www.google.com/calendar/embed?src=vladimir.alexiev@ontotext.com Publications: http://vladimiralexiev.github.io/pubs/
Okay, as of today ...
SP5 - becomes a subclass of Geometry and E94 only E94 - becomes a subclass of E41 Appellation P168 - becomes a subproperty of P1 is identified by Q10 - becomes an inverse subproperty of P168 Q11 - is deprecated in favor of P189 (as of 6.2.4) SP5 - gains a guideline that it allows either literal (E94) or resource with properties (E53)
Thus we can use identified_by
to an SP5 resource (as it's a subclass of E94, which is a subclass of E41, which is the range of P1), or shortcut through P168 directly to the literal (as E94 is also simultaneously a literal).
If we need to have multiple declarative geometries for a single phenomenological place, we can use P189 approximates between two E53 Places, where the declarative E53 has P1 / P168.
Have we settled on using asWKT to capture simple lat-long points?
I think where we're at is:
P168
with a single WKT literal. Meaning yes, lat,long is a WKT Point()
Place P189_approximates Place
, and then have the definitions associated with those approximate places.I think we should document this and then discuss GeoJSON in a separate issue.
Documentation updated, re-raised the GeoJSON consideration as #300.
The spatial hierarchy is easy with P89, but at some point we may need to set actual lat/long coordinates for a Place. The model has P168 place is defined by, with a range of E94 Space Primitive. E94 should be mapped in RDF to rdfs:Literal, to allow for different datatypes.
Lat/Long could (vaguely) be considered Appellations or Identifiers -- in combination, the pair does identify a point in space. This doesn't work for polygons, of course.
My preference is to use P168 and punt on the representation for now. That doesn't give us much interoperability, but it would be good to have practical requirements for the coords/polygons and to see what systems can actually use.