Мы можем использовать Google Maps API для различных целей в наших проектах, которые могут быть на любой платформе (IOS, Android, Интернет), в этой статье я основное внимание уделяю Интернету. Прежде чем идти дальше, я предполагаю, что вы имеете базовое представление о Javascript и Google Maps API. мы можем искать места с помощью API мест Google, задавая такие параметры, как местоположение (вокруг которого вы хотите искать места), категорию мест (озеро, бассейн, ресторан и т. д.), радиус и т. д. таким образом вы можете найти места только в одном месте.

В документации Google Maps API нет какого-либо определенного способа поиска мест на маршруте, но с помощью некоторых простых методов и логики мы можем очень легко этого добиться.

есть несколько простых шагов

  1. проложите маршрут между двумя точками с помощью API направлений
  2. начертите границу широты и долготы вокруг маршрута
  3. найти все похожие места на маршруте
  4. найти места, которые попадают в многоугольник LAT-LNG

проложить маршрут между двумя точками

сначала нам нужно инициализировать карту на нашей странице, используя следующий код

HTML

<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta charset="utf-8" />
<title>Directions Service</title>
<style>
#map {
height: 100vh;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
</body>

js

let map;
function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
  zoom: 8,
  center: { lat: 19.07596, lng: 72.87764 },
  });
}

скрипт загрузки

// for static loadng
<script defer
  src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
//for dynamic loading
// Create the script tag, set the appropriate attributes
var script = document.createElement('script');
script.src = 'https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap';
script.defer = true;
// Attach your callback function to the `window` object
window.initMap = function() {
  // JS API is loaded and available
};
// Append the 'script' element to 'head'
document.head.appendChild(script);

использовать API маршрутов Google для маршрута

function initMap() {
  var directionsService = new window.google.maps.DirectionsService();
var directionsRenderer = new window.google.maps.DirectionsRenderer();
map = new google.maps.Map(document.getElementById("map"), {
  zoom: 8,
  center: { lat: 19.07596, lng: 72.87764 },
  });
 var request = {
origin: "mumbai",
destination: "pune",
travelMode: "DRIVING"
};
 directionsService.route(request, function (result, status) {
if (status == "OK") {
directionsRenderer.setDirections(result);
}
}
directionsRenderer.setMap(map);
}

нарисуйте границу широты и долготы вокруг маршрута

Это важный шаг, мы можем нарисовать многоугольник на карте с помощью google.map.polygon, но нам не нужен простой многоугольник, такой как прямоугольник или треугольник, нам нужен многоугольник, который в точности похож на синий маршрут, показанный на изображение выше и охватывает весь маршрут.

Чтобы реализовать это, я создаю небольшой и простой алгоритм, который берет все путевые точки между маршрутами и возвращает массив, содержащий все точки, необходимые для генерации границы широты и долготы.

Отправляя запрос маршрута в API, вы получаете ответ, состоящий из кода состояния и результата, который является объектом.

нам понадобится overview_polyline из этого объекта ответа, который содержит все путевые точки на маршруте в закодированном формате и к которому можно получить доступ с помощью result.routes [0] .overview_polyline

wwlsBg|x{LvLsUh@uH~BgFf]aZnJ{K|Fo\bAqLuEcKuTca@uIaObAgAfC_GvE}CtI_AlHgBbI{JzC_QtEwP`Quc@rNy_@x@wLvD_KbMkM~HcF@qC_FcSw@cEmEoQkPin@{HqZuLix@qMw}@kFiWeFuLeHuHkKeKyByDy@yDfAa[`Dkw@lF_aBpA_TnHStBnAvJr@ns@c@nJ_Ajc@u^fTqQxJ{Cto@{E~OgAxDuARoHMkEzYs^lJeNlCiU|Cs]mA{MaWef@gPkXqn@qdAaG{Ke@iIpAoFtIwMdOaUvn@sfAf`@om@lP_ZbGeS`LeU`Tqa@ll@cm@rXwWvP_Ip`@ye@vo@ok@|}A}sArE_BtL]`|@bUlPrEtOz@puAuVlQwEnQgK`b@k^~c@{g@l[{]~SmZvKkUzp@azArGsHpLwEbTuFv|@ib@tqBe`ArbAqe@f`@}QjMsI~p@a`A|l@{|@`J}TbI_WpG{PvGiHl_@kVbi@}|@l[kRpZsPff@qWdTeNrGqMbTc|@xMei@zHuMrNcJ|RkJ`Zid@rRkJ~EiLc@uKkBwNdF{XtEiTtDwJrHmHFsBaNwOg@iD|@oCxFaBrOqBjQ}HnDkCKgBmFuJ}HoEXaBvDkDcCwFyOkM_DqG}PuJ{@aB\sB|Bs@dQnHlH`GjHpMxFzHrCt@|BsA_@kE}KuDqCsE{DaL[wDaI{H_FyBsH_Gg@eMfAeDzNcIzViLpc@eItAsCoBiIzD_NAkE{MgOiAeI_DgLiD_HeVkN}JgH}CoJmAcJeBsf@f@u[bEyUvKwVzNs]vEgOzGmU`CsTjBqLjCcCpGg@hRAj]aJd[fBrb@hF|E\vLyCdF_IJc_@nBmPxEwRt@qLoC{Rei@uzBu[ozCyHou@aIkm@}Kwn@eDgV@yKdBaNxHeStKsLhTmJdMaBtYiAvMsDrRoNdAgBn]gh@hQg_@rh@ev@fd@sr@|Kgt@xUqmBT{M_AmJ_UekA}Dm]qDeNoMwi@eHqf@yJot@VwMdCsKlf@_xAh^igAn@aKs@kQ`@iKbCiJzLaOn{@s^hIcFlNePja@wg@b`@e]xlAqdA|DuIdAeHRyt@~Bsr@rAaAhIm@hRuFv|@}WdTuGp}@kW~qAc`@b_B}c@ju@iS~YeIl@yCgAoNbA{YtJmW`Ak`@bDiQjAqE^mCnAgd@xE_`@~No]rM}PjUiVx\}]tTgOdD}DnAeGlCsApIs@zZqJzo@ib@paAio@zJiLdy@cpAdEcM~@eFvEoYvDsOtKhEhBmDtJgGzT_ItBy@^sDj@sA

расшифровать эту ломаную линию с помощью пакета NPM google-polyline

чтобы использовать пакет NPM в браузере, я использую browserify

var polyline = require( ‘google-polyline’ )
polyline.decode( result.routes[0].overview_polyline )

это декодированная полилиния

// these are all waypoints between two locations
[
[19.07596, 72.87764],
[19.07376, 72.88126],
[19.07355, 72.88281],
[19.07291, 72.88397],
.
.
.
[18.52082, 73.85554],
[18.52044, 73.85686],
]

присвоить его переменной

let waypoints = []
function initMap() {
.
.
.
directionsService.route(request, function (result, status) {
if (status == "OK") {
directionsRenderer.setDirections(result);
waypoints = polyline.decode(result.routes[0].overview_polyline);
}
}
directionsRenderer.setMap(map);
}

Алгоритм для получения границы широты и долготы

Если нам нужно добавить расстояние по широте или долготе, есть математическая формула

для широты: new latitude = latitude + (distance / R) * (180 / pi)

по долготе: new longitude = longitude + (distaance/ R) * (180 / pi) / cos(latitude * pi/180);

где

расстояние = расстояние, которое вы хотите добавить (в метрах)

R = радиус земли (метры)

pi = 3.14

для этого метода нам нужно только добавить расстояние по широте. поскольку широта горизонтальна, дополнительное изменение расстояния будет вертикальным

положительное расстояние (например, 1000) для изменения вверх

отрицательное расстояние (например, -1000) для изменения в сторону уменьшения

приведенный ниже код принимает широту и возвращает верхнюю и нижнюю широту с разницей в указанные метры.

function PolygonArray(latitude) {
const R = 6378137;
const pi = 3.14;
//distance in meters
const upper_offset = 1000;
const lower_offset = -1000;
Lat_up = upper_offset / R;
Lat_down = lower_offset / R;
//OffsetPosition, decimal degrees
lat_upper = latitude + (Lat_up * 180) / pi;
lat_lower = latitude + (Lat_down * 180) / pi;
return [lat_upper, lat_lower];
}

передавая широту путевых точек, которые мы сохранили ранее, мы получаем верхнюю и нижнюю границы маршрута. Затем сохраните верхние координаты в массиве с именем UpperBound, а нижние координаты в массиве с именем LowerBound (координаты должны иметь вид {lat: latitude, lng: longitude}). мы должны изменить нижнюю границу, чтобы установить координаты в правильное положение и нарисовать точный многоугольник.

function PolygonPoints() {
let polypoints = waypoints
let PolyLength = polypoints.length;
let UpperBound = [];
let LowerBound = [];
for (let j = 0; j <= PolyLength - 1; j++) {
let NewPoints = PolygonArray(polypoints[j][0]);
UpperBound.push({ lat: NewPoints[0], lng: polypoints[j][1] });
LowerBound.push({ lat: NewPoints[1], lng: polypoints[j][1] });
}
let reversebound = LowerBound.reverse();
let FullPoly = UpperBound.concat(reversebound);
return FullPoly;
}

назначьте путевые точки переменной polypoints, а затем присвойте пустые массивы UpperBound и LowerBound соответственно. затем переберите полипоинты и вызовите функцию PolygonArray и поместите возвращаемые ею значения в UpperBound и LowerBound. затем переверните нижнюю границу. и назначьте ему обратную связь после этого concat UpperBound и обратную привязку и верните его как FullPoly

FullPoly содержит все координаты, необходимые для рисования многоугольника вокруг маршрута.

Рисование многоугольника на карте

используя метод google.maps.Polygon API карт Google, мы можем нарисовать многоугольник на карте

let waypoints = []
function initMap() {
.
.
.
directionsService.route(request, function (result, status) {
if (status == "OK") {
directionsRenderer.setDirections(result);
waypoints = polyline.decode(result.routes[0].overview_polyline);
}
}
const PolygonCoords = PolygonPoints();
const PolygonBound = new google.maps.Polygon({
paths: PolygonCoords,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35,
});
//to hide polygon set strokeOpacity and fillColor = 0
PolygonBound.setMap(map);
directionsRenderer.setMap(map);
}

найти все похожие места на маршруте

чтобы найти все места на маршруте, мы должны пройти через путевые точки и искать места вокруг соответствующих координат, но если мы рассмотрим все координаты в путевых точках, то вы можете представить, сколько запросов вы собираетесь делать в API мест. вы в конечном итоге обанкротитесь из-за того, что каждый раз отправляет столько запросов для одного маршрута JK :-), мы можем избежать этого, увеличив цикл более чем на 20 точек или более и установив максимально возможный радиус так что мы можем получить результаты в очень небольшом количестве запросов, чтобы найти места, код выглядит следующим образом

function initMap() {
.
.
.
service = new google.maps.places.PlacesService(map);
for(let j = 0;j< waypoints.length;j+=40){
service.nearbySearch({
location: { lat:waypoints[j][0], lng:waypoints[j][1] },
radius: '20000',
type: ['restaurant']
}, callback);
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
new google.maps.Marker({
position: results[i].geometry.location,
map,
title: "Hello World!"
});
}
}
}
}
}

в коде j увеличивается на 40 пунктов, а радиус равен 20000

найти места, которые попадают в полигон LAT-LNG

В API карт Google есть метод под названием containsLocation, с помощью которого мы можем узнать, находится ли данная координата внутри многоугольника или нет. containsLocation требует двух параметров: координата и многоугольник.

function initMap() {
.
.
.
service = new google.maps.places.PlacesService(map);
for(let j = 0;j< waypoints.length;j+=40){
service.nearbySearch({
location: { lat:waypoints[j][0], lng:waypoints[j][1] },
radius: '20000',
type: ['restaurant']
}, callback);
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
if(google.maps.geomet
ry.poly.containsLocation(results[i].geometry.location,PolygonBound) == true) {
new google.maps.Marker({
position: results[i].geometry.location,
map,
title: "Hello World!"
});
}
}
}
}
}
}

в приведенном выше коде мы перебираем результаты, возвращаемые API-интерфейсом Places, если этот результат находится в многоугольнике, а затем помещаем маркер для этой позиции

уф, теперь можно найти места между любыми маршрутами.

Репозиторий GitHub

примечание: вы также можете использовать другие API для поиска мест, например Foursquare API.