DRB Geolocation Addon
The DRB geolocation add-on extracts the geolocation (named geometries + CRS) of a DRB node. Geolocation comes from two composed mechanisms:
- declarative descriptors:
geoloc:RDF blocks attached to topic class URIs, loaded from installed TTL packages and Fuseki (the same double source as the core topic DAO); - intrinsic providers: georeferencing carried by the data itself (raster affine transform or ground control points), read at access time, never declared.
The legacy cortex.yml YAML model is gone. There is no drb-metadata
dependency: this add-on is the only geolocation source.
Model overview
| Unit | Responsibility |
|---|---|
drb.addons.geolocation.model |
Output types GeoLocation / GeoLocationSet and their conversions |
drb.addons.geolocation.formats |
Registry of extracted-value formats (geometry and CRS parsers), entry-point extensible |
drb.addons.geolocation.providers |
Intrinsic geolocation plugins keyed by format-topic URIs |
drb.addons.geolocation.core |
geoloc: descriptor decoding + GeolocationAddon (resolution, inheritance, binding) |
drb.addons.geolocation.validator |
Static TTL validation, used by the geoloc-validator script |
The geoloc: descriptor vocabulary
Namespace http://knowledge-base.gael.fr/drb/addons/geolocation/, prefix
geoloc:. This is deliberately not GeoSPARQL: GeoSPARQL predicates
carry geometry data literals, while geoloc: carries extraction rules
(XQuery programs run against a node). GeoSPARQL datatype URIs are reused
as format terms, since they already type the extracted string exactly:
geo:gmlLiteral, geo:wktLiteral, geo:geoJSONLiteral. CRS formats have
no GeoSPARQL equivalent and live in the geoloc: namespace: geoloc:epsg,
geoloc:wktCrs.
One building block: a geoloc:geometry block attached to a topic class
URI. One block = one named geometry, exactly one source, and an optional
CRS.
Block rules
- Exactly one source per block:
geoloc:xquery(extraction),geoloc:value(constant), orgeoloc:children(aggregate). A block declaring zero or several of these is skipped with a warning at load time — a malformed block never aborts loading globally. geoloc:formatis mandatory forxquery/valuesources and must be a registered geometry format term. An unknown or missing format also skips the block with a warning (thegeoloc-validatorcatches this statically).- CRS precedence: an explicit
geoloc:crssub-block wins over a CRS embedded in the format (GMLsrsName, GeoJSON implicit EPSG:4326), which wins over the default EPSG:4326. geoloc:childrenaggregate semantics: the pattern is a/-separated glob matched withfnmatchagainst each descendant's structural child names (the pattern's segment count bounds the walk depth); every matching child is geolocated recursively (its own intrinsic provider or its own descriptors);geoloc:selectpicks one named geometry from each child's set (default: every geometry of each child); every collected geometry is reprojected to EPSG:4326 before aggregation, and the aggregated result is always EPSG:4326.geoloc:aggregateselects the mode:geoloc:union(shapely unary union),geoloc:envelope(bounding box of the union, default),geoloc:collection(GeometryCollection).subClassOfinheritance: declarations are collected by walking the topic'ssubClassOfchain; on equal names, the most specific topic wins. Intrinsic providers enter the set with the lowest precedence, so a declarative block can override a provider-published name.- Reserved name: the shipped raster provider publishes under
bounds; family descriptors reference it withgeoloc:select "bounds"in ageoloc:childrenblock. - Skip-and-warn: every rule above that a block violates causes that one
block to be skipped (logged at
WARNING), never a global load failure.
Example: XQuery source and explicit CRS
@prefix geoloc: <http://knowledge-base.gael.fr/drb/addons/geolocation/> .
@prefix geo: <http://www.opengis.net/ont/geosparql#> .
@prefix sentinel-1: <http://knowledge-base.gael.fr/drb/sentinel-1/> .
# XQuery source: product footprint from the manifest
sentinel-1:product geoloc:geometry [
geoloc:name "footprint" ;
geoloc:format geo:gmlLiteral ;
geoloc:xquery """<XQuery returning the frameSet GML polygon>""" ;
] .
# Explicit CRS when the geometry value does not carry one
sentinel-1:product geoloc:geometry [
geoloc:name "scene-center" ;
geoloc:format geo:wktLiteral ;
geoloc:xquery """<XQuery returning a WKT POINT>""" ;
geoloc:crs [ geoloc:format geoloc:epsg ;
geoloc:xquery """<XQuery returning the code>""" ] ;
] .
Example: children aggregate composing the raster provider
# Children aggregate: composes the intrinsic provider, zero duplication
sentinel-1:product geoloc:geometry [
geoloc:name "measurements" ;
geoloc:children "measurement/s1*-grd-*.tiff" ; # relative glob pattern
geoloc:select "bounds" ; # named geometry taken from each child
geoloc:aggregate geoloc:union ; # union | envelope | collection
] .
Family descriptor packages (drbx-kb-geolocation-sentinel-1, -sentinel-2)
are out of scope of this repository; naming follows the KB convention of
hyphenated family identifiers (sentinel-1, sentinel-2, never
sentinel1).
Python usage
from drb.topics import resolver
from drb.addons.geolocation import GeolocationAddon, GeoLocationSet
topic, node = resolver.resolve("<data_url>")
# the canonical addon interface
geoset = GeolocationAddon().apply(node, topic=topic)
geoset.names() # declared/published names, no evaluation
footprint = geoset["footprint"] # evaluated on first access, then memoized
footprint.transform("EPSG:2154") # a new, reprojected GeoLocation
footprint.to_wkt()
footprint.to_geojson() # a GeoJSON Feature (RFC 7946, WGS84)
geoset.transform("EPSG:2154").to_geojson() # a GeoJSON FeatureCollection
GeoLocationSet is a lazy Mapping[str, GeoLocation]: a geometry is only
extracted the first time its name is accessed, then cached. This matters
because a geoloc:children aggregate may open many rasters through
zip/S3 — apply() itself never triggers extraction, and one name failing
to evaluate (GeolocationExtractionError, raised at access) does not
prevent the other names in the same set from being read.
If no declaration and no provider apply to the node's topic chain,
apply() raises GeolocationNotAvailable.
Provider extension point
Intrinsic providers publish geolocation without any RDF declaration, keyed
by the format-topic class URIs they serve. Register a provider class
through the drb.addon.geolocation.provider entry point group; the
built-in RasterProvider (declared for drb:image and drb:jp2) is
loaded the same way.
from drb.addons.geolocation import GeolocationProvider, GeoLocation
class MyProvider(GeolocationProvider):
def topics(self) -> list[str]:
return ["http://www.gael.fr/drb#my-format"]
def names(self) -> set[str]:
return {"bounds"} # static, no node access
def extract(self, node) -> dict[str, GeoLocation]:
... # called lazily, on first access only
return {"bounds": GeoLocation("bounds", crs, geometry)}
[project.entry-points."drb.addon.geolocation.provider"]
my-provider = "my_package.geolocation:MyProvider"
The shipped RasterProvider reads node.get_impl(rasterio.DatasetReader)
only — it is transport-agnostic and never opens files itself. It derives
bounds from the affine transform and CRS when present (e.g. Sentinel-2
JP2 bands), falling back to the convex hull of the ground control points
when only GCPs are available (e.g. Sentinel-1 GeoTIFF measurements), and
raises GeolocationExtractionError when the raster carries neither.
Intrinsic raster geolocation requires drb-driver-image at runtime
(not a hard dependency of this package) to provide the rasterio node
implementation.
Format extension point
Geometry and CRS value formats are registered functions, keyed by URI
(GeoSPARQL datatypes for geometry, geoloc: terms for CRS). Register
additional formats through the drb.addon.geolocation.format entry point
group: each entry point resolves to a zero-argument callable that performs
the registration.
from drb.addons.geolocation.formats import register_geometry_format
def register():
register_geometry_format(
"http://example.org/my-format", parse_my_format)
# parse_my_format(value: str) -> (shapely.Geometry, pyproj.CRS | None)
[project.entry-points."drb.addon.geolocation.format"]
my-format = "my_package.geolocation:register"
Static validation: geoloc-validator
The geoloc-validator console script statically checks geoloc:geometry
blocks in one or more Turtle files: unparsable Turtle, more than one or zero
sources per block, and unknown/missing formats or aggregate modes are all
reported without evaluating any XQuery.
geoloc-validator path/to/cortex.ttl [more.ttl ...]
Exit code 0 when every file is clean, 1 as soon as one problem is
reported (one line per problem, on stderr).
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file drb_addon_geolocation-1.0.0.tar.gz.
File metadata
- Download URL: drb_addon_geolocation-1.0.0.tar.gz
- Upload date:
- Size: 55.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6fdc7a0d67ff3f21393c8a103b8400c12b169d21ed14b13375d7729e5bd7df4c
|
|
| MD5 |
1effa03cb53a49ebfb62517b049c6251
|
|
| BLAKE2b-256 |
6d4cc2a466316f76029965af95e34809dbe4637802ee1b9d13f0eae85f18a642
|
File details
Details for the file drb_addon_geolocation-1.0.0-py3-none-any.whl.
File metadata
- Download URL: drb_addon_geolocation-1.0.0-py3-none-any.whl
- Upload date:
- Size: 19.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e707323069f29cb84c0ff5a0a38550beb0e9287843c58aef995ada5623a085f
|
|
| MD5 |
c84a28e904388832dbaa012e3b717701
|
|
| BLAKE2b-256 |
aa73aad5894ee88754c8851c5f27495f20a6d643686d2cee1f2835c412e2aece
|