# Rijnland water authority geoservices (ArcGIS REST)

The ArcGIS server of the Rijnland water authority, hosted by a supplier (enl-mcs.nl). Almost every service is one type of managed asset: valves, culverts, pumping stations, weirs, watercourses, flood defences. On 16 October 2026 our index held 230 layers; the current register of structures alone has 57,032 features and the watercourses 187,861 line segments. Rijnland is not listed as a publisher on data.overheid.nl or in the National Georegister, so this is the only public entry point. On reuse, Rijnland itself says it is not allowed without permission; we only show descriptions and counts.

- Publisher: Hoogheemraadschap van Rijnland
- Area: Netherlands · Finest detail: feature (Rijnland management area)
- Period: actuele stand, plus oude momentopnamen (EFM2020, EFM2021, KPI2020) · Refreshed: yearly
- Access: Open · Licence: niet open (volgens Rijnland zelf; alleen metadata in de index)
- Join keys: dienst + laagnaam, CODE (objectcode van Rijnland), OBJECTID, RD-coördinaten (EPSG:28992)
- Status: grijs · 128 diensten in 10 mappen · ArcGIS 12.1
- URL: https://rijnland.enl-mcs.nl/arcgis/rest/services

## What can you do with it?
- **What does a water authority actually manage?.** The register of structures counts 34,159 culverts, 15,337 bridges, 2,602 weirs and 468 pumping stations. One statistics call shows how many assets lie behind a region's water management.
- **Read the definitions.** Most services carry a description with the definition of the asset (what is a culvert, a valve). Useful as a glossary for a story about water.
- **Current versus draft.** The Leggers folder has the current register and the draft for consultation side by side (surface water, structures, regional flood defences). Compare the two to see what the authority wants to change.

## How to process it
1. **Browse by folder.** The root holds the current assets (usually one layer per service); Leggers the legal registers; folders with a year are old snapshots.
   `https://rijnland.enl-mcs.nl/arcgis/rest/services/Leggers?f=json`
2. **Count by type.** Statistics work: a single call returns the number per type of structure.
   `https://rijnland.enl-mcs.nl/arcgis/rest/services/Leggers/Legger_kunstwerkenVigerend/MapServer/0/query?where=1%3D1&outStatistics=%5B%7B%22statisticType%22%3A%22count%22%2C%22onStatisticField%22%3A%22OBJECTID%22%2C%22outStatisticFieldName%22%3A%22n%22%7D%5D&groupByFieldsForStatistics=KUNSTWERKTYPE&orderByFields=n%20DESC&f=json`
3. **Look at a few features.** With outSR=4326 and f=geojson. maxRecordCount is usually 1,000; keep it to a few features as long as the licence is not open.
   `https://rijnland.enl-mcs.nl/arcgis/rest/services/Leggers/Legger_kunstwerkenVigerend/MapServer/0/query?where=KUNSTWERKTYPE%3D%27Gemaal%27&outFields=CODE,NAAM,KUNSTWERKTYPE&outSR=4326&resultRecordCount=5&f=geojson`
4. **Just the count.** returnCountOnly gives the number of features in a layer without downloading anything.
   `https://rijnland.enl-mcs.nl/arcgis/rest/services/Watergang_as/MapServer/0/query?where=1%3D1&returnCountOnly=true&f=json`

