GeoJSON
GeoJSON is a geospatial data interchange format based on JavaScript Object Notation (JSON) that enables the encoding of geographic data structures, including geometries, features with associated properties, and collections of features.[1] It supports a set of geometry types derived from the OpenGIS Simple Features specification, such as Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, and GeometryCollection, allowing representation of simple spatial features like points, lines, and areas.[1] Coordinates in GeoJSON are expressed in the World Geodetic System 1984 (WGS 84) reference system using decimal degrees, with longitude preceding latitude and an optional altitude value in meters.[1]
The format originated in open-source geospatial communities around 2007, with an initial specification published in 2008 by a group of developers to provide a lightweight, text-based alternative for web-based mapping and data exchange.[2] It gained popularity for its simplicity and compatibility with JSON, which is widely used in web applications, APIs, and databases.[3] In 2016, GeoJSON was formalized as an Internet standard by the Internet Engineering Task Force (IETF) through RFC 7946, developed by the GeoJSON Working Group to ensure interoperability and prevent extensions that could fragment implementations.[1] This standardization replaced the earlier informal specification and emphasized adherence to core types without introducing new geometry classes.[1]
Key aspects of GeoJSON include its use of Feature objects to bundle a geometry with non-spatial attributes in a properties member, and FeatureCollection objects to group multiple features, facilitating the representation of complex datasets like maps or spatial analyses.[1] The format's design prioritizes human-readability and machine-parsability, making it suitable for applications in web mapping libraries, geographic information systems (GIS), and data visualization tools.[3] Implementations must handle antimeridian crossings by splitting geometries where necessary, ensuring global coverage without distortion.[1] Since its standardization, GeoJSON has become a de facto standard for open geospatial data on the web, supported by major platforms and libraries.[3]
Introduction
Definition and Purpose
GeoJSON is an open standard format for encoding a variety of geographic data structures using JavaScript Object Notation (JSON). It defines JSON objects and conventions for representing simple geographical features—such as points, lines, and polygons—along with their non-spatial attributes, enabling the serialization of geospatial information in a lightweight, text-based manner.[1]
The primary purpose of GeoJSON is to serve as a geospatial data interchange format, facilitating the sharing and integration of geographic data across systems, particularly in web applications where JavaScript's native support for JSON allows for straightforward parsing and manipulation without requiring specialized software. This design promotes interoperability in geographic information systems (GIS) and mapping contexts by avoiding proprietary formats, making it accessible for developers to overlay features on maps or process spatial data in APIs and databases.[1][4]
At its core, GeoJSON employs the World Geodetic System 1984 (WGS 84) datum, corresponding to EPSG:4326, as the default coordinate reference system, with coordinates specified as decimal degrees in the order of longitude first, followed by latitude. This standardization ensures consistent representation of positions on Earth's surface, aligning with common practices in web mapping and GPS technologies.[1]
GeoJSON builds directly on the JSON data interchange format defined in RFC 8259, leveraging its simplicity and universality to address broader needs for geospatial data exchange in open web environments.[1][5]
Key Characteristics
GeoJSON is designed as a simple, human-readable text format based on JavaScript Object Notation (JSON), which facilitates easy generation, parsing, and transmission of geospatial data without requiring binary encoding.[1] This textual nature makes it particularly suitable for web-based applications, where it can be directly embedded in documents or exchanged via HTTP without additional processing.[1]
The format is self-describing, incorporating metadata such as the "bbox" member to define the bounding box of coordinates, which aids in efficient spatial indexing and rendering.[1] It also supports foreign members—additional key-value pairs outside the core specification—to include extensions or application-specific data while preserving interoperability.[1]
GeoJSON has deliberate limitations to maintain simplicity, supporting only two-dimensional geometries and explicitly discouraging positions with more than three elements (longitude, latitude, and optionally altitude, though altitude is not semantically interpreted).[1] It does not encode topology, measured geometries, or higher-dimensional data, focusing instead on basic point, line, and polygon representations.[1] By default, coordinates are interpreted in the WGS84 coordinate reference system using decimal degrees.[1]
Extensibility is achieved through the allowance of custom properties in Feature objects and foreign members at any level, enabling developers to add non-standard attributes without violating core compliance, provided they do not conflict with reserved names.[1]
GeoJSON files typically use the .geojson or .json extensions, with the registered MIME type application/geo+json for internet media exchange.[1]
History
Development
The development of GeoJSON originated in March 2007, when a group of developers including Howard Butler, Martin Daly, Allan Doyle, Sean Gillies, Tim Schaub, and Christopher Schmidt established a dedicated mailing list to coordinate efforts on creating a standardized format for geographic data interchange.[6] The initiative emerged from informal discussions in open-source communities, such as IRC channels for projects like OpenLayers and GDAL, where the need for a simple, parsable representation of geospatial information became evident.[7]
The primary motivation was to develop a lightweight, human-readable alternative to verbose XML-based formats like Geography Markup Language (GML) and Keyhole Markup Language (KML), which were cumbersome for web-based applications relying on JavaScript.[8] This format aimed to leverage the growing popularity of JSON for efficient data exchange in browser environments, enabling easier integration with web mapping tools without requiring heavy parsing libraries.[9]
By June 2008, the group released the GeoJSON 1.0 specification, which outlined core elements such as geometry objects for points, lines, and polygons, along with basic feature encoding to associate properties with spatial data.[10] This early version emphasized simplicity and adherence to JSON syntax rules, setting the foundation for broader adoption.[11]
The project progressed through open-source collaboration, with contributions from GIS professionals, web developers, and technologists via the mailing list and integrations in libraries like OpenLayers, fostering iterative refinements based on practical use cases in geospatial software.[12]
Standardization
GeoJSON was formally standardized by the Internet Engineering Task Force (IETF) through the Geographic JSON Working Group, culminating in the publication of RFC 7946 in August 2016.[1] This RFC, authored by Howard Butler, Martin Daly, Allan Doyle, Sean Gillies, Stefan Hagen, and Tim Schaub, obsoleted the informal 2008 GeoJSON specification and established a precise, interoperable format for encoding geographic data structures using JavaScript Object Notation (JSON).[1]
The RFC introduced several key refinements to enhance consistency and usability. It clarified coordinate reference system (CRS) handling by deprecating the optional "crs" member from the 2008 specification and mandating the World Geodetic System 1984 (WGS 84) as the default and sole supported CRS, with coordinates expressed as longitude and latitude in decimal degrees.[13] Additionally, it provided guidelines on coordinate precision, recommending at least six decimal places to maintain accuracy in calculations, while limiting position arrays to a maximum of three elements (longitude, latitude, and optional elevation) to simplify parsing and avoid ambiguity.[14]
Following the core specification, RFC 8142 was published in April 2017 to address streaming and large-scale data needs.[15] Authored by Sean Gillies, this document defines the GeoJSON text sequence format (media type "application/geo+json-seq"), which allows sequences of GeoJSON objects separated by record separators and line feeds, enabling incremental parsing of arbitrarily large datasets without requiring a single, monolithic JSON structure.[15] Maintenance of the standard has since been handled through the geojson.org website, which serves as the central resource for the specification and community discussions.[3]
As of 2025, GeoJSON remains a stable Internet Standard with no major revisions or new RFCs issued since 2017, reflecting its maturity and widespread adoption in geospatial applications, libraries, and web services.[1][15][3]
Specification
Object Model
GeoJSON documents consist of a single top-level JSON object that adheres to the specifications outlined in RFC 8259 for JavaScript Object Notation (JSON).[16] This object must include a required member named "type", whose value indicates one of three primary top-level types: a Geometry object, a Feature object, or a FeatureCollection object.[17] These types form the core hierarchy of GeoJSON, enabling the representation of spatial data ranging from simple geometric primitives to collections of spatially associated entities.[17]
All coordinate values within GeoJSON objects are expressed as double-precision floating-point numbers, ensuring precise representation of positions in a two- or three-dimensional coordinate reference system.[13] Optional members may be included at the top level, such as "bbox", which defines a bounding box as an array of the form [west, south, east, north] for two-dimensional data (or extended for higher dimensions).[18] This bounding box provides a spatial extent for the represented data, facilitating efficient querying and rendering. The Geometry type serves as the foundational element, with its "type" value specifying subtypes such as Point or Polygon (detailed further in the Geometry Types section). For unlocated or undefined positions, use a Feature object with "geometry": null; Geometry objects require a "coordinates" member as an array (empty arrays may be interpreted as empty or null geometries by some processors).[19][20] This model ensures GeoJSON's interoperability across geospatial applications while maintaining simplicity and extensibility through JSON's structure.[16]
Geometry Types
GeoJSON supports a set of geometry primitives that represent spatial features in a hierarchical structure based on the JSON format. These geometries are defined using positions, which are arrays of two or three numbers representing coordinates in the WGS 84 spatial reference system; any additional elements beyond three are ignored. A position consists of a longitude (first element, in decimal degrees), a latitude (second element, in decimal degrees), and an optional altitude (third element, in meters above the ellipsoid if present); when altitude is omitted, the geometry is treated as two-dimensional.[14][13]
The basic geometry types include Point, LineString, and Polygon, which form the foundation for more complex structures like MultiPoint, MultiLineString, MultiPolygon, and GeometryCollection. Each geometry object is a JSON object with a "type" member specifying its kind and a "coordinates" member holding the position data in a nested array format. These types adhere to the Simple Features specification for geometry representation, ensuring interoperability with geographic information systems.[17]
A Point geometry represents a single position in space. Its "coordinates" member is simply a position array, such as [100.0, 0.0] for a location at longitude 100 degrees east and latitude 0 degrees. Points are the atomic building blocks for other geometries and cannot contain nested structures.[21]
A LineString geometry consists of an array of two or more positions that define a continuous line. The "coordinates" member is thus an array of position arrays, for example, [[100.0, 0.0], [101.0, 1.0]], connecting the specified points in sequence without interpolation between them. LineStrings must have at least two distinct positions to form a valid line; degenerate cases with repeated positions are permitted but represent zero-length segments.[22]
A Polygon geometry delineates a surface area enclosed by linear rings. The "coordinates" member is an array of arrays of positions, where the first element is the exterior ring (oriented counterclockwise) and subsequent elements, if any, are interior rings representing holes (oriented clockwise). Each linear ring must contain at least four positions, with the first and last positions identical to close the ring automatically. For instance, a simple polygon without holes might use [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]]] as coordinates. Polygons follow the right-hand rule for orientation, and linear rings crossing the antimeridian require splitting into multiple rings or using MultiPolygon.[23]
MultiPoint, MultiLineString, and MultiPolygon extend the base types by aggregating multiple instances. A MultiPoint geometry's "coordinates" is an array of positions, such as [[100.0, 0.0], [101.0, 1.0]], representing disconnected points. A MultiLineString has an array of LineString coordinate arrays, allowing disjoint lines, while a MultiPolygon contains an array of Polygon coordinate arrays for separate polygonal areas. These multi-types support at least one component geometry, enabling representation of complex, non-contiguous features without nesting the same type recursively.[24][22][23]
The GeometryCollection type allows heterogeneous combinations of the above geometries in a single object. Its "coordinates" member is replaced by a "geometries" member, an array of geometry objects (each with its own "type" and coordinates), such as a mix of Point and LineString. Nesting is supported recursively, but collections of the same geometry type (e.g., multiple Points) should use MultiPoint instead for efficiency, and deep nesting is discouraged to avoid complexity. GeometryCollections provide flexibility for representing compound spatial entities.[25]
Feature and FeatureCollection
A GeoJSON Feature object represents a spatially located entity, combining a geometry with associated attributes to model real-world features such as points of interest or boundaries. It must include a member named "type" with the value "Feature", a "geometry" member that holds a Geometry object or null for features without location, and a "properties" member containing a JSON object for attributes or null if none are present.[20] An optional "id" member may be included as a string or number to uniquely identify the feature when applicable.[20]
Features are designed to be self-contained and idempotent units, encapsulating all necessary spatial and descriptive data for independent processing without reliance on external context.[20] This structure allows features to be extracted, modified, or analyzed individually while maintaining their integrity.
A GeoJSON FeatureCollection object serves as a container for multiple features, enabling the representation of datasets with many entities. It requires a "type" member set to "FeatureCollection" and a "features" member that is a JSON array of Feature objects, which may be empty to denote an absent dataset.[26] An optional "bbox" member can specify a bounding box as an array of coordinates enclosing all features in the collection, typically in the format [west, south, east, north] for 2D data.[18]
Like individual features, each element in a FeatureCollection is self-contained, supporting modular operations such as filtering or rendering subsets of the data.[26] The following example illustrates a simple FeatureCollection with two features:
json
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"prop0": "value0"
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[102.0, 0.0], [103.0, 1.0]]
},
"properties": {
"prop0": "value1"
}
}
],
"bbox": [101.0, 0.0, 104.0, 1.0]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.3)
### Properties and Coordinate Reference Systems
In GeoJSON, the properties of a feature are stored as a member named "properties" within a [Feature](/page/Feature) object, which is a JSON object or [null](/page/Null) value containing key-value pairs that hold non-spatial attribute data associated with the feature. These properties can include strings, numbers, booleans, arrays, objects, or null values, allowing flexible representation of [metadata](/page/Metadata) such as names, descriptions, or measurements without embedding coordinate reference system (CRS) information.[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.2)
The coordinate reference system in GeoJSON defaults to the [World Geodetic System](/page/World_Geodetic_System) 1984 (WGS 84) with the CRS84 axis order, where coordinates are expressed as [longitude](/page/Longitude) followed by [latitude](/page/Latitude) in [decimal degrees](/page/Decimal_degrees), and an optional third element for [elevation](/page/Elevation) in meters. RFC 7946 explicitly deprecates the inclusion of an explicit CRS member, as found in earlier specifications, recommending instead that alternative CRS be handled through external context, wrappers, or extensions to maintain [interoperability](/page/Interoperability).[](https://datatracker.ietf.org/doc/html/rfc7946#section-4)[](https://datatracker.ietf.org/doc/html/rfc7946#section-4)
An optional "bbox" member provides a bounding [box](/page/Box) envelope for spatial indexing and extent queries, represented as a flat [array](/page/Array) of 2*n elements (where n is the number of dimensions, typically 2 for [2D](/page/2D)), listing the lower-left (southwest) corner coordinates followed by the upper-right (northeast) corner coordinates in the default CRS. This member can appear in [Geometry](/page/Geometry), [Feature](/page/Feature), or FeatureCollection objects to define the minimum and maximum coordinate ranges.[](https://datatracker.ietf.org/doc/html/rfc7946#section-5)
GeoJSON permits foreign members—additional JSON members beyond the core specification—for extensibility, such as custom attributes or legacy elements like a deprecated "crs" object for non-default projections, though their use is discouraged to avoid reducing compatibility with standard parsers. Implementers are advised to process only recognized members and ignore others to ensure robustness.[](https://datatracker.ietf.org/doc/html/rfc7946#section-6.1)
## Examples
### Geometry Objects
Geometry objects in GeoJSON are the fundamental building blocks for representing spatial data, consisting of a mandatory "type" member specifying the geometry kind and a "coordinates" member containing position arrays in longitude-latitude order (with longitude first). These objects adhere to the Well-Known Text (WKT) for [simple features](/page/Simple_Features), excluding curves and surfaces, and assume a default coordinate reference system of WGS84 (as detailed in the Properties and Coordinate Reference Systems section). An optional "bbox" member may be included as a two-dimensional bounding box array [west, south, east, north] to denote the coordinate range.[](https://datatracker.ietf.org/doc/html/rfc7946#section-3)
A Point geometry represents a single position and requires exactly one coordinate pair.
```json
{
"type": "Point",
"coordinates": [100.0, 0.0]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.2)
A LineString geometry defines a sequence of connected line segments via an array of two or more positions; the first and last positions are not required to match, as rings are not implied here.
```json
{
"type": "LineString",
"coordinates": [[100.0, 0.0], [101.0, 1.0]]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.4)
A [Polygon](/page/Polygon) [geometry](/page/Geometry) delineates an area bounded by linear rings, starting with the exterior ring (counter-clockwise oriented) followed by zero or more interior rings (holes, [clockwise](/page/Clockwise) oriented); each ring consists of four or more positions, with the first and last positions identical to explicitly close the ring; the closing position is repeated at the end.
```json
{
"type": "[Polygon](/page/Polygon)",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
],
[
[100.8, 0.8],
[100.8, 0.2],
[100.2, 0.2],
[100.2, 0.8],
[100.8, 0.8]
]
]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#appendix-A.3)
Multi-geometries aggregate multiple instances of a single geometry type into an array of coordinate sets. For example, a MultiPoint consists of an array of positions.
```json
{
"type": "MultiPoint",
"coordinates": [[100.0, 0.0], [101.0, 1.0]]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.3)
A MultiLineString uses an array of LineString coordinate arrays.
```json
{
"type": "MultiLineString",
"coordinates": [[[100.0, 0.0], [101.0, 1.0]], [[102.0, 2.0], [103.0, 3.0]]]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.5)
A MultiPolygon employs an array of Polygon coordinate arrays.
```json
{
"type": "MultiPolygon",
"coordinates": [[[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]]]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.7)
A GeometryCollection geometry holds an array of heterogeneous geometry objects, enabling mixtures such as points and lines within one structure; though nesting of GeometryCollections is discouraged.
```json
{
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [100.0, 0.0]
},
{
"type": "LineString",
"coordinates": [[101.0, 0.0], [102.0, 1.0]]
}
]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.8)
To illustrate bbox usage, a Point may include it for spatial extent.
```json
{
"type": "Point",
"coordinates": [-100.0, 40.0],
"bbox": [-100.0, 40.0, -100.0, 40.0]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-5)
### Feature Objects
A [Feature](/page/Feature) object in [GeoJSON](/page/GeoJSON) is a [JSON](/page/JSON) object that represents a spatially bounded [entity](/page/Entity), such as a building, [river](/page/River), or administrative [region](/page/Region), combining geometric representation with associated descriptive attributes.[](https://datatracker.ietf.org/doc/html/rfc7946) It must include a member named "type" with the literal string value "Feature", a "geometry" member that references a valid [Geometry](/page/Geometry) object or null, and a "properties" member containing a JSON object of non-spatial attributes.[](https://datatracker.ietf.org/doc/html/rfc7946) Optional members include "id", which provides a [unique identifier](/page/Unique_identifier) as a [string](/page/String) or number, and "bbox", an array defining the bounding box of the feature's coordinates.[](https://datatracker.ietf.org/doc/html/rfc7946) The geometry follows the syntax detailed in the Geometry Objects section, enabling integration of spatial data with properties like names, populations, or other metadata.[](https://datatracker.ietf.org/doc/html/rfc7946)
The following example illustrates a basic Feature object with a Point geometry and simple properties:
```json
{
"type": "Feature",
"id": "example-point",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"name": "Example Location",
"population": 1000
}
}
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"prop0": "value0"
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [[102.0, 0.0], [103.0, 1.0]]
},
"properties": {
"prop0": "value1"
}
}
],
"bbox": [101.0, 0.0, 104.0, 1.0]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.3)
### Properties and Coordinate Reference Systems
In GeoJSON, the properties of a feature are stored as a member named "properties" within a [Feature](/page/Feature) object, which is a JSON object or [null](/page/Null) value containing key-value pairs that hold non-spatial attribute data associated with the feature. These properties can include strings, numbers, booleans, arrays, objects, or null values, allowing flexible representation of [metadata](/page/Metadata) such as names, descriptions, or measurements without embedding coordinate reference system (CRS) information.[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.2)
The coordinate reference system in GeoJSON defaults to the [World Geodetic System](/page/World_Geodetic_System) 1984 (WGS 84) with the CRS84 axis order, where coordinates are expressed as [longitude](/page/Longitude) followed by [latitude](/page/Latitude) in [decimal degrees](/page/Decimal_degrees), and an optional third element for [elevation](/page/Elevation) in meters. RFC 7946 explicitly deprecates the inclusion of an explicit CRS member, as found in earlier specifications, recommending instead that alternative CRS be handled through external context, wrappers, or extensions to maintain [interoperability](/page/Interoperability).[](https://datatracker.ietf.org/doc/html/rfc7946#section-4)[](https://datatracker.ietf.org/doc/html/rfc7946#section-4)
An optional "bbox" member provides a bounding [box](/page/Box) envelope for spatial indexing and extent queries, represented as a flat [array](/page/Array) of 2*n elements (where n is the number of dimensions, typically 2 for [2D](/page/2D)), listing the lower-left (southwest) corner coordinates followed by the upper-right (northeast) corner coordinates in the default CRS. This member can appear in [Geometry](/page/Geometry), [Feature](/page/Feature), or FeatureCollection objects to define the minimum and maximum coordinate ranges.[](https://datatracker.ietf.org/doc/html/rfc7946#section-5)
GeoJSON permits foreign members—additional JSON members beyond the core specification—for extensibility, such as custom attributes or legacy elements like a deprecated "crs" object for non-default projections, though their use is discouraged to avoid reducing compatibility with standard parsers. Implementers are advised to process only recognized members and ignore others to ensure robustness.[](https://datatracker.ietf.org/doc/html/rfc7946#section-6.1)
## Examples
### Geometry Objects
Geometry objects in GeoJSON are the fundamental building blocks for representing spatial data, consisting of a mandatory "type" member specifying the geometry kind and a "coordinates" member containing position arrays in longitude-latitude order (with longitude first). These objects adhere to the Well-Known Text (WKT) for [simple features](/page/Simple_Features), excluding curves and surfaces, and assume a default coordinate reference system of WGS84 (as detailed in the Properties and Coordinate Reference Systems section). An optional "bbox" member may be included as a two-dimensional bounding box array [west, south, east, north] to denote the coordinate range.[](https://datatracker.ietf.org/doc/html/rfc7946#section-3)
A Point geometry represents a single position and requires exactly one coordinate pair.
```json
{
"type": "Point",
"coordinates": [100.0, 0.0]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.2)
A LineString geometry defines a sequence of connected line segments via an array of two or more positions; the first and last positions are not required to match, as rings are not implied here.
```json
{
"type": "LineString",
"coordinates": [[100.0, 0.0], [101.0, 1.0]]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.4)
A [Polygon](/page/Polygon) [geometry](/page/Geometry) delineates an area bounded by linear rings, starting with the exterior ring (counter-clockwise oriented) followed by zero or more interior rings (holes, [clockwise](/page/Clockwise) oriented); each ring consists of four or more positions, with the first and last positions identical to explicitly close the ring; the closing position is repeated at the end.
```json
{
"type": "[Polygon](/page/Polygon)",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
],
[
[100.8, 0.8],
[100.8, 0.2],
[100.2, 0.2],
[100.2, 0.8],
[100.8, 0.8]
]
]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#appendix-A.3)
Multi-geometries aggregate multiple instances of a single geometry type into an array of coordinate sets. For example, a MultiPoint consists of an array of positions.
```json
{
"type": "MultiPoint",
"coordinates": [[100.0, 0.0], [101.0, 1.0]]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.3)
A MultiLineString uses an array of LineString coordinate arrays.
```json
{
"type": "MultiLineString",
"coordinates": [[[100.0, 0.0], [101.0, 1.0]], [[102.0, 2.0], [103.0, 3.0]]]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.5)
A MultiPolygon employs an array of Polygon coordinate arrays.
```json
{
"type": "MultiPolygon",
"coordinates": [[[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]]]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.7)
A GeometryCollection geometry holds an array of heterogeneous geometry objects, enabling mixtures such as points and lines within one structure; though nesting of GeometryCollections is discouraged.
```json
{
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [100.0, 0.0]
},
{
"type": "LineString",
"coordinates": [[101.0, 0.0], [102.0, 1.0]]
}
]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.8)
To illustrate bbox usage, a Point may include it for spatial extent.
```json
{
"type": "Point",
"coordinates": [-100.0, 40.0],
"bbox": [-100.0, 40.0, -100.0, 40.0]
}
```[](https://datatracker.ietf.org/doc/html/rfc7946#section-5)
### Feature Objects
A [Feature](/page/Feature) object in [GeoJSON](/page/GeoJSON) is a [JSON](/page/JSON) object that represents a spatially bounded [entity](/page/Entity), such as a building, [river](/page/River), or administrative [region](/page/Region), combining geometric representation with associated descriptive attributes.[](https://datatracker.ietf.org/doc/html/rfc7946) It must include a member named "type" with the literal string value "Feature", a "geometry" member that references a valid [Geometry](/page/Geometry) object or null, and a "properties" member containing a JSON object of non-spatial attributes.[](https://datatracker.ietf.org/doc/html/rfc7946) Optional members include "id", which provides a [unique identifier](/page/Unique_identifier) as a [string](/page/String) or number, and "bbox", an array defining the bounding box of the feature's coordinates.[](https://datatracker.ietf.org/doc/html/rfc7946) The geometry follows the syntax detailed in the Geometry Objects section, enabling integration of spatial data with properties like names, populations, or other metadata.[](https://datatracker.ietf.org/doc/html/rfc7946)
The following example illustrates a basic Feature object with a Point geometry and simple properties:
```json
{
"type": "Feature",
"id": "example-point",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"name": "Example Location",
"population": 1000
}
}
This structure allows the feature to encapsulate both location and attributes, facilitating applications in mapping and data analysis.[1]
A FeatureCollection object groups multiple Feature objects into an array under a "features" member, providing a container for datasets of related entities; it may also include an optional "bbox" that encompasses all features in the collection.[1] For instance:
json
{
"type": "FeatureCollection",
"bbox": [-180.0, -90.0, 180.0, 90.0],
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"name": "First Location",
"population": 1000
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [103.0, 1.0]
},
"properties": {
"name": "Second Location",
"population": 2000
}
}
]
}
{
"type": "FeatureCollection",
"bbox": [-180.0, -90.0, 180.0, 90.0],
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"name": "First Location",
"population": 1000
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [103.0, 1.0]
},
"properties": {
"name": "Second Location",
"population": 2000
}
}
]
}
This format supports efficient handling of multiple features, such as in web-based geographic information systems.[1]
Features can represent entities without spatial location by using null for the geometry member, preserving properties for non-geometric data like events or abstract concepts.[1] An example is:
json
{
"type": "Feature",
"geometry": null,
"properties": {
"event": "Conference",
"date": "2025-11-09",
"attendees": 500
}
}
{
"type": "Feature",
"geometry": null,
"properties": {
"event": "Conference",
"date": "2025-11-09",
"attendees": 500
}
}
Such null geometry features extend GeoJSON's utility beyond purely spatial contexts.[1]
For more intricate spatial representations, a Feature can incorporate complex geometries like MultiPolygon alongside detailed properties.[1] Consider this example of a national boundary:
json
{
"type": "Feature",
"id": "country-boundary",
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[102.0, 2.0],
[103.0, 2.0],
[103.0, 3.0],
[102.0, 3.0],
[102.0, 2.0]
]
],
[
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
]
]
]
},
"properties": {
"name": "Example Country",
"capital": "Capital City",
"area": 500000,
"population": 50000000
}
}
{
"type": "Feature",
"id": "country-boundary",
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[102.0, 2.0],
[103.0, 2.0],
[103.0, 3.0],
[102.0, 3.0],
[102.0, 2.0]
]
],
[
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
]
]
]
},
"properties": {
"name": "Example Country",
"capital": "Capital City",
"area": 500000,
"population": 50000000
}
}
This demonstrates how Features integrate hierarchical geometries with substantive attributes to model real-world geographic phenomena.[1]
Variants
Newline-delimited GeoJSON
Newline-delimited GeoJSON, also known as GeoJSONSeq or NDJSON applied to GeoJSON, is a streaming format that consists of a sequence of individual GeoJSON objects—such as Features or Geometry objects—each serialized as a single JSON text and separated by newline characters (LF, or \n).[27] This variant enables sequential processing without requiring the entire document to be loaded into memory, making it suitable for handling large datasets incrementally.[28]
The format was standardized in RFC 8142, published in 2017, which defines GeoJSON Text Sequences under the media type application/geo+json-seq.[29] While the RFC primarily specifies the use of an ASCII record separator (RS, 0x1E) followed by a line feed (LF) to delimit objects—allowing compatibility with binary streams and non-text protocols—many implementations and tools adopt a pure newline-delimited approach for simplicity in text-based environments.[29] Each object in the sequence must be a valid GeoJSON text, UTF-8 encoded, and the sequence can mix types like Geometry, Feature, or even FeatureCollection objects, though the latter is less common in streaming contexts.[29]
This format is particularly efficient for use cases involving streaming APIs, real-time data feeds, and big data processing pipelines, where parsing an entire FeatureCollection could be resource-intensive for datasets with tens of thousands or millions of features.[29] Unlike standard GeoJSON, no overarching FeatureCollection wrapper is required; instead, each line represents an independent, self-contained GeoJSON object that can be validated and processed on-the-fly.[27] For validation, tools check that every line parses to a complete GeoJSON object without trailing commas or other JSON array artifacts, ensuring robustness in sequential reading.[30]
For example, a simple newline-delimited GeoJSON file might contain:
{"type":"[Feature](/page/Feature)","properties":{"name":"[Point A](/page/Point_A)"},"geometry":{"type":"Point","coordinates":[-122.4194,37.7749]}}
{"type":"[Feature](/page/Feature)","properties":{"name":"[Point B](/page/Point_B)"},"geometry":{"type":"Point","coordinates":[-122.4194,37.785]}}
{"type":"[Feature](/page/Feature)","properties":{"name":"[Point A](/page/Point_A)"},"geometry":{"type":"Point","coordinates":[-122.4194,37.7749]}}
{"type":"[Feature](/page/Feature)","properties":{"name":"[Point B](/page/Point_B)"},"geometry":{"type":"Point","coordinates":[-122.4194,37.785]}}
This structure facilitates easy appending of new objects and integration with tools like command-line utilities for vector tile generation or database ingestion.[30]
TopoJSON
TopoJSON is an extension of GeoJSON that encodes topology to represent geographic data structures more compactly by sharing line segments known as arcs, rather than duplicating coordinates for adjacent geometries.[31] Developed by Mike Bostock in 2012, it builds on GeoJSON's object model while introducing topological relationships that allow geometries to reference shared boundaries, such as the common edge between two polygons.[32] This approach eliminates redundancy inherent in discrete GeoJSON representations, where borders between features like states or countries are stored multiple times.[33]
The primary benefits of TopoJSON include significantly smaller file sizes, often achieving up to 80% reduction compared to equivalent GeoJSON data through techniques like quantized delta-encoding of coordinates.[31] Additionally, it preserves exact topology, enabling precise spatial operations such as union or simplification without introducing errors from coordinate duplication.[33] These advantages make it particularly useful for web mapping applications where efficient data transfer and topological integrity are critical.
TopoJSON files are typically generated by converting GeoJSON data using command-line tools or libraries, producing a structure that includes an array of arcs (sequences of quantized points), named objects (geometries that reference arcs by index), and an optional transform object for dequantization (specifying scale and translate parameters).[33] For rendering, TopoJSON must be decoded back to GeoJSON or rendered directly by compatible libraries, as it is not backward-compatible with standard GeoJSON parsers.[31] This decoding step is necessary for integration with tools expecting discrete geometries, though it adds a processing overhead.
Implementations and Usage
Software Libraries
Several open-source software libraries provide robust support for reading, writing, and manipulating GeoJSON data across various programming languages, enabling developers to perform spatial operations, validate structures against the RFC 7946 specification, and convert to other formats such as Shapefiles. These libraries are essential for geospatial applications, offering features like geometry validation, coordinate transformations, and integration with broader GIS toolkits.[34]
In JavaScript, Turf.js serves as a modular geospatial analysis engine that processes GeoJSON for operations including buffering, intersection, and distance calculations, with the @turf/turf package receiving over 600,000 weekly downloads on npm as of late 2024, reflecting its widespread adoption in web GIS projects.[35] D3.js facilitates GeoJSON visualization through data-driven graphics, commonly used for rendering maps and choropleths in browsers. Leaflet and OpenLayers provide native GeoJSON support for interactive web mapping, allowing direct loading of FeatureCollections as layers with built-in parsing and rendering capabilities.
Python libraries form a comprehensive ecosystem for GeoJSON handling. GeoPandas extends the pandas DataFrame to geospatial data, supporting GeoJSON read/write operations and spatial joins while integrating with other formats for analysis.[36] Fiona handles input/output for vector data, including GeoJSON, with GeoJSON-like access protocols for efficient file processing and validation against RFC 7946.[37] It often pairs with Shapely, which manipulates GeoJSON geometries for tasks like union and simplification, ensuring compliance with the format's coordinate reference system requirements.
For other languages, GDAL/OGR offers C++-based support with bindings for multiple ecosystems, enabling GeoJSON translation to and from over 80 vector formats, including Shapefiles, and full RFC 7946 compliance for reading and writing Feature objects.[34] In R, the geojsonio package converts data frames, spatial classes, and shapefiles to and from GeoJSON or TopoJSON, facilitating seamless integration in statistical geospatial workflows.[38] Java developers commonly use GeoTools, an open-source GIS toolkit that parses and generates GeoJSON while supporting advanced spatial operations through its data store abstractions.[39] Additionally, simple-features-geojson-java provides lightweight reading and writing of Simple Feature geometries in GeoJSON format.[40]
These libraries collectively underscore GeoJSON's ubiquity in web GIS as of 2025, with JavaScript implementations alone accumulating millions of annual downloads and powering a significant portion of open-source geospatial projects.[35] Common functionalities across them include schema validation per RFC 7946 and bidirectional conversions, promoting interoperability in diverse development environments.
Applications in Web Mapping
GeoJSON serves as a foundational format for web mapping due to its compatibility with JavaScript and web standards, enabling seamless integration into browser-based applications. It can be loaded dynamically using the Fetch API, a native web technology for retrieving resources asynchronously, allowing developers to fetch .geojson files from servers and parse them directly in JavaScript. Once loaded, GeoJSON data is commonly rendered using HTML5 Canvas for performant 2D graphics or SVG for scalable vector illustrations, facilitating the drawing of geographic features like points, lines, and polygons on interactive maps.
Prominent JavaScript mapping libraries provide built-in support for GeoJSON, enhancing its utility in web environments. Leaflet, an open-source library for mobile-friendly interactive maps, uses the L.geoJSON method to create layers from GeoJSON objects, supporting styling, popups, and filtering for features such as polygons and markers.[41] Mapbox GL JS, a WebGL-based library, incorporates GeoJSON sources via its addSource API, enabling efficient rendering of vector data with options for dynamic updates and clustering.[42] Similarly, the ArcGIS Maps SDK for JavaScript includes a GeoJSONLayer class that loads data from URLs or inline objects, mapping GeoJSON geometries to native types for visualization and querying in enterprise web maps.[43]
In practical use cases, GeoJSON powers interactive web maps, such as overlays on OpenStreetMap (OSM) base layers in Leaflet applications, where it displays user-generated geographic data like trails or boundaries.[41] For data visualization, it supports choropleth maps, as demonstrated in Leaflet's population density example, where state polygons are colored by attribute values to highlight regional variations.[44]
GeoJSON's interoperability extends to RESTful APIs and cloud services, streamlining data exchange in web mapping workflows. The Overpass API, which queries OSM data, outputs results in JSON that can be converted to GeoJSON, and tools like Overpass Turbo enable direct export to GeoJSON files for immediate use in web maps.[45][46] For storage and distribution, GeoJSON files are routinely hosted on Amazon S3, leveraging its scalability for serving geospatial data to web applications via public URLs, often in conjunction with Amazon Location Service for optimized map overlays.[47]
Despite its advantages, GeoJSON faces performance challenges in web mapping when handling large files, as parsing and rendering extensive FeatureCollections can lead to browser slowdowns during zooming or panning.[48] Solutions include tiling the data into smaller chunks using libraries like GeoJSON-VT, which slices GeoJSON into vector tiles for on-demand loading, or employing variants such as TopoJSON to reduce file sizes by encoding topologies with shared arcs.[48][31]