@souriscloud/nativescript-google-maps-sdk
适用于Nativescript的Google Maps SDK插件 - 与NS8兼容
npm i --save @souriscloud/nativescript-google-maps-sdk

适用于Google Maps SDK的NativeScript插件

这是一个跨平台(iOS & Android)的Nativescript插件,用于Google Maps API

NPM version Dependency status

NPM

先决条件

iOS - 必须安装Cocoapods

Android - 必须安装最新版本的Google Play Services SDK

Google Maps API密钥 - 访问Google开发者控制台,创建项目,并启用Google Maps Android APIGoogle Maps SDK for iOS API。然后,在凭证下创建一个API密钥。

安装

使用NativeScript CLI工具安装插件

Nativescript 7+

tns plugin add @souriscloud/nativescript-google-maps-sdk

Nativescript < 7

tns plugin add [email protected]

设置

请参阅包含的示例代码此处

请参阅现场演示此处

为Android配置API密钥

Nativescript < 4

首先,将必要的模板资源文件复制到Android应用资源文件夹中

cp -r node_modules/nativescript-google-maps-sdk/platforms/android/res/values app/App_Resources/Android/

接下来,通过取消注释app/App_Resources/Android/values/nativescript_google_maps_api.xml文件中的nativescript_google_maps_api_key字符串,并将其中的PUT_API_KEY_HERE替换为您之前创建的API密钥来修改您的文件。

最后,通过在app/App_Resources/Android/AndroidManifest.xml文件中在<application>标签之间插入以下内容来修改您的文件

<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/nativescript_google_maps_api_key" />

Nativescript 4+

首先,将必要的模板资源文件复制到Android应用资源文件夹中

cp -r node_modules/nativescript-google-maps-sdk/platforms/android/res/values app/App_Resources/Android/src/main/res

接下来,通过取消注释app/App_Resources/Android/src/main/res/values/nativescript_google_maps_api.xml文件中的nativescript_google_maps_api_key字符串,并将其中的PUT_API_KEY_HERE替换为您之前创建的API密钥来修改您的文件。

最后,通过在您的app/App_Resources/Android/src/main/AndroidManifest.xml文件中在<application>标签之间插入以下内容来修改您的文件

<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/nativescript_google_maps_api_key" />

插件将默认为Android Google Play Services SDK的最新可用版本。如果您需要更改版本,您可以通过添加一个project.ext属性,如googlePlayServicesVersion,进行更改

//   /app/App_Resources/Android/app.gradle

project.ext {
googlePlayServicesVersion = "+"
}

为iOS配置API密钥

在您的app.js中,使用以下代码添加您的API密钥(将PUT_API_KEY_HERE替换为您之前创建的API密钥)

if (application.ios) {
GMSServices.provideAPIKey("PUT_API_KEY_HERE");
}

如果您正在使用Angular,请按照以下方式修改您的app.module.ts

import * as platform from "platform";
declare var GMSServices: any;

....

if (platform.isIOS) {
GMSServices.provideAPIKey("PUT_API_KEY_HERE");
}

添加MapView

通过将xmlns:maps="nativescript-google-maps-sdk"命名空间添加到您的<Page>标签,然后使用<maps:mapView />标签创建MapView来修改您的视图

<!-- /app/main-page.xml -->

<Page
xmlns="http://www.nativescript.org/tns.xsd"
xmlns:maps="nativescript-google-maps-sdk"
>
<GridLayout>
<maps:mapView
latitude="{{ latitude }}"
longitude="{{ longitude }}"
zoom="{{ zoom }}"
bearing="{{ bearing }}"
tilt="{{ tilt }}"
mapAnimationsEnabled="{{ mapAnimationsEnabled }}"
padding="{{ padding }}"
mapReady="onMapReady"
markerSelect="onMarkerSelect"
markerBeginDragging="onMarkerBeginDragging"
markerEndDragging="onMarkerEndDragging"
markerDrag="onMarkerDrag"
cameraChanged="onCameraChanged"
cameraMove="onCameraMove"
/>
</GridLayout>
</Page>

