Статьи

Сопоставление с Geocoder PHP и Leaflet.js

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

Однако самым сложным является преобразование этих данных в координаты, которые может понять карта. К счастью, Geocoder PHP позволяет нам подключаться к различным поставщикам геокодирования. В сочетании с Leaflet.js , простой библиотекой Javascript, создание карт очень просто.

начало

С Composer , в том числе Geocoder PHP библиотека проста:

{
  "require": {
    "willdurand/geocoder": "*"
  }
}

Давайте также добавим HTML в простой файл index.php

 <?php
require 'vendor/autoload.php';

?>
<!DOCTYPE html>
<html>
<head>
    <title>A simple map with Geocoder PHP and Leaflet.js</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-lg-12 page-header">
            <h1 id="header">A simple map with Geocoder PHP and Leaflet.js</h1>
        </div>
        <div class="row-fluid">
            <div class="col-lg-8">

            </div>
        </div>
    </div><!-- /row -->
</div> <!-- /container -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
</body>
</html>

Настройка геокодера

Геокодер считает себя недостающей библиотекой геокодера для PHP. Его можно использовать в три простых шага:

  1. Зарегистрировать адаптер
  2. Зарегистрировать провайдера
  3. Geocode!

Зарегистрировать адаптер

Адаптер служит механизмом для подключения и получения данных для выбранного вами поставщика через их API. Некоторые адаптеры используют встроенные функции PHP 5.3+, такие как cURL и сокеты. Другие, такие как Buzz, Guzzle и Zend HTTP Client, используют сторонние библиотеки с открытым исходным кодом, которые просто требуют, чтобы вы добавили их зависимость в ваш файл композитора.

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

В этом примере мы будем использовать cURL и включенный класс CurlHTTPAdapter внутри библиотеки Geocoder PHP.

В нашем файле index.php

 // Setup geocoder adapter.
$adapter = new \Geocoder\HttpAdapter\CurlHttpAdapter();

Зарегистрировать провайдера

Существует множество провайдеров геокодирования, которые поддерживаются встроенной библиотекой Geocoder PHP, в том числе Google Maps , Bing Maps , Nominatim через Openstreetmap и TomTom .

Полный список можно найти в README в репозитории Geocoder PHP.

Каждый поставщик, представленный соответствующими классами, имеет свои параметры. В зависимости от ваших потребностей, вы можете зарегистрировать несколько провайдеров для различных обстоятельств. Это может быть полезно, если вашему приложению необходимо нанести на карту определенные улицы в Сан-Хосе, Коста-Рика, используя Openstreetmap, и найти быстрый маршрут в Пекине, Китай, используя Baidu.

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

 // Create a chain of providers.
// Be sure to include my previously created adapter.
$chain = new \Geocoder\Provider\ChainProvider(
    array(
        new \Geocoder\Provider\GoogleMapsProvider($adapter),
    )
);

// Instantiate the geocoder.
$geocoder = new \Geocoder\Geocoder();

// Register my providers.
$geocoder->registerProvider($chain);

Geocode

Теперь мы можем передать адрес методу geocode()$geocoder Это вернет объект результата, который был создан через провайдера, выбранного ранее. Этот результирующий объект имеет getLatitude()getLongitude()

 // Demo locations
$locations = array(
    array(
        'address' => '3324 N California Ave, Chicago, IL, 60618',
        'title' => 'Hot Dougs',
    ),
    array(
        'address' => '11 S White, Frankfort, IL, 60423',
        'title' => 'Museum',
    ),
    array(
        'address' => '1000 Sterling Ave, , Flossmoor, IL, 60422',
        'title' => 'Library',
    ),
    array(
        'address' => '2053 Ridge Rd, Homewood, IL, 60430',
        'title' => 'Twisted Q',
    )
);

foreach ($locations as $key => $value) {
    // Try to geocode.
    try {
        $geocode = $geocoder->geocode($value['address']);
        $longitude = $geocode->getLongitude();
        $latitude = $geocode->getLatitude();

    } catch (Exception $e) {
        echo $e->getMessage();
    }
}

