uni-app 谷歌地图标记点 @markertap 点击事件没有回调 急急急 希望尽快解决下

发布于 1周前 作者 yuanlaile 来自 Uni-App

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> 

操作步骤:

预期结果:

实际结果:

bug描述:

  • 谷歌地图标记点,@markertap点击事件没有回调。iOS可以,Android不行。

2 回复

请问解决了嘛??


在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组件或其他地图服务,或者考虑开发原生插件来更深入地集成谷歌地图功能。

回到顶部