Skip to main content
Documentation Menu(GeoJSON Developer)
Developer Reference Guide

Philippine GIS & GeoJSON Integration Guide

A technical developer manual covering spatial coordinate projections, RFC 7946 GeoJSON schemas, TopoJSON simplification, and Turf.js spatial join algorithms for Philippine maps.

1. Philippine Coordinate Reference Systems (CRS)

Geographic coordinate data in the Philippines is published using two distinct reference frameworks. Web mapping engines and mobile GPS sensors operate in WGS 84, while official cadastral surveys, land titles, and municipal boundary delineations by the National Mapping and Resource Information Authority (NAMRIA) use the Philippine Reference System of 1992 (PRS92).

WGS 84 (EPSG:4326): Web Standard

The global standard coordinate system used by web mapping libraries including Mapbox GL JS, Leaflet, Turf.js, and OpenLayers. Coordinates are expressed in decimal degrees (for example, Latitude 14.5995° N, Longitude 120.9842° E). All mapaPH GeoJSON and TopoJSON assets use EPSG:4326 with longitude preceding latitude as required by RFC 7946.

PRS92 (EPSG:3121 to 3125): Cadastral

Philippine Reference System 1992, established by Executive Order No. 45 series of 1993. Used by NAMRIA and the Department of Environment and Natural Resources (DENR) for official land titling and cadastral surveys across 5 Philippine Transverse Mercator (PTM) zones. Coordinates are expressed in grid meters (Northing and Easting). Requires datum transformation before rendering in browser maps.

Datum transformation note: Transforming coordinates between PRS92 and WGS 84 requires a 7-parameter Molodensky-Badekas or Bursa-Wolf Helmert transformation. Using a simple spherical projection creates positional offsets between 50 meters and 120 meters on ground coordinates, which causes coastal features to display in open sea.

2. mapaPH RFC 7946 GeoJSON Feature Schema

Boundary GeoJSON files exported from mapaPH tools comply with the Internet Engineering Task Force (IETF) RFC 7946 standard. Every administrative polygon contains standard properties aligned with the Philippine Standard Geographic Code (PSGC) published quarterly by the Philippine Statistics Authority (PSA).

{
  "type": "FeatureCollection",
  "name": "philippine_municipalities_2024",
  "crs": {
    "type": "name",
    "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" }
  },
  "features": [
    {
      "type": "Feature",
      "id": "037114000",
      "properties": {
        "psgc": "037114000",
        "psgc10": "0307114000",
        "name": "Subic",
        "level": "Municipality",
        "province": "Zambales",
        "provincePsgc": "037100000",
        "region": "Central Luzon",
        "regionCode": "03",
        "incomeClass": "1st",
        "population2020": 111912,
        "landAreaSqKm": 287.16
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [120.2312, 14.8814],
            [120.2451, 14.8923],
            [120.2684, 14.8752],
            [120.2312, 14.8814]
          ]
        ]
      }
    }
  ]
}

RFC 7946 Compliance Rules

  • Axis order: Coordinates are always stored as [longitude, latitude, elevation]. Longitude ranges from 116.0° E to 127.0° E; latitude ranges from 4.5° N to 21.5° N.
  • Winding order (Right-hand rule): Exterior polygon boundary rings run counter-clockwise. Interior boundary rings representing land enclaves or water bodies run clockwise.
  • Coordinate decimal precision: Six decimal places (0.000001°) provides approximately 0.11 meters (11 centimeters) ground precision at Philippine latitudes. Exporting beyond six decimal places increases JSON payload size without adding genuine surveying resolution.
  • Archipelagic MultiPolygons: Philippine coastal provinces and island municipalities (such as Palawan, Romblon, Batanes, and Sulu) must use MultiPolygon geometries to avoid self-intersecting lines between discrete islands.

3. Client-Side Spatial Queries with Turf.js

To identify which Philippine province, city, or municipality contains a GPS position recorded from a delivery vehicle, mobile application, or field sensor, execute point-in-polygon queries client-side using Turf.js.

import * as turf from '@turf/turf';

// Point coordinate: Kilometer Zero (KM 0), Luneta Park, Manila
// Turf expects coordinates as [longitude, latitude]
const sensorPoint = turf.point([120.9787, 14.5826]);

