fils/oihBook huggingface dataset:
Spatial Geometry#
About#
For spatial geometry Ocean InfoHub guidance will be to use the OGC GeoSPARQL
vocabulary to express geometry using Well Known Text (WKT).  The schema.org spatial types and propeties are not well
defined and difficult at times to reliably translate to geometries for use in more Open Geospatial Consortium (OGC)
environments.
Simple GeoSPARQL WKT#
The following is a simple example of how to embed a WKT string via GeoSPARQL into a JSON-LD record.
Well Know Text (WKT) is a OGC standard referenced at: https://www.ogc.org/standards/wkt-crs.
A more accessible description and set of examples can be found at WikiPedia:
Well-known text representation of geometry.
 1{
 2    "@context": {
 3      "@vocab": "https://schema.org/",
 4      "geosparql": "http://www.opengis.net/ont/geosparql#"
 5    },
 6    "@id": "https://example.org/id/XYZ",
 7    "@type": "Dataset",
 8    "name": "Data set name",
 9    "geosparql:hasGeometry": {
10        "@type": "http://www.opengis.net/ont/sf#Point",
10        "@type": "http://www.opengis.net/ont/sf#Point",
11        "geosparql:asWKT": {
12            "@type": "http://www.opengis.net/ont/geosparql#wktLiteral",
13            "@value": "POINT(-76 -18)"
14        },
15        "geosparql:crs": {
16            "@id": "http://www.opengis.net/def/crs/OGC/1.3/CRS84"
17        }
18    }
19}
Line 4 declare the GeoSPARQL prefix for the vocabulary that we will leverage in this document.
Lines 9-17 are the GeoSPARQL node and property definitions.  In this case our type is a simple
point geometry.  We then go on to declare the asWKT with a type and value.  The value
is our actual WKT string for our geometry.   We can further
declare the coordinate reference system (CRS) of the geometry using the crs property.
import json
from pyld import jsonld
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils
sys.path.insert(0, parentdir)
from lib import jbutils
with open("../../../odis-in/dataGraphs/thematics/spatial/graphs/basic.json") as dgraph:
    doc = json.load(dgraph)
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
WKT Bounding Box#
Note that WKT doesn’t directly have a bounding box, in that case you
would need to use a polygon.  The following is an example of a WKT string:
would need to use a polygon.  The following is an example of a WKT string:
POLYGON((45.066730529474505 2.6430807905900235,47.395832091974505 2.6430807905900235,47.395832091974505 0.3588601145746598,45.066730529474505 0.3588601145746598,45.066730529474505 2.6430807905900235))
This following the pattern:
'POLYGON(x1 y1, x1 y2, x2 y2, x2 y1, x1 y1)'
Classic Schema.org#
Ocean InfoHub only recommends the use of Schema.org spatial geometries in
the case where a provider wishes to be properly indexed by Google and to have the
spatial information used by Google for maps.  Note, the lack of spatial information will
not prevent Google from indexing your resources.
Schema.org spatial geometries are not well defined in comparison to OGC standards and
recommendations.  Also, converting from Schema.org spatial to geometries in WKT or GeoJSON
can be problematic.  There are inconsistencies with
Schema.org guidance for textual geometry representation and that of Well
Known Text (WKT).
That said, if you desire to leverage Schema.org geometries an example follows.  This
That said, if you desire to leverage Schema.org geometries an example follows.  This
is a simple example of the existing Schema.org pattern for a lat long value.   There is the
pending GeospatialGeometry which is a
type Intangible (and not Place referenced by spatialCoverage).  This will be a
subtype of GeoShape.
Schema.org spatial relations are guided by DE-9IM.
 1{
 2  "@context": {
 3    "@vocab": "https://schema.org/"
 4  },
 5  "@id": "https://example.org/id/XYZ",
 6  "@type": "Dataset",
 7  "name": "Data set name",
 8  "spatialCoverage": {
 9    "@type": "Place",
10    "geo": {
11      "@type": "GeoCoordinates",
12      "latitude": 39.3280,
13      "longitude": 120.1633
14    }
15  }
16}
import json
from pyld import jsonld
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils
sys.path.insert(0, parentdir)
from lib import jbutils
with open("../../../odis-in/dataGraphs/thematics/spatial/graphs/sos.json") as dgraph:
    doc = json.load(dgraph)
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
Option review, SOS Issue 105#
There are several approaches to expressing spatial geometries in JSON-LD.
While Ocean InfoHub will recommend the use of GeoSPARQL, it is worth noting that there
are alternative and solid cases for using them
One such case could be the case where your WKT geometry string are highly detailed and
as a result quite long.  These might result in both very large JSON-LD documents that are hard to
read and maintain.  It may also be that this imparts a performance penalty in your GeoSPARQL
queries.
It may be tha that you simplify your WKT geometry strings to a more basic form.  Then link out
to the detailed geometry in a separate document.   The simplified WKT (or Schema.org spatial)
make the documents smaller and easier to read and could help query performance.  The resource
can then point to a dereferencable URL for the detailed geometry.
ref Selfie:  When linking out to complex geometries we recommend following: https://docs.ogc.org/per/20-067.html
From the referenced SOS issue 105:
 1{
 2    "@context": {
 3        "@version": 1.1,
 4        "geoblob": {
 5            "@id": "http://example.com/vocab/json",
 6            "@type": "@json"
 7        },
 8        "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
 9        "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
10        "xsd": "http://www.w3.org/2001/XMLSchema#",
11        "description": "http://igsn.org/core/v1/description",
11        "description": "http://igsn.org/core/v1/description",
12        "geosparql": "http://www.opengis.net/ont/geosparql#",
13        "schema": "https://schema.org/"
14    },
15    "@id": "https://samples.earth/id/do/bqs2dn2u6s73o70jdup0",
16    "@type": "http://igsn.org/core/v1/Sample",
17    "description": "A fake ID for testing",
18    "schema:subjectOf": [
19        {
20            "schema:url": "https://samples.earth/id/do/bqs2dn2u6s73o70jdup0.geojson",
21            "@type": "schema:DigitalDocument",
22            "schema:format": [
23                "application/vnd.geo+json"
24            ],
25            "schema:conformsTo": "https://igsn.org/schema/spatial.schema.json"
26        }
27    ],
28    "geosparql:hasGeometry": {
29        "@id": "_:N98e75cacc29f40deb555eb583cb162dc",
30        "@type": "http://www.opengis.net/ont/sf#Point",
31        "geosparql:asWKT": {
31        "geosparql:asWKT": {
32            "@type": "http://www.opengis.net/ont/geosparql#wktLiteral",
33            "@value": "POINT(-76 -18)"
34        },
35        "geosparql:crs": {
36            "@id": "http://www.opengis.net/def/crs/OGC/1.3/CRS84"
37        }
38    },
39    "geoblob": {
40        "type": "GeometryCollection",
41        "geometries": [{
42            "type": "Point",
43            "coordinates": [-76, -18]
44        }]
45    },
46    "schema:spatialCoverage": {
47        "@type": "schema:Place",
48        "schema:geo": {
49          "@type": "schema:GeoCoordinates",
50          "schema:latitude": -18,
51          "schema:longitude": -76
52        }
53      }
54}
import json
from pyld import jsonld
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils
sys.path.insert(0, parentdir)
from lib import jbutils
with open("../../../odis-in/dataGraphs/thematics/spatial/graphs/issue105.json") as dgraph:
    doc = json.load(dgraph)
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
References#
GeoAPI at GitHub
Science on Schema Issue 105
Leverages subjectOf to connect to a Thing / CreativeWork
https://www.unsalb.org/
https://www.un.org/geospatial/
schema.org/spatial
schema.org/GeospatialGeometry
SOS patern follows:
spatialCoverage -> Place -> geo -> GeoCoordinates OR GeoShape
Some groups are using GeoNode
schema.org issues
ICAN & Schema.org
OGC SELFIE
Think broad
schema.org issues
ICAN & Schema.org
OGC SELFIE
Think broad
Science on Schema spatial for dataset guidance
Service#
About#
This section will provide information on the service type.  This is not
one of the main OIH types.  However, we will provide guidance here on describing
services using schema.org.
It should be noted that this might be a simple link to an OpenAPI or some
other descriptor document.  Also, schema.org is not rich enough for complex
descriptions and itself borrows from the Hydra
vocabulary.  It may be required to leverage Hydra if complex descriptions are
needed.
The graph describes a service than can be invoked with:
curl --data-binary "@yourfile.jpg" -X POST https://us-central1-top-operand-112611.cloudfunctions.net/function-1
This with POST a jpeg to the service and get back a simple text response with some information
about the image.
 1{
 2  "@context": {
 3    "@vocab": "https://schema.org/"
 4  },
 5  "@type": "Service",
 6  "@id": "URL:  Optional. A URL that resolves to *this* JSON-LD document, NOT the URL of the Service that this JSON-LD document describes. To link to the Service itself, please use 'url' and/or 'identifier')",
 7  "aggregateRating": {"@type": "https://schema.org/aggregateRating"},
8  "areaServed": [
 9    "Text: The geographic area where the service is provided.",
10    {"@type": "https://schema.org/Place"},
11    {"@type": "https://schema.org/GeoShape"},
12    {"@type": "https://schema.org/AdministrativeArea"}
13  ],
14  "audience": {"@type": "https://schema.org/Audience"},
15  "availableChannel": {"@type": "https://schema.org/ServiceChannel"},
16  "award": "Text: An award won by or for this service.",
17  "brand": [
18    "Text: The brand(s) associated with the service, or the brand(s) maintained by an organization or business person.",
19    {"@type": "https://schema.org/Brand"},
20    {"@type": "https://schema.org/Organization"}
21  ],
22  "broker": [
23  {"@type": "https://schema.org/Person"},
24  {"@type": "https://schema.org/Organization"}
25  ],
26  "category": [
27    "Text: A category for the service.",
28    "URL",
29    {"@type": "https://schema.org/CategoryCode"},
29    {"@type": "https://schema.org/CategoryCode"},
30    {"@type": "https://schema.org/PhysicalActivityCategory"},
31    {"@type": "https://schema.org/Thing"}
32  ],
33  "hasOfferCatalog": "https://schema.org/OfferCatalog",
34  "hoursAvailable": "https://schema.org/OpeningHoursSpecification",
35  "isRelatedTo": [
36    {"@type": "https://schema.org/Product"},
37    {"@type": "https://schema.org/Service"}
38  ] ,
39  "isSimilarTo": [
40    {"@type": "https://schema.org/Product"},
41    {"@type": "https://schema.org/Service"}
42  ] ,
43  "logo": [
44    {"@type": "https://schema.org/ImageObject"},
45    "URL"
46  ] ,
47  "offers": [
48    {"@type": "https://schema.org/Demand"},
49    {"@type": "https://schema.org/Offer"}
50  ] ,
51  "provider": [
52    "Text: The service provider, service operator, or service performer; the goods producer. Another party (a seller) may offer those services or goods on behalf of the provider.",
53    {"@type": "https://schema.org/Person"},
54    {"@type": "https://schema.org/Organization"}
55  ],
56  "providerMobility": "Text: Indicates the mobility of a provided service (e.g. 'static', 'dynamic').",
57  "review": {"@type": "https://schema.org/Review"},
58 
59  "serviceOutput":  {"@type": "https://schema.org/Thing"},
60  "serviceType":  [
61    "Text: Human-readable terms of service documentation",
62    {"@type": "https://schema.org/GovernmentBenefitsType"}
63  ],
64  "slogan": "Text: A slogan or motto associated with the item.",
65  "termsOfService": [
66    "Text: Human-readable terms of service documentation",
67    {"@type": "https://schema.org/Url"}
68  ],
69
70  
71  "additionalType": [
72    "Text: An additional type for the item, typically used for adding more specific types from external vocabularies in microdata syntax.",
73    "URL"
74  ],
75  "alternateName": "Text: An alternative name for this Thing.",
76  "description": "Text: Free text which describes this Thing.",
76  "description": "Text: Free text which describes this Thing.",
77  "disambiguatingDescription": "Text: A sub property of description. A short description of the item used to disambiguate from other, similar items. Information from other properties (in particular, name) may be necessary for the description to be useful for disambiguation",
78  "identifier": [
79      {"@type": "https://schema.org/PropertyValue"},
80      "Text - The identifier property represents any kind of identifier for any kind of Thing, such as ISBNs, GTIN codes, UUIDs etc. Schema.org provides dedicated properties for representing many of these, either as textual strings or as URL (URI) links. See background notes for more details.",
81      "URL"
82  ],
83  "image": [
84      "URL",
85      {"@type": "https://schema.org/ImageObject"}
86  ],
87  "mainEntityOfPage": [
88    "URL",
89    {"@type": "https://schema.org/CreativeWork"}
90  ],
91  "name": "Text: The name of the item.",
92  "potentialAction": {"@type": "https://schema.org/Action"},
93  "sameAs": "URL",
94  "subjectOf": "URL",
93  "sameAs": "URL",
94  "subjectOf": "URL",
95  "url": "URL - the URL to the item described by this JSON-LD document"
96}
import json
from pyld import jsonld
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils
with open("../../../odis-in/dataGraphs/thematics/services/graphs/service.json") as dgraph:
    doc = json.load(dgraph)
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
/tmp/ipykernel_3668524/3307491376.py in <module>
     16 
     17 compacted = jsonld.compact(doc, context)
---> 18 jbutils.show_graph(compacted)
~/src/Projects/OIH/odis-arch/bookRev1/lib/jbutils.py in show_graph(doc, size)
     44     for edge in rdf:
     45         subj = short_name(edge['subject'])
---> 46         obj = short_name(edge['object'])
---> 46         obj = short_name(edge['object'])
     47         pred = short_name(edge['predicate'])
     48         if subj and obj and pred:
~/src/Projects/OIH/odis-arch/bookRev1/lib/jbutils.py in short_name(value, max_length)
     22             # If the URL is too long, hide it
     23             if len(short_url) > max_length:
---> 24                 pieces = split_uri(short_url)
     25                 return join_uri(pieces[0], '...')
     26             else:
NameError: name 'split_uri' is not defined
References#
https://schema.org/docs/actions.html
https://schema.org/Action
https://www.w3.org/TR/web-share/
https://www.hydra-cg.com/spec/latest/core/
Experts and Institutions#
About#
This thematic type provides a way to describe the experts and institutions.
In this case the following definitions are used:
Expert:  A person who has a deep understanding of a particular subject area.
Institution: A group of people working together to provide a particular service.
Example: Person Graph#
The following graph present a basic record we might use for a person.
We will break down some of the key properties used in this graph.
As Ocean InfoHub is levergaing Schema.org we are
using schema.org/Person for this type.
Any of the properties of Person seen there are valid to use in such a record.
While publishers are free to use as many elements as they wish, our goal
with this documentation is provide a simple example that address some of the search
and discovery goals of OIH along with those properties most useful in the linking
of resources between OIH participants.
 1{
 2  "@context": {
 3    "@vocab": "https://schema.org/"
 4  },
 5  "@id": "https://example.org/id/x",
 6  "@type": "Person",
 7  "name": "Jane Doe",
 8  "jobTitle": "Professor",
 9  "workLocation": {
10    "@type": "Place",
9  "workLocation": {
10    "@type": "Place",
11    "address": "54 Ocean Drive, 23521 Ocean City, CountryName",
12    "name": "Place name"
13  },
14  "telephone": "(425) 123-4567",
15  "url": "http://www.janedoe.com",
16  "knowsAbout": [
17    {
18      "@type": "Text",
19      "description": "Invasive species in brackish water"
20    },
21    {
22      "@type": "URL",
23      "url": "https://www.wikidata.org/wiki/Q183368"
24    },
25    {
26      "@id": "https://example.org/id/course/x",
27      "@type": "Course",
28      "description": "In this course ...",
29      "url": "URL to the course"
30    }
31  ],
32  "identifier": {
33    "@id": "https://orcid.org/0000-0002-2257-9127",
34    "@type": "PropertyValue",
35    "propertyID": "https://registry.identifiers.org/registry/orcid",
35    "propertyID": "https://registry.identifiers.org/registry/orcid",
36    "url": "https://orcid.org/0000-0002-2257-9127",
37    "description": "Optional description of this record..."
38  },
39  "nationality": [
40    {
41      "@type": "Country",
42      "name": "Fiji"
43    },
44    {
45      "@type": "DefinedTerm",
46      "url": "https://unece.org/trade/cefact/unlocode-code-list-country-and-territory",
47      "inDefinedTermSet": "UN/LOCODE Code List by Country and Territory",
48      "name": "Fiji",
49      "termCode": "FJ"
50    }
51  ],
52  "knowsLanguage": {
53    "@type": "Language",
54    "name": "Spanish",
55    "alternateName": "es"
56  }
57}
import json
from pyld import jsonld
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils
sys.path.insert(0, parentdir)
from lib import jbutils
with open("../../../book/thematics/expinst/graphs/person.json") as dgraph:
    doc = json.load(dgraph)
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
jbutils.show_graph(compacted)
Details: Identifier#
For each profile there are a few key elements we need to know about.  One
key element is what the authoritative reference or canonical identifier is for
a resource.
import json
from rdflib.extras.external_graph_libs import rdflib_to_networkx_multidigraph
from rdflib.extras.external_graph_libs import rdflib_to_networkx_graph
from pyld import jsonld
import graphviz
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils
with open("../../../odis-in/dataGraphs/thematics/expinst/graphs/person.json") as dgraph:
    doc = json.load(dgraph)
frame = {
  "@context": {"@vocab": "https://schema.org/"},
  "@explicit": "true",
  "@type":     "Person",
  "identifier": ""
}
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
framed = jsonld.frame(compacted, frame)
jd = json.dumps(framed, indent=4)
print(jd)
jbutils.show_graph(framed)
{
    "@context": {
{
    "@context": {
        "@vocab": "https://schema.org/"
    },
    "@id": "https://example.org/id/x",
    "@type": "Person",
    "identifier": {
        "@id": "https://orcid.org/0000-0002-2257-9127",
        "@type": "PropertyValue",
        "description": "Optional description of this record...",
        "propertyID": "https://registry.identifiers.org/registry/orcid",
        "url": "https://orcid.org/0000-0002-2257-9127"
    }
}
Details: nationality#
Nationality provide connections to languages a person is
connected with.  The property, schema.org/nationality,
is used to present that.  In the OIH we need to state what the semantics of
nationality are for our use case.
import json
from rdflib.extras.external_graph_libs import rdflib_to_networkx_multidigraph
from rdflib.extras.external_graph_libs import rdflib_to_networkx_graph
from pyld import jsonld
import graphviz
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils
sys.path.insert(0, parentdir)
from lib import jbutils
with open("../../../odis-in/dataGraphs/thematics/expinst/graphs/person.json") as dgraph:
    doc = json.load(dgraph)
frame = {
  "@context": {"@vocab": "https://schema.org/"},
  "@explicit": "true",
  "@type":     "Person",
  "nationality": ""
}
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
framed = jsonld.frame(compacted, frame)
jd = json.dumps(framed, indent=4)
print(jd)
jbutils.show_graph(framed)
{
    "@context": {
        "@vocab": "https://schema.org/"
    },
"@context": {
        "@vocab": "https://schema.org/"
    },
    "@id": "https://example.org/id/x",
    "@type": "Person",
    "nationality": [
        {
            "@type": "Country",
            "name": "Fiji"
        },
        {
            "@type": "DefinedTerm",
            "inDefinedTermSet": "UN/LOCODE Code List by Country and Territory",
            "name": "Fiji",
            "termCode": "FJ",
            "url": "https://unece.org/trade/cefact/unlocode-code-list-country-and-territory"
        }
    ]
}
Note
The visual above demonstrates an issue that can be seen in several of the graph.  Where we
don’t use an @id the graph will be represented as a “blank node”.
These will be uniquely identified in the graph, however, in the construction of the visual
this is a common blank node and results in the double arrows pointing to an underscore.
This is a visualization issue and not a proper representation of the graph structure.
Details: knowsLanguage#
Knows about provide connections to languages a person is
connected with.  The property, schema.org/knowsLanguage,
is used to present that.   Multiple languages can be expressed using the JSON
is used to present that.   Multiple languages can be expressed using the JSON
array [] syntax.
import json
from rdflib.extras.external_graph_libs import rdflib_to_networkx_multidigraph
from rdflib.extras.external_graph_libs import rdflib_to_networkx_graph
from pyld import jsonld
import graphviz
import os, sys
currentdir = os.path.dirname(os.path.abspath(''))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from lib import jbutils
with open("../../../odis-in/dataGraphs/thematics/expinst/graphs/person.json") as dgraph:
    doc = json.load(dgraph)
frame = {
  "@context": {"@vocab": "https://schema.org/"},
  "@explicit": "true",
  "@type":     "Person",
  "knowsLanguage": ""
}
context = {
    "@vocab": "https://schema.org/",
}
compacted = jsonld.compact(doc, context)
framed = jsonld.frame(compacted, frame)
jd = json.dumps(framed, indent=4)
print(jd)
jbutils.show_graph(framed)
print(jd)
jbutils.show_graph(framed)
{
    "@context": {
        "@vocab": "https://schema.org/"
    },
    "@id": "https://example.org/id/x",
    "@type": "Person",
    "knowsLanguage": {
        "@type": "Language",
        "alternateName": "es",
        "name": "Spanish"
    }
}
Details: Knows About#
Knows about provide connections to resources a person is
connected with.  The property, schema.org/knowsAbout,
can connect a Person or Organization to Text, URL or any Thing type.
import json
from rdflib.extras.external_graph_libs import rdflib_to_networkx_multidigraph
from rdflib.extras.external_graph_libs import rdflib_to_networkx_graph
from pyld import jsonld