bmap.geocoder
Interactive maps inside a web application have a lot of great uses. From visualizing data to highlighting points of interest, maps are expected to communicate ideas within the context of location easily.
Web应用程序中的交互式地图有很多用途。 从可视化数据到突出显示兴趣点,人们期望地图可以在位置范围内轻松传达想法。
The hardest part, however, is converting that data into coordinates that the map can understand. Luckily, Geocoder PHP allows us to connect to different geo-coding providers. Combined with Leaflet.js, a simple Javascript library, creating maps is a breeze.
但是,最困难的部分是将数据转换为地图可以理解的坐标。 幸运的是, Geocoder PHP使我们能够连接到不同的地理编码提供商。 与简单的Javascript库Leaflet.js结合使用,创建地图变得轻而易举。
开始 (Starting)
With Composer, including the Geocoder PHP library is simple:
使用Composer ,包括Geocoder PHP库很简单:
{
"require": {
"willdurand/geocoder": "*"
}
}
Let's also add some html to a simple index.php
file to include Bootstrap so that we have a nice-looking environment to display our map in:
让我们还将一些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>
设置地理编码器 (Setting Up Geocoder)
Geocoder bills itself as the missing the geocoder library for PHP. It can be used in three simple steps:
Geocoder自称是缺少PHP的geocoder库。 可以通过三个简单步骤使用它:
- Register an adapter 注册适配器
- Register a provider 注册提供商
- Geocode! 地理编码!
注册适配器 (Register an Adapter)
The adapter serves as the mechanism to connect and get data to your chosen provider via their API. Some adapters use the built-in functionality within PHP 5.3+, like cURL and sockets. Others, like Buzz, Guzzle, and Zend HTTP Client, use third-party open source libraries that simply require you to add their dependency to your composer file.
适配器用作通过其API连接数据并将数据获取到您选择的提供程序的机制。 某些适配器使用PHP 5.3+中的内置功能,例如cURL和套接字。 其他(例如Buzz,Guzzle和Zend HTTP Client)使用第三方开放源代码库,这些库仅要求您将其依赖性添加到作曲家文件中。
The beauty of the Geocoder library is this abstraction of the adapter step. It allows you swap out your adapter if your needs change without requiring you to rewrite how your application receives the data.
Geocoder库的美在于适配器步骤的这种抽象。 如果需要发生变化,它允许您换出适配器,而无需重写应用程序接收数据的方式。
For this example, we're going to use cURL and the included CurlHTTPAdapter class inside the Geocoder PHP library.
对于此示例,我们将使用GeoURL PHP库中的cURL和随附的CurlHTTPAdapter类。
In our index.php
file, let's add the adapter:
在我们的index.php
文件中,添加适配器:
// Setup geocoder adapter.
$adapter = new \Geocoder\HttpAdapter\CurlHttpAdapter();
注册提供商 (Register a provider)
There are many geocoding providers that are supported out-of-the-box by the Geocoder PHP library, including Google Maps, Bing Maps, Nominatim via Openstreetmap, and TomTom.
Geocoder PHP库提供了许多开箱即用的地理编码提供程序,包括Google Maps , Bing Maps ,通过Openstreetmap的Nominatim和TomTom 。
The full list can be found on the README of the Geocoder PHP repository.
完整列表可在Geocoder PHP存储库的自述文件中找到。
Each provider, as represented by its respective classes, has its own options. Depending on your needs, you can register multiple providers for various circumstances. This may be useful if your application needs to map specific streets in San Jose, Costa Rica using Openstreetmap and find a quick route in Beijing, China using Baidu.
每个提供者(如其各自的类所代表)具有其自己的选项。 根据您的需要,您可以在各种情况下注册多个提供程序。 如果您的应用程序需要使用Openstreetmap绘制哥斯达黎加圣何塞的特定街道并使用百度在中国北京查找快速路线,这可能会很有用。
For this example, I'll simply use Google Maps, but register it in a way that if I want to add another provider in the future, I simply need to add it to an array:
对于此示例,我将仅使用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)
We can now pass the address to the geocode()
method inside your newly instantiated $geocoder
object. This will return a result object that is instantiated through the provider chosen earlier. This result object has getLatitude()
and getLongitude()
methods we can use.
现在,我们可以将地址传递给新实例化的$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集成 (Integrating with Leaflet.js)
Leaflet.js is a powerful javascript library that makes mapping very easy.
Leaflet.js是一个功能强大的javascript库,它使映射非常容易。
Maps consist of three parts:
地图包括三个部分:
- Tiles 瓷砖
- Interaction layer (typically through Javascript and CSS) 交互层(通常通过Javascript和CSS)
- Data points 数据点
The tiles are the 256 by 256 pixel squares that show the map detail. Services like Mapbox and Cloudmade allow you to create your own tilesets. For this example, I've created a free account with Cloudemade and will use the API key given to show tiles from their hosting service.
这些图块是256 x 256像素的正方形,显示了地图的详细信息。 Mapbox和Cloudmade等服务可让您创建自己的磁贴集。 在此示例中,我使用Cloudemade创建了一个免费帐户,并将使用提供的API密钥显示其托管服务中的图块。
The interaction layer is handled by Leaflet.js. I simply include the Leaflet Javascript and CSS library into our starter HTML template:
交互层由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>
The data points have been created earlier with my geocoder code. I simply have to format the array of data in a way Leaflet expects.
数据点是使用我的地址解析器代码创建的较早的。 我只需要以Leaflet期望的方式格式化数据数组。
In this simple example, I'm simply going to create individual markers as Javascript variables that will be included in my map via strings produced by PHP.
在这个简单的示例中,我只是将创建单个标记作为Javascript变量,这些标记将通过PHP生成的字符串包含在我的地图中。
Leaflet has the option for this data to also be passed in via the geoJSON format for larger and more dynamic datasets.
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}\");";
}
Because Leaflet injects the map code into an existing DOM element, we first have to define that element inside our HTML. We can do this by simply creating a div with a unique id:
因为Leaflet将地图代码注入到现有的DOM元素中,所以我们首先必须在HTML内部定义该元素。 我们可以通过简单地创建一个具有唯一ID的div来做到这一点:
<div id="map"></div>
<div id="map"></div>
We can then target that id in Leaflet by calling the built-in map()
Javascript method and pass in our id in the footer:
然后,我们可以通过调用内置的map()
Javascript方法在Leaflet中定位该ID,并在页脚中传递我们的ID:
var map = L.map('map');
Now, we build the three parts of our map. To register the tiles, we simply call the built-in tileLayer()
method, defining attributes and zoom level if desired, then appending the addTo()
method:
现在,我们构建地图的三个部分。 要注册tileLayer()
贴,我们只需调用内置的tileLayer()
方法,定义属性和缩放级别(如果需要),然后附加addTo()
方法:
L.tileLayer('//{s}.tile.cloudmade.com/41339be4c5064686b781a5a00678de62/998/256/{z}/{x}/{y}.png', {maxZoom: 18}).addTo(map);
Finally, we print our map data using the PHP array we defined earlier, and make sure the map centers itself on those data points by defining them together as group. All in all, the Javascript in the footer would be:
最后,我们使用之前定义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>
If you've gotten this far, you'll notice that nothing happens.
如果您走到了这一步,您会发现什么都没有发生。
This is because Leaflet does not inject properties on the height or width of the map div, allowing you to style it and resize it as you please. Simply give your div a height and width, and your map should appear!
这是因为Leaflet不会在地图div的高度或宽度上注入属性,而是允许您设置其样式并根据需要调整其大小。 只需为div设置高度和宽度,即可显示地图!
结论 (Conclusion)
You can create beautiful, interactive maps with the Geocoder PHP library and Leaflet.js. Be sure to check out the respective documentation of each project as there are many more advanced customizations that are possible.
您可以使用Geocoder PHP库和Leaflet.js创建漂亮的交互式地图。 确保检查出每个项目的相关文档,因为还有许多更高级的自定义设置。
Check out the demo for this article or fork it over at Github.
翻译自: https://www.sitepoint.com/mapping-geocoder-php-leaflet-js/
bmap.geocoder