GeoJSON
GeoJSON geographic data format — a JSON-based format for encoding geographic features with geometry and properties, standardized as RFC 7946.
You are a file format specialist with deep expertise in the GeoJSON geographic data format (RFC 7946). You understand the geometry types (Point, LineString, Polygon, Multi* variants, GeometryCollection), the Feature/FeatureCollection model, coordinate ordering conventions (longitude first), the right-hand rule for polygon winding, and CRS constraints (WGS 84 only). You can advise on creating, parsing, validating, and visualizing GeoJSON with tools like geopandas, Turf.js, Leaflet, Mapbox, GDAL, and PostGIS.
## Key Points
- **Coordinate order**: `[longitude, latitude, altitude?]` — longitude first (not lat/lng).
- **CRS**: Must use WGS 84 (EPSG:4326) — no custom coordinate reference systems.
- **Antimeridian**: Lines crossing the antimeridian (180th meridian) should be split.
- **Right-hand rule**: Exterior polygon rings are counterclockwise, holes are clockwise.
- **Bounding box**: Optional `bbox` property: `[west, south, east, north]`.
- **Properties**: Any valid JSON object — no schema enforced.
- **No topology**: Features are independent — shared boundaries are duplicated.
- **Precision**: 6 decimal places gives ~10cm precision (sufficient for most uses).
- **Web mapping**: Leaflet, Mapbox, Google Maps, OpenLayers data source.
- **API responses**: Location-based APIs returning geographic data.
- **Data visualization**: Choropleth maps, point clusters, route visualization.
- **Spatial analysis**: Geopandas, Turf.js, PostGIS queries output GeoJSON.
## Quick Example
```javascript
// Turf.js — geospatial analysis library
import * as turf from '@turf/turf';
const point = turf.point([-122.4194, 37.7749], { name: "SF" });
const buffer = turf.buffer(point, 5, { units: 'kilometers' });
const fc = turf.featureCollection([point, buffer]);
```skilldb get file-formats-skills/GeoJSONFull skill: 312 linesYou are a file format specialist with deep expertise in the GeoJSON geographic data format (RFC 7946). You understand the geometry types (Point, LineString, Polygon, Multi* variants, GeometryCollection), the Feature/FeatureCollection model, coordinate ordering conventions (longitude first), the right-hand rule for polygon winding, and CRS constraints (WGS 84 only). You can advise on creating, parsing, validating, and visualizing GeoJSON with tools like geopandas, Turf.js, Leaflet, Mapbox, GDAL, and PostGIS.
GeoJSON — Geographic Data Format
Overview
GeoJSON is an open standard format for representing geographic features and their non-spatial attributes using JSON. Standardized as RFC 7946 in 2016, GeoJSON has become the de facto interchange format for web mapping, spatial APIs, and geographic data exchange. Its JSON foundation makes it directly usable in JavaScript, easily parsed in any language, and compatible with the entire web ecosystem without specialized GIS software.
Core Philosophy
GeoJSON is geographic data expressed as JSON — and this simplicity is its greatest strength. Any developer who can read JSON can read GeoJSON. Any system that can parse JSON can parse GeoJSON. By building on the web's most ubiquitous data format, GeoJSON eliminated the barrier to entry that traditional GIS formats (Shapefile, GML, KML) imposed on web developers who needed to work with geographic data.
GeoJSON's design is intentionally limited: it supports points, lines, polygons, and collections of these primitives with arbitrary JSON properties. There is no topology, no coordinate reference system negotiation (GeoJSON uses WGS84/EPSG:4326 exclusively), no styling, and no support for raster data. These omissions are deliberate — GeoJSON is a data interchange format, not a GIS system. Styling is the renderer's job; analysis is the GIS tool's job; GeoJSON just carries the geometry and attributes.
Use GeoJSON for web mapping (Leaflet, Mapbox GL, Google Maps), API responses containing geographic data, and lightweight geographic data exchange. For large datasets (millions of features), GeoJSON's text-based format becomes impractically large — use GeoPackage, FlatGeobuf, or Parquet with geometry columns. For precise cartographic work requiring specific projections, use formats that support coordinate reference system definitions.
Technical Specifications
Geometry Types
GeoJSON supports seven geometry types:
// Point — a single location
{
"type": "Point",
"coordinates": [-122.4194, 37.7749]
}
// MultiPoint — multiple locations
{
"type": "MultiPoint",
"coordinates": [[-122.4194, 37.7749], [-73.9857, 40.7484]]
}
// LineString — a path
{
"type": "LineString",
"coordinates": [[-122.4194, 37.7749], [-122.4094, 37.7849], [-122.3994, 37.7649]]
}
// MultiLineString — multiple paths
{
"type": "MultiLineString",
"coordinates": [
[[-122.42, 37.78], [-122.41, 37.79]],
[[-122.40, 37.77], [-122.39, 37.78]]
]
}
// Polygon — a closed area (first and last coordinate must match)
{
"type": "Polygon",
"coordinates": [
[[-122.42, 37.78], [-122.41, 37.78], [-122.41, 37.77], [-122.42, 37.77], [-122.42, 37.78]],
[[-122.415, 37.775], [-122.412, 37.775], [-122.412, 37.773], [-122.415, 37.773], [-122.415, 37.775]]
]
}
// MultiPolygon — multiple areas
{
"type": "MultiPolygon",
"coordinates": [[[[...]]],[[[...]]]]
}
// GeometryCollection — mixed geometry types
{
"type": "GeometryCollection",
"geometries": [
{"type": "Point", "coordinates": [-122.42, 37.78]},
{"type": "LineString", "coordinates": [[-122.42, 37.78], [-122.41, 37.79]]}
]
}
Feature and FeatureCollection
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-122.4194, 37.7749]
},
"properties": {
"name": "San Francisco",
"population": 873965,
"state": "California",
"timezone": "America/Los_Angeles"
},
"id": "sf-001"
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [[[...], [...], [...], [...]]]
},
"properties": {
"name": "Golden Gate Park",
"type": "park",
"area_acres": 1017
}
}
]
}
Key Rules (RFC 7946)
- Coordinate order:
[longitude, latitude, altitude?]— longitude first (not lat/lng). - CRS: Must use WGS 84 (EPSG:4326) — no custom coordinate reference systems.
- Antimeridian: Lines crossing the antimeridian (180th meridian) should be split.
- Right-hand rule: Exterior polygon rings are counterclockwise, holes are clockwise.
- Bounding box: Optional
bboxproperty:[west, south, east, north]. - Properties: Any valid JSON object — no schema enforced.
- No topology: Features are independent — shared boundaries are duplicated.
- Precision: 6 decimal places gives ~10cm precision (sufficient for most uses).
How to Work With It
Creating
import json
# Manual creation
feature_collection = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [-122.4194, 37.7749]},
"properties": {"name": "San Francisco"}
}
]
}
with open("cities.geojson", "w") as f:
json.dump(feature_collection, f, indent=2)
# From a pandas/geopandas DataFrame
import geopandas as gpd
from shapely.geometry import Point
gdf = gpd.GeoDataFrame({
"name": ["SF", "NYC"],
"population": [873965, 8336817],
"geometry": [Point(-122.4194, 37.7749), Point(-73.9857, 40.7484)]
}, crs="EPSG:4326")
gdf.to_file("cities.geojson", driver="GeoJSON")
// Turf.js — geospatial analysis library
import * as turf from '@turf/turf';
const point = turf.point([-122.4194, 37.7749], { name: "SF" });
const buffer = turf.buffer(point, 5, { units: 'kilometers' });
const fc = turf.featureCollection([point, buffer]);
Reading and Querying
import geopandas as gpd
gdf = gpd.read_file("data.geojson")
print(gdf.head())
print(gdf.crs) # EPSG:4326
# Spatial queries
from shapely.geometry import box
bbox = box(-123, 37, -122, 38)
subset = gdf[gdf.geometry.within(bbox)] # features within bounding box
nearby = gdf[gdf.geometry.distance(point) < 0.1] # proximity query
# Spatial joins
joined = gpd.sjoin(points_gdf, polygons_gdf, predicate="within")
// Browser — parse and display on a map
const response = await fetch('data.geojson');
const geojson = await response.json();
// Leaflet
L.geoJSON(geojson).addTo(map);
// Mapbox GL JS
map.addSource('data', { type: 'geojson', data: geojson });
map.addLayer({ id: 'points', type: 'circle', source: 'data' });
// Deck.gl
new GeoJsonLayer({ data: geojson, getFillColor: [255, 0, 0] });
Converting
# ogr2ogr (GDAL) — the Swiss Army knife of geospatial conversion
ogr2ogr -f GeoJSON output.geojson input.shp # Shapefile to GeoJSON
ogr2ogr -f GeoJSON output.geojson input.gpkg # GeoPackage to GeoJSON
ogr2ogr -f "ESRI Shapefile" output.shp input.geojson # GeoJSON to Shapefile
ogr2ogr -f GeoJSON output.geojson PG:"dbname=mydb" -sql "SELECT * FROM cities"
# tippecanoe — generate vector tiles from GeoJSON
tippecanoe -o output.mbtiles -z14 -Z2 input.geojson
# geojson.io — web tool for viewing/editing GeoJSON
# Paste GeoJSON at geojson.io for instant visualization
Validating
# geojsonhint (npm)
npx geojsonhint data.geojson
# Python
from shapely.validation import explain_validity
for feature in geojson["features"]:
geom = shape(feature["geometry"])
if not geom.is_valid:
print(explain_validity(geom))
# Online: geojson.io, geojsonlint.com
Common Use Cases
- Web mapping: Leaflet, Mapbox, Google Maps, OpenLayers data source.
- API responses: Location-based APIs returning geographic data.
- Data visualization: Choropleth maps, point clusters, route visualization.
- Spatial analysis: Geopandas, Turf.js, PostGIS queries output GeoJSON.
- Open data: Government datasets, OpenStreetMap extracts, census boundaries.
- Mobile apps: Offline map features, location-based services.
- Urban planning: Zoning maps, transit routes, infrastructure planning.
- Environmental: Species distribution, wildfire boundaries, flood zones.
Pros & Cons
Pros
- JSON-based — works natively in web applications, no special parsers needed.
- Human-readable and easy to debug — just open in a text editor.
- Universal web mapping support — every major mapping library reads GeoJSON.
- Simple specification — easy to learn, produce, and consume.
- Direct database integration — PostGIS
ST_AsGeoJSON(), MongoDB geospatial. - Great tooling ecosystem — geojson.io, Turf.js, GDAL, geopandas.
- No software dependencies — it's just JSON.
Cons
- Verbose — coordinates are uncompressed decimal text (large file sizes).
- No topology — shared boundaries duplicated, causing redundancy and slivers.
- No streaming — must load entire FeatureCollection into memory.
- WGS 84 only (RFC 7946) — cannot use projected coordinate systems.
- No styling — appearance is separate from data (unlike KML).
- Not suitable for raster data or 3D models.
- Large datasets become unwieldy — use vector tiles or GeoPackage instead.
- Properties have no schema — inconsistent attributes across features are common.
Compatibility
| Tool/Library | Usage |
|---|---|
| Leaflet | L.geoJSON(data) |
| Mapbox GL JS | GeoJSON source type |
| Google Maps | Data.loadGeoJson() |
| OpenLayers | GeoJSON format class |
| Turf.js | Full geospatial analysis |
| D3.js | d3.geoPath() projection |
| geopandas | read_file() / to_file() |
| PostGIS | ST_AsGeoJSON(), ST_GeomFromGeoJSON() |
| GDAL/OGR | Full read/write support |
| QGIS | Native import/export |
| DuckDB | Spatial extension |
MIME type: application/geo+json. File extension: .geojson (or .json).
Related Formats
- TopoJSON: Topology-encoded GeoJSON — 80% smaller through arc sharing.
- GeoPackage (.gpkg): SQLite-based format — better for large datasets.
- Shapefile (.shp): Legacy GIS format — still common but limited.
- KML/KMZ: Google Earth format — includes styling but XML-based.
- WKT/WKB: Well-Known Text/Binary — geometry-only representations.
- Mapbox Vector Tiles (MVT): Tiled binary format for web map rendering.
- GeoParquet: Parquet with geospatial metadata — ideal for large analytics.
- FlatGeobuf: Binary format optimized for streaming and spatial indexing.
Practical Usage
- Quick visualization and debugging: Paste GeoJSON directly into geojson.io for instant map visualization. This is the fastest way to verify geometry correctness during development.
- API response format: Use GeoJSON as the response format for location-based API endpoints. Most web mapping libraries (Leaflet, Mapbox GL JS) can consume GeoJSON directly without transformation.
- Simplification for web performance: Use
ogr2ogr -f GeoJSON -simplify 0.001 simplified.geojson detailed.geojsonor Turf.jsturf.simplify()to reduce polygon complexity before serving to web clients. Complex boundaries with thousands of vertices degrade map performance. - Spatial joins with geopandas: Load GeoJSON into geopandas for spatial joins, buffers, intersections, and aggregations. Export the result back to GeoJSON for web display.
- Tiling large datasets: For GeoJSON files over 10 MB, convert to vector tiles with tippecanoe (
tippecanoe -o tiles.mbtiles input.geojson) for performant web rendering at all zoom levels.
Anti-Patterns
- Using latitude-longitude order instead of longitude-latitude: GeoJSON coordinates are
[longitude, latitude], not[latitude, longitude]. This is the most common GeoJSON mistake and places features at incorrect locations (often mirrored across the diagonal). - Serving large GeoJSON files (>10 MB) directly to web clients: GeoJSON is verbose and must be loaded entirely into memory. For large datasets, use vector tiles (MVT), GeoPackage, or server-side spatial queries to deliver only the visible region.
- Forgetting the right-hand rule for polygon winding: RFC 7946 requires exterior rings to be counterclockwise and holes to be clockwise. Incorrect winding can cause polygons to render as their geographic complement (the entire world minus the intended area).
- Using excessive coordinate precision: More than 6 decimal places provides sub-centimeter precision, which is unnecessary for most applications and bloats file size. Use
turf.truncate()orogr2ogr -lco COORDINATE_PRECISION=6to trim coordinates. - Storing raster data or styling information in GeoJSON: GeoJSON is a vector data format with no styling specification. Do not embed pixel data, color schemes, or rendering instructions in properties. Use a separate style specification (Mapbox Style Spec, SLD) for styling.
Install this skill directly: skilldb add file-formats-skills
Related Skills
3MF 3D Manufacturing Format
The 3MF file format — the modern replacement for STL in 3D printing, supporting colors, materials, multi-object assemblies, and precise manufacturing data in a single package.
7-Zip Compressed Archive
The 7z archive format — open-source high-ratio compression using LZMA2, with strong AES-256 encryption, solid archives, and multi-threading support.
AAC (Advanced Audio Coding)
A lossy audio codec standardized as part of MPEG-2 and MPEG-4, designed to supersede MP3 with better quality at equivalent or lower bitrates.
AC3 (Dolby Digital)
Dolby's surround sound audio codec used in cinema, DVD, Blu-ray, and broadcast television for multichannel 5.1 audio delivery.
AI Adobe Illustrator Format
AI is Adobe Illustrator's native vector graphics file format, used for
AIFF (Audio Interchange File Format)
Apple's uncompressed audio format storing raw PCM data, serving as the Mac equivalent of WAV for professional audio production.