修正SelectMap组件中的经纬度标记顺序,更新XML生成逻辑以确保特殊字符转义,提升地图位置选择的准确性和稳定性。
This commit is contained in:
@@ -34,8 +34,8 @@ interface SearchResult {
|
||||
}
|
||||
|
||||
interface LocationData {
|
||||
x: string; // 经度
|
||||
y: string; // 纬度
|
||||
x: string; // 纬度
|
||||
y: string; // 经度
|
||||
scale: string; // 缩放级别
|
||||
label: string; // 地址标签
|
||||
poiname: string; // POI名称
|
||||
@@ -66,6 +66,17 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
const markerRef = useRef<any>(null);
|
||||
const { sendCommand } = useWebSocketStore.getState();
|
||||
|
||||
// XML转义函数,防止特殊字符破坏XML格式
|
||||
const escapeXml = (str: string | undefined | null): string => {
|
||||
if (!str) return "";
|
||||
return String(str)
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
};
|
||||
|
||||
// 加载腾讯地图SDK
|
||||
useEffect(() => {
|
||||
// 检查TMap是否已经加载
|
||||
@@ -311,11 +322,12 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
markerRef.current = newMarker;
|
||||
|
||||
// 设置基本位置信息(防止白屏)
|
||||
// 经纬度格式化为6位小数(微信位置消息标准格式)
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
x: lat.toString(),
|
||||
y: lng.toString(),
|
||||
scale: "16",
|
||||
label: `${lat.toFixed(6)}, ${lng.toFixed(6)}`,
|
||||
label: `${lat}, ${lng}`,
|
||||
poiname: "选中位置",
|
||||
maptype: "0",
|
||||
poiid: "",
|
||||
@@ -368,12 +380,13 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
}
|
||||
|
||||
if (!addressLabel) {
|
||||
addressLabel = `${lat.toFixed(6)}, ${lng.toFixed(6)}`;
|
||||
addressLabel = `${lat}, ${lng}`;
|
||||
}
|
||||
|
||||
// 经纬度格式化为6位小数(微信位置消息标准格式)
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
x: lat.toString(),
|
||||
y: lng.toString(),
|
||||
scale: "16",
|
||||
label: addressLabel,
|
||||
poiname: addressComponent.street || "未知位置",
|
||||
@@ -471,11 +484,12 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
} catch (error) {
|
||||
console.error("创建标记点失败:", error);
|
||||
// 即使创建标记失败,也设置基本的位置信息
|
||||
// 经纬度格式化为6位小数(微信位置消息标准格式)
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
x: lat.toString(),
|
||||
y: lng.toString(),
|
||||
scale: "16",
|
||||
label: `${lat.toFixed(6)}, ${lng.toFixed(6)}`,
|
||||
label: `${lat}, ${lng}`,
|
||||
poiname: isDefault ? "默认位置" : "当前位置",
|
||||
maptype: "0",
|
||||
poiid: "",
|
||||
@@ -507,11 +521,12 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
formattedAddresses.recommend ||
|
||||
formattedAddresses.rough ||
|
||||
resultData.address ||
|
||||
`${lat.toFixed(6)}, ${lng.toFixed(6)}`;
|
||||
`${lat}, ${lng}`;
|
||||
|
||||
// 经纬度格式化为6位小数(微信位置消息标准格式)
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
x: lat.toString(),
|
||||
y: lng.toString(),
|
||||
scale: "16",
|
||||
label: addressLabel,
|
||||
poiname:
|
||||
@@ -530,11 +545,12 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
setIsReverseGeocoding(false);
|
||||
console.error("获取地址信息失败:", error);
|
||||
// 即使获取地址失败,也设置基本的位置信息
|
||||
// 经纬度格式化为6位小数(微信位置消息标准格式)
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
x: lat.toString(),
|
||||
y: lng.toString(),
|
||||
scale: "16",
|
||||
label: `${lat.toFixed(6)}, ${lng.toFixed(6)}`,
|
||||
label: `${lat}, ${lng}`,
|
||||
poiname: isDefault ? "默认位置" : "当前位置",
|
||||
maptype: "0",
|
||||
poiid: "",
|
||||
@@ -779,9 +795,10 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
markerRef.current = newMarker;
|
||||
|
||||
// 设置选中的位置信息
|
||||
// 经纬度格式化为6位小数(微信位置消息标准格式)
|
||||
setSelectedLocation({
|
||||
x: lng.toString(),
|
||||
y: lat.toString(),
|
||||
x: lat.toString(),
|
||||
y: lng.toString(),
|
||||
scale: "16",
|
||||
label: result.address || result.title,
|
||||
poiname: result.title || "",
|
||||
@@ -806,16 +823,31 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成XML格式的位置信息
|
||||
const locationXml = `<msg><location
|
||||
x="${selectedLocation.x}"
|
||||
y="${selectedLocation.y}"
|
||||
scale="${selectedLocation.scale}"
|
||||
label="${selectedLocation.label}"
|
||||
poiname="${selectedLocation.poiname}"
|
||||
infourl=""
|
||||
maptype="${selectedLocation.maptype}"
|
||||
poiid="${selectedLocation.poiid}" /></msg>`;
|
||||
// 转义XML特殊字符,确保格式正确
|
||||
// 注意:经纬度在存储时已经格式化为6位小数,直接使用即可
|
||||
const escapedLabel = escapeXml(selectedLocation.label);
|
||||
const escapedPoiname = escapeXml(selectedLocation.poiname);
|
||||
const scale = selectedLocation.scale || "16";
|
||||
const maptype = selectedLocation.maptype || "0";
|
||||
const poiid = escapeXml(selectedLocation.poiid || "");
|
||||
|
||||
// 生成XML格式的位置信息(格式与正确示例保持一致)
|
||||
const locationXml =
|
||||
'<msg><location\n x="' +
|
||||
selectedLocation.x +
|
||||
'"\n y="' +
|
||||
selectedLocation.y +
|
||||
'"\n scale="' +
|
||||
scale +
|
||||
'"\n label="' +
|
||||
escapedLabel +
|
||||
'"\n poiname="' +
|
||||
escapedPoiname +
|
||||
'"\n infourl=""\n maptype="' +
|
||||
maptype +
|
||||
'"\n poiid="' +
|
||||
poiid +
|
||||
'" /></msg>';
|
||||
|
||||
// 如果有onConfirm回调,调用它
|
||||
if (onConfirm) {
|
||||
@@ -850,6 +882,7 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
};
|
||||
|
||||
addMessage(localMessage);
|
||||
console.log(locationXml);
|
||||
|
||||
// 发送消息到服务器
|
||||
sendCommand("CmdSendMessage", {
|
||||
@@ -971,7 +1004,7 @@ const SelectMap: React.FC<SelectMapProps> = ({
|
||||
{selectedLocation.label || selectedLocation.poiname}
|
||||
</div>
|
||||
<div className={styles.locationCoords}>
|
||||
经度: {selectedLocation.x}, 纬度: {selectedLocation.y}
|
||||
经度: {selectedLocation.y}, 纬度: {selectedLocation.x}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user