Simple GIS API for districts, municipalities and parishes (Portugal-style codes). See working version here
src/- application sourcesrc/index.js- server bootstrap and route registrationsrc/api/- API controllersDocsController.js- Open API documentation endpointGisController.js- GIS endpoints (districts, municipalities, parishes, limits, gps)CountryController.js- country information endpointDangerController.js- danger/risk endpoints (fire and flood hazards)WeatherController.js- weather endpoint (uses OpenWeatherMap)FarmacyController.js- pharmacies endpoint (get all pharmacies for a municipality)ZipCodeController.js- postal code lookup
src/helpers/db.js- database helpersutils/- utilities to optimize datacodigos-postais.js- update latitude and longitude of a road in codigos_postais table
swagger/- OpenAPI specsswagger.yaml- main OpenAPI spec
- Node.js (v16+ recommended)
- A running PostgreSQL instance with PostGIS (optional for local testing of GIS endpoints)
Open a terminal in the project root and run:
npm installCreate a .env file (or set environment variables) with:
GEOCODING_API_KEY="your google geocode api key"
WEATHER_API_KEY="your openweather api key"
DB_HOST=127.0.0.1
DB_PORT=5432
DB_NAME=dbgis
DB_USER=dbgis_usr
DB_PASSWORD=passwordnpm run devThis runs the server (default configured in src/index.js). If the server fails to start, check the console for the error and ensure required env vars and DB are available.
A minimal Swagger UI is served from /docs and points at swagger/swagger.yaml by default. You can also open the raw YAML at /swagger.yaml.
To validate the OpenAPI spec locally, run:
npx @apidevtools/swagger-cli validate .\swagger\gis-swagger.yaml(If you prefer a single combined spec, swagger/swagger.yaml has been trimmed to contain only the GIS endpoints.)
GET /api/gis/distritos— list districtsGET /api/gis/distrito/{dtmnfr}— get district by 2-digit codeGET /api/gis/distrito/{dtmnfr}/municipios— municipalities in districtGET /api/gis/distrito/{dtmnfr}/limites— GeoJSON limits for districtGET /api/gis/municipio/{dtmnfr}— get municipality by 4-digit codeGET /api/gis/municipio/{dtmnfr}/freguesia— parishes in municipalityGET /api/gis/municipio/{dtmnfr}/limites— GeoJSON limits for municipalityGET /api/gis/freguesia/{dtmnfr}— get parish by 6-digit codeGET /api/gis/freguesia/{dtmnfr}/limites— GeoJSON limits for parishGET /api/gis/gps?lat={lat}&lng={lng}— find parish containing coordinates
GET /api/gis/pais/portugal— get country information for Portugal including districts
GET /api/perigos/incendios?lat={lat}&lng={lng}— get fire danger/risk level for coordinatesGET /api/perigos/inundacoes?lat={lat}&lng={lng}— get flood/inundation risk level for coordinates
- The GIS endpoints depend on PostGIS queries — if your DB is not populated or PostGIS is not available, responses may be empty or errors will be returned.
WeatherControllerandZipCodeControllerexist insrc/api/but the mainswagger/swagger.yamlhas been trimmed to reflect only the GIS routes per your request. If you'd like them re-added to the spec or to the/docsUI, tell me and I will reintroduce them.
- Create a branch
- Make changes
- Run tests (if added)
- Open a PR