GeoJSON is a standardized format for representing geographic data structures based on JSON. There are many great tools for visualizing GeoJSON data. Moreover, this format is good not only in the storage of coordinates of certain points. It, in addition to points, allows you to describe other objects: lines, polygons, collections of objects.
Points - Point objects
GeoJSON point looks like this:{
"type": "Point",
"coordinates": [-80.1347334, 25.7663562]
}
This point represents a park in Miami Beach, Florida, USA. You can easily visualize this point on the map using the geojson.io project .Point on the mapIt is important to note that the coordinate in the property iscoordinates
written in the format[lng, lat]
. Longitude in GeoJSON comes before latitude . This is because longitude represents the east-west direction (axisx
on a typical map), and latitude represents the north-south direction (axisy
on a typical map). GeoJSON authors sought to maintain coordinate orderx, y
.A typical example of using GeoJSON points is geocoding - address translation like "429 Lenox Ave, Miami Beach, FL" to coordinates expressed in longitude and latitude. For example, we use the APIGeocoding Mapbox. To access this API, an HTTP request must be made to the following endpoint:https:
In response, the following code will come:{"type":"FeatureCollection","query":["429","lenox","ave","miami"],"features":[{"id":"address.8052276751051244","type":"Feature","place_type":["address"],"relevance":1,"properties":{"accuracy":"rooftop"},"text":"Lenox Avenue","place_name":"429 Lenox Avenue, Miami Beach, Florida 33139, United States","center":[-80.139145,25.77409],"geometry":{"type":"Point","coordinates":[-80.139145,25.77409]}, ...}
If you look closely at the answer, it turns out that features[0].geometry
in the JSON code it is a GeoJSON point:{"type":"Point","coordinates":[-80.139145,25.77409]}
Visualization of the coordinates of theAPI static maps Mapbox is a great tool for displaying points on maps. Below is a script that decodes the string passed to it and returns the URL to the image that shows the first search result.const axios = require('axios');
async function search(str) {
const geocoderUrl = 'https://api.mapbox.com/geocoding/v5/mapbox.places/' +
encodeURIComponent(str) +
'.json?access_token=' +
'pk.eyJ1IjoibWF0dGZpY2tlIiwiYSI6ImNqNnM2YmFoNzAwcTMzM214NTB1NHdwbnoifQ.Or19S7KmYPHW8YjRz82v6g';
const res = await axios.get(geocoderUrl).then(res => res.data);
const point = res.features[0].geometry;
return 'https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/' +
'pin-l-1+333(' + point.coordinates[0] + ',' + point.coordinates[1] + ')/' +
point.coordinates[0] + ',' + point.coordinates[1] +
',14.25,0,0/600x600/' +
'?access_token=pk.eyJ1IjoibWF0dGZpY2tlIiwiYSI6ImNqNnM2YmFoNzAwcTMzM214NTB1NHdwbnoifQ.Or19S7KmYPHW8YjRz82v6g';
}
search('429 Lenox Ave, Miami Beach').then(res => console.log(res));
An example of visualizing a point on a mapLines - LineString objects
In GeoJSON lines, objects LineString
represent arrays of coordinates that describe a line on a map. The following is a GeoJSON object LineString
representing the approximate border between the states of California and Oregon in the USA:{
"type": "LineString",
"coordinates": [[-124.2, 42], [-120, 42]]
}
Rendering a LineString on a MapLines, using a navigation API like Mapbox , are used to render a step-by-step path between two points. One way to represent a road from a point[-80.139145,25.77409]
(WeWork Miami Beach office) to a point[-80.2752743,25.7938434]
(Miami International Airport) is to use a GeoJSON objectLineString
:{
"type": "LineString",
"coordinates": [
[-80.139153, 25.774281],
[-80.13829, 25.774307],
[-80.142029, 25.774479],
[-80.148438, 25.772148],
[-80.151237, 25.772232],
[-80.172043, 25.78116],
[-80.177322, 25.787195],
[-80.185326, 25.787212],
[-80.189804, 25.785891],
[-80.19268, 25.785954],
[-80.202301, 25.789175],
[-80.207954, 25.788721],
[-80.223, 25.782646],
[-80.231026, 25.78261],
[-80.238007, 25.784889],
[-80.246025, 25.784403],
[-80.249611, 25.785175],
[-80.253166, 25.786049],
[-80.259262, 25.786324],
[-80.264038, 25.786186],
[-80.264221, 25.787256],
[-80.264214, 25.791618],
[-80.264221, 25.792633],
[-80.264069, 25.795443],
[-80.263397, 25.795652],
[-80.263786, 25.794928],
[-80.267723, 25.794926],
[-80.271141, 25.794859],
[-80.273163, 25.795704],
[-80.275009, 25.796482],
[-80.277481, 25.796461],
[-80.278435, 25.795622],
[-80.278061, 25.794088],
[-80.275276, 25.793804]
]
}
Objects LineString
that are some routes can be very complex. The above object, for example, describes a short 15-minute ride. This is how it all looks on the map.Path from one point to anotherHere is a simple script that returns aLineString
representation of the path between 2 points using thedirections
MapboxAPI.const axios = require('axios');
async function directions(fromPt, toPt) {
const fromCoords = fromPt.coordinates.join(',');
const toCoords = toPt.coordinates.join(',');
const directionsUrl = 'https://api.mapbox.com/directions/v5/mapbox/driving/' +
fromCoords + ';' + toCoords + '?' +
'geometries=geojson&' +
'access_token=pk.eyJ1IjoibWF0dGZpY2tlIiwiYSI6ImNqNnM2YmFoNzAwcTMzM214NTB1NHdwbnoifQ.Or19S7KmYPHW8YjRz82v6g';
const res = await axios.get(directionsUrl).then(res => res.data);
return res.routes[0].geometry;
}
const wework = { type: 'Point', coordinates: [-80.139145,25.77409] };
const airport = { type: 'Point', coordinates: [-80.2752743,25.7938434] };
directions(wework, airport).then(res => {
console.log(res);
});
Polygons - Polygon Objects
GeoJSON polygons, objects Polygon
, are used to describe closed areas on maps. These can be areas in the shape of a triangle, square, dodecagon , or any other shape with a fixed number of sides. For example, the following GeoJSON object roughly describes the borders of the state of Colorado in the USA:{
"type": "Polygon",
"coordinates": [[
[-109, 41],
[-102, 41],
[-102, 37],
[-109, 37],
[-109, 41]
]]
}
Visualization of a polygon on a mapGeoJSON polygons can be used to describe very complex shapes. For example, for some time Uber used the only GeoJSON-training ground, which includes all 3 major airports in the San Francisco Bay area.Complex GeoJSON polygonTrue, it should be noted that GeoJSON polygons cannot represent circles and ellipses.What are polygons used for? Usually - to describe geofences . For example, imagine that you work in Uber or in Lyft. You need to show users who book trips from the airport a special screen. In order to do this, you will need to find out if the point from which the trip is ordered is located within the polygon describing the airport (or several airports as in the previous figure).One way to verify that a GeoJSON point is within the polygon is to use the Turpm npm module. The module @turf/boolean-point-in-polygon
allows you to find out if a point is within the polygon.const pointInPolygon = require('@turf/boolean-point-in-polygon').default;
const colorado = {
"type": "Polygon",
"coordinates": [[
[-109, 41],
[-102, 41],
[-102, 37],
[-109, 37],
[-109, 41]
]]
};
const denver = {
"type": "Point",
"coordinates": [-104.9951943, 39.7645187]
};
const sanFrancisco = {
"type": "Point",
"coordinates": [-122.4726194, 37.7577627]
};
console.log(pointInPolygon(denver, colorado));
console.log(pointInPolygon(sanFrancisco, colorado));
The Turf package allows you to find out whether a point is within the polygon using the Node.js. But what if we are interested in obtaining the same information by executing queries to the database? In this case, you should be aware that the built-in MongoDB statement$geoIntersects
supports GeoJSON. Therefore, for example, you can write a query that allows you to find out which US state corresponds to a certain point on the map:const mongoose = require('mongoose');
run().catch(err => console.log(err));
async function run() {
await mongoose.connect('mongodb://localhost:27017/geotest', {
useNewUrlParser: true,
useUnifiedTopology: true
});
await mongoose.connection.dropDatabase();
const State = mongoose.model('State', mongoose.Schema({
name: String,
location: mongoose.Schema({
type: String,
coordinates: [[[Number]]]
})
}));
const colorado = await State.create({
name: 'Colorado',
location: {
"type": "Polygon",
"coordinates": [[
[-109, 41],
[-102, 41],
[-102, 37],
[-109, 37],
[-109, 41]
]]
}
});
const denver = {
"type": "Point",
"coordinates": [-104.9951943, 39.7645187]
};
const sanFrancisco = {
"type": "Point",
"coordinates": [-122.4726194, 37.7577627]
};
let res = await State.findOne({
location: {
$geoIntersects: { $geometry: denver }
}
});
res.name;
res = await State.findOne({
location: {
$geoIntersects: { $geometry: sanFrancisco }
}
});
res;
}
Summary
GeoJSON is not only storage of coordinates of points. You can store paths in this format. Using GeoJSON data, you can find out when a user entered the geofence. And if necessary, then GeoJSON even allows you to create isochrones . Around the GeoJSON format, a set of great tools has formed. So, the resource geojson.io allows you to perform simple visualization of coordinates on the map. The Mapbox project provides access to advanced geographic APIs. The Turf package allows you to perform geospatial computing in browsers and in Node.js.MongoDB supports queries related to geographic data. And if you store the geographical coordinates of points in the form of pairs of values, without using the GeoJSON format, this means that you miss the opportunity to use some wonderful development tools.Dear readers! Do you use the GeoJSON format?