uni-app 谷歌地图标记点 @markertap 点击事件没有回调 急急急 希望尽快解决下
uni-app 谷歌地图标记点 @markertap 点击事件没有回调 急急急 希望尽快解决下
示例代码:
<template>
<view class="pi-map">
<map id="map"
ref="map"
class="pi-map"
scale="data.scale"
latitude="data.latitude"
longitude="data.longitude"
[@markertap](/user/markertap)="onTap"/>
</view>
</template>
<script lang="ts" setup>
import { reactive, ref, onMounted, computed, watch, nextTick } from 'vue';
import { getCurrentInstance } from 'vue';
import config from "@/config";
const img = '/static/logo.png';
const { ctx }: any = getCurrentInstance();
// 地图属性
const data = reactive({
title: 'map',
scale: 16,
latitude: 13.743980890903845,
longitude: 100.48840066400577,
markers: [] as Array<any>
});
const mapContext = ref<UniApp.MapContext>();
const platform = ref('');
const markers = ref([]);
const mounted = () => {
platform.value = uni.getSystemInfoSync().platform;
nextTick(() => {
mapContext.value = uni.createMapContext("map", ctx);
addClusters();
});
setTimeout(() => {
addMarkers([{
latitude: 13.743980890903845,
longitude: 100.48840066400577,
treeNodeId: 22132132,
},{
latitude: 13.753980890903845,
longitude: 100.48840066400577,
treeNodeId: 22132133,
},{
latitude: 13.750980890903845,
longitude: 100.48840066400577,
treeNodeId: 22132134,
}]);
}, 1000)
}
/**
* 添加聚合点
*/
const addClusters = () => {
// 仅调用初始化,才会触发 on.("markerClusterCreate", (e) => {})
mapContext.value?.initMarkerCluster({
enableDefaultStyle: false,
zoomOnClick: true,
gridSize: 60,
complete(res: any) {
console.log('initMarkerCluster', res)
}
});
//聚合点创建监听事件,需要重新设置聚合点的样式(图标,文本),不然不会显示
mapContext.value?.on("markerClusterCreate", (e: any) => {
console.log("markerClusterCreate", e);
let clusterMarkers = [] as Array<any>
const clusters = e.clusters // 新产生的聚合簇
clusters.forEach((cluster: any, index: any) => {
const {
center, // 聚合点的经纬度数组
clusterId, // 聚合簇id
markerIds // 已经聚合了的标记点id数组
} = cluster
const content = (markerIds.length > 99 ? '99+' : markerIds.length) + '';
let clusterObj = {
clusterId, //必须
...center,
width: 40,
height: 40,
iconPath: img,
label: { // 定制聚合簇样式
content: content,
fontSize: 16,
color: '#ffffff',
textAlign: 'center',
anchorX: platform.value === 'ios'? undefined : (content.length > 1? -9 : -5),
anchorY: platform.value === 'ios'? -30 : -10,
},
// {x, y},x表示横向(0-1),y表示竖向(0-1)。{x: .5, y: 1} 表示底边中点
anchor: {
x: 0.5,
y: 0.5
}
}
clusterMarkers.push(clusterObj)
})
// 添加聚合簇
mapContext.value?.addMarkers({
markers: clusterMarkers,
clear: false, //是否先清空地图上所有的marker
})
});
mapContext.value?.on('markerClusterClick', (res: any) => {
showStationDetail(res.cluster.markerIds);
});
}
/**
* 判断纬度是否合法,纬度的合法范围在 -90 到 90 之间。
* @param latitude 维度
*/
const isValidLatitude = (latitude: string) => {
return Number(latitude) >= -90 && Number(latitude) < 90;
}
/**
* 判断经度是否合法,经度的合法范围在 -180 到 180 之间。
* @param longitude
*/
const isValidLongitude = (longitude: string) => {
return Number(longitude) >= -180 && Number(longitude) <= 180;
}
/**
* 生成markId,使用treedId,长度大于9时取后面9位
* @param treeId
*/
const getMarkId = (treeId:string): number => {
const id = treeId.length > 9? treeId.slice(treeId.length - 9, treeId.length) : treeId;
return Number(id);
}
/**
* 添加标记点
* @param stationList 站点列表
*/
const addMarkers = (stationList ?: Array<any>) => {
if (!mapContext.value) {
return;
}
stationList = stationList || [];
const positions = stationList.filter(item => item.latitude
&& item.longitude
&& isValidLatitude(item.latitude)
&& isValidLongitude(item.longitude)).map(item => {
return {
id: getMarkId(item.treeNodeId),
latitude: Number(item.latitude),
longitude: Number(item.longitude),
}
});
const markers = [] as Array<any>
positions.forEach((p, i) => {
markers.push(
Object.assign({}, {
width: 40,
height: 40,
}, p)
)
});
console.log('addMarkers', markers)
console.log("mapContext.value", mapContext.value)
mapContext.value?.addMarkers({
markers,
clear: true,
complete(res) {
console.log('addMarkers', res)
}
})
};
// 点击标记点事件处理
const onMarker = (e: any) => {
console.log('onMarker');
uni.showToast({
duration: 1500,
title: '点击了标记点',
icon: 'none'
})
}
const onTap = (e: any) => {
console.log('onTap', e);
}
onMounted(mounted);
</script>
<style lang="scss" scoped>
@import './index';
</style>
操作步骤:
- 点击标记点@markertap绑定方法无回调
预期结果:
- @markertap有回调
实际结果:
- 没有调@markertap绑定方法
bug描述:
- 谷歌地图标记点,@markertap点击事件没有回调。iOS可以,Android不行。
请问解决了嘛??
在uni-app中使用谷歌地图并处理标记点(Marker)点击事件时,如果@markertap
没有触发回调,可能是事件绑定不正确或者某些配置未正确设置。以下是一个完整的示例代码,展示如何在uni-app中集成谷歌地图并处理标记点击事件。
首先,确保你的项目中已经集成了Google Maps JavaScript API。这通常需要在manifest.json
中配置合法域名或者在你的HTML文件中通过script标签引入API。
1. 引入Google Maps JavaScript API
在pages/index/index.vue
的<template>
部分,使用web-view组件加载谷歌地图,并通过URL参数传递API key和初始位置信息(注意,这里不是最佳实践,仅用于演示目的。实际开发中应考虑使用更安全的地图集成方式,如uni-app的map组件扩展或使用原生插件)。
<template>
<view>
<web-view :src="mapUrl"></web-view>
</view>
</template>
2. 在<script>中设置mapUrl
<script>
export default {
data() {
return {
apiKey: 'YOUR_GOOGLE_MAPS_API_KEY', // 替换为你的API Key
latitude: 37.7749, // 初始纬度
longitude: -122.4194, // 初始经度
zoom: 15, // 初始缩放级别
mapUrl: ''
};
},
mounted() {
this.mapUrl = `https://www.google.com/maps/embed/v1/place?key=${this.apiKey}&q=${this.latitude},${this.longitude}&zoom=${this.zoom}`;
},
methods: {
// 假设你有一个方法来处理标记点击事件(实际在web-view中处理较复杂,这里仅展示思路)
handleMarkerTap() {
console.log('Marker tapped!');
}
}
};
</script>
3. 注意:使用web-view的限制
由于web-view
加载的是外部网页,直接在uni-app中监听其内部事件较为困难。一种解决方案是通过URL hash或postMessage等方式与web-view内部通信,但这需要谷歌地图页面配合相应的JavaScript代码。
更推荐的方案是使用uni-app的map
组件结合谷歌地图的瓦片图层(如果谷歌允许的话,注意API使用条款),这样可以更直接地控制事件和交互。不过,由于谷歌地图的服务条款和API限制,直接使用其瓦片图层可能不被允许或需要额外的步骤。
结论
直接使用web-view
加载谷歌地图并监听标记点击事件在uni-app中较为复杂,且可能违反谷歌地图API的使用规定。建议探索使用uni-app的map
组件或其他地图服务,或者考虑开发原生插件来更深入地集成谷歌地图功能。