属性

以下属性可用于调整相机视图

属性 描述和数据类型
latitude 纬度,以度为单位:number
longitude 经度,以度为单位:number
zoom 缩放级别(见此处):number
bearing 方位角,以度为单位:number
tilt 倾斜角,以度为单位:number
padding 顶部、底部、左侧和右侧的内边距量,以设备独立像素为单位:number[](数组)
mapAnimationsEnabled 是否动画相机更改:Boolean

事件

以下事件可用

事件 描述
mapReady 当MapView准备好使用时触发
myLocationTapped 当点击“我的位置”按钮时触发
coordinateTapped 当在地图上点击坐标时触发
coordinateLongPress 当在地图上长按坐标时触发
markerSelect 当选择标记时触发
markerBeginDragging 当标记开始拖动时触发
markerEndDragging 当标记结束拖动时触发
markerDrag 在标记被拖动时重复触发
markerInfoWindowTapped 当点击标记的信息窗口时触发
markerInfoWindowClosed 当标记的信息窗口关闭时触发
shapeSelect 当选择形状(例如CirclePolygonPolyline)时触发 (注意:必须显式配置shape.clickable = true; 以触发此事件)
cameraChanged 摄像头更改后触发
cameraMove 在摄像头移动时重复触发
indoorBuildingFocused 当聚焦在建筑物上时触发(当前居中的建筑物,由用户选择或由位置提供者选择)
indoorLevelActivated 当聚焦建筑物的层级发生变化时触发

本地地图对象

MapView的gMap属性为您提供了访问平台本地地图对象的权限——有关如何使用它,请参阅适当的SDK参考:iOS | Android

UI 设置

mapReady事件触发后,您可以通过在mapView.settings上配置以下属性来调整地图的UI设置

属性 描述和数据类型
compassEnabled 是否启用指南针:Boolean
indoorLevelPickerEnabled 是否启用室内层级选择器:Boolean
mapToolbarEnabled ** 仅限Android ** 是否启用地图工具栏:Boolean
myLocationButtonEnabled 是否启用“我的位置”按钮:Boolean
rotateGesturesEnabled 是否启用指南针:Boolean
scrollGesturesEnabled 是否启用地图滚动手势:Boolean
tiltGesturesEnabled 是否启用地图倾斜手势:Boolean
zoomGesturesEnabled 是否启用地图缩放手势:Boolean
zoomControlsEnabled ** 仅限Android ** 是否启用地图缩放控件:Boolean

样式

使用gMap.setStyle(style);来设置地图样式(Google Maps 样式参考 | 样式向导)。

Angular

onMapReady事件处理器内部使用this.mapView.setStyle(<Style>JSON.parse(this.styles));。在此示例中,this.mapViewMapView对象,而this.styles是使用样式向导创建的JSON文件的引用。从插件导入的<Style>类型为{ Style }

基本示例

//  /app/main-page.js

var mapsModule = require("nativescript-google-maps-sdk");

function onMapReady(args) {
var mapView = args.object;

console.log("Setting a marker...");
var marker = new mapsModule.Marker();
marker.position = mapsModule.Position.positionFromLatLng(-33.86, 151.20);
marker.title = "Sydney";
marker.snippet = "Australia";
marker.userData = { index : 1};
mapView.addMarker(marker);

// Disabling zoom gestures
mapView.settings.zoomGesturesEnabled = false;
}

function onMarkerSelect(args) {
console.log("Clicked on " +args.marker.title);
}

function onCameraChanged(args) {
console.log("Camera changed: " + JSON.stringify(args.camera));
}

function onCameraMove(args) {
console.log("Camera moving: "+JSON.stringify(args.camera));
}

exports.onMapReady = onMapReady;
exports.onMarkerSelect = onMarkerSelect;
exports.onCameraChanged = onCameraChanged;
exports.onCameraMove = onCameraMove;

自定义信息窗口(Beta)

[!WARNING] 如果您正在使用NS7,则infoWindowTemplate将无法从xml文件中工作!一个临时解决方案是在代码背后声明infoWindow模板,如下所示

