Waterways
National Philippines rivers, streams, canals, lakes, and related water features, derived from the HOT OSM / HDX Philippines waterways export.
This is OSM-derived volunteer mapping for maps and overlays — not NAMRIA cadastral hydrography and not a navigation chart. Completeness varies by region.
Illustration of the layer list and map chrome. Live maps use signed PMTiles (HOT OSM), not this static outline. Keep © OpenStreetMap contributors on every map.
| License | ODbL — keep © OpenStreetMap contributors on every map |
| Source of truth | PostGIS (gis.waterways_*). PMTiles are a simplified paint derivative |
| Auth | API key required to list layers and mint a paint session. Range tile requests use a short-lived signed URL, not the API key |
Waterways are not a GeoJSON list of rivers. You mint a signed PMTiles URL and the map library Range-fetches tiles (HTTP 206).
Request access if you do not have a key yet.
Layers
Section titled “Layers”| Slug | Geometry | Typical content |
|---|---|---|
ph_waterways_lines | lines | Rivers, streams, canals, drains |
ph_waterways_polygons | polygons | Lakes, reservoirs, wetlands, water bodies |
ph_waterways_points | points | Springs and other waterway points |
Use these slugs with the tiles endpoints. MapLibre source-layer is the same as the slug.
How paint works
Section titled “How paint works”Your app + API key → POST /v1/tiles/sessions { "slug": "ph_waterways_lines" } ← signed pmtiles:// URL (exp + HMAC)
MapLibre → HTTP Range GETs on /tiles/pmtiles/ph_waterways_lines?exp=&sig= → Worker serves tiles from private storage (206)The Worker does not query PostGIS for each map tile. Rebuilds from PostGIS to PMTiles are an offline job, not a public API.
Sample calls and output
Section titled “Sample calls and output”All /v1/tiles* calls need Authorization: Bearer $API_KEY. Without a key, production returns 401.
1. List layers
Section titled “1. List layers”curl -sS https://api.gis.ph/v1/tiles \ -H "Authorization: Bearer $API_KEY"{ "data": [ { "slug": "ph_waterways_lines", "title": "PH Waterways (lines)", "open_access": false, "paint_path": "/tiles/pmtiles/ph_waterways_lines" }, { "slug": "ph_waterways_polygons", "title": "PH Waterways (polygons)", "open_access": false, "paint_path": "/tiles/pmtiles/ph_waterways_polygons" }, { "slug": "ph_waterways_points", "title": "PH Waterways (points)", "open_access": false, "paint_path": "/tiles/pmtiles/ph_waterways_points" } ], "error": null}The array can include other allowlisted layers (for example LULC). Find the ph_waterways_* slugs in data[].slug.
Unauthenticated:
{"message":"Unauthorized"}2. Mint a waterways session
Section titled “2. Mint a waterways session”This is the call an app uses.
curl -sS -X POST https://api.gis.ph/v1/tiles/sessions \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"slug":"ph_waterways_lines","ttl_seconds":3600}'{ "data": { "slug": "ph_waterways_lines", "url": "https://api.gis.ph/tiles/pmtiles/ph_waterways_lines?exp=1724380000&sig=…", "path": "/tiles/pmtiles/ph_waterways_lines?exp=1724380000&sig=…", "maplibre_url": "pmtiles://https://api.gis.ph/tiles/pmtiles/ph_waterways_lines?exp=1724380000&sig=…", "exp": 1724380000, "expires_at": "2026-08-23T01:32:00.000Z", "ttl_seconds": 3600 }, "error": null}Pass data.maplibre_url to MapLibre. That is the client output — not a FeatureCollection of rivers.
- Default TTL is 3600 seconds (min 60, max 86400).
- Re-mint before
expires_at, or when Range requests start returning 401. - Unknown slug → 404. Missing key → 401. Signing not configured → 503.
3. Range paint (what the map does next)
Section titled “3. Range paint (what the map does next)”GET /tiles/pmtiles/:slug?exp=&sig=
curl -sS -D - -o /dev/null \ -H "Range: bytes=0-16383" \ "$URL_FROM_SESSION"206 + binary PMTiles bytes (Content-Type: application/vnd.pmtiles). No JSON geometries.
| Status | Meaning |
|---|---|
| 401 | Missing/invalid key, or expired/bad exp/sig |
| 404 | Unknown slug, or object missing in storage |
| 403 | GET without Range (full-file download is disabled) |
| 206 | Tile / header bytes |
/tmp/:slug is a deprecated alias of the same handler — use /tiles/pmtiles/:slug.
MapLibre
Section titled “MapLibre”Register the pmtiles protocol, then use data.maplibre_url from the session.
import maplibregl from "maplibre-gl";import { Protocol } from "pmtiles";
const protocol = new Protocol();maplibregl.addProtocol("pmtiles", protocol.tile);
const session = await fetch("https://api.gis.ph/v1/tiles/sessions", { method: "POST", headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ slug: "ph_waterways_lines", ttl_seconds: 3600 }),}).then((r) => r.json());
map.addSource("waterways", { type: "vector", url: session.data.maplibre_url, attribution: "© OpenStreetMap contributors",});
map.addLayer({ id: "waterways-line", type: "line", source: "waterways", "source-layer": "ph_waterways_lines", paint: { "line-color": "#3b82f6", "line-width": 1.25 },});Polygons: slug ph_waterways_polygons, layer type fill. Points: slug ph_waterways_points, layer type circle.
Do not put a long-lived API key in a public webpage. Mint sessions from your backend, or use a restricted key and still treat it as a secret.
Attribution and caveats
Section titled “Attribution and caveats”- Show © OpenStreetMap contributors (ODbL) on the map.
- Data is crowd-sourced; gaps and tagging errors are expected.
- Snapshot is a HOT export (refresh is operational, not a client-facing version pin today).
- Geometry in tiles is simplified for paint. Server-side “waterways near X” queries are not this endpoint.