一、注册账号
-
Google map platform 去Get started。
二、使用Google Cloud
三、使用API密钥
四、开始使用
准备工作 加载MAPJS
-
方式一 旧版本脚本加载(适用于非SPA应用)
index.html插入 -
方式二 旧版本脚本加载(适用SPA/微前端)
这种方式本质上和方式一是一致的,不过此种方式多一种弊端,多次进入页面会导致页面上一直append 这段js进去,不推荐此方式。const MAPAPISCHEME = "maps.googleapis.com/maps/api/js… YOUR GOOGLE MAP KEY }&callback=initMap&libraries=drawing" const script = document.createElement('script'); script.src = MAPAPISCHEME; document.body.appendChild(script);
必需参数(旧版)
加载 Maps JavaScript API 时必须提供以下参数。
- key:您的 API 密钥。除非指定了有效的 API 密钥,否则 Maps JavaScript API 不会加载。
- callback:Maps JavaScript API 完全加载后要调用的全局函数的名称。
可选参数(旧版)
使用这些参数可以请求特定版本的 Maps JavaScript API、加载其他库、将地图本地化或指定 HTTP 引荐来源网址检查政策
- v:要使用的 Maps JavaScript API 的版本。
- libraries:要加载的其他 Maps JavaScript API 库的逗号分隔列表。
- language:要使用的语言。该参数会影响控件名称、版权通知、行车路线、控件标签和对服务请求的响应。请参阅支持的语言列表。
- region:要使用的区域代码。它会根据给定国家或地区更改地图的行为。
- solution_channel:Google Maps Platform 提供了许多类型的示例代码,可帮助您快速上手。为了跟踪更复杂的代码示例的采用情况并提高解决方案质量,Google 在示例代码的 API 调用中添加了 solution_channel 查询参数。注意:此查询参数仅供 Google 使用。如需了解详情,请参阅 Google Maps Platform 解决方案参数。
- auth_referrer_policy:Maps JS 客户可以在 Cloud 控制台中配置 HTTP 引荐来源网址限制,以限制哪些网址可以使用特定的 API 密钥。默认情况下,这类限制可以配置为仅允许某些路径使用某个 API 密钥。如果同一网域或同一来源的任何网址都可以使用该 API 密钥,您可以在授权来自 Maps JavaScript API 的请求时设置 auth_referrer_policy=origin,以限制发送的数据量。此参数从版本 3.46 开始提供。如果指定了此参数并且在 Cloud 控制台中启用了 HTTP 引荐来源网址限制,则只有在 HTTP 引荐来源网址限制与当前网站的网域匹配(未指定路径)的情况下,Maps JavaScript API 才能加载。
-
方式三 使用NPM加载
-
安装 npm install @googlemaps/js-api-loader
import { Loader } from "@googlemaps/js-api-loader"
const loader = new Loader({ apiKey: "YOUR_API_KEY", version: "weekly", ...additionalOptions, });
loader.load().then(async () => { const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary; map = new Map(document.getElementById("map") as HTMLElement, { center: { lat: -34.397, lng: 150.644 }, zoom: 8, }); });
-
方式三 使用动态库(适用非SPA/SPA/微前端)
异步加载,没有那么多乱七八糟的bug,推荐此方式 -
将内嵌引导加载程序加载器添加到应用代码中,以加载 Maps JavaScript API,如以下代码段所示:
其中参数示意如下:
必填参数
- key:您的 API 密钥。除非指定了有效的 API 密钥,否则 Maps JavaScript API 不会加载。
可选参数
- v:要加载的 Maps JavaScript API 的版本。
- libraries:要加载的其他 Maps JavaScript API 库的逗号分隔列表。通常不建议指定一组固定的库,但对于希望微调其网站上的缓存行为的开发者,不妨使用。
- language:要使用的语言。该参数会影响控件名称、版权通知、行车路线、控件标签和对服务请求的响应。请参阅支持的语言列表。
- region:要使用的区域代码。它会根据给定国家或地区更改地图的行为。
- solutionChannel:Google Maps Platform 提供了许多类型的示例代码,可帮助您快速上手。为了跟踪更复杂的代码示例的采用情况并提高解决方案质量,Google 在示例代码的 API 调用中添加了 solutionChannel 查询参数。
- authReferrerPolicy:Maps JS 客户可以在 Cloud 控制台中配置 HTTP 引荐来源网址限制,以限制哪些网址可以使用特定的 API 密钥。默认情况下,这类限制可以配置为仅允许某些路径使用某个 API 密钥。如果同一网域或同一来源的任何网址都可以使用该 API 密钥,您可以在授权来自 Maps JavaScript API 的请求时设置 authReferrerPolicy: "origin",以限制发送的数据量。如果指定了此参数并且在 Cloud 控制台中启用了 HTTP 引荐来源网址限制,则只有在 HTTP 引荐来源网址限制与当前网站的网域(未指定路径)匹配的情况下,Maps JavaScript API 才会加载。
迁移到 Dynamic Library Import API
首先,将旧版脚本加载代码替换为内嵌引导加载程序加载器代码。
之前
<script async
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
之后
接下来,更新您的应用代码:
- 将 initMap() 函数更改为异步函数。
- 调用 importLibrary() 以加载并访问所需的库。
之前
let map;
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
}
window.initMap = initMap;
之后
let map;
// initMap is now async
async function initMap() {
// Request libraries when needed, not in the script tag.
const { Map } = await google.maps.importLibrary("maps");
// Short namespaces can be used.
map = new Map(document.getElementById("map"), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
}
initMap();
typescript
-
安装类型语言包
npm i -D @types/google.maps
-
使用
let map: google.maps.Map; const center: google.maps.LatLngLiteral = {lat: 30, lng: -110};
function initMap(): void { map = new google.maps.Map(document.getElementById("map") as HTMLElement, { center, zoom: 8 }); }
最佳实践
<script>
(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
key: "YOUR_API_KEY_HERE",
libraries:'drawing'
// Add other bootstrap parameters as needed, using camel case.
// Use the 'v' parameter to indicate the version to load (alpha, beta, weekly, etc.)
});
</script>
<script setup lang="ts">
import { IndoesiaPoint } from '@/global/const'
import { watchEffect } from 'vue'
let map: google.maps
const initMap = async () => {
const center = IndoesiaPoint
const { Map } = await google.maps.importLibrary('maps')
map = new Map(document.getElementById('map'), {
zoom: 8,
center,
mapTypeControl: true,
zoomControl: true
})
}
watchEffect(() => {
console.log('watchEffect')
initMap()
})
</script>
<template>
<div class="page-map">
<div id="map"></div>
</div>
</template>
<style scoped lang="less">
.page-map {
height: 100vh;
width: 100vw;
}
#map {
/* The height is 400 pixels */
width: 100%;
height: 100%;
/* The width is the width of the web page */
border-radius: 10px;
#content {
color: red;
}
}
</style>
效果
五、Marker
使用marker
google.maps.Marker 类
通过调用 const {Marker} = await google.maps.importLibrary("marker")进行使用。
最佳实践
marker
<script setup lang="ts">
import { IndoesiaPoint } from '@/global/const'
import { watchEffect } from 'vue'
let map: any
let markers: google.maps.Marker[] = []
const initMap = async () => {
const center = IndoesiaPoint
// @ts-ignore
const { Map } = await google.maps.importLibrary('maps')
map = new Map(document.getElementById('map'), {
zoom: 10,
center,
mapTypeControl: true,
zoomControl: true
})
// 加载marker
initMarker()
}
const initMarker = async () => {
// @ts-ignore
const { Marker } = await google.maps.importLibrary('marker')
// 可以循环加载多个
const marker = new Marker({
optimized: true,
position: { lat: -6.905924, lng: 107.59888 },
title: `印尼唐格朗`,
icon: '//static.xyb2b.com/images/bd56d0f777c22d4286b206ff71e7259d.svg',
map
})
markers.push(marker)
}
watchEffect(() => {
console.log('watchEffect')
initMap()
})
</script>
<template>
<div class="page-map">
<div id="map"></div>
</div>
</template>
<style scoped lang="less">
.page-map {
height: 100vh;
width: 100vw;
}
#map {
/* The height is 400 pixels */
width: 100%;
height: 100%;
/* The width is the width of the web page */
border-radius: 10px;
#content {
color: red;
}
}
</style>
添加点击事件
const initMarker = async () => {
...
marker.addListener('click', () => {
infowindow.setContent('loading...')
infowindow?.open({
anchor: marker,
map: map
})
let contentStr = '这是我想放置的数据' // 这里可以放你想显示的任何数据
infowindow.setContent(contentStr)
})
....
}
删除maerker
Tips可以通过setMap(null)来消除已经渲染的marker
外层定义一个markers ,将每一个marker push进去后每次需要删除的时候,循环markers去setMap(null)
// 删除marker
const deleteMarker = () => {
markers?.forEach((m) => {
m?.setMap(null)
})
}
六、多边形
Polyline 类 (多段线)
google.maps.Polyline 类
折线是地图上的连接线段的线性叠加层。
此类扩展了 MVCObject。
通过调用 const {Polyline} = await google.maps.importLibrary("maps") 访问。
最佳实践
<script setup lang="ts">
import { IndoesiaPoint } from '@/global/const'
import { watchEffect } from 'vue'
import type { Points } from './interface'
const iconUrl = '//static.xyb2b.com/images/a666c7fd32b9cf97848f1d271de0f1bf.svg'
let map: any
let markers: google.maps.Marker[] = []
let infowindow: google.maps.InfoWindow
let polylines: google.maps.Polyline = []
// 模拟多段线
const polylinePaths: Points[] = [
{ lat: -7.101935050883591, lng: 107.4588552036972 },
{ lat: -6.694838728520297, lng: 107.75462324500616 },
{ lat: -6.847630347242984, lng: 108.19105762732289 },
{ lat: -7.178153561208554, lng: 108.13234630024549 },
{ lat: -7.5499689900116005, lng: 107.909873169182 },
{ lat: -6.64506887158396, lng: 106.31099036415657 },
{ lat: -8.021581922136363, lng: 108.26073130399932 }
]
const initMap = async () => {
const center = IndoesiaPoint
// @ts-ignore
const { Map } = await google.maps.importLibrary('maps')
map = new Map(document.getElementById('map'), {
zoom: 10,
center,
mapTypeControl: true,
zoomControl: true
})
// @ts-ignore
const { InfoWindow } = await google.maps.importLibrary('maps')
infowindow = new InfoWindow()
// 加载marker
initMarker()
// 多段线Polyline 类
initPolyline()
}
const initMarker = async () => {
deleteMarker()
// @ts-ignore
const { Marker } = await google.maps.importLibrary('marker')
// 可以循环加载多个
const marker = new Marker({
optimized: true,
position: { lat: -6.905924, lng: 107.59888 },
title: `印尼唐格朗`,
icon: iconUrl,
map
})
marker.addListener('click', () => {
infowindow.setContent('loading...')
infowindow?.open({
anchor: marker,
map: map
})
let contentStr = '这是我想放置的数据' // 这里可以放你想显示的任何数据
infowindow.setContent(contentStr)
})
markers.push(marker)
}
// 删除marker
const deleteMarker = () => {
markers?.forEach((m) => {
m?.setMap(null)
})
}
// 批量设置marker
const setMarker = async (position: Points) => {
// @ts-ignore
const { Marker } = await google.maps.importLibrary('marker')
// 可以循环加载多个
const marker = new Marker({
optimized: true,
position: position,
title: `${Object.values(position).join(',')}`,
icon: iconUrl,
map
})
marker.addListener('click', () => {
infowindow.setContent('loading...')
infowindow?.open({
anchor: marker,
map: map
})
let contentStr = '这是我想放置的数据' // 这里可以放你想显示的任何数据
infowindow.setContent(contentStr)
})
markers.push(marker)
}
// 多段线
const initPolyline = async () => {
//@ts-ignore
const { Polyline } = await google.maps.importLibrary('maps')
const polyline = new Polyline({
map,
path: polylinePaths,
strokeColor: '#FF6801',
strokeOpacity: 0.9,
strokeWeight: 3,
clickable: false
})
polylines.push(polyline)
// 可以配合 设置marker 让路线更具体
polylinePaths.forEach((position: Points) => {
setMarker(position)
})
}
watchEffect(() => {
console.log('watchEffect')
initMap()
})
</script>
<template>
<div class="page-map">
<div id="map"></div>
</div>
</template>
<style scoped lang="less">
.page-map {
height: 100vh;
width: 100vw;
}
#map {
/* The height is 400 pixels */
width: 100%;
height: 100%;
/* The width is the width of the web page */
border-radius: 10px;
#content {
color: red;
}
}
</style>
Polygon 类(多段线闭合)
google.maps.Polygon 类
多边形(类似于折线)可定义一系列有序的相连坐标。此外,多边形会形成一个闭合环并定义一个填充区域。请参阅开发者指南中的示例,从简单的多边形、带孔的多边形开始,等等。请注意,您还可以使用数据层创建多边形。数据图层可让您更轻松地创建内环,因为它会为您处理内外侧路径的顺序。
此类扩展了 MVCObject。
通过调用 const {Polygon} = await google.maps.importLibrary("maps") 访问
最佳实践
...
// polygon类 闭合线
const initPolygon = async () => {
// @ts-ignore
const { Polygon } = await google.maps.importLibrary('maps')
const polygon = new Polygon({
path: polylinePaths,
strokeColor: '#FF6801',
strokeOpacity: 0.9,
strokeWeight: 3,
clickable: false,
fillColor: '#FF6801',
map
})
polyons.push(polygon)
}
...
附:本文源码 github.com/JolyI/googl…
未完待续
下一节: