Google 地图数据层提供了一个可用于存储任意地理空间数据的容器。您可以使用数据层存储自定义数据,或者使用它在 Google 地图上显示 GeoJSON 数据。
概述
观看这个 DevBytes 视频可详细了解数据层。
借助 Maps JavaScript API,您可以使用各种叠加层(例如标记、多段线、多边形等)为地图添加标记。其中每种注释都既包含样式信息,也包含位置数据。google.maps.Data
类是一个可用于存储任意地理空间数据的容器。如果不想添加上述叠加层,您也可以使用数据层向地图添加任意地理位置数据。如果这些数据包含几何图形(例如点、线或多边形),API 会默认将其渲染为标记、多段线和多边形。您可以像设置普通叠加层一样设置这些地图项的样式,也可以根据数据集中包含的其他属性应用样式规则。
借助 google.maps.Data
类,您可以:
- 在地图上绘制多边形。
- 向地图添加 GeoJSON 数据。
GeoJSON 是互联网上表示地理空间数据的一种标准。Data
类按照 GeoJSON 的结构表示其数据,让您能够轻松显示 GeoJSON 数据。使用loadGeoJson()
方法可轻松导入 GeoJSON 数据,并显示点、线串和多边形。 - 使用
google.maps.Data
模拟任意数据。
现实世界中的大多数实体都有与之相关的其他属性。例如,商店有营业时间,道路有车流速度,而每个女童子军巡回演出团都有销售饼干的场地。您可以使用google.maps.Data
来模拟这些属性,并相应地设置数据的样式。 - 选择数据的表示方式,而且随时可以改变主意。
借助数据层,您可以决定数据的呈现和互动方式。例如,在地图上查找便利店时,您可以选择仅显示销售公交车票的那些商店。
绘制多边形
Data.Polygon
类会为您处理多边形环绕。您可以向该类传递由一个或多个线性环(以纬度/经度坐标的形式指定)构成的数组。第一个线性环用于指定多边形的外边界。如果传递多个线性环,则第二个及后续线性环用于指定多边形中的内路径(孔)。
下例创建了一个内含两个孔的矩形多边形:
TypeScript
// This example uses the Google Maps JavaScript API's Data layer // to create a rectangular polygon with 2 holes in it. function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 6, center: { lat: -33.872, lng: 151.252 }, } ); // Define the LatLng coordinates for the outer path. const outerCoords = [ { lat: -32.364, lng: 153.207 }, // north west { lat: -35.364, lng: 153.207 }, // south west { lat: -35.364, lng: 158.207 }, // south east { lat: -32.364, lng: 158.207 }, // north east ]; // Define the LatLng coordinates for an inner path. const innerCoords1 = [ { lat: -33.364, lng: 154.207 }, { lat: -34.364, lng: 154.207 }, { lat: -34.364, lng: 155.207 }, { lat: -33.364, lng: 155.207 }, ]; // Define the LatLng coordinates for another inner path. const innerCoords2 = [ { lat: -33.364, lng: 156.207 }, { lat: -34.364, lng: 156.207 }, { lat: -34.364, lng: 157.207 }, { lat: -33.364, lng: 157.207 }, ]; map.data.add({ geometry: new google.maps.Data.Polygon([ outerCoords, innerCoords1, innerCoords2, ]), }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// This example uses the Google Maps JavaScript API's Data layer // to create a rectangular polygon with 2 holes in it. function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 6, center: { lat: -33.872, lng: 151.252 }, }); // Define the LatLng coordinates for the outer path. const outerCoords = [ { lat: -32.364, lng: 153.207 }, // north west { lat: -35.364, lng: 153.207 }, // south west { lat: -35.364, lng: 158.207 }, // south east { lat: -32.364, lng: 158.207 }, // north east ]; // Define the LatLng coordinates for an inner path. const innerCoords1 = [ { lat: -33.364, lng: 154.207 }, { lat: -34.364, lng: 154.207 }, { lat: -34.364, lng: 155.207 }, { lat: -33.364, lng: 155.207 }, ]; // Define the LatLng coordinates for another inner path. const innerCoords2 = [ { lat: -33.364, lng: 156.207 }, { lat: -34.364, lng: 156.207 }, { lat: -34.364, lng: 157.207 }, { lat: -33.364, lng: 157.207 }, ]; map.data.add({ geometry: new google.maps.Data.Polygon([ outerCoords, innerCoords1, innerCoords2, ]), }); } window.initMap = initMap;
加载 GeoJSON
GeoJSON 是在互联网上共享地理空间数据时可遵循的通用标准。它体量小且易于理解,非常适合用于共享和协作。利用数据层,您只需编写一行代码,即可向 Google 地图添加 GeoJSON 数据。
map.data.loadGeoJson('google.json');
每个地图均有一个 map.data
对象充当数据层,用于存储任意地理空间数据,包括 GeoJSON。您可以通过调用 data
对象的 loadGeoJSON()
方法来加载和显示 GeoJSON 文件。下例显示了如何添加地图并加载外部 GeoJSON 数据。
TypeScript
let map: google.maps.Map; function initMap(): void { map = new google.maps.Map(document.getElementById("map") as HTMLElement, { zoom: 4, center: { lat: -28, lng: 137 }, }); // NOTE: This uses cross-domain XHR, and may not work on older browsers. map.data.loadGeoJson( "https://storage.googleapis.com/mapsdevsite/json/google.json" ); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
let map; function initMap() { map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: { lat: -28, lng: 137 }, }); // NOTE: This uses cross-domain XHR, and may not work on older browsers. map.data.loadGeoJson( "https://storage.googleapis.com/mapsdevsite/json/google.json", ); } window.initMap = initMap;
试用示例
GeoJSON 示例
本页面上的大多数示例都使用一个通用的 GeoJSON 文件。此文件在澳大利亚上方以多边形形式勾勒出“Google”中的六个字符。在测试数据层时,您可以根据需要随意复制或修改此文件。
注意:若要从其他域加载 JSON 文件,该域必须已启用跨域资源共享。
在下方展开 google.json 旁边的小箭头即可看到此文件的完整文本。
google.json
{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "letter": "G", "color": "blue", "rank": "7", "ascii": "71" }, "geometry": { "type": "Polygon", "coordinates": [ [ [123.61, -22.14], [122.38, -21.73], [121.06, -21.69], [119.66, -22.22], [119.00, -23.40], [118.65, -24.76], [118.43, -26.07], [118.78, -27.56], [119.22, -28.57], [120.23, -29.49], [121.77, -29.87], [123.57, -29.64], [124.45, -29.03], [124.71, -27.95], [124.80, -26.70], [124.80, -25.60], [123.61, -25.64], [122.56, -25.64], [121.72, -25.72], [121.81, -26.62], [121.86, -26.98], [122.60, -26.90], [123.57, -27.05], [123.57, -27.68], [123.35, -28.18], [122.51, -28.38], [121.77, -28.26], [121.02, -27.91], [120.49, -27.21], [120.14, -26.50], [120.10, -25.64], [120.27, -24.52], [120.67, -23.68], [121.72, -23.32], [122.43, -23.48], [123.04, -24.04], [124.54, -24.28], [124.58, -23.20], [123.61, -22.14] ] ] } }, { "type": "Feature", "properties": { "letter": "o", "color": "red", "rank": "15", "ascii": "111" }, "geometry": { "type": "Polygon", "coordinates": [ [ [128.84, -25.76], [128.18, -25.60], [127.96, -25.52], [127.88, -25.52], [127.70, -25.60], [127.26, -25.79], [126.60, -26.11], [126.16, -26.78], [126.12, -27.68], [126.21, -28.42], [126.69, -29.49], [127.74, -29.80], [128.80, -29.72], [129.41, -29.03], [129.72, -27.95], [129.68, -27.21], [129.33, -26.23], [128.84, -25.76] ], [ [128.45, -27.44], [128.32, -26.94], [127.70, -26.82], [127.35, -27.05], [127.17, -27.80], [127.57, -28.22], [128.10, -28.42], [128.49, -27.80], [128.45, -27.44] ] ] } }, { "type": "Feature", "properties": { "letter": "o", "color": "yellow", "rank": "15", "ascii": "111" }, "geometry": { "type": "Polygon", "coordinates": [ [ [131.87, -25.76], [131.35, -26.07], [130.95, -26.78], [130.82, -27.64], [130.86, -28.53], [131.26, -29.22], [131.92, -29.76], [132.45, -29.87], [133.06, -29.76], [133.72, -29.34], [134.07, -28.80], [134.20, -27.91], [134.07, -27.21], [133.81, -26.31], [133.37, -25.83], [132.71, -25.64], [131.87, -25.76] ], [ [133.15, -27.17], [132.71, -26.86], [132.09, -26.90], [131.74, -27.56], [131.79, -28.26], [132.36, -28.45], [132.93, -28.34], [133.15, -27.76], [133.15, -27.17] ] ] } }, { "type": "Feature", "properties": { "letter": "g", "color": "blue", "rank": "7", "ascii": "103" }, "geometry": { "type": "Polygon", "coordinates": [ [ [138.12, -25.04], [136.84, -25.16], [135.96, -25.36], [135.26, -25.99], [135, -26.90], [135.04, -27.91], [135.26, -28.88], [136.05, -29.45], [137.02, -29.49], [137.81, -29.49], [137.94, -29.99], [137.90, -31.20], [137.85, -32.24], [136.88, -32.69], [136.45, -32.36], [136.27, -31.80], [134.95, -31.84], [135.17, -32.99], [135.52, -33.43], [136.14, -33.76], [137.06, -33.83], [138.12, -33.65], [138.86, -33.21], [139.30, -32.28], [139.30, -31.24], [139.30, -30.14], [139.21, -28.96], [139.17, -28.22], [139.08, -27.41], [139.08, -26.47], [138.99, -25.40], [138.73, -25.00 ], [138.12, -25.04] ], [ [137.50, -26.54], [136.97, -26.47], [136.49, -26.58], [136.31, -27.13], [136.31, -27.72], [136.58, -27.99], [137.50, -28.03], [137.68, -27.68], [137.59, -26.78], [137.50, -26.54] ] ] } }, { "type": "Feature", "properties": { "letter": "l", "color": "green", "rank": "12", "ascii": "108" }, "geometry": { "type": "Polygon", "coordinates": [ [ [140.14,-21.04], [140.31,-29.42], [141.67,-29.49], [141.59,-20.92], [140.14,-21.04] ] ] } }, { "type": "Feature", "properties": { "letter": "e", "color": "red", "rank": "5", "ascii": "101" }, "geometry": { "type": "Polygon", "coordinates": [ [ [144.14, -27.41], [145.67, -27.52], [146.86, -27.09], [146.82, -25.64], [146.25, -25.04], [145.45, -24.68], [144.66, -24.60], [144.09, -24.76], [143.43, -25.08], [142.99, -25.40], [142.64, -26.03], [142.64, -27.05], [142.64, -28.26], [143.30, -29.11], [144.18, -29.57], [145.41, -29.64], [146.46, -29.19], [146.64, -28.72], [146.82, -28.14], [144.84, -28.42], [144.31, -28.26], [144.14, -27.41] ], [ [144.18, -26.39], [144.53, -26.58], [145.19, -26.62], [145.72, -26.35], [145.81, -25.91], [145.41, -25.68], [144.97, -25.68], [144.49, -25.64], [144, -25.99], [144.18, -26.39] ] ] } } ] }
设置 GeoJSON 数据的样式
使用 Data.setStyle()
方法可指定数据的显示方式。setStyle()
方法接受的参数是一个 StyleOptions
对象字面量,或者是一个用于为每个地图项计算样式的函数。
简单的样式规则
若要设置地图项样式,最简单的方式是将 StyleOptions
对象字面量传递给 setStyle()
。这将为集合中的每个地图项设置一个样式。请注意,每个地图项类型都只能渲染一部分可用选项。也就是说,可以在一个对象字面量中合并不同地图项类型的样式。例如,以下代码段同时设置了仅影响点类几何图形的自定义 icon
,以及仅影响多边形的 fillColor
。
map.data.setStyle({ icon: '//example.com/path/to/image.png', fillColor: 'green' });
如需详细了解有效的样式/地图项组合,请参阅样式选项。
以下示例展示了如何使用 StyleOptions
对象字面量为多个地图项设置描边和填充颜色。请注意,每个多边形的样式都相同。
// Set the stroke width, and fill color for each polygon map.data.setStyle({ fillColor: 'green', strokeWeight: 1 });
声明式的样式规则
如果您想更新大量叠加层(例如标记或多段线)的样式,通常需要遍历地图上的每个叠加层,并单独为其设置样式。借助数据层,您能够以声明方式设置规则,这些规则将应用于整个数据集。当数据或规则更新时,样式将自动应用于每个地图项。您可以使用地图项属性自定义其样式。
例如,下面的代码会通过检查 google.json
中每个字符在 ASCII 字符集中的位置来设置其颜色。在这个示例中,我们已经将字符位置随数据一起进行了编码。
// Color Capital letters blue, and lower case letters red. // Capital letters are represented in ascii by values less than 91 map.data.setStyle(function(feature) { var ascii = feature.getProperty('ascii'); var color = ascii > 91 ? 'red' : 'blue'; return { fillColor: color, strokeWeight: 1 }; });
移除样式
如果您想移除任何已应用的样式,请将空的对象字面量传递给 setStyles()
方法。
// Remove custom styles. map.data.setStyle({});
这将移除您已指定的所有自定义样式,而地图项将使用默认样式进行渲染。如果您不想再渲染相应地图项,请将 StyleOptions
的 visible
属性设置为 false
。
// Hide the Data layer. map.data.setStyle({visible: false});
重写默认样式
样式规则通常应用于数据层中的每个地图项。不过,有时您可能需要将特殊样式规则应用于特定地图项。例如,为了在点击某个地图项时突出显示该地图项。
如需应用特殊样式规则,请使用 overrideStyle()
方法。您使用 overrideStyle()
方法更改的任何属性会在 setStyle()
中已指定的全局样式基础上叠加应用。例如,下面的代码将在用户点击多边形时更改其填充颜色,但不会设置任何其他样式。
// Set the global styles. map.data.setStyle({ fillColor: 'green', strokeWeight: 3 }); // Set the fill color to red when the feature is clicked. // Stroke weight remains 3. map.data.addListener('click', function(event) { map.data.overrideStyle(event.feature, {fillColor: 'red'}); });
调用 revertStyle()
方法可撤销所有样式重写。
样式选项
在为每个地图项设置样式时可用的选项取决于地图项类型。例如,fillColor
将仅在多边形类几何图形上渲染,而 icon
将仅在点类几何形状上渲染。如需了解详情,请参阅 StyleOptions
的参考文档。
适用于所有几何图形
clickable
:如果设置为true
,地图项会接收鼠标和触摸事件。visible
:如果设置为true
,地图项就会显示。zIndex
:所有地图项按照其zIndex
的顺序显示在地图上,值较高的地图项会显示在值较低的地图项前面。标记始终显示在线串和多边形前面。
适用于点几何图形
cursor
:鼠标悬停时显示的鼠标光标。icon
:针对点几何图形显示的图标。shape
:定义用于检测命中的图像地图。title
:鼠标悬停时显示的文本。
适用于线几何图形
strokeColor
:描边颜色。支持所有 CSS3 颜色,扩展的已命名颜色除外。strokeOpacity
:描边不透明度介于 0.0 和 1.0 之间。strokeWeight
:描边宽度(以像素为单位)。
可用于多边形几何图形
fillColor
:填充颜色。支持所有 CSS3 颜色,扩展的已命名颜色除外。fillOpacity
:填充不透明度介于0.0
和1.0.
之间strokeColor
:描边颜色。支持所有 CSS3 颜色,扩展的已命名颜色除外。strokeOpacity
:描边不透明度介于 0.0 和 1.0 之间。strokeWeight
:描边宽度(以像素为单位)。
添加事件处理脚本
地图项会响应事件,例如 mouseup
或 mousedown
。您可以添加事件监听器,以便用户与地图上的数据互动。在下面的示例中,我们添加了一个鼠标悬停事件,该事件会在鼠标光标下方显示相应地图项的相关信息。
// Set mouseover event for each feature. map.data.addListener('mouseover', function(event) { document.getElementById('info-box').textContent = event.feature.getProperty('letter'); });
数据层事件
以下事件是所有地图项的通用事件,无论其几何图形类型如何:
addfeature
click
dblclick
mousedown
mouseout
mouseover
mouseup
removefeature
removeproperty
rightclick
setgeometry
setproperty
如需详细了解这些事件,请参阅 google.maps.data 类的参考文档。
动态更改外观
您可以向 google.maps.data.setStyle()
方法传递用于计算每个地图项样式的函数,以设置数据层的样式。每次更新地图项的属性时,系统都会调用此函数。
在以下示例中,我们为 click
事件添加了一个事件监听器,用于更新地图项的 isColorful
属性。设置属性后,地图项样式会立即更新以反映所做的更改。
// Color each letter gray. Change the color when the isColorful property // is set to true. map.data.setStyle(function(feature) { var color = 'gray'; if (feature.getProperty('isColorful')) { color = feature.getProperty('color'); } return /** @type {!google.maps.Data.StyleOptions} */({ fillColor: color, strokeColor: color, strokeWeight: 2 }); }); // When the user clicks, set 'isColorful', changing the color of the letters. map.data.addListener('click', function(event) { event.feature.setProperty('isColorful', true); }); // When the user hovers, tempt them to click by outlining the letters. // Call revertStyle() to remove all overrides. This will use the style rules // defined in the function passed to setStyle() map.data.addListener('mouseover', function(event) { map.data.revertStyle(); map.data.overrideStyle(event.feature, {strokeWeight: 8}); }); map.data.addListener('mouseout', function(event) { map.data.revertStyle(); });