var mapView = null;

export function onMapReady(args) {
mapView = args.object;
mapView.infoWindowTemplate = `<StackLayout orientation="vertical" width="200" height="150" >
<Label text="{{title}}" className="title" width="125" />
<Label text="{{snippet}}" className="snippet" width="125" />
<Label text="{{'LAT: ' + position.latitude}}" className="infoWindowCoordinates" />
<Label text="{{'LON: ' + position.longitude}}" className="infoWindowCoordinates" />
</StackLayout>`
;
}

要使用自定义标记信息窗口,请按如下方式在视图中定义一个模板

<!-- /app/main-page.xml -->
<Page
xmlns="http://www.nativescript.org/tns.xsd"
xmlns:maps="nativescript-google-maps-sdk"
>
<GridLayout>
<maps:mapView mapReady="onMapReady">
<!-- Default Info Window Template -->
<maps:mapView.infoWindowTemplate>
<StackLayout orientation="vertical" width="200" height="150" >
<Label text="{{title}}" className="title" width="125" />
<Label text="{{snippet}}" className="snippet" width="125" />
<Label text="{{'LAT: ' + position.latitude}}" className="infoWindowCoordinates" />
<Label text="{{'LON: ' + position.longitude}}" className="infoWindowCoordinates" />
</StackLayout>
</maps:mapView.infoWindowTemplate>
<!-- Keyed Info Window Templates -->
<maps:mapView.infoWindowTemplates>
<template key="testWindow">
<StackLayout orientation="vertical" width="160" height="160" >
<Image src="res://icon" stretch="fill" height="100" width="100" className="infoWindowImage" />
<Label text="Let's Begin!" className="title" />
</StackLayout>
</template>
</maps:mapView.infoWindowTemplates>
</maps:mapView>
</GridLayout>
</Page>

...并按如下方式设置infoWindowTemplate属性

var marker = new mapsModule.Marker();
marker.infoWindowTemplate = 'testWindow';

这将配置标记使用具有给定键的信息窗口模板。如果没有找到该键的模板,则将使用默认的信息窗口模板。

** 已知问题: iOS信息窗口中无法显示远程图像(本地图像正常工作)

与Angular一起使用

请参阅此处包含的Angular演示代码这里

// /app/map-example.component.ts

import {Component, ElementRef, ViewChild} from '@angular/core';
import {registerElement} from "nativescript-angular/element-registry";

// Important - must register MapView plugin in order to use in Angular templates
registerElement("MapView", () => require("nativescript-google-maps-sdk").MapView);

@Component({
selector: 'map-example-component',
template: `
<GridLayout>
<MapView (mapReady)="onMapReady($event)"></MapView>
</GridLayout>
`

})
export class MapExampleComponent {

@ViewChild("MapView") mapView: ElementRef;

//Map events
onMapReady = (event) => {
console.log("Map Ready");
};
}

Angular 8 支持

如果您正在使用 Angular 8,需要对 @ViewChild 指令进行临时修复,Angular 9 中将不再需要。

@ViewChild("MapView", {static: false}) mapView: ElementRef;

集群支持(问题 #57

多亏了 @naderio,正在开发一个独立的插件:请参阅 nativescript-google-maps-utils

获取帮助

咨询 Nativescript 社区是获取帮助的最佳途径。

如果您有问题,首先查看是否有人在 Stack Overflow 上遇到过类似的情况。如果找不到任何信息,尝试 自己提问。请确保添加所有必要的细节以便重现问题,并包含“NativeScript”和"google-maps"标签,以便您的提问能够被 NativeScript 社区看到。

如果您需要比 Stack Overflow 提供的问答格式更多的帮助,尝试 加入 NativeScript 社区的 Slack。Slack 聊天是一个很好的地方,可以获取帮助解决问题,以及与其他 NativeScript 开发者交流。

最后,如果您发现了 NativeScript Google Maps SDK 自身的問題,或者请求新功能,请在这里报告:问题