文件
mashangyoujiu/Public/js/get-position-map-tencent.js

386 行
14 KiB
JavaScript
可执行文件

// 全局JSONP回调函数
window.geocodeCallback = function(result) {
if (window.vueMapComponent) {
window.vueMapComponent.handleGeocodeResult(result);
}
};
window.reverseGeocodeCallback = function(result) {
if (window.vueMapComponent) {
window.vueMapComponent.handleReverseGeocodeResult(result);
}
};
Vue.component('get-position-map-tencent', {
template: `<div>
<el-input type="text" id="suggestId" v-model="keyword"
placeholder="搜索地址"
@keydown.enter.exact.native.prevent="addressSearch">
<template slot="append">
<el-button @click="addressSearch">搜索</el-button>
</template>
</el-input>
<div ref="mapContent" style="height: 380px;width: 610px;border: 1px solid #DCDFE6"></div>
</div>`,
props: {
'longitude': {
type: Number,
default: '',
},//经度
'latitude': {
type: Number,
default: '',
},//纬度
'address': {
type: String,
default: '',
},//地图中心的地址
'getCountType': {
type: Number,
default: 1,// 1单个地址 2多个地址
},
},
data() {
return {
mapLoading: false,
mapApp: null,
marker: null,
mapContent: "", // 地图挂载dom
center: {
lng: 116.397475,
lat: 39.908817,
},
keyword: "",
key: '', // API key将从后端获取
currentSearchAddress: '',
currentReverseLat: 0,
currentReverseLng: 0,
};
},
methods: {
//获取腾讯地图API Key
async getTencentMapKey() {
try {
const response = await fetch('/index.php/Retail/Store/getTencentMapKey', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
});
const result = await response.json();
if (result.status === 1 && result.key) {
this.key = result.key;
return true;
} else {
console.error('获取腾讯地图API Key失败:', result.msg || '未知错误');
this.$message.error('获取地图配置失败,请联系管理员');
return false;
}
} catch (error) {
console.error('获取腾讯地图API Key异常:', error);
this.$message.error('获取地图配置异常,请检查网络连接');
return false;
}
},
//初始化地图
async mapInit() {
if (this.mapApp && this.mapApp.destroy) {
this.mapApp.destroy();
} else {
this.mapContent.innerHTML = "";
}
// 如果没有API key,先获取
if (!this.key) {
const success = await this.getTencentMapKey();
if (!success) {
return; // 获取API key失败,停止初始化
}
}
this.checkScript();
},
//检查腾讯地图API是否已加载
checkScript() {
if (typeof TMap !== 'undefined' && TMap.Map) {
this.tencentMapInit();
} else {
// 动态加载腾讯地图API GL
const script = document.createElement('script');
script.src = `https://map.qq.com/api/gljs?v=1.exp&key=${this.key}`;
script.onload = () => {
this.waitForTMapLoad().then(() => {
this.tencentMapInit();
}).catch(error => {
console.error('腾讯地图API加载失败:', error);
this.$message.error('地图加载失败,请刷新页面重试');
});
};
script.onerror = () => {
console.error('腾讯地图API脚本加载失败');
this.$message.error('地图脚本加载失败,请检查网络连接');
};
document.head.appendChild(script);
}
},
// 等待腾讯地图API加载完成
waitForTMapLoad() {
return new Promise((resolve, reject) => {
if (typeof TMap !== 'undefined' && TMap.Map) {
resolve();
} else {
let attempts = 0;
const maxAttempts = 50;
const checkInterval = setInterval(() => {
attempts++;
if (typeof TMap !== 'undefined' && TMap.Map) {
clearInterval(checkInterval);
resolve();
} else if (attempts >= maxAttempts) {
clearInterval(checkInterval);
reject(new Error('腾讯地图API加载超时'));
}
}, 100);
}
});
},
//初始化腾讯地图
tencentMapInit() {
try {
// 设置全局引用
window.vueMapComponent = this;
// 创建地图实例
this.mapApp = new TMap.Map(this.mapContent, {
center: new TMap.LatLng(this.center.lat, this.center.lng),
zoom: 15,
viewMode: '2D',
mapStyleId: 'style1'
});
// 地图点击事件
this.mapApp.on('click', (evt) => {
const latLng = evt.latLng;
this.updateMapMaker(latLng.lat, latLng.lng);
this.reverseGeocode(latLng.lat, latLng.lng);
});
// 初始化标记点
this.updateMapMaker(this.center.lat, this.center.lng);
this.mapLoading = true;
console.log('腾讯地图初始化成功');
} catch (error) {
console.error('地图初始化失败:', error);
this.$message.error('地图初始化失败: ' + error.message);
}
},
//更新地图标记点
updateMapMaker(lat, lng, address = '', callback = null) {
if (!this.mapApp) return;
// 清除之前的标记点
if (this.marker) {
this.marker.setMap(null);
}
// 创建新的标记点
this.marker = new TMap.MultiMarker({
map: this.mapApp,
styles: {
'marker-style': new TMap.MarkerStyle({
width: 25,
height: 35,
anchor: { x: 12, y: 35 },
src: 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/marker.png'
})
},
geometries: [{
id: 'location-marker',
styleId: 'marker-style',
position: new TMap.LatLng(lat, lng),
properties: {
title: address || '当前位置'
}
}]
});
// 更新地图中心
this.mapApp.setCenter(new TMap.LatLng(lat, lng));
// 更新数据
this.updateData(lat, lng, address);
if (callback) callback();
},
// 处理地理编码JSONP回调
handleGeocodeResult(result) {
if (result.status === 0 && result.result && result.result.location) {
const location = result.result.location;
const lat = location.lat;
const lng = location.lng;
const address = this.currentSearchAddress;
this.updateMapMaker(lat, lng, address);
this.$message.success(`搜索成功!找到地址: ${address}`);
console.log('地址搜索成功:', result);
} else {
this.$message.error('未找到该地址,请检查地址是否正确');
console.error('地址搜索失败:', result);
}
},
// 处理反向地理编码JSONP回调
handleReverseGeocodeResult(result) {
const lat = this.currentReverseLat;
const lng = this.currentReverseLng;
if (result.status === 0 && result.result && result.result.address) {
const address = result.result.address;
this.updateData(lat, lng, address);
console.log('反向地理编码成功:', result);
} else {
this.updateData(lat, lng, '无法获取地址信息');
console.error('反向地理编码失败:', result);
}
},
// 反向地理编码(根据坐标获取地址)
async reverseGeocode(lat, lng) {
if (!this.mapApp) {
console.log('地图未初始化');
return;
}
// 确保有API key
if (!this.key) {
const success = await this.getTencentMapKey();
if (!success) {
this.updateData(lat, lng, '获取地址配置失败');
return;
}
}
// 保存当前坐标
this.currentReverseLat = lat;
this.currentReverseLng = lng;
// 使用JSONP方式调用腾讯地图WebService API
const reverseGeocodeUrl = `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=${this.key}&output=jsonp&callback=reverseGeocodeCallback`;
// 创建script标签进行JSONP请求
const script = document.createElement('script');
script.src = reverseGeocodeUrl;
script.onerror = () => {
this.updateData(lat, lng, '地址获取失败');
console.error('反向地理编码JSONP请求失败');
};
document.head.appendChild(script);
// 清理script标签
setTimeout(() => {
if (script.parentNode) {
document.head.removeChild(script);
}
}, 5000);
},
//关键词查询
async addressSearch() {
const address = this.keyword.trim();
if (!address) {
this.$message.error('请输入要搜索的地址');
return;
}
if (!this.mapApp) {
this.$message.error('地图未初始化,请稍后再试');
return;
}
// 确保有API key
if (!this.key) {
const success = await this.getTencentMapKey();
if (!success) {
return;
}
}
this.$message.info('正在搜索地址...');
// 保存当前搜索的地址
this.currentSearchAddress = address;
// 使用JSONP方式调用腾讯地图WebService API
const geocodeUrl = `https://apis.map.qq.com/ws/geocoder/v1/?address=${encodeURIComponent(address)}&key=${this.key}&output=jsonp&callback=geocodeCallback`;
// 创建script标签进行JSONP请求
const script = document.createElement('script');
script.src = geocodeUrl;
script.onerror = () => {
this.$message.error('地址搜索失败,请检查网络连接');
console.error('JSONP请求失败');
};
document.head.appendChild(script);
// 清理script标签
setTimeout(() => {
if (script.parentNode) {
document.head.removeChild(script);
}
}, 5000);
},
//更新数据
updateData(lat, lng, address = '') {
this.center.lat = lat;
this.center.lng = lng;
// 更新父组件的数据
this.$emit('update:longitude', lng);
this.$emit('update:latitude', lat);
if (address) {
this.$emit('update:address', address);
}
},
//获取初始数据
getInitData(callback) {
if (this.longitude && this.latitude) {
this.center.lng = this.longitude;
this.center.lat = this.latitude;
}
if (this.address) {
this.keyword = this.address;
}
if (callback) callback();
},
},
mounted() {
this.mapContent = this.$refs.mapContent;
this.getInitData(() => {
this.mapInit();
});
},
created() {
this.getInitData();
},
beforeDestroy() {
// 清理全局引用
if (window.vueMapComponent === this) {
window.vueMapComponent = null;
}
}
});