Skip to content
Historical Gazetteers & Place Data

To publish place data as GeoJSON well, write valid RFC 7946 with coordinates in longitude/latitude order, WGS84 only, a stable identifier on every feature, and a documented convention for any historical dates — then validate before release. The most damaging mistake by far is reversing longitude and latitude, which silently relocates your entire collection. This checklist keeps a whole collection consistent, documented and defensible rather than one file that happens to render.

What is the one bug that breaks most GeoJSON?

Coordinate order. GeoJSON stores [longitude, latitude] — the reverse of how almost everyone says or writes coordinates. Swap them and Exeter (50.7°N, 3.5°W) lands in the Arabian Sea. Build a guard into your export so this can never ship:

python
def assert_lonlat(features):
    for f in features:
        lon, lat = f["geometry"]["coordinates"][:2]
        assert -180 <= lon <= 180 and -90 <= lat <= 90, f"bad order: {lon},{lat}"
        # for UK data, sanity-check the bounding box
        assert -11 <= lon <= 2 and 49 <= lat <= 61, f"outside GB: {lon},{lat}"

The second assertion — a domain bounding box — catches reversals that the first misses, because a swapped 50.7/-3.5 still passes the global range check.

Which CRS and coordinate precision should I use?

RFC 7946 mandates WGS84 in decimal degrees, longitude/latitude. Do not attach a custom crs member (it was removed from the modern spec); reproject other systems to WGS84 first. For precision, round to about six decimal places.

Decimal placesApprox. precisionUse
4~11 mcoarse place points
5~1.1 mmost place data
6~0.1 mprecise features
7+< 0.1 mfalse precision — avoid

Six decimals is plenty for place data and trims file size; storing fifteen digits implies a precision your sources never had.

How do I structure features for a place collection?

Each feature gets a stable id, used both as the GeoJSON id and inside properties so consumers can link back to your gazetteer.

json
{
  "type": "Feature",
  "id": "places:Exeter",
  "geometry": { "type": "Point", "coordinates": [-3.5339, 50.7184] },
  "properties": {
    "pid": "places:Exeter",
    "name": "Exeter",
    "ftype": "settlement",
    "start": "0050",
    "end": "",
    "uncertainty_m": 200,
    "source": "GBHGIS 2024"
  }
}

Keeping pid in properties as well as the top-level id is deliberate: some tools drop the id member on import, and you do not want the identifier to vanish.

How should historical dates go in GeoJSON?

Plain GeoJSON has no time field, so adopt a convention and document it. ISO 8601 start/end strings in properties cover most needs; for richer temporal modelling — multiple when-spans, fuzzy dates — switch to Linked Places Format, which extends GeoJSON precisely for this. Whatever you choose, write it in the README so a consumer never has to guess whether start is a year or a full date.

How do I keep a large file usable?

For a few thousand features, one FeatureCollection is fine. Beyond that, round coordinates, drop unused properties, and consider newline-delimited GeoJSON (one feature per line) for streaming, or vector tiles for web maps. A 200 MB GeoJSON that locks the browser helps nobody; tiling or NDJSON keeps it responsive.

How do I validate before publishing?

Never publish unvalidated. Run three checks every release:

bash
# structural + geometry validation
npx geojsonhint places.geojson
# or
geojson-validate places.geojson

Then open the file in a viewer (geojson.io, QGIS, or a Leaflet preview) and eyeball it — reversed coordinates and self-intersecting polygons are obvious to the eye and invisible in a diff. Make validation a release gate, not an afterthought.

Key Takeaways

  • GeoJSON is [longitude, latitude]; guard every export with a domain bounding-box check.
  • Use WGS84 only (RFC 7946); reproject other systems and never add a custom crs member.
  • Round to about six decimal places — more digits imply false precision.
  • Put a stable identifier in both the feature id and properties so it cannot be lost on import.
  • Document a date convention (ISO start/end) or adopt Linked Places Format for rich time models.
  • Validate structurally and visually as a release gate, every single time.

Frequently Asked Questions

What coordinate order does GeoJSON use?

GeoJSON uses longitude then latitude — the opposite of how people usually say coordinates aloud. Reversing the two is the single most common GeoJSON bug, putting English places in the Arabian Sea.

Which coordinate reference system must GeoJSON use?

The GeoJSON specification (RFC 7946) mandates WGS84, written as longitude/latitude in decimal degrees. Reproject any other CRS to WGS84 before publishing; do not add a custom crs member.

How should I include a stable identifier in GeoJSON?

Put a persistent identifier in each feature's properties and, ideally, use it as the feature 'id' member too. This lets consumers link your places back to a gazetteer or authority file.

How do I keep a large GeoJSON file usable?

Round coordinates to about six decimal places, consider newline-delimited GeoJSON or vector tiles for very large sets, and validate before release. Six decimals is roughly 0.1 m precision, ample for place data.

Should historical dates go in GeoJSON properties?

Yes, but use a clear convention such as ISO 8601 start/end fields, or adopt Linked Places Format if your temporal model is rich. Plain GeoJSON has no native time field, so document whatever you choose.

How do I validate GeoJSON before publishing?

Run it through a schema validator and a geometry checker such as geojsonhint or geojson-validate, and open it in a map viewer to eyeball the result. Validation catches reversed coordinates and broken geometries before users do.