๐ฆพ Turf.js & Exporting to GeoJSON
My users can place markers, circles, polygons and polylines on the map. I'd like to store these in a geospatial database that expects them in the โGeoJSON formatโ. What is GeoJSON and how do I convert the user-generated Google Maps shapes to GeoJSON?
As a JavaScript developer, you're already be familiar with JavaScript Object Notation (JSON). After all, you already saw it in action when we discussed the .toJSON() method in the chapter on ๐ Markers, Lines, & Shapes .
JSON is human readable, predictable, and easily serializable. It powers RESTful APIs and, at the end of the day, lets you interact with this handbook.
Now, GeoJSON is a popular JSON-based open standard used for encoding geographic data structures. It's standardized, lightweight, and based on the same coordinate system adopted by Google Maps .
In Google Maps, coordinates pairs always declare the respective coordinate type, i.e.:
const coordinates = { lat: 40.6419, lng: -73.9921 }; GeoJSON is a bit more efficient. It drops the lat / lng keywords and works exclusively with arrays:
const coordinates = [-73.9921, 40.6419]; Notice that the longitude comes before the latitude.
In a way, this makes sense โ longitude corresponds to the x axis, latitude to y.
Coordinate positions of the form [longitude, latitude] are the basic building blocks of all GeoJSON geometries. Each geometry must specify its type. Here are the geometries we'll be using:
A
Pointgeometry{ "type": "Point", "coordinates": [-73.9921, 40.6419] }A
LineStringgeometry{ "type": "LineString", "coordinates": [ [-73.9921, 40.6419], [-73.8921, 40.6419] ] }A
Polygongeometry. Notice that unlike Google Maps polygons , GeoJSON polygons must form a closed loop โ i.e. the first and last coordinate pairs must be equal.{ "type": "Polygon", "coordinates": [ [ [-73.9921, 40.7563], [-73.9949, 40.7562], ... [-73.9921, 40.7563] ] ] }
Now, while the above geometries are already valid GeoJSON objects, you're likely to see them out there as part of a larger collection. The simplest such collection is the GeometryCollection:
{
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [-73.9921, 40.6419]
},
{
"type": "LineString",
"coordinates": [
[-73.9921, 40.6419],
[-73.8921, 40.6419]
]
}
]
} That's neat, but just like markers , geographic objects often contain more data than just their raw coordinates โ think object names & IDs, date created & modified, background & stroke colors and so on.
Put another way, how do we elegantly associate GeoJSON geometries with metadata? Enter:
A GeoJSON feature is an object of type Feature that is associated with a geometry and a set of JSON properties:
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-73.9921, 40.6419]
},
"properties": {
"id": "bacb28a2-e1b5-11ed-b5ea-0242ac120002",
"title": "Marker 1",
"svgIcon": "data:image/svg+xml;utf-8,%0A%3Csvg..."
...
}
} The properties may be an empty object {} or null but they must be defined.
Note that while the GeoJSON standard allows an id on the root level, it's good practice to keep it inside the properties โ where it belongs .
Also, while it's technically possible to include foreign keys on the root level, it's worthwhile not to pollute the Feature syntax with them.