更新SelectMap组件以使用新版腾讯地图API,优化地图加载和用户位置获取逻辑,增强错误处理和用户体验。
This commit is contained in:
@@ -13,7 +13,7 @@
|
||||
<script type="text/javascript" src="/websdk.js"></script>
|
||||
<script
|
||||
charset="utf-8"
|
||||
src="https://map.qq.com/api/js?v=2.exp&key=5ZSBZ-23ICU-XDKVU-4ZQ7Z-O35AJ-XUF6S"
|
||||
src="https://map.qq.com/api/gljs?v=1.exp&libraries=service&key=7DZBZ-ZSRK3-QJN3W-O5VTV-4E2P6-7GFYX"
|
||||
></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -4,10 +4,11 @@ import { SearchOutlined, EnvironmentOutlined } from "@ant-design/icons";
|
||||
import { useWebSocketStore } from "@/store/module/websocket/websocket";
|
||||
import styles from "./selectMap.module.scss";
|
||||
|
||||
// 声明腾讯地图类型
|
||||
// 声明腾讯地图类型(新版TMap API)
|
||||
declare global {
|
||||
interface Window {
|
||||
qq: any;
|
||||
TMap: any;
|
||||
geolocationRef: any; // 全局IP定位服务引用
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,281 +59,454 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
const [map, setMap] = useState<any>(null);
|
||||
const [isReverseGeocoding, setIsReverseGeocoding] = useState(false);
|
||||
const [isLocating, setIsLocating] = useState(false);
|
||||
const [tmapLoaded, setTmapLoaded] = useState(false);
|
||||
const mapContainerRef = useRef<HTMLDivElement>(null);
|
||||
const geocoderRef = useRef<any>(null);
|
||||
const searchServiceRef = useRef<any>(null);
|
||||
const suggestServiceRef = useRef<any>(null);
|
||||
const markerRef = useRef<any>(null);
|
||||
const { sendCommand } = useWebSocketStore.getState();
|
||||
|
||||
// 加载腾讯地图SDK
|
||||
useEffect(() => {
|
||||
// 检查TMap是否已经加载
|
||||
if (window.TMap) {
|
||||
setTmapLoaded(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// 动态加载腾讯地图SDK(使用与index.html相同的密钥)
|
||||
const script = document.createElement("script");
|
||||
script.src =
|
||||
"https://map.qq.com/api/gljs?v=1.exp&libraries=service&key=7DZBZ-ZSRK3-QJN3W-O5VTV-4E2P6-7GFYX";
|
||||
script.async = true;
|
||||
script.onload = () => {
|
||||
console.log("腾讯地图SDK加载成功");
|
||||
setTmapLoaded(true);
|
||||
};
|
||||
script.onerror = () => {
|
||||
console.error("腾讯地图SDK加载失败");
|
||||
message.error("地图加载失败,请刷新页面重试");
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
|
||||
return () => {
|
||||
// 清理script标签
|
||||
if (document.head.contains(script)) {
|
||||
document.head.removeChild(script);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 初始化地图
|
||||
useEffect(() => {
|
||||
if (visible && mapContainerRef.current && window.qq && window.qq.maps) {
|
||||
// 创建地图实例
|
||||
const center = new window.qq.maps.LatLng(39.908823, 116.39747); // 默认北京
|
||||
const mapInstance = new window.qq.maps.Map(mapContainerRef.current, {
|
||||
center: center,
|
||||
zoom: 13,
|
||||
});
|
||||
if (visible && mapContainerRef.current && tmapLoaded && window.TMap) {
|
||||
console.log("开始初始化地图");
|
||||
|
||||
setMap(mapInstance);
|
||||
|
||||
// 创建地理编码服务
|
||||
geocoderRef.current = new window.qq.maps.Geocoder({
|
||||
complete: (result: any) => {
|
||||
setIsReverseGeocoding(false);
|
||||
try {
|
||||
if (result && result.detail) {
|
||||
const detail = result.detail;
|
||||
const location = detail.location || detail.latLng;
|
||||
if (location) {
|
||||
const lat =
|
||||
location.lat || (location.getLat ? location.getLat() : null);
|
||||
const lng =
|
||||
location.lng || (location.getLng ? location.getLng() : null);
|
||||
|
||||
if (lat && lng) {
|
||||
// 构建地址标签
|
||||
let addressLabel = "";
|
||||
if (detail.formatted_addresses) {
|
||||
addressLabel =
|
||||
detail.formatted_addresses.recommend ||
|
||||
detail.formatted_addresses.rough ||
|
||||
"";
|
||||
}
|
||||
if (!addressLabel && detail.address) {
|
||||
addressLabel = detail.address;
|
||||
}
|
||||
if (!addressLabel && detail.addressComponents) {
|
||||
const addr = detail.addressComponents;
|
||||
const parts = [];
|
||||
if (addr.province) parts.push(addr.province);
|
||||
if (addr.city) parts.push(addr.city);
|
||||
if (addr.district) parts.push(addr.district);
|
||||
if (addr.street) parts.push(addr.street);
|
||||
if (addr.street_number) parts.push(addr.street_number);
|
||||
addressLabel = parts.join("");
|
||||
}
|
||||
if (!addressLabel) {
|
||||
addressLabel = `${lat.toFixed(6)}, ${lng.toFixed(6)}`;
|
||||
}
|
||||
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
scale: "16",
|
||||
label: addressLabel,
|
||||
poiname:
|
||||
detail.addressComponents?.street || detail.poiid || "",
|
||||
maptype: "0",
|
||||
poiid: detail.poiid || "",
|
||||
});
|
||||
} else {
|
||||
message.warning("无法解析位置信息");
|
||||
}
|
||||
} else {
|
||||
message.warning("未找到位置信息");
|
||||
}
|
||||
} else {
|
||||
message.warning("获取地址信息失败:返回数据为空");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("解析地址信息错误:", error);
|
||||
message.error("解析地址信息失败");
|
||||
}
|
||||
},
|
||||
error: (error: any) => {
|
||||
setIsReverseGeocoding(false);
|
||||
console.error("反向地理编码错误:", error);
|
||||
message.error("获取地址信息失败,请稍后重试");
|
||||
},
|
||||
});
|
||||
|
||||
// 创建搜索服务
|
||||
searchServiceRef.current = new window.qq.maps.SearchService({
|
||||
complete: (result: any) => {
|
||||
setIsSearching(false);
|
||||
if (result && result.detail) {
|
||||
const pois = result.detail.pois || [];
|
||||
if (pois.length > 0) {
|
||||
const searchResults = pois.map((poi: any) => {
|
||||
const location = poi.location || poi.latLng;
|
||||
return {
|
||||
id:
|
||||
poi.id ||
|
||||
`${location.lat || location.getLat()},${
|
||||
location.lng || location.getLng()
|
||||
}`,
|
||||
title: poi.title || poi.name || "",
|
||||
address: poi.address || poi.ad_info?.adcode || "",
|
||||
location: {
|
||||
lat: location.lat || location.getLat(),
|
||||
lng: location.lng || location.getLng(),
|
||||
},
|
||||
adcode: poi.adcode || poi.ad_info?.adcode || "",
|
||||
city: poi.city || poi.ad_info?.city || "",
|
||||
district: poi.district || poi.ad_info?.district || "",
|
||||
};
|
||||
});
|
||||
setSearchResults(searchResults);
|
||||
} else {
|
||||
setSearchResults([]);
|
||||
message.info("未找到相关地址");
|
||||
}
|
||||
} else {
|
||||
setSearchResults([]);
|
||||
message.info("未找到相关地址");
|
||||
}
|
||||
},
|
||||
error: () => {
|
||||
setIsSearching(false);
|
||||
message.error("搜索失败,请重试");
|
||||
},
|
||||
});
|
||||
|
||||
// 地图点击事件
|
||||
window.qq.maps.event.addListener(mapInstance, "click", (event: any) => {
|
||||
const lat = event.latLng.lat;
|
||||
const lng = event.latLng.lng;
|
||||
|
||||
// 更新标记点
|
||||
if (markerRef.current) {
|
||||
markerRef.current.setMap(null);
|
||||
}
|
||||
|
||||
const newMarker = new window.qq.maps.Marker({
|
||||
position: new window.qq.maps.LatLng(lat, lng),
|
||||
map: mapInstance,
|
||||
try {
|
||||
// 创建地图实例
|
||||
const center = new window.TMap.LatLng(39.908823, 116.39747); // 默认北京
|
||||
const mapInstance = new window.TMap.Map(mapContainerRef.current, {
|
||||
center: center,
|
||||
zoom: 13,
|
||||
rotation: 0,
|
||||
pitch: 0,
|
||||
});
|
||||
|
||||
markerRef.current = newMarker;
|
||||
setMap(mapInstance);
|
||||
|
||||
// 反向地理编码
|
||||
if (geocoderRef.current) {
|
||||
setIsReverseGeocoding(true);
|
||||
geocoderRef.current.getAddress(new window.qq.maps.LatLng(lat, lng));
|
||||
}
|
||||
});
|
||||
// 创建地理编码服务(用于反向地理编码)
|
||||
geocoderRef.current = new window.TMap.service.Geocoder();
|
||||
|
||||
// 获取用户当前位置
|
||||
if (navigator.geolocation) {
|
||||
setIsLocating(true);
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
position => {
|
||||
setIsLocating(false);
|
||||
const userLat = position.coords.latitude;
|
||||
const userLng = position.coords.longitude;
|
||||
// 使用腾讯地图内置的定位服务
|
||||
window.geolocationRef = window.TMap.service.Geolocation;
|
||||
|
||||
// 移动地图中心到用户位置
|
||||
const userLocation = new window.qq.maps.LatLng(userLat, userLng);
|
||||
mapInstance.setCenter(userLocation);
|
||||
mapInstance.setZoom(16);
|
||||
// 创建搜索建议服务
|
||||
suggestServiceRef.current = new window.TMap.service.Suggestion({
|
||||
pageSize: 10,
|
||||
autoExtend: true,
|
||||
});
|
||||
|
||||
// 添加标记点
|
||||
// 地图点击事件处理函数
|
||||
const handleMapClick = (evt: any) => {
|
||||
try {
|
||||
const lat = evt.latLng.getLat();
|
||||
const lng = evt.latLng.getLng();
|
||||
|
||||
console.log("地图点击:", lat, lng);
|
||||
|
||||
// 更新标记点
|
||||
if (markerRef.current) {
|
||||
markerRef.current.setMap(null);
|
||||
markerRef.current = null;
|
||||
}
|
||||
|
||||
const newMarker = new window.qq.maps.Marker({
|
||||
position: userLocation,
|
||||
// 创建新标记
|
||||
const newMarker = new window.TMap.MultiMarker({
|
||||
id: "marker-layer",
|
||||
map: mapInstance,
|
||||
geometries: [
|
||||
{
|
||||
id: "selected-marker",
|
||||
styleId: "marker",
|
||||
position: new window.TMap.LatLng(lat, lng),
|
||||
properties: {
|
||||
title: "选中位置",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
markerRef.current = newMarker;
|
||||
|
||||
// 获取用户位置的地址信息
|
||||
if (geocoderRef.current) {
|
||||
setIsReverseGeocoding(true);
|
||||
geocoderRef.current.getAddress(userLocation);
|
||||
}
|
||||
},
|
||||
error => {
|
||||
// 设置基本位置信息(防止白屏)
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
scale: "16",
|
||||
label: `${lat.toFixed(6)}, ${lng.toFixed(6)}`,
|
||||
poiname: "选中位置",
|
||||
maptype: "0",
|
||||
poiid: "",
|
||||
});
|
||||
|
||||
// 反向地理编码获取地址
|
||||
setIsReverseGeocoding(true);
|
||||
geocoderRef.current
|
||||
.getAddress({ location: new window.TMap.LatLng(lat, lng) })
|
||||
.then((result: any) => {
|
||||
setIsReverseGeocoding(false);
|
||||
console.log("反向地理编码结果:", result);
|
||||
|
||||
try {
|
||||
if (result && result.result) {
|
||||
const resultData = result.result;
|
||||
const address = resultData.address || "";
|
||||
const addressComponent = resultData.address_component || {};
|
||||
const formattedAddresses =
|
||||
resultData.formatted_addresses || {};
|
||||
|
||||
// 构建地址标签
|
||||
let addressLabel =
|
||||
formattedAddresses.recommend ||
|
||||
formattedAddresses.rough ||
|
||||
address;
|
||||
|
||||
if (!addressLabel) {
|
||||
const parts = [];
|
||||
if (addressComponent.province)
|
||||
parts.push(addressComponent.province);
|
||||
if (addressComponent.city)
|
||||
parts.push(addressComponent.city);
|
||||
if (addressComponent.district)
|
||||
parts.push(addressComponent.district);
|
||||
if (addressComponent.street)
|
||||
parts.push(addressComponent.street);
|
||||
if (addressComponent.street_number)
|
||||
parts.push(addressComponent.street_number);
|
||||
addressLabel = parts.join("");
|
||||
}
|
||||
|
||||
if (!addressLabel) {
|
||||
addressLabel = `${lat.toFixed(6)}, ${lng.toFixed(6)}`;
|
||||
}
|
||||
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
scale: "16",
|
||||
label: addressLabel,
|
||||
poiname: addressComponent.street || "未知位置",
|
||||
maptype: "0",
|
||||
poiid: resultData.poi_id || "",
|
||||
});
|
||||
} else {
|
||||
message.warning("获取详细地址信息失败,将使用坐标显示");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("解析地址信息错误:", error);
|
||||
message.warning("解析地址信息失败,将使用坐标显示");
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
setIsReverseGeocoding(false);
|
||||
console.error("反向地理编码错误:", error);
|
||||
message.warning("获取详细地址信息失败,将使用坐标显示");
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("地图点击处理错误:", error);
|
||||
message.error("处理地图点击时出错,请重试");
|
||||
}
|
||||
};
|
||||
|
||||
// 绑定地图点击事件
|
||||
mapInstance.on("click", handleMapClick);
|
||||
|
||||
// 使用腾讯地图API初始化用户位置
|
||||
const initializeUserLocation = (
|
||||
lat: number,
|
||||
lng: number,
|
||||
isDefault: boolean = false,
|
||||
) => {
|
||||
console.log(isDefault ? "使用默认位置:" : "用户位置:", lat, lng);
|
||||
|
||||
// 移动地图中心到位置
|
||||
const userLocation = new window.TMap.LatLng(lat, lng);
|
||||
mapInstance.setCenter(userLocation);
|
||||
mapInstance.setZoom(16);
|
||||
|
||||
// 添加标记点
|
||||
if (markerRef.current) {
|
||||
markerRef.current.setMap(null);
|
||||
markerRef.current = null;
|
||||
}
|
||||
|
||||
const newMarker = new window.TMap.MultiMarker({
|
||||
id: "marker-layer",
|
||||
map: mapInstance,
|
||||
geometries: [
|
||||
{
|
||||
id: "user-location",
|
||||
styleId: "marker",
|
||||
position: userLocation,
|
||||
properties: {
|
||||
title: isDefault ? "默认位置" : "当前位置",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
markerRef.current = newMarker;
|
||||
|
||||
// 使用腾讯地图服务获取该位置的地址信息
|
||||
setIsReverseGeocoding(true);
|
||||
geocoderRef.current
|
||||
.getAddress({ location: userLocation })
|
||||
.then((result: any) => {
|
||||
setIsReverseGeocoding(false);
|
||||
if (result && result.result) {
|
||||
const resultData = result.result;
|
||||
const formattedAddresses = resultData.formatted_addresses || {};
|
||||
const addressComponent = resultData.address_component || {};
|
||||
|
||||
const addressLabel =
|
||||
formattedAddresses.recommend ||
|
||||
formattedAddresses.rough ||
|
||||
resultData.address ||
|
||||
`${lat.toFixed(6)}, ${lng.toFixed(6)}`;
|
||||
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
scale: "16",
|
||||
label: addressLabel,
|
||||
poiname:
|
||||
addressComponent.street ||
|
||||
(isDefault ? "默认位置" : "当前位置"),
|
||||
maptype: "0",
|
||||
poiid: resultData.poi_id || "",
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
setIsReverseGeocoding(false);
|
||||
console.error("获取地址信息失败:", error);
|
||||
// 即使获取地址失败,也设置基本的位置信息
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
scale: "16",
|
||||
label: `${lat.toFixed(6)}, ${lng.toFixed(6)}`,
|
||||
poiname: isDefault ? "默认位置" : "当前位置",
|
||||
maptype: "0",
|
||||
poiid: "",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 使用腾讯地图IP定位获取用户位置
|
||||
setIsLocating(true);
|
||||
try {
|
||||
if (window.geolocationRef) {
|
||||
window.geolocationRef.getLocation({
|
||||
timeout: 10000,
|
||||
convert: true,
|
||||
success: function (result: any) {
|
||||
setIsLocating(false);
|
||||
if (result && result.location) {
|
||||
const { lat, lng } = result.location;
|
||||
message.info("已定位到您的大致位置");
|
||||
initializeUserLocation(lat, lng, false);
|
||||
} else {
|
||||
// IP定位失败:使用默认位置
|
||||
message.info("无法获取您的位置,已定位到北京");
|
||||
// 使用默认位置(北京市)
|
||||
initializeUserLocation(39.908823, 116.39747, true);
|
||||
}
|
||||
},
|
||||
error: function () {
|
||||
setIsLocating(false);
|
||||
message.info("无法获取您的位置,已定位到北京");
|
||||
// 使用默认位置(北京市)
|
||||
initializeUserLocation(39.908823, 116.39747, true);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// 地理编码服务未初始化:使用默认位置
|
||||
setIsLocating(false);
|
||||
console.error("获取位置失败:", error);
|
||||
// 如果获取位置失败,使用默认位置(北京)
|
||||
message.info("无法获取您的位置,已定位到默认位置");
|
||||
},
|
||||
{
|
||||
enableHighAccuracy: true,
|
||||
timeout: 10000,
|
||||
maximumAge: 0,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
message.info("您的浏览器不支持地理定位功能");
|
||||
message.info("无法获取您的位置,已定位到北京");
|
||||
// 使用默认位置(北京市)
|
||||
initializeUserLocation(39.908823, 116.39747, true);
|
||||
}
|
||||
} catch (error) {
|
||||
// 捕获任何可能的错误,防止白屏
|
||||
console.error("定位过程中发生错误:", error);
|
||||
setIsLocating(false);
|
||||
message.error("定位服务出现异常,已定位到北京");
|
||||
// 使用默认位置(北京市)
|
||||
initializeUserLocation(39.908823, 116.39747, true);
|
||||
}
|
||||
|
||||
return () => {
|
||||
// 清理地图事件监听
|
||||
if (mapInstance) {
|
||||
mapInstance.off("click", handleMapClick);
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("初始化地图时出错:", error);
|
||||
message.error("地图加载失败,请刷新页面重试");
|
||||
setIsLocating(false);
|
||||
}
|
||||
}
|
||||
}, [visible, tmapLoaded]);
|
||||
|
||||
// 搜索地址(获取搜索建议)
|
||||
const handleSearch = () => {
|
||||
try {
|
||||
if (!searchValue.trim()) {
|
||||
message.warning("请输入搜索关键词");
|
||||
return;
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (mapInstance) {
|
||||
window.qq.maps.event.clearListeners(mapInstance, "click");
|
||||
}
|
||||
};
|
||||
}
|
||||
}, [visible]);
|
||||
if (!suggestServiceRef.current) {
|
||||
message.error("搜索服务未初始化,请刷新页面重试");
|
||||
return;
|
||||
}
|
||||
|
||||
// 搜索地址
|
||||
const handleSearch = () => {
|
||||
if (!searchValue.trim()) {
|
||||
message.warning("请输入搜索关键词");
|
||||
return;
|
||||
}
|
||||
setIsSearching(true);
|
||||
suggestServiceRef.current
|
||||
.getSuggestions({
|
||||
keyword: searchValue,
|
||||
location: map ? map.getCenter() : undefined,
|
||||
})
|
||||
.then((result: any) => {
|
||||
setIsSearching(false);
|
||||
console.log("搜索建议结果:", result);
|
||||
|
||||
if (!searchServiceRef.current) {
|
||||
message.error("搜索服务未初始化");
|
||||
return;
|
||||
if (result && result.data && result.data.length > 0) {
|
||||
const searchResults = result.data.map((item: any) => ({
|
||||
id: item.id,
|
||||
title: item.title || item.name || "",
|
||||
address: item.address || "",
|
||||
location: {
|
||||
lat: item.location.lat,
|
||||
lng: item.location.lng,
|
||||
},
|
||||
adcode: item.adcode || "",
|
||||
city: item.city || "",
|
||||
district: item.district || "",
|
||||
}));
|
||||
setSearchResults(searchResults);
|
||||
} else {
|
||||
setSearchResults([]);
|
||||
message.info("未找到相关地址");
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
setIsSearching(false);
|
||||
console.error("搜索失败:", error);
|
||||
message.error("搜索失败,请重试");
|
||||
// 确保搜索状态被重置
|
||||
setSearchResults([]);
|
||||
});
|
||||
} catch (error) {
|
||||
setIsSearching(false);
|
||||
console.error("搜索处理错误:", error);
|
||||
message.error("搜索过程中出错,请重试");
|
||||
setSearchResults([]);
|
||||
}
|
||||
|
||||
setIsSearching(true);
|
||||
searchServiceRef.current.search(searchValue);
|
||||
};
|
||||
|
||||
// 选择搜索结果
|
||||
const handleSelectResult = (result: SearchResult) => {
|
||||
if (!map) return;
|
||||
try {
|
||||
if (!map) {
|
||||
message.error("地图未初始化,请刷新页面重试");
|
||||
return;
|
||||
}
|
||||
|
||||
const lat = result.location.lat;
|
||||
const lng = result.location.lng;
|
||||
const lat = result.location.lat;
|
||||
const lng = result.location.lng;
|
||||
|
||||
// 移动地图中心
|
||||
map.setCenter(new window.qq.maps.LatLng(lat, lng));
|
||||
map.setZoom(16);
|
||||
console.log("选择搜索结果:", result);
|
||||
|
||||
// 更新标记点
|
||||
if (markerRef.current) {
|
||||
markerRef.current.setMap(null);
|
||||
// 移动地图中心
|
||||
map.setCenter(new window.TMap.LatLng(lat, lng));
|
||||
map.setZoom(16);
|
||||
|
||||
// 更新标记点
|
||||
if (markerRef.current) {
|
||||
markerRef.current.setMap(null);
|
||||
markerRef.current = null;
|
||||
}
|
||||
|
||||
const newMarker = new window.TMap.MultiMarker({
|
||||
id: "marker-layer",
|
||||
map: map,
|
||||
geometries: [
|
||||
{
|
||||
id: "selected-poi",
|
||||
styleId: "marker",
|
||||
position: new window.TMap.LatLng(lat, lng),
|
||||
properties: {
|
||||
title: result.title,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
markerRef.current = newMarker;
|
||||
|
||||
// 设置选中的位置信息
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
scale: "16",
|
||||
label: result.address || result.title,
|
||||
poiname: result.title || "",
|
||||
maptype: "0",
|
||||
poiid: result.id || "",
|
||||
});
|
||||
|
||||
// 清空搜索结果
|
||||
setSearchResults([]);
|
||||
setSearchValue("");
|
||||
} catch (error) {
|
||||
console.error("选择搜索结果错误:", error);
|
||||
message.error("选择位置时出错,请重试");
|
||||
}
|
||||
|
||||
const newMarker = new window.qq.maps.Marker({
|
||||
position: new window.qq.maps.LatLng(lat, lng),
|
||||
map: map,
|
||||
});
|
||||
|
||||
markerRef.current = newMarker;
|
||||
|
||||
// 设置选中的位置信息
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
scale: "16",
|
||||
label: result.address || result.title,
|
||||
poiname: result.title || "",
|
||||
maptype: "0",
|
||||
poiid: result.id || "",
|
||||
});
|
||||
|
||||
// 清空搜索结果
|
||||
setSearchResults([]);
|
||||
setSearchValue("");
|
||||
};
|
||||
|
||||
// 确认选择
|
||||
const handleConfirm = () => {
|
||||
if (!selectedLocation) {
|
||||
message.warning("请先选择位置");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (!selectedLocation) {
|
||||
message.warning("请先选择位置");
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成XML格式的位置信息
|
||||
const locationXml = `<msg><location
|
||||
// 生成XML格式的位置信息
|
||||
const locationXml = `<msg><location
|
||||
x="${selectedLocation.x}"
|
||||
y="${selectedLocation.y}"
|
||||
scale="${selectedLocation.scale}"
|
||||
@@ -342,54 +516,58 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
maptype="${selectedLocation.maptype}"
|
||||
poiid="${selectedLocation.poiid}" /></msg>`;
|
||||
|
||||
// 如果有onConfirm回调,调用它
|
||||
if (onConfirm) {
|
||||
onConfirm(locationXml);
|
||||
// 如果有onConfirm回调,调用它
|
||||
if (onConfirm) {
|
||||
onConfirm(locationXml);
|
||||
}
|
||||
|
||||
// 如果有addMessage和contract,发送位置消息
|
||||
if (addMessage && contract) {
|
||||
const messageId = +Date.now();
|
||||
const localMessage = {
|
||||
id: messageId,
|
||||
wechatAccountId: contract.wechatAccountId,
|
||||
wechatFriendId: contract?.chatroomId ? 0 : contract.id,
|
||||
wechatChatroomId: contract?.chatroomId ? contract.id : 0,
|
||||
tenantId: 0,
|
||||
accountId: 0,
|
||||
synergyAccountId: 0,
|
||||
content: locationXml,
|
||||
msgType: 48, // 位置消息类型
|
||||
msgSubType: 0,
|
||||
msgSvrId: "",
|
||||
isSend: true,
|
||||
createTime: new Date().toISOString(),
|
||||
isDeleted: false,
|
||||
deleteTime: "",
|
||||
sendStatus: 1,
|
||||
wechatTime: Date.now(),
|
||||
origin: 0,
|
||||
msgId: 0,
|
||||
recalled: false,
|
||||
seq: messageId,
|
||||
};
|
||||
|
||||
addMessage(localMessage);
|
||||
|
||||
// 发送消息到服务器
|
||||
sendCommand("CmdSendMessage", {
|
||||
wechatAccountId: contract.wechatAccountId,
|
||||
wechatChatroomId: contract?.chatroomId ? contract.id : 0,
|
||||
wechatFriendId: contract?.chatroomId ? 0 : contract.id,
|
||||
msgSubType: 0,
|
||||
msgType: 48,
|
||||
content: locationXml,
|
||||
seq: messageId,
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭弹窗并重置状态
|
||||
handleClose();
|
||||
} catch (error) {
|
||||
console.error("确认位置时出错:", error);
|
||||
message.error("发送位置信息时出错,请重试");
|
||||
}
|
||||
|
||||
// 如果有addMessage和contract,发送位置消息
|
||||
if (addMessage && contract) {
|
||||
const messageId = +Date.now();
|
||||
const localMessage = {
|
||||
id: messageId,
|
||||
wechatAccountId: contract.wechatAccountId,
|
||||
wechatFriendId: contract?.chatroomId ? 0 : contract.id,
|
||||
wechatChatroomId: contract?.chatroomId ? contract.id : 0,
|
||||
tenantId: 0,
|
||||
accountId: 0,
|
||||
synergyAccountId: 0,
|
||||
content: locationXml,
|
||||
msgType: 48, // 位置消息类型
|
||||
msgSubType: 0,
|
||||
msgSvrId: "",
|
||||
isSend: true,
|
||||
createTime: new Date().toISOString(),
|
||||
isDeleted: false,
|
||||
deleteTime: "",
|
||||
sendStatus: 1,
|
||||
wechatTime: Date.now(),
|
||||
origin: 0,
|
||||
msgId: 0,
|
||||
recalled: false,
|
||||
seq: messageId,
|
||||
};
|
||||
|
||||
addMessage(localMessage);
|
||||
|
||||
// 发送消息到服务器
|
||||
sendCommand("CmdSendMessage", {
|
||||
wechatAccountId: contract.wechatAccountId,
|
||||
wechatChatroomId: contract?.chatroomId ? contract.id : 0,
|
||||
wechatFriendId: contract?.chatroomId ? 0 : contract.id,
|
||||
msgSubType: 0,
|
||||
msgType: 48,
|
||||
content: locationXml,
|
||||
seq: messageId,
|
||||
});
|
||||
}
|
||||
|
||||
// 关闭弹窗并重置状态
|
||||
handleClose();
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
|
||||
73
Touchkebao/腾讯地图定位服务修复说明.md
Normal file
73
Touchkebao/腾讯地图定位服务修复说明.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 腾讯地图定位服务修复说明
|
||||
|
||||
## 问题描述
|
||||
|
||||
在 `selectMap.tsx` 文件中使用腾讯地图定位服务时出现以下错误:
|
||||
|
||||
```
|
||||
TypeError: window.TMap.service.Location is not a constructor
|
||||
at selectMap.tsx:121:33
|
||||
```
|
||||
|
||||
## 原因分析
|
||||
|
||||
错误原因是尝试将 `TMap.service.Location` 作为构造函数使用,但在腾讯地图 GL API 中,定位服务不是通过构造函数方式创建的。
|
||||
|
||||
## 修复方法
|
||||
|
||||
### 1. 修改定位服务的初始化方式
|
||||
|
||||
将原来的代码:
|
||||
|
||||
```typescript
|
||||
// 创建IP定位服务
|
||||
window.geolocationRef = new window.TMap.service.Location({
|
||||
timeout: 10000,
|
||||
convert: true,
|
||||
});
|
||||
```
|
||||
|
||||
修改为:
|
||||
|
||||
```typescript
|
||||
// 使用腾讯地图内置的定位服务
|
||||
window.geolocationRef = window.TMap.service.Geolocation;
|
||||
```
|
||||
|
||||
### 2. 修改定位服务的调用方式
|
||||
|
||||
在调用定位服务时,将配置参数直接传入 `getLocation` 方法:
|
||||
|
||||
```typescript
|
||||
window.geolocationRef.getLocation({
|
||||
timeout: 10000,
|
||||
convert: true,
|
||||
success: function (result: any) {
|
||||
// 处理成功回调
|
||||
},
|
||||
error: function () {
|
||||
// 处理错误回调
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 技术说明
|
||||
|
||||
1. **腾讯地图 GL API 中的定位服务**:
|
||||
- 正确的服务名称是 `TMap.service.Geolocation`,而非 `TMap.service.Location`
|
||||
- 它是一个对象,不需要使用 `new` 关键字实例化
|
||||
- 配置参数应该直接传递给 `getLocation` 方法
|
||||
|
||||
2. **定位服务参数**:
|
||||
- `timeout`:定位超时时间,单位毫秒
|
||||
- `convert`:是否将坐标转换为腾讯地图坐标系
|
||||
|
||||
3. **回调处理**:
|
||||
- `success`:定位成功回调函数,返回位置信息
|
||||
- `error`:定位失败回调函数
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 确保腾讯地图 SDK 已正确加载
|
||||
2. 确保 API 密钥有定位服务的权限
|
||||
3. 定位精度可能受网络环境影响
|
||||
Reference in New Issue
Block a user