Будуємо маршрути за допомогою OpenStreetMap, OSRM і Leaflet

Привіт,% username%! Хочу написати маленьку статейку про те, як за допомогою OpenStreetMap, OSRM і Leaflet прокладати маршрути в своєму проекті. Розповідати що представляють із себе вищевказані технології я не буду — на Хабре про них писалося не раз вже, стаття буде маленька і тільки у справі. Отже, якщо ви хочете будувати маршрути — прошу під кат.
 
 image
 
Отже, приступимо. Для роботи нам знадобиться JQuery і Leaflet. Останній можна взяти на офіційному сайті — leafletjs.com
При бажанні можна використовувати CDN (від себе зазначу — досить швидко вантажиться).
 
 
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />

 
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>

 
Далі нам знадобиться контейнер, куди буде завантажуватися карта. Створюємо div і даємо йому ідентифікатор map
 
 
<div id="map"></div>

 
При необхідності йому можна задавати ширину / висоту, використовувати у спливаючих вікнах і пр.
Тепер безпосередньо ініціалізація — прив'язуємо карту до нашого div'у.
 
 
var map = L.map('map');

 
Після цього в наш div завантажується карта. Але що в даному випадку довантажити Leaflet? Явно не те місто, де ми знаходимося. Для виправлення цього пишемо наступний код:
 
 
map.setView([55.7422, 37.5719], 11);

 
Дана конструкція завантажить нам карту Москви (координати потрібно вставляти в черговості LatLng, zoom), де zoom — масштаб. Ах так, мало не забув — нам потрібно вказати, звідки брати зображення для карти. Джерела можуть бути самі різні, від офіційного сайту до власного сервера. Візьмемо офіційний сайт:
 
 
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map);

 
На цьому етапі у нас в наш div завантажується карта потрібного нам міста. Тепер приступимо до побудови маршрутів. Для початку будемо додавати по кліку на карті маркер. Всього маркерів буде 2 — для початку шляху і кінця, не будемо поки робити маршрутизацію з декількома точками. Отже, нам потрібно обробляти подію 'click' по карті. У мене це реалізовано так:
 
 
map.on('click', function(e) {
        onMapClick(e);
    });
function onMapClick(e) {
        if (loc1 == null) {
            loc1 = new L.marker(e.latlng, {draggable: 'true'});
            loc1.on('dragend', function(event) {
                //отправляем запрос маршрута
            });
            map.addLayer(loc1);
        }
        else if (loc2 == null) {
            loc2 = new L.marker(e.latlng, {draggable: 'true'});
            loc2.on('dragend', function(event) {
                //отправляем запрос марурута
            });
            map.addLayer(loc2);
            //отправляем запрос маршрута
        }
    }
    ;

 
Після кліка по карті функція onMapClick перевіряє, чи існують точки loc1 і loc2. Якщо існують обидві точки — відстежується тільки переміщення маркера по карті ('dragend'). Само перетягування включається за допомогою параметра draggable: 'true'. Маркери є, перетягування відстежується, залишилося тільки прикрутити промальовування маршруту. Куди відправляти запит — вирішувати Вам, можна використовувати OSRM (і я вам це настійно раджу, безкоштовний інструмент з високою швидкістю роботи). Я ж використовую власний сервер, який мені віддає результат polyline-рядку. В інтернеті є готова реалізація для всіх ЯП по декодуванню цього рядка в масив значень. Як це реалізувати у вашому випадку — вирішувати тільки Вам. У мене декодування виконується за допомогою php і результат повертається у вигляді масиву координат. Отже, метод відправлення запитів і самої промальовування маршрутів:
 
 

var polyline;

    function sendPost() {
        if (loc2 != null && loc1 != null) {
            var p1 = loc1.getLatLng(),
                    p2 = loc2.getLatLng();
            $.post(
                    //куда шлем запрос,
                    {l1: p1.lat + ',' + p1.lng, l2: p2.lat + ',' + p2.lng},
            function(data) {
                if (data) {
                    if (polyline) {
                        map.removeLayer(polyline);
                    }
                    var points = data;
                    polyline = new L.polyline(points, {color: 'red'});
                    map.addLayer(polyline);
                    map.fitBounds(polyline.getBounds());
                }
            },
                    "json"
                    );
        }
    }

 
Зізнаюся відразу — javascript знаю вкрай жахливо, але Ви це вже, напевно, зрозуміли. Але продовжимо. Задаємо змінну polyline, яку потім будемо використовувати для створення лінії маршруту. Лінію будемо додавати новим шаром для того, щоб при перетягуванні можна було видалити старий маршрут. При успішно виконаному запиті йде перевірка — існує вже шар чи ні. Якщо існує (тобто є вже маршрут) — видаляється і будується новий.
 
Ось, в принципі, і все. Прошу досвідчених програмістів сильно не лаятися — стаття більше орієнтована на новачків, таких як я. При виконанні даної задачі я зіткнувся з відсутністю в мережі прикладів для побудови маршрутів за допомогою даної бібліотеки та інших дрібних нюансів, з якими я зіткнувся. З радістю відповім на всі ваші питання і додам те, що на вашу думку я упустив.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.