Web应用程序中的交互式地图有很多用途。 从可视化数据到突出显示兴趣点,人们期望地图可以在位置范围内轻松传达想法。
但是,最困难的部分是将数据转换为地图可以理解的坐标。 幸运的是, Geocoder PHP使我们能够连接到不同的地理编码提供商。 与简单的Javascript库Leaflet.js结合使用,轻松创建地图。
开始
使用Composer ,包括Geocoder PHP库很简单:
{
"require": {
"willdurand/geocoder": "*"
}
}
让我们还将一些html添加到一个简单的index.php
文件中,以包含Bootstrap,以便我们有一个漂亮的环境来显示我们的地图:
<?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>
设置地理编码器
Geocoder自称是缺少PHP的geocoder库。 可通过三个简单步骤使用它:
- 注册适配器
- 注册提供商
- 地理编码!
注册适配器
适配器用作通过其API连接数据并将数据获取到您选择的提供程序的机制。 某些适配器使用PHP 5.3+中的内置功能,例如cURL和套接字。 其他(例如Buzz,Guzzle和Zend HTTP Client)使用第三方开放源代码库,这些库仅要求您将其依赖性添加到作曲家文件中。
Geocoder库的美在于适配器步骤的这种抽象。 如果需要发生变化,它使您可以换出适配器,而无需重写应用程序接收数据的方式。
在此示例中,我们将使用GeoURL PHP库中的cURL和随附的CurlHTTPAdapter类。
在我们的index.php
文件中,添加适配器:
// Setup geocoder adapter.
$adapter = new \Geocoder\HttpAdapter\CurlHttpAdapter();
注册提供商
Geocoder PHP库提供了许多开箱即用的地理编码提供程序,包括Google Maps , Bing Maps ,通过Openstreetmap的Nominatim和TomTom 。
完整列表可在Geocoder PHP存储库的自述文件中找到。
每个提供者(如其各自的类所代表)具有其自己的选项。 根据您的需要,您可以在各种情况下注册多个提供程序。 如果您的应用程序需要使用Openstreetmap绘制哥斯达黎加圣何塞的特定街道并使用百度在中国北京查找快速路线,这可能会很有用。
对于此示例,我将仅使用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);
地理编码
现在,我们可以将地址传递给新实例化的$geocoder
对象内的geocode()
方法。 这将返回通过先前选择的提供程序实例化的结果对象。 此结果对象具有我们可以使用的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 x 256像素的正方形,显示了地图的详细信息。 Mapbox和Cloudmade等服务可让您创建自己的磁贴集。 在此示例中,我使用Cloudemade创建了一个免费帐户,并将使用提供的API密钥显示其托管服务中的图块。
交互层由Leaflet.js处理。 我只是将Leaflet Javascript和CSS库包含在我们的入门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生成的字符串包含在我的地图中。
Leaflet可以选择将此数据也通过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中定义该元素。 我们可以通过简单地创建一个具有唯一ID的div来做到这一点:
<div id="map"></div>
然后,我们可以通过调用内置的map()
Javascript方法在Leaflet中定位该ID,并在页脚中传递我们的ID:
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不会在map div的高度或宽度上注入属性,而是允许您设置其样式并根据需要调整其大小。 只需为div设置高度和宽度,即可显示地图!
结论
您可以使用Geocoder PHP库和Leaflet.js创建漂亮的交互式地图。 请确保检查每个项目的相关文档,因为还有许多更高级的自定义设置。
From: https://www.sitepoint.com/mapping-geocoder-php-leaflet-js/