Home › FAQ
The INSPIRE geoservices are really cool. As geospatial data and services are special and complicated, they are quite difficult to discover and use. The wrapper sits between your browser and the upstream national services, handling several things:
Access-Control-Allow-Origin headers, so browsers would block direct
cross-origin JavaScript requests. The wrapper proxies responses so the
“Show on map” buttons and form submissions work.Referer
that browsers don't allow JavaScript to override; the wrapper adds them server-side.Data is organised by NUTS region (country level and major/sub-region level where available).
?legend for the legend graphic.WMS and WFS only. Other OGC service types that the national providers also publish are not proxied, even when a region's WMS/WFS provider offers them:
/wmts/ tile proxy was removed. Some
upstream WMTS services (e.g. Maanmittauslaitos, Finland) require a
Referer header or an API key, so they are not usable directly from a
browser either. Use the WMS for the same layer, or /tile, which
cuts XYZ tiles from WMS.
Yes, a processor rather than an endpoint over a store: /sparql (GET or POST,
parameter query; a GET without a query returns a SPARQL 1.1 Service Description), with a form at
/sparql.html. The wrapper has no triple store: a query must
name its data with FROM / FROM NAMED clauses whose URIs are
this wrapper's own /wfs routes, for example
SELECT ?s ?name
FROM <wfs?s=https://sgx.geodatenzentrum.de/wfs_dlm250_inspire&type=/inspire/hy-p/4.0%23Watercourse&bbox=9.90,53.50,10.10,53.60>
WHERE { ?s a <inspire/hy-p/4.0#Watercourse> ; <inspire/hy-p/4.0#geographicalName> ?name }
IRIs in a query are relative to the wrapper's own base (its origin plus any path it is
mounted under, e.g. /inspire/), so write them without a leading slash:
<wfs?…>, <inspire/hy-p/4.0#Watercourse>. A root-relative
</wfs?…> resolves to the host root and is rejected as external where the
wrapper is mounted under a path.
Each named graph is fetched through /wfs (complete: every feature the
bounding box matches, unless count is given), unioned, and the query runs
over the union; external graph URIs are rejected. Results: SPARQL JSON/XML/TSV for
SELECT, Turtle/RDF/XML or GeoJSON for CONSTRUCT and DESCRIBE. GeoSPARQL functions are
available; bind geo:hasGeometry/geo:asWKT for anything you pass to a
function and locn:geometry for the map (see
FAQ: geometry representations).
The INSPIRE in your country page lists INSPIRE services for all EU member states.
See the regions list for current coverage. Not all EU member states are included: some require API key registration, some only offer download services or ATOM feeds rather than WMS/WFS, and some national geoportals are offline. Some services are HTTP-only and cannot be proxied from an HTTPS page.
A Coordinate Reference System (CRS) defines how coordinates map to locations on Earth. The OGC standards use the older term Spatial Reference System (SRS) for the same concept. The most common CRS is EPSG:4326 (WGS 84), which uses latitude/longitude in degrees — this is what GPS devices and most web maps use.
A projection converts the curved surface of the Earth to a flat map. Web maps typically use Web Mercator (EPSG:3857) for display, but the underlying data is often served in geographic coordinates (EPSG:4326 or EPSG:4258).
All GeoJSON returned by the wrapper is in WGS 84 (EPSG:4326, lon/lat), regardless of what CRS the upstream service uses. Leaflet receives standard GeoJSON and needs no special CRS configuration on the client side.
Some German states (NRW, Sachsen) only support ETRS89 (EPSG:4258) on their WFS endpoints, not WGS 84 (EPSG:4326). ETRS89 and WGS 84 are practically identical (less than 1 m difference in Europe), so the bounding box coordinates work the same way. The wrapper automatically uses the appropriate SRS for each region.
Bounding boxes use the format W,S,E,N in decimal degrees (EPSG:4326, WGS 84). W and E are longitude, S and N are latitude.
Note: WMS 1.3.0 and WFS 2.0.0 require lat/lon axis order (S,W,N,E) when using EPSG:4326. The wrapper translates from the more intuitive lon/lat (W,S,E,N) to the standard axis order automatically before forwarding requests upstream.
The wrapper always returns GeoJSON in WGS 84 lon/lat, regardless of the upstream axis
order or projection. For GML-based services the conversion is done server-side;
for services that provide native GeoJSON output the wrapper requests
SRSNAME=EPSG:4326 so the upstream reprojection happens there. If you need
the raw upstream GML (in its original CRS and axis order), use the
/wfs.gml?type=…&bbox=…&s=… suffix — axis
order and projection then depend on the individual upstream service.
Some upstream WMS services impose a maximum image dimension (width or height in pixels). The wrapper respects these limits and returns whatever the upstream server provides. Known limits: Netherlands PDOK 2500 px, Poland GUGiK 2048 px, Denmark Dataforsyningen 3000 px. If you need a larger area, split your bounding box into smaller tiles.
The wrapper requests an image whose longer side is max_size pixels
(default 4000, lower for some services — see FAQ: Maximum image size).
The shorter side is computed from the bbox aspect ratio. Each pixel covers:
ground per pixel = bbox width (or height) / pixel width (or height)
If your bbox covers a large area, each pixel spans more ground and the image is effectively downsampled. For example, a DOP (orthophoto) layer at 20 cm ground resolution and 4000 pixels wide requires a bbox no wider than 4000 × 0.2 m = 800 m to render every source pixel. A wider bbox still works but returns a downsampled image.
Some upstream WMS services only render at certain zoom levels. For example, Bavaria DTK50 and DTK25 require zoom ≥ 14, and NRW nDOM requires zoom ≥ 14. The interactive maps show a warning when the active layer needs a higher zoom level. If you use the API directly and get a blank image, try increasing the zoom level (i.e. requesting a smaller bounding box).
This wrapper serves only services that meet a machine-checkable INSPIRE test. Everything else lives in the sibling wrappers. The test differs by service kind, because a WFS and a WMS can be INSPIRE in different senses.
http://inspire.ec.europa.eu/schemas/, or reached through the
wrapper's XSD-import vocabulary map. This is the same test that decides whether
a feature type gets an /inspire/{theme}/{version}# class URI in the
RDF output, so a WFS that fails it is one whose data the INSPIRE vocabulary
cannot describe. An INSPIRE-looking feature type name under some other
namespace does not count: a name is not a schema.
The test is per service, not per feature type:
one INSPIRE-namespaced feature type admits the whole service, INSPIRE
remainder and all. Feature types on an admitted service that aren't
INSPIRE-namespaced (a national extension, a third-party dataset folded in, a
test layer) aren't dropped either — they get a
local vocab stub instead of an
/inspire/{theme}/{version}# class. Only when a service has
zero INSPIRE-namespaced feature types is the whole service excluded.
GetCapabilities must contain an
<inspire_vs:ExtendedCapabilities> carrying either an
<inspire_common:MetadataUrl> (metadata linked) or an
<inspire_common:ResourceType> (metadata inline) — the two
scenarios the
View
Services Technical Guidance allows. INSPIRE-themed layer names alone do
not qualify — a name is not conformance, for the same reason the WFS test
rejects INSPIRE-looking feature-type names.
ExtendedCapabilities is an INSPIRE-specific block a server adds
on top of the plain OGC GetCapabilities response (which only
describes layers, formats and bounding boxes). It is what actually carries
the INSPIRE-mandated service metadata — the metadata URL/inline
resource type, supported languages, response language — and looks like:
<Capability>
<inspire_vs:ExtendedCapabilities>
<inspire_common:MetadataUrl>...</inspire_common:MetadataUrl>
<inspire_common:SupportedLanguages>...</inspire_common:SupportedLanguages>
...
</inspire_vs:ExtendedCapabilities>
</Capability>
A server can declare the inspire_vs/inspire_common
XML namespaces — just an xmlns: attribute, costs nothing
— without ever emitting this block, and layer names can look like
INSPIRE Annex naming (OI.OrthoimageCoverage) by convention
alone. Neither commits the server to being a registered INSPIRE view
service, which is why the test below checks for the element itself, not
the namespace declaration or the naming convention.
The test is conformance, not intent. A number of national services are named “INSPIRE” and declare the INSPIRE XML namespaces, but then publish no extended capabilities at all. Those are not served here, even though they are plainly INSPIRE-intended. A rule a service either passes or fails is reproducible and survives re-running discovery; “looks INSPIRE-ish” is not. If such a service later fixes its capabilities document, re-running discovery picks it up automatically — nothing is maintained by hand.
Declaring the namespace is not enough on its own: xmlns:inspire_common
on the root element with an empty body tells a client nothing about the service.
Note also that inspire_vs is the view (WMS) namespace and
inspire_dls the download (WFS) one; each kind is tested against
its own.
/wfs?s={service}&typenames={type}&eq={property}:{value} selects the
features whose property equals the value; like={property}:{pattern} matches a
pattern (* any string, ? one character, case-insensitive). The
value follows the last colon, so the property may be a path into nested objects
with its own prefix colons. A bbox may be added; without one the query runs
over the whole service. count/offset and the format suffixes work
as usual. The wrapper turns this into one OGC Filter Encoding 2.0 (FES) document — with the
bbox folded in as fes:BBOX, because a WFS 2.0 server rejects the KVP
BBOX and FILTER parameters side by side.
GET /wfs?s={wfs-uri}&typenames=hy-p:Watercourse&bbox=9.9,53.5,10.1,53.6
&like=hy-p:geographicalName/gn:GeographicalName/gn:spelling/gn:SpellingOfName/gn:text:*Elbe*
The INSPIRE name is a nested gn:GeographicalName object, so the property is
the full path down to gn:text — a bare gn:name matches nothing
upstream. Property names and paths for a type follow from its features (or from
/wfs?s={wfs-uri}&type={type}, the type's metadata page).
GET /wfs?s={geographical-names-wfs-uri}&typenames=gn:NamedPlace
&eq=gn:name/gn:GeographicalName/gn:spelling/gn:SpellingOfName/gn:text:Pegnitzgn: inside a hydrography type) are not in that list; for those the wrapper
assumes the latest schema version it mirrors under /inspire/{prefix}/. That
is a guess — a wrong version matches nothing rather than failing — and the exact
xmlns declarations sent upstream are in the document's PROV
(prov:hadPrimarySource, the upstream GetFeature URL). Any other unknown
prefix is a 400.filter=FILTER parameter unchanged — for anything eq/like
cannot express (ranges, fes:And/fes:Or, spatial operators).
Declare your namespaces yourself, and do not combine it with
bbox: the upstream rejects the pair (put a fes:BBOX inside your
filter instead). filter, eq and like are
alternatives.
GET /wfs?s={wfs-uri}&typenames=hy-p:Watercourse
&filter=<fes:Filter xmlns:fes="http://www.opengis.net/fes/2.0"
xmlns:hy-p="http://inspire.ec.europa.eu/schemas/hy-p/4.0">
<fes:PropertyIsEqualTo>
<fes:ValueReference>hy-p:origin</fes:ValueReference>
<fes:Literal>natural</fes:Literal>
</fes:PropertyIsEqualTo>
</fes:Filter>/wms layer with a time dimension supports Memento-style temporal
negotiation: its URI is the original resource (latest data) and acts as its own
TimeGate. Send an Accept-Datetime: Thu, 25 Jun 2020 12:00:00 GMT
header and the wrapper replies 302 to the corresponding memento —
the same URI with a time= component identifying a 30-day window ending at
the requested date. time= is memento URI syntax minted by the TimeGate, not
a query knob. Memento responses carry Memento-Datetime and a
Link (rel="original timegate") header. There is no TimeMap at
present: the earlier one listed Sentinel-2 acquisitions and moved to linked-cdse with
that service.filter parameter (see
FAQ: WFS filtering), e.g. a
PropertyIsGreaterThan filter on beginLifespanVersion.At discovery time the wrapper probes each WFS service to determine which lookup method it supports. Services that advertise the standard stored query receive:
…?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature &STOREDQUERY_ID=urn:ogc:def:query:OGC-WFS::GetFeatureById &ID=FI_AU_ADMINISTRATIVEUNIT_COUNTRY_FI
All other services receive the standard RESOURCEID parameter instead.
Several upstream services cannot handle either request, each for a different reason:
RESOURCEID request and require a
TYPENAMES parameter alongside it. Known cases: Lower Saxony ATKIS
WFS (inspire.niedersachsen.de), GeoDanmark FKG
(geofa.geodanmark.dk), and ArcGIS Server WFS endpoints
(e.g. geoserveis.icgc.cat/servei/…).
The feature ID often encodes the type name but the wrapper does not currently
extract it automatically.RESOURCEID.
Known case: Greek environment portal (geoportal.ypen.gr).inspire.brandenburg.de/services/tn_bdlm_wfs).mapy.geoportal.gov.pl) explicitly warns
“No featureid defined for typename” for every feature type.fid-* hashes as
gml:id values cannot be queried by ID across sessions.
Known case: Catalonia ICGC GeoServer (geoserveis.icgc.cat/geoserver/ows).wfs.geonorge.no/skwms1/wfs.stedsnavn)
accepts the request but returns an empty FeatureCollection regardless of ID.http://inspire.ec.europa.eu/schemas/hy-p/4.0#length),
GeoNovum, or standard RDF predicates (rdf:type,
owl:sameAs, …) for SPARQL results.
Full URI keys are shown as their local name (the part after # or the last
/); clicking opens the definition. CURIE-style keys such as
rdf:type expand to their full URI and link likewise.rdf:type/wfs/vocab/hy-p/4.0#Watercourse for INSPIRE).
For SPARQL DESCRIBE results the
type URI from the upstream RDF graph is shown directly.identifier<gml:identifier> in the GML response. Its value is the
canonical persistent URI for the feature (e.g.
https://registry.gdi-de.org/id/de.hh/…). In RDF output this URI appears
as owl:sameAs on the feature's fragment-URI subject.inspireIdinspireId element from each schema namespace (e.g.
hy:inspireId from the HydroBase schema and hy-p:inspireId
from the PhysicalWaters schema). Because the panel label is the local name fragment,
both appear as inspireId. The full property URI (visible on hover)
distinguishes them. Their values are usually identical — both encode the same
localId + namespace pair.
Together with the identifier row (the URI form of the same identifier),
a single INSPIRE feature can show the same persistent identifier three times in different encodings._droppedGeometryTin, Grid,
LinearGrid). The feature is shown without geometry.
The RDF/XML and Turtle outputs carry geometry as a locn:geometry XML literal
containing the raw GML in the upstream coordinate reference system (e.g. EPSG:25832).
The GeoJSON and JSON-LD outputs project all coordinates to WGS 84 and encode the
geometry as a GeoJSON object, so the three representations are not graph-isomorphic.
After loading features, the link area shows an Upstream link pointing directly
to the source service request that produced the result — for example the WFS
GetFeature call.
This lets you inspect or replay the raw upstream response independently of the wrapper.
To protect upstream INSPIRE services from excessive load, rate limiting is in place: each IP address may make 50 requests per 10 minutes. The allowance refills continuously, so after hitting the limit you regain roughly one request every 12 seconds. Requests over the limit receive HTTP status 429.
Registered heavy users can bypass the limit with an API key, sent as an HTTP header:
Authorization: Bearer <your-api-key>
Contact the operator (see below) to request a key.