/**
 * Identifies the administrative unit containing the coordinate.
 * Bounding-box pre-filtering runs first to skip distant polygons in O(1) time.
 */
export function findContainingBoundary(point, featureCollection) {
  const ptCoord = point.geometry.coordinates;

  for (const feature of featureCollection.features) {
    // 1. Fast bounding-box pre-check
    const bbox = turf.bbox(feature);
    if (
      ptCoord[0] < bbox[0] || ptCoord[0] > bbox[2] ||
      ptCoord[1] < bbox[1] || ptCoord[1] > bbox[3]
    ) {
      continue;
    }

    // 2. Exact ray-casting point-in-polygon test
    if (turf.booleanPointInPolygon(point, feature)) {
      return {
        psgc: feature.properties.psgc,
        name: feature.properties.name,
        province: feature.properties.province,
        region: feature.properties.region
      };
    }
  }

  return null;
}

Performance Optimization for 1,642 Municipalities

Iterating through 1,642 municipal MultiPolygons using raw turf.booleanPointInPolygon takes between 250 milliseconds and 600 milliseconds on mobile processors. Pre-computing bounding boxes using turf.bbox() and filtering coordinates before running the ray-casting algorithm reduces query latency to under 4 milliseconds per coordinate.

4. TopoJSON Arc-Sharing and Web Optimization

A raw GeoJSON file containing all 1,642 Philippine cities and municipalities with high-resolution coastlines exceeds 45 megabytes. Distributing this volume of JSON over cellular connections causes substantial browser parsing pauses. Converting to TopoJSON reduces transfer size by over 85 percent through topological arc sharing.

Raw GeoJSON

~48.5 MB

Every shared municipal border coordinate is duplicated in both adjacent polygons. High memory consumption.

TopoJSON (Quantized)

~3.8 MB

Shared borders are encoded once as indexed arcs. Float coordinates quantized into integer delta grids.

TopoJSON + Brotli

~820 KB

Compressed network payload suitable for mobile devices and instant offline caching via service workers.

Command-Line Conversion with Mapshaper

The open-source Mapshaper CLI tool enables automated simplification while preserving topological adjacency without generating sliver gaps or overlapping polygons:

# 1. Install Mapshaper CLI
npm install -g mapshaper

# 2. Simplify municipal boundaries to 15% detail using Visvalingam weighting
# -clean fixes self-intersections; -filter-islands removes sub-pixel micro-islands
mapshaper ph_municipalities_raw.geojson \
  -clean \
  -simplify dp 15% keep-shapes \
  -filter-islands min-area=50000m2 \
  -o format=topojson precision=0.0001 ph_municipalities_optimized.topojson

5. Reprojecting NAMRIA Shapefiles to WGS 84 via GDAL

When ingesting official cadastral files or land zoning shapefiles from NAMRIA, the DENR Land Management Bureau, or local city planning offices, the input vectors are typically projected in PRS92 Philippine Transverse Mercator (PTM) Zones I through V. Use the Geospatial Data Abstraction Library (GDAL/OGR) to transform these layers into WGS 84 GeoJSON:

# Transform PRS92 Zone III (Metro Manila / Central Luzon, EPSG:3123) to WGS 84 (EPSG:4326)
ogr2ogr -f "GeoJSON" \
  -s_srs "EPSG:3123" \
  -t_srs "EPSG:4326" \
  -lco COORDINATE_PRECISION=6 \
  manila_zoning_wgs84.geojson \
  manila_zoning_prs92.shp

EPSG Codes for Philippine Zones

  • EPSG:3121: PRS92 / PTM Zone I (Palawan, 117° E)
  • EPSG:3122: PRS92 / PTM Zone II (Western Luzon, 119° E)
  • EPSG:3123: PRS92 / PTM Zone III (Metro Manila, 121° E)
  • EPSG:3124: PRS92 / PTM Zone IV (Bicol / Eastern Visayas, 123° E)
  • EPSG:3125: PRS92 / PTM Zone V (Mindanao, 125° E)

Common Ingestion Checklist

  • Verify input projection file (.prj) exists in Shapefile directory.
  • Confirm coordinates fall within 116° E to 127° E longitude.
  • Set string encoding to UTF-8 to preserve ñ characters in town names.
  • Verify polygon winding order before importing into spatial databases.