GeoJSON — это стандартизованный формат представления географических структур данных, основанный на JSON. Существует множество замечательных инструментов для визуализации GeoJSON-данных. При этом данный формат хорош не только в деле хранения координат неких точек. Он, помимо точек, позволяет описывать и другие объекты: линии, полигоны, коллекции объектов.
{
"type": "Point",
"coordinates": [-80.1347334, 25.7663562]
}
coordinates
записывается в формате [lng, lat]
. Долгота в GeoJSON идёт перед широтой. Это так из-за того, что долгота представляет направление «восток-запад» (ось x
на типичной карте), а широта — направление «север-юг» (ось y
на типичной карте). Авторы GeoJSON стремились к сохранению порядка координат x, y
.https://api.mapbox.com/geocoding/v5/mapbox.places/429%20lenox%20ave%20miami.json?access_token=pk.eyJ1IjoibWF0dGZpY2tlIiwiYSI6ImNqNnM2YmFoNzAwcTMzM214NTB1NHdwbnoifQ.Or19S7KmYPHW8YjRz82v6g&cachebuster=1581993735895&autocomplete=true
{"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]}, ...}
features[0].geometry
в JSON-коде — это GeoJSON-точка:{"type":"Point","coordinates":[-80.139145,25.77409]}
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));
LineString
, представляют массивы координат, описывающие линию на карте. Ниже показан GeoJSON-объект LineString
, представляющий приблизительную границу между штатами Калифорния и Орегон в США:{
"type": "LineString",
"coordinates": [[-124.2, 42], [-120, 42]]
}
[-80.139145,25.77409]
(офис WeWork в Майами-Бич) до точки [-80.2752743,25.7938434]
(международный аэропорт Майами) заключается в использовании GeoJSON-объекта LineString
:{
"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]
]
}
LineString
, представляющие собой некие маршруты, могут быть очень сложными. Вышеприведённый объект, например, описывает короткую 15-минутную поездку. Вот как всё это выглядит на карте.LineString
-представление пути между 2 точками с использованием API directions
Mapbox.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);
});
Polygon
, используются для описания замкнутых областей на картах. Это могут быть области, имеющие форму треугольника, квадрата, двенадцатиугольника, или любой другой фигуры с фиксированным количеством сторон. Например, следующий GeoJSON-объект грубо описывает границы штата Колорадо в США:{
"type": "Polygon",
"coordinates": [[
[-109, 41],
[-102, 41],
[-102, 37],
[-109, 37],
[-109, 41]
]]
}
@turf/boolean-point-in-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]
};
// true
console.log(pointInPolygon(denver, colorado));
// false
console.log(pointInPolygon(sanFrancisco, colorado));
$geoIntersects
поддерживает GeoJSON. Поэтому, например, можно написать запрос, который позволяет выяснить, какому штату США соответствует некая точка на карте: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; // null
}
К сожалению, не доступен сервер mySQL