## Interesting combinations
- How high are the flood defences? → [ahn](https://www.opendataindex.nl/en/bron/ahn.md) via coördinaten. Overlay the regional flood defences on the AHN elevation model and read the crest height.
- Where flooding risk and pumping stations meet → [klimaateffectatlas](https://www.opendataindex.nl/en/bron/klimaateffectatlas.md) via geometrie. Put the pumping stations and watercourses next to the flooding maps from the Klimaateffectatlas.

## Similar sources
- [Andere waterschappen in het Nationaal Georegister](https://www.nationaalgeoregister.nl/geonetwork/srv/dut/catalog.search#/search?any=legger): Many water authorities publish their register as WMS/WFS with metadata and licence in the NGR; Rijnland does not.
- [rws-waterinfo](https://www.opendataindex.nl/en/bron/rws-waterinfo.md): Water level and discharge measurements in national waters; no water authority assets.

## What to watch out for
- **Not open according to Rijnland.** Two of these services are also items in Rijnland's ArcGIS Online. There it says: copying or sharing materials is not allowed without prior permission. It is the only statement on reuse; ask permission before you publish.
- **Old snapshots next to current layers.** Folders such as EFM2020, EFM2021, KPI2020 and WBP6 hold old versions (e.g. Regionale kering en zone 2018). Choose deliberately; layers carry no dates.
- **Test services.** Pilot_data_portaal_afvalwaterketen is labelled 'Data portaal - test' on the server itself (waste water systems of Alphen aan den Rijn, Bodegraven-Reeuwijk and Waddinxveen). Do not use it as an official source.
- **Server at a supplier.** The address (rijnland.enl-mcs.nl) belongs to a supplier, not to Rijnland itself, and may change with a new contract.

## API (ArcGIS REST)

- Base: https://rijnland.enl-mcs.nl/arcgis/rest/services
- Access: No key or token: the directory and all calls below worked anonymously. (tested)
- Formats: json, geojson, pbf, png (export, WMS)
- Size: 234 leaf layers in 128 queryable services (206 unique names) (tested)
- Filtering: SQL-like where clause on the layer's fields, plus an optional spatial filter (geometry). Group and count with outStatistics.; =, <>, >, >=, <, <=, LIKE, IN, IS NULL, BETWEEN, AND, OR, NOT

### Endpoints
- `GET ?f=json`: Directory: version, folders and services (name + type).
- `GET /{map}?f=json`: Services in one folder.
- `GET /{dienst}/MapServer?f=json`: Service: layers and tables (id, name, group layer or not), maxRecordCount, capabilities, projection, description.
- `GET /{dienst}/MapServer/{laag}?f=json`: Layer: fields (name, type, alias, length), geometry type, maxRecordCount, supportedQueryFormats and advancedQueryCapabilities (pagination, statistics, orderBy, distinct).
- `GET /{dienst}/MapServer/{laag}/query`: Query features with a where clause or spatial filter; also count (returnCountOnly) and group (outStatistics). Response in JSON, GeoJSON or PBF.
- `GET /{dienst}/MapServer/legend?f=json`: Legend per layer: labels and symbols (PNG as base64).
- `GET /{dienst}/MapServer/export?bbox=…&bboxSR=4326&size=600,400&format=png&f=image`: Map image as PNG for a rectangle; with f=json you get a link to the image. Without bbox: error 'bbox must be specified'.
- `GET https://rijnland.enl-mcs.nl/arcgis/services/{map}/{dienst}/MapServer/WMSServer?request=GetCapabilities&service=WMS`: WMS 1.3.0 of the same MapServer: path without /rest/ and with /WMSServer. Only for services whose supportedExtensions lists WMSServer.

### Parameters
- `where`: Condition in SQL-92 style: 1=1 for everything, text in single quotes (GEMEENTE='Zwolle'), LIKE with %, AND/OR, dates as DATE 'YYYY-MM-DD'. Required when there is no other filter. (tested)
- `outFields`: Fields in the response, comma-separated, or * for all fields. (tested)
- `returnGeometry`: false = attributes only (much smaller response). (tested)
- `outSR`: Projection of the geometry in the response; 4326 = degrees (WGS84). Default is the layer's projection, here RD (28992). (tested)
- `f`: Format: json (Esri JSON), geojson, pbf (protobuf), pjson (indented) or html (browse in the browser). (tested)
- `resultOffset`: Pagination: number of features to skip (from 0). Use together with orderByFields for a stable order. (tested)
- `resultRecordCount`: Maximum number of features in this response (capped at the layer's maxRecordCount). (tested)
- `orderByFields`: Sort order, e.g. 'OBJECTID' or 'n DESC' (also on a statistics field). (tested)
- `returnCountOnly`: true = only the number of features matching where: {"count": …}. (tested)
- `outStatistics`: Server-side statistics: list of {statisticType, onStatisticField, outStatisticFieldName}; statisticType count, sum, min, max, avg, stddev or var. URL-encode it. (tested)
- `groupByFieldsForStatistics`: Fields to group by with outStatistics (like GROUP BY). (tested)
- `returnDistinctValues`: true with outFields and returnGeometry=false: the unique values of those fields. (tested)
- `geometry`: Spatial filter: a point 'x,y' or envelope 'xmin,ymin,xmax,ymax', with geometryType (esriGeometryPoint, esriGeometryEnvelope), inSR (input projection), spatialRel (esriSpatialRelIntersects) and optionally distance + units (esriSRUnit_Meter) for a radius. (platform)

### Fields of the example layer (10)
`OBJECTID` OID, `CODE` String, `NAAM` String, `KUNSTWERKTYPE` String, `STATUSOBJECT` String, `HOOFDFUNCTIE` String, `BEDIENING` String, `GEWOONONDERHOUD` String, `STATUSLEGGER` String, `OBJECTBEGINTIJD` Date

### Limits and pitfalls
- At most 1.000 (meestal; 29 diensten 2.000) features per response (the layer's maxRecordCount; varies per layer, see /{layer}?f=json). If there are more, the response has exceededTransferLimit: true: fetch the rest with resultOffset and resultRecordCount. (tested)
- No key and no documented rate limit. Take it easy (a few requests per second) and prefer statistics or counts over fetching all features. (experience)
- Regarding reuse, Rijnland states in its ArcGIS Online items that copying or sharing without prior permission is not allowed. The API works anonymously, but ask for permission before publishing data; counts and descriptions are safe. (experience)
- ArcGIS Server 12.1, the newest of the servers in our index. Almost every service is one kind of managed asset (valves, culverts, pumping stations, watercourses) with a meaningful service description. (tested)
- Folders with a year (EFM2020, EFM2021, KPI2020, WBP6) are old snapshots; Leggers/…Vigerend is the current state. (experience)
- Errors come back with HTTP 200 and a JSON object {"error": {"code": 400, …}} ('Failed to execute query.' for an unknown field in where). Always check for an error field, not just the status code. (tested)
- The server gives no modification date per service or layer (no editingInfo). How current a layer is, is not stated. (tested)
- Group layers (with subLayerIds) have no query; query the leaf layers below them. Raster layers have no fields and no count. (platform)

### Example
```
https://rijnland.enl-mcs.nl/arcgis/rest/services/Leggers/Legger_kunstwerkenVigerend/MapServer/0/query?where=1%3D1&outStatistics=%5B%7B%22statisticType%22%3A%22count%22%2C%22onStatisticField%22%3A%22OBJECTID%22%2C%22outStatisticFieldName%22%3A%22n%22%7D%5D&groupByFieldsForStatistics=KUNSTWERKTYPE&orderByFields=n%20DESC&f=json
```

## How to fetch it

### curl
```bash
curl "https://rijnland.enl-mcs.nl/arcgis/rest/services/Leggers/Legger_kunstwerkenVigerend/MapServer/0/query?where=1%3D1&returnCountOnly=true&f=json"
```

### python
```python
import requests

laag = "https://rijnland.enl-mcs.nl/arcgis/rest/services/Leggers/Legger_kunstwerkenVigerend/MapServer/0/query"
stat = '[{"statisticType":"count","onStatisticField":"OBJECTID","outStatisticFieldName":"n"}]'
r = requests.get(laag, params={"where": "1=1", "outStatistics": stat,
                               "groupByFieldsForStatistics": "KUNSTWERKTYPE", "f": "json"})
for f in r.json()["features"]:
    a = f["attributes"]
    print(a["KUNSTWERKTYPE"], a.get("n", a.get("N")))  # de naam van het telveld verschilt per server
```

## Who uses it
- [Hoogheemraadschap van Rijnland](https://www.rijnland.net): Maps and registers on the water authority's own website


## What is in it: 230 map layers

All services and layers on this ArcGIS server, fetched every night. Every layer has its own page with fields, geometry and a query call.

- Kinds: kaartlaag 224, raster 6
- With an API call on the dataset page: 230
- Search: https://www.opendataindex.nl/api/catalogus/arcgis-rijnland?q=… or the MCP function zoek_datasets with herkomst=arcgis-rijnland
- Every row has its own page: https://www.opendataindex.nl/en/dataset/arcgis-rijnland/<key>

### Folders
- Afrastering (1)
- Afrastering (1)
- Afwateringseenheid (1)
- Aquaduct (1)
- Bebouwde kom (1)
- Boezemgebied (1)
- Bouwwerk (1)
- Bruggen in HHR (1)
- Collectie Waterstaatswerken archief (1)
- Contour (1)
- Coupure (1)
- Data portaal - test (42)
- Dijkverbetering (1)
- Duiker punt (1)
- Duingebied (1)
- Effluent gemaal (1)
- EFM2020 (2): Regionale kering en zone 2018 (2)
- EFM2021 (5): AWZIs binnen het gebied van HHR (1), Map (1), Map (1), Rioolgemaal (influent) (1), Transportleidingsegment (1)
- Gebied (5): Grens Rijnland formeel (1), Grens Rijnland formeel mask (1), Grens Rijnland Inspire (1), Map (2)
- Gemaal (1)
- Gemaal (1)
- Gemeente (1)
- Indeling watergebiedsplannen (1)
- Individuele Behandeling Afvalwater (1)
- Individuele Behandeling Afvalwater (1)
- Inlaat (1)
- InlaatRijnland (1)
- Inspectieput (1)
- Installatie (1)
- Kadastraal perceel Rijnland Kadaster (1)
- Kader Richtlijn Water gebieden (4)
- KPI2020 (47): 14 Biodiversiteit (3), Aanpak wateroverlast (1), Dijkverbetering (1), Peilbesluitgebied overzicht (1), Peilgebied vigerend besluit (1), Verbeterinstallatie (1), WBP6FABRICationsVisiekaart (39)
- Kunstwerk dam (1)
- Kunstwerk Duiker (1)
- Legger regionale kering vigerend (1)
- Leggers (28): Legger kunstwerken Inspraak (3), Legger kunstwerkenVigerend (3), Legger Oppervlaktewater inspraak (5), Legger Oppervlaktewater Vigerend (5), Legger Primaire Kering Vigerend (4), Legger regionale kering inspraak (2), Legger regionale kering vigerend (5), Map (1)
- Lozingspunt (1)
- Map (1)
- Map (1)
- Map (1)
- … and 59 more folders

## Examples with real figures (1)

For each example the finding, the reference date and the call that fetches exactly these figures.

- **Structures in Rijnland's current register by type: most culverts (34,159 structures), then bridges and weirs** (november 2026). Table https://rijnland.enl-mcs.nl/arcgis/rest/services/Leggers/Legger_kunstwerkenVigerend/MapServer/0. [Example](https://www.opendataindex.nl/en/voorbeeld/geoservices-rijnland-kunstwerken)
  - `https://rijnland.enl-mcs.nl/arcgis/rest/services/Leggers/Legger_kunstwerkenVigerend/MapServer/0/query?where=1%3D1&outStatistics=%5B%7B%22statisticType%22%3A%22count%22%2C%22onStatisticField%22%3A%22OBJECTID%22%2C%22outStatisticFieldName%22%3A%22n%22%7D%5D&groupByFieldsForStatistics=KUNSTWERKTYPE&orderByFields=n%20DESC&f=json`
  - `https://rijnland.enl-mcs.nl/arcgis/rest/services/Leggers/Legger_kunstwerkenVigerend/MapServer/0/query?where=1%3D1&returnCountOnly=true&f=json`
