@capacitor/google-maps
Capacitor 上的 Google 地图
安装
npm install @capacitor/google-maps
npx cap sync
API 密钥
要在任何平台上使用 Google Maps SDK,都需要获取与启用了结算功能的帐户相关联的 API 密钥。这些密钥可以从 Google Cloud Console 获取。这对于 Android、iOS 和 JavaScript 所有三个平台都是必需的。有关获取这些 API 密钥的更多信息,可以在每个平台的 Google Maps 文档 中找到。
iOS
Google Maps SDK 支持通过 enableCurrentLocation(bool) 显示用户的当前位置。要使用此功能,Apple 要求在 Info.plist 中指定隐私描述:
NSLocationAlwaysUsageDescription(隐私 - 始终使用位置说明)NSLocationWhenInUseUsageDescription(隐私 - 使用时使用位置说明)
在 iOS 指南 中阅读有关 配置 Info.plist 的更多信息,了解如何在 Xcode 中设置 iOS 权限。
主 Google Maps SDK 现在支持在 Apple Silicon Mac 的模拟器上运行,但请确保安装了最新版本的 Google-Maps-iOS-Utils。
如果您之前为获取未发布版本添加了变通方法,现在可以通过从 ios/App/Podfile 中删除以下行来移除它:
pod 'Google-Maps-iOS-Utils', :git => 'https://github.com/googlemaps/google-maps-ios-utils.git', :commit => '637954e5bcb2a879c11a6f2cead153a6bad5339f'
然后从 ios/App/ 文件夹运行 pod update Google-Maps-iOS-Utils:
cd ios/App
pod update Google-Maps-iOS-Utils
Android
适用于 Android 的 Google Maps SDK 要求您将 API 密钥添加到项目中的 AndroidManifest.xml 文件。
<meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR_API_KEY_HERE"/>
要使用某些定位功能,SDK 还要求将以下权限添加到您的 AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
变量
此插件将使用以下项目变量(定义在您应用的 variables.gradle 文件中):
googleMapsPlayServicesVersion:com.google.android.gms:play-services-maps的版本(默认:18.1.0)googleMapsUtilsVersion:com.google.maps.android:android-maps-utils的版本(默认:3.4.0)googleMapsKtxVersion:com.google.maps.android:maps-ktx的版本(默认:3.4.0)googleMapsUtilsKtxVersion:com.google.maps.android:maps-utils-ktx的版本(默认:3.4.0)kotlinxCoroutinesVersion:org.jetbrains.kotlinx:kotlinx-coroutines-android和org.jetbrains.kotlinx:kotlinx-coroutines-core的版本(默认:1.6.4)androidxCoreKTXVersion:androidx.core:core-ktx的版本(默认:1.10.0)kotlin_version:org.jetbrains.kotlin:kotlin-stdlib的版本(默认:1.8.20)
使用
Google Maps Capacitor 插件附带一个 Web 组件,必须在您的应用程序中使用它来渲染地图,因为它使我们能够在 iOS 上更有效地嵌入原生视图。该插件将自动注册此 Web 组件以供您的应用程序使用。
对于 Angular 用户,您会收到一个错误警告,提示 Angular 编译器不认识此 Web 组件。通过修改声明组件的模块以允许自定义 Web 组件可以解决此问题。
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
在您的 HTML 中包含此组件,并为其分配一个 ID,以便稍后可以轻松查询该元素引用。
<capacitor-google-map id="map"></capacitor-google-map>
在 Android 上,地图渲染在整个 WebView 下方,并使用此组件在滚动事件期间管理其定位。这意味着作为开发者,您必须确保 WebView 从各层一直到最底部都是透明的。在典型的 Ionic 应用程序中,这意味着在诸如 IonContent 和根 HTML 标签等元素上设置透明度,以确保可以看见地图。如果在 Android 上看不到您的地图,这应该是您首先检查的事项。
在 iOS 上,我们直接将地图渲染到 WebView 中,因此不需要相同的透明度效果。我们仍在研究 Android 的替代方法,并希望在未来的更新中更好地解决此问题。
Google Map 元素本身没有样式,因此您应该设置其样式以适合页面结构的布局。因为我们正在向此插槽渲染一个视图,所以元素本身没有宽度或高度,请务必显式设置它们。
capacitor-google-map {
display: inline-block;
width: 275px;
height: 400px;
}
接下来,我们应该创建地图引用。这是通过从 Capacitor 插件导入 GoogleMap 类并调用 create 方法,并传入所需的参数来完成的。
import { GoogleMap } from '@capacitor/google-maps';
const apiKey = 'YOUR_API_KEY_HERE';
const mapRef = document.getElementById('map');
const newMap = await GoogleMap.create({
id: 'my-map', // 此地图实例的唯一标识符
element: mapRef, // 对 capacitor-google-map 元素的引用
apiKey: apiKey, // 您的 Google Maps API 密钥
config: {
center: {
// 地图初始渲染的位置
lat: 33.6,
lng: -117.9,
},
zoom: 8, // 地图初始渲染的缩放级别
},
});
此时,您的地图应该在您的应用程序中创建完成。使用返回的地图引用,您可以以多种方式轻松地与地图交互,这里展示了其中几种。
const newMap = await GoogleMap.create({...});
// 向地图添加标记
const markerId = await newMap.addMarker({
coordinate: {
lat: 33.6,
lng: -117.9
}
});
// 以编程方式移动地图
await newMap.setCamera({
coordinate: {
lat: 33.6,
lng: -117.9
}
});
// 启用标记聚类
await newMap.enableClustering();
// 处理标记点击
await newMap.setOnMarkerClickListener((event) => {...});
// 清理地图引用
await newMap.destroy();
完整示例
Angular
import { GoogleMap } from '@capacitor/google-maps';
@Component({
template: `
<capacitor-google-map #map></capacitor-google-map>
<button (click)="createMap()">创建地图</button>
`,
styles: [
`
capacitor-google-map {
display: inline-block;
width: 275px;
height: 400px;
}
`,
],
})
export class MyMap {
@ViewChild('map')
mapRef: ElementRef<HTMLElement>;
newMap: GoogleMap;
async createMap() {
this.newMap = await GoogleMap.create({
id: 'my-cool-map',
element: this.mapRef.nativeElement,
apiKey: environment.apiKey,
config: {
center: {
lat: 33.6,
lng: -117.9,
},
zoom: 8,
},
});
}
}
```### React
```jsx
import { GoogleMap } from '@capacitor/google-maps';
import { useRef } from 'react';
const MyMap: React.FC = () => {
const mapRef = useRef<HTMLElement>();
let newMap: GoogleMap;
async function createMap() {
if (!mapRef.current) return;
newMap = await GoogleMap.create({
id: 'my-cool-map',
element: mapRef.current,
apiKey: process.env.REACT_APP_YOUR_API_KEY_HERE,
config: {
center: {
lat: 33.6,
lng: -117.9
},
zoom: 8
}
})
}
return (
<div className="component-wrapper">
<capacitor-google-map ref={mapRef} style={{
display: 'inline-block',
width: 275,
height: 400
}}></capacitor-google-map>
<button onClick={createMap}>创建地图</button>
</div>
)
}
export default MyMap;
Javascript
<capacitor-google-map id="map"></capacitor-google-map>
<button onclick="createMap()">创建地图</button>
<style>
capacitor-google-map {
display: inline-block;
width: 275px;
height: 400px;
}
</style>
<script>
import { GoogleMap } from '@capacitor/google-maps';
const createMap = async () => {
const mapRef = document.getElementById('map');
const newMap = await GoogleMap.create({
id: 'my-map', // 地图实例的唯一标识符
element: mapRef, // 指向 capacitor-google-map 元素的引用
apiKey: 'YOUR_API_KEY_HERE', // 你的 Google Maps API 密钥
config: {
center: {
// 地图初始渲染的中心位置
lat: 33.6,
lng: -117.9,
},
zoom: 8, // 地图初始渲染的缩放级别
},
});
};
</script>
API
create(...)enableTouch()disableTouch()enableClustering(...)disableClustering()addMarker(...)addMarkers(...)removeMarker(...)removeMarkers(...)addPolygons(...)removePolygons(...)addCircles(...)removeCircles(...)addPolylines(...)removePolylines(...)destroy()setCamera(...)getMapType()setMapType(...)enableIndoorMaps(...)enableTrafficLayer(...)enableAccessibilityElements(...)enableCurrentLocation(...)setPadding(...)fitBounds(...)setOnBoundsChangedListener(...)setOnCameraIdleListener(...)setOnCameraMoveStartedListener(...)setOnClusterClickListener(...)setOnClusterInfoWindowClickListener(...)setOnInfoWindowClickListener(...)setOnMapClickListener(...)setOnMarkerClickListener(...)setOnPolygonClickListener(...)setOnCircleClickListener(...)setOnPolylineClickListener(...)setOnMarkerDragStartListener(...)setOnMarkerDragListener(...)setOnMarkerDragEndListener(...)setOnMyLocationButtonClickListener(...)setOnMyLocationClickListener(...)- 接口
- 类型别名
- 枚举
create(...)
create(options: CreateMapArgs, callback?: MapListenerCallback<MapReadyCallbackData> | undefined) => Promise<GoogleMap>
| 参数 | 类型 |
|---|---|
options | |
callback | |
返回值: Promise<GoogleMap>
enableTouch()
enableTouch() => Promise<void>
disableTouch()
disableTouch() => Promise<void>
enableClustering(...)
enableClustering(minClusterSize?: number | undefined) => Promise<void>
| 参数 | 类型 | 描述 |
|---|---|---|
minClusterSize | number | 可以聚合成一个标记簇的最小标记数量。默认值为 4 个标记。 |
disableClustering()
disableClustering() => Promise<void>
addMarker(...)
addMarker(marker: Marker) => Promise<string>
| 参数 | 类型 |
|---|---|
marker | |
返回值: Promise<string>
addMarkers(...)
addMarkers(markers: Marker[]) => Promise<string[]>
| 参数 | 类型 |
|---|---|
markers | Marker[] |
返回值: Promise<string[]>
removeMarker(...)
removeMarker(id: string) => Promise<void>
| 参数 | 类型 |
|---|---|
id | string |
removeMarkers(...)
removeMarkers(ids: string[]) => Promise<void>
| 参数 | 类型 |
|---|---|
ids | string[] |
addPolygons(...)
addPolygons(polygons: Polygon[]) => Promise<string[]>
| 参数 | 类型 |
|---|---|
polygons | Polygon[] |
返回值: Promise<string[]>
--------------------### removePolygons(...)
removePolygons(ids: string[]) => Promise<void>
| 参数 | 类型 |
|---|---|
ids | string[] |
addCircles(...)
addCircles(circles: Circle[]) => Promise<string[]>
| 参数 | 类型 |
|---|---|
circles | Circle[] |
返回值: Promise<string[]>
removeCircles(...)
removeCircles(ids: string[]) => Promise<void>
| 参数 | 类型 |
|---|---|
ids | string[] |
addPolylines(...)
addPolylines(polylines: Polyline[]) => Promise<string[]>
| 参数 | 类型 |
|---|---|
polylines | Polyline[] |
返回值: Promise<string[]>
removePolylines(...)
removePolylines(ids: string[]) => Promise<void>
| 参数 | 类型 |
|---|---|
ids | string[] |
destroy()
destroy() => Promise<void>
setCamera(...)
setCamera(config: CameraConfig) => Promise<void>
| 参数 | 类型 |
|---|---|
config | |
getMapType()
getMapType() => Promise<MapType>
获取当前地图类型
返回值:
Promise<MapType>
setMapType(...)
setMapType(mapType: MapType) => Promise<void>
| 参数 | 类型 |
|---|---|
mapType | |
enableIndoorMaps(...)
enableIndoorMaps(enabled: boolean) => Promise<void>
| 参数 | 类型 |
|---|---|
enabled | boolean |
enableTrafficLayer(...)
enableTrafficLayer(enabled: boolean) => Promise<void>
| 参数 | 类型 |
|---|---|
enabled | boolean |
enableAccessibilityElements(...)
enableAccessibilityElements(enabled: boolean) => Promise<void>
| 参数 | 类型 |
|---|---|
enabled | boolean |
enableCurrentLocation(...)
enableCurrentLocation(enabled: boolean) => Promise<void>
| 参数 | 类型 |
|---|---|
enabled | boolean |
setPadding(...)
setPadding(padding: MapPadding) => Promise<void>
| 参数 | 类型 |
|---|---|
padding | |
fitBounds(...)
fitBounds(bounds: LatLngBounds, padding?: number | undefined) => Promise<void>
设置地图视口以包含给定的边界区域。
| 参数 | 类型 | 描述 |
|---|---|---|
bounds | LatLngBounds | 要适配到视口中的边界区域。 |
padding | number | 可选,以像素为单位的边距。边界区域将被适配到地图去除边距后剩余的区域内。 |
setOnBoundsChangedListener(...)
setOnBoundsChangedListener(callback?: MapListenerCallback<CameraIdleCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnCameraIdleListener(...)
setOnCameraIdleListener(callback?: MapListenerCallback<CameraIdleCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnCameraMoveStartedListener(...)
setOnCameraMoveStartedListener(callback?: MapListenerCallback<CameraMoveStartedCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnClusterClickListener(...)
setOnClusterClickListener(callback?: MapListenerCallback<ClusterClickCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
--------------------### setOnClusterInfoWindowClickListener(...)
setOnClusterInfoWindowClickListener(callback?: MapListenerCallback<ClusterClickCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnInfoWindowClickListener(...)
setOnInfoWindowClickListener(callback?: MapListenerCallback<MarkerClickCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnMapClickListener(...)
setOnMapClickListener(callback?: MapListenerCallback<MapClickCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnMarkerClickListener(...)
setOnMarkerClickListener(callback?: MapListenerCallback<MarkerClickCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnPolygonClickListener(...)
setOnPolygonClickListener(callback?: MapListenerCallback<PolygonClickCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnCircleClickListener(...)
setOnCircleClickListener(callback?: MapListenerCallback<CircleClickCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnPolylineClickListener(...)
setOnPolylineClickListener(callback?: MapListenerCallback<PolylineCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnMarkerDragStartListener(...)
setOnMarkerDragStartListener(callback?: MapListenerCallback<MarkerClickCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnMarkerDragListener(...)
setOnMarkerDragListener(callback?: MapListenerCallback<MarkerClickCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
setOnMarkerDragEndListener(...)
setOnMarkerDragEndListener(callback?: MapListenerCallback<MarkerClickCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |
--------------------### setOnMyLocationButtonClickListener(...)
setOnMyLocationButtonClickListener(callback?: MapListenerCallback<MyLocationButtonClickCallbackData> | undefined) => Promise<void>
| 参数 | 类型 |
|---|---|
callback | |