Интеграция с Leaflet.js

Leaflet.js — это мощная библиотека javascript, которая делает отображение очень простым.

Карты состоят из трех частей:

  1. плитки
  2. Уровень взаимодействия (обычно через Javascript и CSS)
  3. Точки данных

Плитки — это квадраты 256 на 256 пикселей, которые показывают детали карты. Такие сервисы, как Mapbox и Cloudmade, позволяют создавать собственные наборы плиток. Для этого примера я создал бесплатную учетную запись в Cloudemade и буду использовать ключ API, указанный для показа плиток на их хостинге.

Слой взаимодействия обрабатывается Leaflet.js. Я просто включаю Javascript и библиотеку CSS Leaflet в наш начальный HTML-шаблон:

 <link rel="stylesheet" href="//cdn.leafletjs.com/leaflet-0.6.4/leaflet.css" />
<script src="//cdn.leafletjs.com/leaflet-0.6.4/leaflet.js"></script>

Точки данных были созданы ранее с моим кодом геокодера. Я просто должен отформатировать массив данных так, как ожидает Leaflet.

В этом простом примере я просто собираюсь создать отдельные маркеры как переменные Javascript, которые будут включены в мою карту через строки, созданные PHP.

В брошюре предусмотрена возможность передачи этих данных в формате geoJSON для больших и более динамичных наборов данных.

 $mapdata = $marker_group = array();

foreach ($locations as $key => $value) {
    // Try to geocode.
    try {
        $geocode = $geocoder->geocode($value['address']);
        $longitude = $geocode->getLongitude();
        $latitude = $geocode->getLatitude();

        // Create map data array
        $mapdata[] = markerCreator($latitude, $longitude, $value['title'], $key);

        // Marker grouping array
        $marker_group[] = "marker{$key}";

    } catch (Exception $e) {
        echo $e->getMessage();
    }
}

function markerCreator($lat, $long, $label, $key) {
    return "var marker{$key} = L.marker([{$lat}, {$long}]).addTo(map);
    marker{$key}.bindPopup(\"{$label}\");";
}

Поскольку Leaflet внедряет код карты в существующий элемент DOM, мы сначала должны определить этот элемент внутри нашего HTML. Мы можем сделать это, просто создав div с уникальным идентификатором:

<div id="map"></div>

Затем мы можем нацелить этот идентификатор в Leaflet, вызвав встроенный метод map()

 var map = L.map('map');

Теперь мы строим три части нашей карты. Чтобы зарегистрировать плитки, мы просто вызываем встроенный метод tileLayer()addTo()

 L.tileLayer('//{s}.tile.cloudmade.com/41339be4c5064686b781a5a00678de62/998/256/{z}/{x}/{y}.png', {maxZoom: 18}).addTo(map);

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

 <script>
    var map = L.map('map');

    L.tileLayer('//{s}.tile.cloudmade.com/41339be4c5064686b781a5a00678de62/998/256/{z}/{x}/{y}.png', {maxZoom: 18}).addTo(map);

    <?php print implode('', $mapdata); ?>

    var group = new L.featureGroup([<?php print implode(', ', $marker_group); ?>]);
    map.fitBounds(group.getBounds());
</script>

Если вы зашли так далеко, вы заметите, что ничего не происходит.

Это связано с тем, что Leaflet не вводит свойства по высоте или ширине div карты, что позволяет вам стилизовать его и изменять его по своему усмотрению. Просто дайте вашему div высоту и ширину, и ваша карта должна появиться!

Вывод

Вы можете создавать красивые интерактивные карты с помощью библиотеки Geocoder PHP и Leaflet.js. Обязательно ознакомьтесь с соответствующей документацией каждого проекта, так как существует множество более сложных настроек, которые возможны.

Проверьте демо для этой статьи или раскошелиться на Github.