Интерактивные карты внутри веб-приложения имеют множество полезных применений. Предполагается, что от визуализации данных до выделения интересных мест карты будут легко передавать идеи в контексте местоположения.
Однако самым сложным является преобразование этих данных в координаты, которые может понять карта. К счастью, 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. Его можно использовать в три простых шага:
- Зарегистрировать адаптер
- Зарегистрировать провайдера
- 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, которая делает отображение очень простым.
Карты состоят из трех частей:
- плитки
- Уровень взаимодействия (обычно через Javascript и CSS)
- Точки данных
Плитки — это квадраты 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.