maps-api-v3
您已经设计了一个闪亮的新网站; 仔细选择颜色,版式和照片,以完美反映公司的品牌形象。 然后您的客户要求您添加地图。 当然,您可以使用地图构建“向导”,例如每个Google帐户随附的地图。 但是,让我们面对现实吧,它们的功能是有限的,而且看起来很普通!
另一方面,Google Maps API使您可以自由创建完全自定义的地图,从而可以完成各种有趣的事情。 朴次茅斯历史地图是我最近使用此API构建的网站。
本系列教程将向您展示如何使用Google Maps API创建自定义地图。 这将涉及到使用JavaScript弄脏双手,但这是值得的。
这些教程将涵盖各种内容。 仅举几例:自定义地图颜色,菜单和标记; 通过将您自己的地图设计(例如汉拉德地图)叠加到可缩放的Google地图上,使其栩栩如生; 链接到Flickr API; 图像优化; 响应式设计; 代码优化和验证。 或者,换句话说,当您完成工作时,不仅可以创建精美的地图,还可以查看与构建任何网站相关的许多内容。
情境
这些教程使用了一家英国公司推广音乐节的场景。 上面的“最终产品”图片显示了我们的目标。 看一下演示。
注意:在此示例中,仅Glastonbury标记是“活动的”。
在开始之前,您可能想要下载与本教程相关的文件 。 我为每个活动都提供了一个单独的html文件。
反正什么是API?
API或应用程序编程接口是一种表达公司(例如Facebook,Twitter,You Tube,Google)发布的一组命令(例如功能)的奇特方法。 想法是,您可以使用这些命令来创建其内容的高度自定义版本。 例如,对于Google Maps API,“内容”是地图,而对于Flickr API,“内容”是照片。
当人们谈论“混搭”时,它们意味着他们已经使用了两家或两家以上公司的API来组合内容,例如使来自Flickr的图片出现在Google地图上。 这些API实际上有成千上万种。 请看一下可编程Web以获得更多信息。
我们将在以后的教程中介绍Flickr API,但首先我们将重点关注Google Maps API。 这将使您能够做各种事情,包括自定义颜色,地图标记,弹出框样式,细节级别和缩放级别。 更不用说实际上使地图做一些很酷的事情,例如显示实时数据,对标记进行分组,规划路线,绘制自定义覆盖图,动态显示数据....列表无止境!
Google Maps入门
冒个风险,要开始使用,您需要一个Google帐户。 如果您目前还没有,请前往Google并注册。
有了您的Google帐户,您现在可以冒险进入Google Maps API页面 。 收藏此页; 您会变得非常熟悉。 主要领域是:
- 开发人员指南:代码片段,向您展示如何使用API函数执行某些操作。
- API参考:API中所有功能的完整参考列表。 将此用作使用API可以执行的“购物清单”。 (但是请记住,还有其他库可以让您做更多的事情。稍后我们将介绍这些内容)。
在继续之前,您还需要一个API密钥(由字母和数字组成的长序列,对您来说是唯一的)。 在此处获取您的API密钥。
创建第一个地图
好的,您准备开始构建。
要使提供的地图生效,请用您自己的API密钥替换显示为“ YOUR_API_KEY_GOES_HERE”的位置。 您的地图应类似于上面显示的地图。
该代码的基本原理是,它创建了一个div(称为festival-map
),JavaScript将其加载到该div中。 我在代码中添加了注释,以解释其工作原理,但是值得重点介绍一下。
该代码首先使用Doctype声明<!DOCTYPE html>
将您的应用程序声明为HTML5。
然后为地图设置样式。 <style type="text/css">
和</style>
标记之间的位。 您可以根据要放置地图的位置来调整#festival-map
ID上的样式。 如果要“全屏”地图,则将宽度和高度设置为100%,并删除边距。
然后,跳过JavaScript片刻,body标记之间的代码会建立一个空的html对象,即一个div( festival-map
)来保存地图。 这是一种“占位符”,JavaScript会将地图加载到其中。
<div id="festival-map"></div>
确定-现在查看JavaScript-该代码首先连接到您的Google Maps API密钥。
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY_GOES_HERE&sensor=true"></script>
然后,它将启动到创建地图JavaScript中。 快速提醒:JavaScript函数(例如loadFestivalMap
)是一组命令,它们仅在被其他代码调用时才运行。 这可能看起来很复杂,但实际上只在做一些事情-
- 设置了地图的配置选项(
festivalMapOptions
)(例如,纬度,经度,缩放级别等),并创建了一个空JavaScript变量(festivalMap
),不久该地图将被分配给该JavaScript变量。 (提示: itouchmap是一个方便的站点,可用于查找任何位置的纬度和经度坐标。) - 然后,以下行触发
loadFestivalMap
函数运行:google.maps.event.addDomListener(window, 'load', loadFestivalMap);
- 此函数创建地图,并将其分配给为其创建JavaScript变量(即
festivalMap
)。 在执行此操作时,它还将应用配置选项,并将地图加载到为保存该festival-map
创建的festival-map
div中。 - 最后,
loadMapMarkers
功能被触发到由的最后一行运行loadFestivalMap
功能。
如果这没有任何意义,请仔细阅读完整版代码中的注释, 以进一步解释它们。
图片作为地图标记
到现在为止,您应该已经建立了一个地图并正在运行,并且幸运的是,您还没有对JavaScript感到困惑! 假设一切都很好,我们就可以开始使地图看起来更有趣了。
使用您自己的图像作为地图标记很容易。 与您为地图本身设置属性选项的方式类似(例如center, zoom
如上所述, center, zoom
等),您还可以更改地图标记的属性。 要将其他图像用作地图标记,您只需设置地图标记的icon
属性。 (如果您感兴趣,则Google Maps API-标记部分列出了您可以使用的所有地图标记属性,方法和事件)。
通常,地图标记是.png,因为它们使您可以具有透明背景的不规则形状。
我们还需要为每个标记设置“可点击”区域,以确保.png的“图像”位可点击,而透明位则不可。 如果标记重叠,这真的很重要。
首先,创建地图图标图像( markerIconGlastonbury
),然后创建地图图标形状( markerShapeGlastonbury
),最后将它们链接到地图标记( markerGlastonbury
)。
//Setting the position of the Glastonbury map marker.
var markerPositionGlastonbury = new google.maps.LatLng(51.159803, -2.585585);
//Setting the icon to be used with the Glastonbury map marker.
var markerIconGlastonbury = {
url: 'icons/icon_glas_uk.png',
//The size image file.
size: new google.maps.Size(225, 120),
//The point on the image to measure the anchor from. 0, 0 is the top left.
origin: new google.maps.Point(0, 0),
//The x y coordinates of the anchor point on the marker. e.g. If your map marker was a drawing pin then the anchor would be the tip of the pin.
anchor: new google.maps.Point(189, 116)
};
//Setting the shape to be used with the Glastonbury map marker.
var markerShapeGlastonbury = {
coord: [12,4,216,22,212,74,157,70,184,111,125,67,6,56],
type: 'poly'
};
//Creating the Glastonbury map marker.
markerGlastonbury = new google.maps.Marker({
//uses the position set above.
position: markerPositionGlastonbury,
//adds the marker to the map.
map: festivalMap,
title: 'Glastonbury Festival',
//assigns the icon image set above to the marker.
icon: markerIconGlastonbury,
//assigns the icon shape set above to the marker.
shape: markerShapeGlastonbury,
//sets the z-index of the map marker.
zIndex:102
});
您可以从本页顶部下载完整的html文件,或查看实时版本 。 目前,我只添加了一个地图标记…显然,我会在不久后添加更多标记!
关于Z索引的快速说明
元素(例如地图标记)可以同时具有x,y和z坐标。 Z索引是深度。 它决定了元素如何“堆叠”在彼此之上,以及如何重叠。
如果元素的x和y坐标相同,则具有较高z索引的元素将显示在具有较低z索引的元素的顶部。 (Z索引仅适用于定位的元素,例如相对,固定或绝对)。
到目前为止,地图看起来还可以,因为默认情况下,Google Maps API会为屏幕下方显示的元素提供更高的z索引,因此它们会出现在屏幕上方稍稍上方的项目上方。 例如,怀特岛(Isle of Wight)图标位于格拉斯顿伯里(Glastonbury)和雷丁音乐节(Reading Festival)图标的顶部(请参见下图)。
在本教程的后面,我们将介绍如何更改z索引来操纵地图标记的显示方式。
更改颜色和细节级别
尽管该地图已开始成形,但默认地图与我要实现的总体效果并不完全匹配。 幸运的是,使用API的“样式”选项来自定义地图外观非常简单。
在这一点上,我还应该说我只是参加了一些音乐节来说明这个例子。 这有点随机,我的选择并不能反映我对任何节日的支持或反对意见!
第1步
使用JSON向导来锻炼您希望地图的外观。 您可以更改几乎所有内容的颜色,添加和删除细节,分别设置颜色填充和几何形状等。值得花一些时间来习惯它的工作方式。 (如果您想知道, JSON只是一种格式化信息的方式,因此计算机可以读取它。)
第2步
当您对JSON向导预览中显示的样式感到满意时,请单击Show JSON按钮并复制代码。
第三步
返回到html文档,在打开JavaScript标记之后添加一个变量来保存此信息,然后粘贴代码。
//First, we read in the data describing style.
var style_festival = [
{
"featureType": "administrative",
"stylers": [
{ "visibility": "off" }
]
},{
"featureType": "poi",
"stylers": [
{ "visibility": "off" }
]
},{
"featureType": "transit",
"stylers": [
{ "visibility": "off" }
]
},{
"featureType": "road",
"stylers": [
{ "visibility": "off" }
]
},{
"featureType": "landscape",
"stylers": [
{ "color": "#FFE200" }
]
},{
"featureType": "water",
"stylers": [
{ "visibility": "on" },
{ "color": "#4f92c6" }
]
}
];
第4步
您需要获取地图,才能将刚刚添加的信息视为地图样式。 使用StyledMapType
可以做到这一点。
//Then we use this data to create the styles.
var styled_festival = new google.maps.StyledMapType(style_festival, {name: "Festival style"});
第5步
最后,您需要将新样式分配给地图以“激活”样式。
festivalMap.mapTypes.set('map_styles_festival', styled_festival);
festivalMap.setMapTypeId('map_styles_festival');
请使用本教程开始处的链接下载到目前为止的地图代码副本,或查看本部分教程的实时演示 。 我实际上添加了两种样式。 一个会立即被激活,另一个将在缩放地图以提供更多细节时被激活。 (这将在下面进一步解释。)
这时我也忍不住要添加背景:)看一下body
CSS选择器,看看我是怎么做到的。
弹出框和动态缩放
好的,现在该让地图实际做些事情了! 您可以使用内置的信息窗口叠加 ,但他们并不看起来棒极了 ,他们不能轻易进行定制。 因此,我们将使用信息框库。
第1步
下载Infobox库的副本。 解压缩,并将其存储在靠近地图的文件夹中。 然后在您的html文件顶部附近添加此行。
<script src="infobox/infobox.js" type="text/javascript"></script>
第2步
为每个地图标记添加z索引,以使靠近屏幕底部的z索引显示在上方的z索引的上方。 (即标记离屏幕底部越近,其z索引应该越高。)稍后将显示所有有关您为什么这样做的标记! 例如 -
//Creating the Glastonbury map marker.
markerGlastonbury = new google.maps.Marker({
//uses the position set above.
position: markerPositionGlastonbury,
//adds the marker to the map.
map: festivalMap,
title: 'Glastonbury Festival',
//assigns the icon image set above to the marker.
icon: markerIconGlastonbury,
//assigns the icon shape set above to the marker.
shape: markerShapeGlastonbury,
//sets the z-index of the map marker.
zIndex:107
});
第三步
在每个地图标记之后添加以下代码。 请通读代码中的注释以查看其作用。
//Creates the information to go in the pop-up info box.
var boxTextGlastonbury = document.createElement("div");
boxTextGlastonbury.style.cssText = pop_up_info;
boxTextGlastonbury.innerHTML = '<span class="pop_up_box_text"><img src="content/glastonbury.jpg" width="400" height="285" border="0" /></span>';
//Sets up the configuration options of the pop-up info box.
var infoboxOptionsGlastonbury = {
content: boxTextGlastonbury
,disableAutoPan: false
,maxWidth: 0
,pixelOffset: new google.maps.Size(-241, 0)
,zIndex: null
,boxStyle: {
background: "url('infobox/pop_up_box_top_arrow.png') no-repeat"
,opacity: 1
,width: "430px"
}
,closeBoxMargin: "10px 2px 2px 2px"
,closeBoxURL: "icons/button_close.png"
,infoBoxClearance: new google.maps.Size(1, 1)
,isHidden: false
,pane: "floatPane"
,enableEventPropagation: false
};
//Creates the pop-up infobox for Glastonbury, adding the configuration options set above.
infoboxGlastonbury = new InfoBox(infoboxOptionsGlastonbury);
//Add an 'event listener' to the Glastonbury map marker to listen out for when it is clicked.
google.maps.event.addListener(markerGlastonbury, "click", function (e) {
//Open the Glastonbury info box.
infoboxGlastonbury.open(festivalMap, this);
//Changes the z-index property of the marker to make the marker appear on top of other markers.
this.setZIndex(google.maps.Marker.MAX_ZINDEX + 1);
//Zooms the map.
setZoomWhenMarkerClicked();
//Sets the Glastonbury marker to be the center of the map.
festivalMap.setCenter(markerGlastonbury.getPosition());
});
第4步
在上面的代码中,您调用了setZoomWhenMarkerClicked
函数。 当有人单击标记时,这将放大地图。 但是在您创建此功能之前,绝不会发生很多事情! 这是您需要创建的功能-
function setZoomWhenMarkerClicked(){
var currentZoom = festivalMap.getZoom();
if (currentZoom < 7){
festivalMap.setZoom(7);
}
}
第5步
随着地图放大,您可能希望在地图上显示更多细节。 通过添加事件侦听器并使用getZoom
方法连续检查缩放是否已完成,可以完成此操作。 如果已增加(级别6以上),则setMapTypeId
方法用于设置上面定义的第二种(更详细的)样式。
//Continuously listens out for when the zoom level changes. This includs when the map zooms when a marker is clicked.
google.maps.event.addListener(festivalMap, "zoom_changed", function() {
var newZoom = festivalMap.getZoom();
//If the map is zoomed in, the switch to the style that shows the higher level of detail.
if (newZoom > 6){
festivalMap.setMapTypeId('map_styles_festival_zoomed');
}
//Otherwise the map must be zoomed out, so use the style with the lower level of detail.
else {
festivalMap.setMapTypeId('map_styles_festival');
}
});
第6步
使用CSS为信息框设置样式,使其看起来更漂亮。
//Variable containing the style for the pop-up infobox.
var pop_up_info = "border: 0px solid black; background-color: #ffffff; padding:15px; margin-top: 8px; border-radius:10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; box-shadow: 1px 1px #888;";
步骤7
打开信息框后,地图标记将显示在最前面。 但是,如果关闭信息框,然后将地图缩小到原始位置,则标记将保留在前面。 这看起来很奇怪。
在步骤1中,为每个标记设置z-index。 您现在可以使用它来解决此问题。 您需要创建一个将z-index重置为其原始值的函数(即resetZindexes)
,然后向resetZindexes();)
添加对该函数的调用(即resetZindexes();)
以触发该函数在信息框运行时运行窗口关闭。
转到此页面顶部的链接,以获取到目前为止该站点代码的副本,或者查看此站点的实时版本 。 我只添加了Glastonbury的弹出窗口。 随意自己添加其他人!
定制横幅和导航
我们几乎可以自定义地图的外观了,但是在每天称呼它之前,我们应该添加一些导航控件。
Google地图有12个区域 ,您可以在其中添加地图控件,横幅等。您可以完全自定义这些区域,添加所需的任何html等。
我们将在地图的右侧添加自定义横幅和导航。
第1步
首先,首先定义一个函数来创建菜单。 此代码提取相当长……
//Function that creates the control panel area, ie. the map title and the 2 buttons just beneath it.
function createControlPanel (controlPanelDiv){
controlPanelDiv.style.padding = '0px';
controlUI = document.createElement('div');
controlUI.style.border='0px solid white';
controlUI.style.margin='10px';
controlUI.style.paddingTop='11px';
controlUI.style.paddingBottom='5px';
controlUI.style.paddingLeft='0px';
controlUI.style.paddingRight='0px';
controlUI.style.width='245px';
controlUI.style.height='419px';
controlPanelDiv.appendChild(controlUI);
//Map title
titleBar = document.createElement('div');
titleBar.style.backgroundColor = '#89CBED';
titleBar.style.height='255px';
titleBar.style.width='245px';
titleBar.style.marginTop='0px';
titleBar.style.marginBottom='0px';
titleBar.style.marginLeft='0px';
titleBar.style.marginRight='0px';
titleBar.style.paddingTop='6px';
titleBar.style.paddingBottom='2px';
titleBar.style.paddingLeft='0px';
titleBar.style.paddingRight='0px';
titleBar.style.borderTopLeftRadius='5px';
titleBar.style.borderTopRightRadius='5px';
titleBar.style.borderBottomLeftRadius='0px';
titleBar.style.borderBottomLeftRadius='0px';
titleBar.style.cssFloat='left';
titleBar.innerHTML = '<div align="center"><img src="icons/map_title.png" width="230" height="252" border="0"/></div>';
controlUI.appendChild(titleBar);
yellowStripe = document.createElement('div');
yellowStripe.style.backgroundColor = '#FFFF00';
yellowStripe.style.height='2px';
yellowStripe.style.width='245px';
yellowStripe.style.marginTop='3px';
yellowStripe.style.marginBottom='3px';
yellowStripe.style.marginLeft='0px';
yellowStripe.style.marginRight='0px';
yellowStripe.style.paddingTop='0px';
yellowStripe.style.paddingBottom='0px';
yellowStripe.style.paddingLeft='0px';
yellowStripe.style.paddingRight='0px';
yellowStripe.style.cssFloat='left';
yellowStripe.style.fontFamily='Georgia, serif';
yellowStripe.style.fontSize='14px';
controlUI.appendChild(yellowStripe);
//'Smaller' events button.
smallEvents = document.createElement('div');
smallEvents.style.height='108px';
smallEvents.style.width='129px';
smallEvents.style.marginTop='0px';
smallEvents.style.marginBottom='0px';
smallEvents.style.marginLeft='0px';
smallEvents.style.marginRight='0px';
smallEvents.style.paddingTop='0px';
smallEvents.style.paddingBottom='2px';
smallEvents.style.paddingLeft='0px';
smallEvents.style.paddingRight='0px';
smallEvents.style.cssFloat='left';
smallEvents.innerHTML = '<div align="center" onClick="handelRequests(\'small_events\')" OnMouseOver="this.style.cursor=\'pointer\';" OnMouseOut="this.style.cursor=\'default\';"><img src="icons/button_small_event.png" width="128" height="107" border="0"/></div>';
controlUI.appendChild(smallEvents);
//Umbrella button
brolly = document.createElement('div');
brolly.style.height='149px';
brolly.style.width='94px';
brolly.style.marginTop='0px';
brolly.style.marginBottom='0px';
brolly.style.marginLeft='0px';
brolly.style.marginRight='0px';
brolly.style.paddingTop='0px';
brolly.style.paddingBottom='2px';
brolly.style.paddingLeft='0px';
brolly.style.paddingRight='0px';
brolly.style.cssFloat='left';
brolly.innerHTML = '<div align="center" onClick="handelRequests(\'rainfall\')" OnMouseOver="this.style.cursor=\'pointer\';" OnMouseOut="this.style.cursor=\'default\';"><img src="icons/button_brolly.png" width="93" height="148" border="0"/></div>';
controlUI.appendChild(brolly);
}
关于样式的快速说明:上面的代码使用元素的style
属性来使用JavaScript定义其样式。 要将CSS属性转换为其JavaScript表示法,只需记住没有连字符的属性保持不变,而将具有连字符的属性转换为camelCase ,例如background-image变为backgroundImage。 例外是float
,它变成cssFloat
。
第2步
然后,创建一个div来保存菜单,然后通过调用您在步骤1中刚刚创建的函数将菜单添加到该div中。
//Create control panel (ie. site title and 2 buttons) which appears on the right-hand side.
var controlPanelDiv = document.createElement('div');
var festivalMapControlPanel = new createControlPanel(controlPanelDiv, festivalMap);
第三步
然后设置地图的controls
属性,以将菜单添加到相关位置,在本例中为RIGHT_TOP
。
//Add the control panel and reset button (created previously) to the map.
festivalMap.controls[google.maps.ControlPosition.RIGHT_TOP].push(controlPanelDiv);
第4步
到现在,您应该拥有一些看起来像自定义菜单的内容,该菜单显示在地图的右侧。 所以剩下要做的就是让您的菜单做某事...
在接下来的教程中,我们将使用“较小事件”按钮显示Flickr的照片,并使用“雨伞”按钮显示草绘的降雨图叠加层。 (我知道这是陈词滥调,但夏季确实有很多降雨!)
因此,为了使本教程发挥作用,我重复了上述步骤,还向RIGHT_BOTTOM
区域添加了一个Reset按钮。 这包括在“重置”按钮周围包装代码以调用handelRequests
函数。
//Function that creates the 'Reser map' button.
function createResetButton (resetButtonDiv){
resetButtonDiv.style.padding = '0px';
controlUI2 = document.createElement('div');
controlUI2.style.backgroundColor = '#ffffff';
controlUI2.style.borderRadius='5px';
controlUI2.style.margin='10px';
controlUI2.style.paddingTop='2px';
controlUI2.style.paddingBottom='2px';
controlUI2.style.paddingLeft='2px';
controlUI2.style.paddingRight='5px';
controlUI2.style.textAlign='center';
controlUI2.style.width='148px';
controlUI2.style.height='31px';
controlUI2.innerHTML = '<div onClick="handelRequests(\'reset\')" OnMouseOver="this.style.cursor=\'pointer\';" OnMouseOut="this.style.cursor=\'default\';" ><img src="icons/button_reset.png" width="148" height="31" border="0"/></div>';
resetButtonDiv.appendChild(controlUI2);
}
第5步
handelRequests
函数可以做一些事情-查看代码中的注释。
//Function that is called when either the 'smaller events', unbrella or the 'reset map' buttons are clicked.
function handelRequests (buttonPressed) {
if (buttonPressed === "reset"){
//Resets the zoom, map position and marker z-indexes back to their orignal position. Also closes all infoboxes currently open.
festivalMap.setZoom(festivalMapZoom);
festivalMap.setCenter(festivalMapCenter);
resetZindexes();
//This is a function I've created that closes any info boxes that are open.
closeAllInfoboxes();
}
else if (buttonPressed === "small_events"){
alert("This button will do something useful in a later tutorial!");
}
else if (buttonPressed === "rainfall"){
alert("This button will do something useful in a later tutorial!");
}
}
您可以从此页面顶部获得该教程本部分的html文件的完整副本,或查看实时示例 。 在此示例中,仅Glastonbury地图标记处于活动状态。
接下来是什么?
本教程就是这样! 希望您现在可以进行一些工作,与本页面顶部的图片大致相似。 如果出现问题,请浏览GitHub上的可下载文件 。 我已将代码包含在本教程每个部分的单独文件中,因此您应该能够找出所有错误所在。
下一个教程将探讨如何使用Google maps API将自己的地图(例如汉诺德或历史地图)栩栩如生,使其可缩放和交互。
图片积分
本教程中使用的照片均已根据知识共享许可发布。
- 怀特岛-Tiggy拍摄
- 阅读-克里斯·福特(Chris Ford)拍摄
- 格拉斯顿伯里-Stig Nygaard摄
- 格拉斯顿伯里(弹出图像)-Wonker摄
- 秘密花园-乔安妮·平克尼拍摄
- 纬度-Mike Mantin拍摄
- 利兹-伊恩·威尔逊拍摄
- 公园里的T-伊恩·欧德汉(Ian Oldham)拍摄
- 岩石-菲尔(Phil)和帕姆(Pam Gradwell)摄
- 格拉斯哥伯里-本·安德鲁斯摄
- Backgroung图片-Wonker拍摄
翻译自: https://webdesign.tutsplus.com/tutorials/getting-creative-with-the-google-maps-api--webdesign-13380
maps-api-v3