如何对谷歌地图做客户化定制

google-map-customization

之前的文章中我们介绍了如何把谷歌地图集成到网站的网页里,对于一般的应用需求这种方式已经可以满足,比如地点、路线的展示说明。其实谷歌地图提供了应用编程接口(API)可以对地图做深度定制从而实现一些特定的应用功能,比如给地图加标记、标记群,导入外部地图数据并展示在地图上,地理位置定位,访问后台数据库等。本篇文章介绍地图客户化定制的基本内容,进阶部分的内容将在另一篇文章中介绍。

对谷歌地图做客户化定制首先需要申请 API KEY,然后编写 JavaScript 代码调用谷歌地图 API 访问相应的地图功能。示例代码参考谷歌地图 API 相关的文档指南。

一、地图客户化代码框架

调用谷歌地图功能的客户化代码有一个基本的程序框架,下面详细说明一下:

<!DOCTYPE html>
<html>
  <head>
    <style>
       /* 设置包含地图的标签(div)的样式 */
      #map {
        height: 400px;  /* 地图高度 */
        width: 100%;  /* 地图宽度 */
       }
    </style>
  </head>
  <body>
    <h3>谷歌地图客制化演示</h3>
    <!-- 包含地图的标签 -->
    <div id="map"></div>
    <script>
// 初始化地图对象并调用相应的 Api 函数,也是客户化代码的入口
function initMap() {
  // 地点位置参数
  var beijing = {lat: 39.9042, lng: 116.4074};
  // 以该位置为中心创建地图对象
  var map = new google.maps.Map(
      document.getElementById('map'), {zoom: 8, center: beijing});
  // 把该位置在地图中打上标记
  var marker = new google.maps.Marker({position: beijing, map: map});
}
    </script>
    <!--装载谷歌地图 Api
    * 参数 async 属性表示异步装载
    * 参数 key 就是之前申请的 Api Key
    * 参数 callback 表示地图 Api 装载完成后要调用的函数 initMap(),就是客户化代码
    -->
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=API_KEY&callback=initMap">
    </script>
  </body>
</html>

上面的代码可以分别放到单独的 JavaScript 和 Css 文件中。另外,创建地图对象时传递的参数 “zoom” 代表地图初始显示精度,0 代表显示整个地图,数字越大表示显示精度越高。

二、地图类型

谷歌地图提供了四种不同类型的地图,即缺省的平面道路地图(roadmap)、卫星地图(satellite)、混合地图(hybrid)、地形图(terrain),当创建地图对象的时候,通过给属性参数 mapTypeId 赋值来选择相应的地图。除了创建地图对象时赋值地图类型,还可以调用下面的函数动态修改地图类型:

map.setMapTypeId(‘satellite’);

三、地图坐标系统

谷歌地图支持四种坐标系统,即经纬度坐标、世界坐标、像素坐标、矩形块(瓦片)坐标,这四种坐标系统在谷歌地图的内部算法上可以相互转换。

四、地图本地化

谷歌地图可以缺省设置成不同的国家和语言,这是通过设置国家代码和语言代码来实现的。比如设置地图显示语言为中文可以使用下面的代码:

<script src=”https://maps.googleapis.com/maps/api/js?key=API_KEY&language=zh&region=CN”>
</script>

五、地图显示样式

谷歌地图可以定制地图的显示样式,例如修改地图整体的显示风格,针对地图中不同的元素设置不同的颜色等。比如,把地图的整体颜色风格改成暗蓝色,把道路的颜色改成灰色可以使用下面的代码:

var styledMapType = new google.maps.StyledMapType(
    [
      {elementType: 'geometry', stylers: [{color: '#c8e5e8'}]},
      {
        featureType: 'road',
        elementType: 'geometry',
        stylers: [{color: '#e0e0e0'}]
      }
    ],
    {name: '自定义样式'});
var map = new google.maps.Map(document.getElementById('map'), {
     center: {lat: 39.9042, lng: 116.4074},
     zoom: 8,
     mapTypeControlOptions: {
       mapTypeIds: ['roadmap', 'satellite', 'hybrid', 'terrain',
               'styled_map']
     }
   });

   //设置地图样式为自定义颜色并显示
   map.mapTypes.set('styled_map', styledMapType);
   map.setMapTypeId('styled_map');
六、地图客制化举例

1、标记群
标记群是由一组标记构成,当地图缩小时显示的是标记群的图标和该群中的标记数量,而当放大地图时标记群中的标记就会逐个地显示出来。

function initMap() {
  // 地点位置参数
  var beijing = {lat: 39.9042, lng: 116.4074};
  var shanghai = {lat: 31.2304, lng: 121.4737};
  var guangzhou = {lat: 23.0632, lng: 113.1553};
  var shenzhen = {lat: 22.5427, lng: 114.0579};
  // 以该位置为中心创建地图对象
  var map = new google.maps.Map(
      document.getElementById('map'), {zoom: 3, center: beijing});
  // 创建标记群一
  var cluster1 = [
      new google.maps.Marker({position: beijing, label: '标记群一'}),
      new google.maps.Marker({position: shanghai, label: '标记群一'})
      ];
  // 创建标记群二
  var cluster2 = [
      new google.maps.Marker({position: guangzhou, label: '标记群二'}),
      new google.maps.Marker({position: shenzhen, label: '标记群二'})
      ];
  // 在地图中打上标记群
  var markerCluster = new MarkerClusterer(map, [
            cluster1[0], cluster1[1], cluster2[0], cluster2[1]
            ],
            {imagePath:
'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'});
}
<script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js">
</script>
<script async defer
    src="https://maps.googleapis.com/maps/api/js?key=API_KEY&callback=initMap">
</script>

上面代码中 markerclusterer.js 标记群库可以下载到自己的机器上再引用,标记用的图标(imagePath)可以自己制作并引用。

2、引用外部数据并展示
引用外部地理数据是通过标准的协议和数据格式来获取的(JSON),可以建立自己的数据引用,也可以引用第三方的数据。

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 3,
    center: new google.maps.LatLng(2.8,-187.3),
    mapTypeId: 'terrain'
  });

  // 创建 <script> 标签,设置引用源的URL地址
  var script = document.createElement('script');
  // 通过 JSONP(或者 CORS) 协议请求地震数据,需要目标源支持
  // http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_week.geojsonp
        script.src = 'https://developers.google.com/maps/documentation/javascript/examples/json/earthquake_GeoJSONP.js';
        document.getElementsByTagName('head')[0].appendChild(script);
}

// 对位置点加标记
window.eqfeed_callback = function(results) {
  for (var i = 0; i < results.features.length; i++) {
    var coords = results.features[i].geometry.coordinates;
    var latLng = new google.maps.LatLng(coords[1],coords[0]);
    var marker = new google.maps.Marker({
      position: latLng,
      map: map
    });
  }
}

如果是在同一个主域名地址中的地理数据还可以使用下面的代码引入:

map.data.loadGeoJson('data.json');

如果是跨域引入地理数据,那么请求的响应头需要有如下的声明:

Access-Control-Allow-Origin: *

然后使用下面的代码引入:

map.data.loadGeoJson('http://www.example.com/data.json');

发表评论

邮箱地址不会被公开。 必填项已用*标注