地图修改
This commit is contained in:
parent
7ab1cda769
commit
a9c2b1dae0
|
|
@ -406,9 +406,12 @@
|
||||||
currentLocation: null,
|
currentLocation: null,
|
||||||
currentHeading: 0,
|
currentHeading: 0,
|
||||||
watchPositionId: null,
|
watchPositionId: null,
|
||||||
watchOrientationId: null
|
watchOrientationId: null,
|
||||||
|
watchLocationTimer: null,
|
||||||
|
mapLoaded: false
|
||||||
},
|
},
|
||||||
locationIconCache: null,
|
locationIconCache: null,
|
||||||
|
baiduGeolocation: null,
|
||||||
elements: {
|
elements: {
|
||||||
panel: null,
|
panel: null,
|
||||||
tree: null,
|
tree: null,
|
||||||
|
|
@ -429,15 +432,12 @@
|
||||||
this.state.projectInfo = Utils.safeParseJSON(params.projectInfo, []);
|
this.state.projectInfo = Utils.safeParseJSON(params.projectInfo, []);
|
||||||
this.state.currentClickedProject = Utils.safeParseJSON(params.clickedProject);
|
this.state.currentClickedProject = Utils.safeParseJSON(params.clickedProject);
|
||||||
|
|
||||||
// 初始化地图
|
// 初始化地图(地图加载完成后再初始化定位功能)
|
||||||
this.initMap(this.state.projectInfo);
|
this.initMap(this.state.projectInfo);
|
||||||
|
|
||||||
// 渲染工程列表
|
// 渲染工程列表
|
||||||
this.renderProjectList();
|
this.renderProjectList();
|
||||||
|
|
||||||
// 初始化定位功能
|
|
||||||
this.initLocationTracking();
|
|
||||||
|
|
||||||
// 处理 URL Action
|
// 处理 URL Action
|
||||||
this.handleUrlActions(params);
|
this.handleUrlActions(params);
|
||||||
},
|
},
|
||||||
|
|
@ -505,7 +505,27 @@
|
||||||
this.map.centerAndZoom(center, 12);
|
this.map.centerAndZoom(center, 12);
|
||||||
this.map.enableScrollWheelZoom(true);
|
this.map.enableScrollWheelZoom(true);
|
||||||
|
|
||||||
projectInfo.forEach(p => this.addProjectMarker(p));
|
// 等待地图加载完成
|
||||||
|
this.map.addEventListener('tilesloaded', () => {
|
||||||
|
console.log('地图瓦片加载完成');
|
||||||
|
this.state.mapLoaded = true;
|
||||||
|
|
||||||
|
// 地图加载完成后,添加项目标记
|
||||||
|
projectInfo.forEach(p => this.addProjectMarker(p));
|
||||||
|
|
||||||
|
// 地图加载完成后,初始化定位跟踪
|
||||||
|
this.initLocationTracking();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 也监听地图初始化完成事件(备用)
|
||||||
|
this.map.addEventListener('load', () => {
|
||||||
|
console.log('地图加载完成');
|
||||||
|
if (!this.state.mapLoaded) {
|
||||||
|
this.state.mapLoaded = true;
|
||||||
|
projectInfo.forEach(p => this.addProjectMarker(p));
|
||||||
|
this.initLocationTracking();
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -575,27 +595,474 @@
|
||||||
* 开始监听位置变化
|
* 开始监听位置变化
|
||||||
*/
|
*/
|
||||||
startWatchingPosition() {
|
startWatchingPosition() {
|
||||||
const options = {
|
// 优先使用百度地图SDK定位(直接返回BD09坐标,最准确)
|
||||||
enableHighAccuracy: true, // 高精度定位
|
if (typeof BMapGL !== 'undefined' && BMapGL.Geolocation) {
|
||||||
timeout: 10000,
|
console.log('使用百度地图SDK辅助定位API(优先)');
|
||||||
maximumAge: 0 // 不使用缓存
|
this.startBaiduGeolocation();
|
||||||
|
} else if (typeof uni !== 'undefined' && uni.getLocation) {
|
||||||
|
console.log('使用uni-app GPS定位API(WGS84)');
|
||||||
|
this.startUniAppGPSGeolocation();
|
||||||
|
} else if (typeof plus !== 'undefined' && plus.geolocation) {
|
||||||
|
console.log('使用5+定位API');
|
||||||
|
this.startPlusGeolocation();
|
||||||
|
} else {
|
||||||
|
console.log('使用浏览器定位API');
|
||||||
|
this.startBrowserGeolocation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用百度地图定位(返回BD09坐标,无需转换)- 开启SDK辅助定位
|
||||||
|
*/
|
||||||
|
startBaiduGeolocation() {
|
||||||
|
// 确保地图已加载完成
|
||||||
|
if (!this.map || !this.state.mapLoaded) {
|
||||||
|
console.warn('地图未加载完成,延迟启动百度定位');
|
||||||
|
setTimeout(() => this.startBaiduGeolocation(), 500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const geolocation = new BMapGL.Geolocation();
|
||||||
|
// 开启SDK辅助定位,提高定位精度
|
||||||
|
geolocation.enableSDKLocation();
|
||||||
|
|
||||||
|
console.log('已开启百度地图SDK辅助定位');
|
||||||
|
|
||||||
|
// 获取当前位置,增加超时时间等待GPS定位
|
||||||
|
let retryCount = 0;
|
||||||
|
const maxRetries = 3;
|
||||||
|
|
||||||
|
const tryGetPosition = () => {
|
||||||
|
geolocation.getCurrentPosition((result) => {
|
||||||
|
const status = geolocation.getStatus();
|
||||||
|
console.log('百度地图定位状态:', status, '结果:', result, '重试次数:', retryCount);
|
||||||
|
|
||||||
|
// 百度地图定位成功状态码是0
|
||||||
|
if (status === 0 && result && result.point) {
|
||||||
|
const point = result.point;
|
||||||
|
const accuracy = result.accuracy || 999; // 如果没有精度信息,假设精度较差
|
||||||
|
console.log('百度地图SDK定位成功 - 经度:', point.lng, '纬度:', point.lat, '精度:', accuracy, '米');
|
||||||
|
|
||||||
|
// 验证坐标有效性
|
||||||
|
if (point.lng && point.lat && !isNaN(point.lng) && !isNaN(point.lat) &&
|
||||||
|
Math.abs(point.lng) <= 180 && Math.abs(point.lat) <= 90) {
|
||||||
|
|
||||||
|
// 如果精度太差(大于50米)且还有重试次数,继续重试
|
||||||
|
if (accuracy > 50 && retryCount < maxRetries) {
|
||||||
|
retryCount++;
|
||||||
|
console.log(`精度较差(${accuracy}米),重试获取更精确位置 (${retryCount}/${maxRetries})`);
|
||||||
|
setTimeout(tryGetPosition, 2000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果精度仍然很差(大于100米),切换到GPS定位
|
||||||
|
if (accuracy > 100 && typeof uni !== 'undefined' && uni.getLocation) {
|
||||||
|
console.warn('百度定位精度较差(' + accuracy + '米),切换到GPS定位');
|
||||||
|
this.startUniAppGPSGeolocation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.currentLocation = {
|
||||||
|
lng: point.lng,
|
||||||
|
lat: point.lat,
|
||||||
|
accuracy: accuracy
|
||||||
|
};
|
||||||
|
|
||||||
|
// 使用逆地理编码验证位置(可选,用于调试)
|
||||||
|
this.verifyLocationWithGeocoder(point.lng, point.lat);
|
||||||
|
|
||||||
|
this.updateLocationMarker();
|
||||||
|
} else {
|
||||||
|
console.error('百度定位返回无效坐标:', point);
|
||||||
|
// 降级到uni-app定位
|
||||||
|
if (typeof uni !== 'undefined' && uni.getLocation) {
|
||||||
|
this.startUniAppGPSGeolocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果失败且还有重试次数,继续重试
|
||||||
|
if (retryCount < maxRetries) {
|
||||||
|
retryCount++;
|
||||||
|
console.log(`定位失败,重试 (${retryCount}/${maxRetries})`);
|
||||||
|
setTimeout(tryGetPosition, 2000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn('百度地图定位失败,状态:', status, '尝试备用方案');
|
||||||
|
// 降级到uni-app定位
|
||||||
|
if (typeof uni !== 'undefined' && uni.getLocation) {
|
||||||
|
this.startUniAppGPSGeolocation();
|
||||||
|
} else {
|
||||||
|
this.startBrowserGeolocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
enableHighAccuracy: true,
|
||||||
|
timeout: 30000 // 30秒超时,等待GPS定位
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
tryGetPosition();
|
||||||
|
|
||||||
|
// 持续监听位置变化(使用定时器定期获取)
|
||||||
|
this.state.watchLocationTimer = setInterval(() => {
|
||||||
|
geolocation.getCurrentPosition((result) => {
|
||||||
|
const status = geolocation.getStatus();
|
||||||
|
if (status === 0 && result && result.point) {
|
||||||
|
const point = result.point;
|
||||||
|
const accuracy = result.accuracy || 999;
|
||||||
|
|
||||||
|
// 验证坐标有效性
|
||||||
|
if (point.lng && point.lat && !isNaN(point.lng) && !isNaN(point.lat) &&
|
||||||
|
Math.abs(point.lng) <= 180 && Math.abs(point.lat) <= 90) {
|
||||||
|
|
||||||
|
// 如果精度太差(大于100米),切换到GPS定位
|
||||||
|
if (accuracy > 100 && typeof uni !== 'undefined' && uni.getLocation) {
|
||||||
|
console.warn('百度定位精度持续较差(' + accuracy + '米),切换到GPS定位');
|
||||||
|
clearInterval(this.state.watchLocationTimer);
|
||||||
|
this.startUniAppGPSGeolocation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只更新精度更好的位置(精度提升超过10米,或者精度小于50米)
|
||||||
|
if (!this.state.currentLocation ||
|
||||||
|
(accuracy < this.state.currentLocation.accuracy - 10) ||
|
||||||
|
(accuracy < 50 && this.state.currentLocation.accuracy >= 50)) {
|
||||||
|
|
||||||
|
console.log('位置更新 - 经度:', point.lng, '纬度:', point.lat, '精度:', accuracy, '米');
|
||||||
|
|
||||||
|
this.state.currentLocation = {
|
||||||
|
lng: point.lng,
|
||||||
|
lat: point.lat,
|
||||||
|
accuracy: accuracy
|
||||||
|
};
|
||||||
|
this.updateLocationMarker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
enableHighAccuracy: true,
|
||||||
|
timeout: 30000
|
||||||
|
});
|
||||||
|
}, 5000); // 每5秒更新一次,给GPS更多时间稳定
|
||||||
|
|
||||||
|
// 保存geolocation实例,以便后续使用
|
||||||
|
this.baiduGeolocation = geolocation;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用逆地理编码验证位置(用于调试)
|
||||||
|
*/
|
||||||
|
verifyLocationWithGeocoder(lng, lat) {
|
||||||
|
if (!this.map) return;
|
||||||
|
|
||||||
|
const geocoder = new BMapGL.Geocoder();
|
||||||
|
const point = new BMapGL.Point(lng, lat);
|
||||||
|
|
||||||
|
geocoder.getLocation(point, (result) => {
|
||||||
|
if (result && result.address) {
|
||||||
|
console.log('位置验证 - 地址:', result.address);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用uni-app GPS定位(WGS84坐标,最准确)
|
||||||
|
*/
|
||||||
|
startUniAppGPSGeolocation() {
|
||||||
|
console.log('使用uni-app GPS定位(WGS84)');
|
||||||
|
// 先获取一次当前位置
|
||||||
|
uni.getLocation({
|
||||||
|
type: 'wgs84', // 使用WGS84坐标系(GPS原始坐标),然后转换为BD09
|
||||||
|
altitude: false,
|
||||||
|
geocode: false,
|
||||||
|
highAccuracyExpireTime: 10000, // 增加等待时间,获取GPS定位
|
||||||
|
success: (res) => {
|
||||||
|
console.log('uni-app GPS定位成功:', res.longitude, res.latitude, '精度:', res.accuracy);
|
||||||
|
// uni-app返回的是WGS84坐标,需要转换为BD09
|
||||||
|
this.wgs84ToBd09(res.longitude, res.latitude, (bd09) => {
|
||||||
|
if (bd09 && bd09.lng && bd09.lat) {
|
||||||
|
this.state.currentLocation = {
|
||||||
|
lat: bd09.lat,
|
||||||
|
lng: bd09.lng,
|
||||||
|
accuracy: res.accuracy || 0
|
||||||
|
};
|
||||||
|
console.log('GPS坐标转换完成 - BD09:', bd09.lng, bd09.lat);
|
||||||
|
this.updateLocationMarker();
|
||||||
|
} else {
|
||||||
|
console.error('GPS坐标转换失败,使用GCJ02定位');
|
||||||
|
this.startUniAppGeolocation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('uni-app GPS定位失败:', err);
|
||||||
|
// 降级到GCJ02定位
|
||||||
|
this.startUniAppGeolocation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 持续监听位置变化
|
||||||
|
this.state.watchLocationTimer = setInterval(() => {
|
||||||
|
uni.getLocation({
|
||||||
|
type: 'wgs84',
|
||||||
|
altitude: false,
|
||||||
|
geocode: false,
|
||||||
|
highAccuracyExpireTime: 10000,
|
||||||
|
success: (res) => {
|
||||||
|
this.wgs84ToBd09(res.longitude, res.latitude, (bd09) => {
|
||||||
|
if (bd09 && bd09.lng && bd09.lat) {
|
||||||
|
// 只更新精度更好的位置
|
||||||
|
if (!this.state.currentLocation || res.accuracy < this.state.currentLocation.accuracy || res.accuracy < 20) {
|
||||||
|
this.state.currentLocation = {
|
||||||
|
lat: bd09.lat,
|
||||||
|
lng: bd09.lng,
|
||||||
|
accuracy: res.accuracy || 0
|
||||||
|
};
|
||||||
|
this.updateLocationMarker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('uni-app GPS定位更新失败:', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 3000); // 每3秒更新一次,给GPS更多时间
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用uni-app定位(GCJ02坐标)
|
||||||
|
*/
|
||||||
|
startUniAppGeolocation() {
|
||||||
|
// 先获取一次当前位置
|
||||||
|
uni.getLocation({
|
||||||
|
type: 'gcj02', // 使用GCJ02坐标系(火星坐标),然后转换为BD09
|
||||||
|
altitude: false,
|
||||||
|
geocode: false,
|
||||||
|
highAccuracyExpireTime: 4000,
|
||||||
|
success: (res) => {
|
||||||
|
console.log('uni-app定位成功:', res.longitude, res.latitude, '精度:', res.accuracy);
|
||||||
|
// uni-app返回的是GCJ02坐标,需要转换为BD09
|
||||||
|
this.gcj02ToBd09(res.longitude, res.latitude, (bd09) => {
|
||||||
|
if (bd09 && bd09.lng && bd09.lat) {
|
||||||
|
this.state.currentLocation = {
|
||||||
|
lat: bd09.lat,
|
||||||
|
lng: bd09.lng,
|
||||||
|
accuracy: res.accuracy || 0
|
||||||
|
};
|
||||||
|
console.log('坐标转换完成 - BD09:', bd09.lng, bd09.lat);
|
||||||
|
this.updateLocationMarker();
|
||||||
|
} else {
|
||||||
|
console.error('坐标转换失败,使用备用方案');
|
||||||
|
// 如果转换失败,尝试使用百度地图定位
|
||||||
|
if (typeof BMapGL !== 'undefined' && BMapGL.Geolocation) {
|
||||||
|
this.startBaiduGeolocation();
|
||||||
|
} else {
|
||||||
|
this.startBrowserGeolocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('uni-app定位失败:', err);
|
||||||
|
// 降级到百度地图定位或浏览器定位
|
||||||
|
if (typeof BMapGL !== 'undefined' && BMapGL.Geolocation) {
|
||||||
|
this.startBaiduGeolocation();
|
||||||
|
} else {
|
||||||
|
this.startBrowserGeolocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 持续监听位置变化
|
||||||
|
this.state.watchLocationTimer = setInterval(() => {
|
||||||
|
uni.getLocation({
|
||||||
|
type: 'gcj02',
|
||||||
|
altitude: false,
|
||||||
|
geocode: false,
|
||||||
|
highAccuracyExpireTime: 4000,
|
||||||
|
success: (res) => {
|
||||||
|
this.gcj02ToBd09(res.longitude, res.latitude, (bd09) => {
|
||||||
|
if (bd09 && bd09.lng && bd09.lat) {
|
||||||
|
// 只更新精度更好的位置
|
||||||
|
if (!this.state.currentLocation || res.accuracy < this.state.currentLocation.accuracy || res.accuracy < 50) {
|
||||||
|
this.state.currentLocation = {
|
||||||
|
lat: bd09.lat,
|
||||||
|
lng: bd09.lng,
|
||||||
|
accuracy: res.accuracy || 0
|
||||||
|
};
|
||||||
|
this.updateLocationMarker();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('uni-app定位更新失败:', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 2000); // 每2秒更新一次位置
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用5+定位
|
||||||
|
*/
|
||||||
|
startPlusGeolocation() {
|
||||||
|
const geolocation = plus.geolocation;
|
||||||
|
const options = {
|
||||||
|
enableHighAccuracy: true,
|
||||||
|
timeout: 10000,
|
||||||
|
maximumAge: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取当前位置
|
||||||
|
geolocation.getCurrentPosition(
|
||||||
|
(position) => {
|
||||||
|
console.log('5+定位成功:', position);
|
||||||
|
// 5+返回的是WGS84坐标,需要转换为BD09
|
||||||
|
this.wgs84ToBd09(position.coords.longitude, position.coords.latitude, (bd09) => {
|
||||||
|
this.state.currentLocation = {
|
||||||
|
lat: bd09.lat,
|
||||||
|
lng: bd09.lng,
|
||||||
|
accuracy: position.coords.accuracy || 0
|
||||||
|
};
|
||||||
|
this.updateLocationMarker();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error('5+定位失败:', error);
|
||||||
|
this.startBrowserGeolocation();
|
||||||
|
},
|
||||||
|
options
|
||||||
|
);
|
||||||
|
|
||||||
|
// 持续监听位置变化
|
||||||
|
this.state.watchPositionId = geolocation.watchPosition(
|
||||||
|
(position) => {
|
||||||
|
this.wgs84ToBd09(position.coords.longitude, position.coords.latitude, (bd09) => {
|
||||||
|
this.state.currentLocation = {
|
||||||
|
lat: bd09.lat,
|
||||||
|
lng: bd09.lng,
|
||||||
|
accuracy: position.coords.accuracy || 0
|
||||||
|
};
|
||||||
|
this.updateLocationMarker();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error('5+定位监听错误:', error);
|
||||||
|
},
|
||||||
|
options
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用浏览器定位
|
||||||
|
*/
|
||||||
|
startBrowserGeolocation() {
|
||||||
|
if (!navigator.geolocation) {
|
||||||
|
console.error('浏览器不支持定位');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
enableHighAccuracy: true, // 高精度定位(使用GPS)
|
||||||
|
timeout: 20000, // 增加超时时间到20秒,确保获取高精度定位
|
||||||
|
maximumAge: 0 // 不使用缓存,始终获取最新位置
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('开始浏览器定位,选项:', options);
|
||||||
|
|
||||||
// 先获取一次当前位置
|
// 先获取一次当前位置
|
||||||
navigator.geolocation.getCurrentPosition(
|
navigator.geolocation.getCurrentPosition(
|
||||||
(position) => this.updateLocation(position),
|
(position) => {
|
||||||
(error) => this.handleLocationError(error),
|
console.log('获取到初始位置:', position.coords);
|
||||||
|
this.updateLocation(position);
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error('获取初始位置失败:', error);
|
||||||
|
this.handleLocationError(error);
|
||||||
|
},
|
||||||
options
|
options
|
||||||
);
|
);
|
||||||
|
|
||||||
// 持续监听位置变化
|
// 持续监听位置变化
|
||||||
this.state.watchPositionId = navigator.geolocation.watchPosition(
|
this.state.watchPositionId = navigator.geolocation.watchPosition(
|
||||||
(position) => this.updateLocation(position),
|
(position) => {
|
||||||
(error) => this.handleLocationError(error),
|
console.log('位置更新:', position.coords);
|
||||||
|
this.updateLocation(position);
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error('位置监听错误:', error);
|
||||||
|
this.handleLocationError(error);
|
||||||
|
},
|
||||||
options
|
options
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GCJ02坐标转BD09坐标(百度坐标)
|
||||||
|
*/
|
||||||
|
gcj02ToBd09(gcj_lng, gcj_lat, callback) {
|
||||||
|
const ak = 'iqyZkSZPurf61MhFV7hesbDukHdMBEEb';
|
||||||
|
// 使用6位小数精度(百度API推荐精度)
|
||||||
|
const coords = `${Number(gcj_lng).toFixed(6)},${Number(gcj_lat).toFixed(6)}`;
|
||||||
|
const url = `https://api.map.baidu.com/geoconv/v1/?coords=${coords}&from=3&to=5&ak=${ak}`;
|
||||||
|
|
||||||
|
console.log('GCJ02转BD09 - 输入:', gcj_lng, gcj_lat);
|
||||||
|
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', url, true);
|
||||||
|
xhr.timeout = 10000; // 10秒超时
|
||||||
|
xhr.onreadystatechange = () => {
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
if (xhr.status === 200) {
|
||||||
|
try {
|
||||||
|
const response = JSON.parse(xhr.responseText);
|
||||||
|
if (response.status === 0 && response.result && response.result.length > 0) {
|
||||||
|
const point = response.result[0];
|
||||||
|
const result = {
|
||||||
|
lng: Number(point.x),
|
||||||
|
lat: Number(point.y)
|
||||||
|
};
|
||||||
|
console.log('GCJ02转BD09成功:', result.lng, result.lat);
|
||||||
|
if (callback) callback(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('GCJ02转BD09解析失败:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// API失败,使用算法转换
|
||||||
|
console.warn('GCJ02转BD09 API失败,使用算法转换');
|
||||||
|
const result = this.gcj02ToBd09Fallback(gcj_lng, gcj_lat);
|
||||||
|
if (callback) callback(result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.onerror = () => {
|
||||||
|
console.warn('GCJ02转BD09网络错误,使用算法转换');
|
||||||
|
const result = this.gcj02ToBd09Fallback(gcj_lng, gcj_lat);
|
||||||
|
if (callback) callback(result);
|
||||||
|
};
|
||||||
|
xhr.ontimeout = () => {
|
||||||
|
console.warn('GCJ02转BD09超时,使用算法转换');
|
||||||
|
const result = this.gcj02ToBd09Fallback(gcj_lng, gcj_lat);
|
||||||
|
if (callback) callback(result);
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GCJ02转BD09算法
|
||||||
|
*/
|
||||||
|
gcj02ToBd09Fallback(gcj_lng, gcj_lat) {
|
||||||
|
const x_PI = 3.14159265358979324 * 3000.0 / 180.0;
|
||||||
|
let z = Math.sqrt(gcj_lng * gcj_lng + gcj_lat * gcj_lat) + 0.00002 * Math.sin(gcj_lat * x_PI);
|
||||||
|
let theta = Math.atan2(gcj_lat, gcj_lng) + 0.000003 * Math.cos(gcj_lng * x_PI);
|
||||||
|
let bd_lng = z * Math.cos(theta) + 0.0065;
|
||||||
|
let bd_lat = z * Math.sin(theta) + 0.006;
|
||||||
|
return { lng: bd_lng, lat: bd_lat };
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WGS84坐标转BD09坐标(优先使用百度地图Web API,最准确)
|
* WGS84坐标转BD09坐标(优先使用百度地图Web API,最准确)
|
||||||
*/
|
*/
|
||||||
|
|
@ -609,43 +1076,73 @@
|
||||||
*/
|
*/
|
||||||
wgs84ToBd09WebAPI(wgs_lng, wgs_lat, callback) {
|
wgs84ToBd09WebAPI(wgs_lng, wgs_lat, callback) {
|
||||||
const ak = 'iqyZkSZPurf61MhFV7hesbDukHdMBEEb'; // 百度地图AK
|
const ak = 'iqyZkSZPurf61MhFV7hesbDukHdMBEEb'; // 百度地图AK
|
||||||
const coords = `${wgs_lng},${wgs_lat}`;
|
// 使用6位小数精度(百度API推荐精度)
|
||||||
|
const coords = `${Number(wgs_lng).toFixed(6)},${Number(wgs_lat).toFixed(6)}`;
|
||||||
const url = `https://api.map.baidu.com/geoconv/v1/?coords=${coords}&from=1&to=5&ak=${ak}`;
|
const url = `https://api.map.baidu.com/geoconv/v1/?coords=${coords}&from=1&to=5&ak=${ak}`;
|
||||||
|
|
||||||
|
console.log('调用坐标转换API - WGS84:', wgs_lng, wgs_lat, 'URL:', url);
|
||||||
|
|
||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
xhr.open('GET', url, true);
|
xhr.open('GET', url, true);
|
||||||
xhr.timeout = 5000;
|
xhr.timeout = 10000; // 10秒超时
|
||||||
xhr.onreadystatechange = () => {
|
xhr.onreadystatechange = () => {
|
||||||
if (xhr.readyState === 4) {
|
if (xhr.readyState === 4) {
|
||||||
if (xhr.status === 200) {
|
if (xhr.status === 200) {
|
||||||
try {
|
try {
|
||||||
const response = JSON.parse(xhr.responseText);
|
const responseText = xhr.responseText;
|
||||||
|
console.log('坐标转换API原始响应:', responseText);
|
||||||
|
const response = JSON.parse(responseText);
|
||||||
|
|
||||||
if (response.status === 0 && response.result && response.result.length > 0) {
|
if (response.status === 0 && response.result && response.result.length > 0) {
|
||||||
const point = response.result[0];
|
const point = response.result[0];
|
||||||
const result = { lng: point.x, lat: point.y };
|
// 百度API返回:x=经度,y=纬度
|
||||||
|
const result = {
|
||||||
|
lng: Number(point.x),
|
||||||
|
lat: Number(point.y)
|
||||||
|
};
|
||||||
|
|
||||||
|
// 验证转换结果的有效性
|
||||||
|
if (isNaN(result.lng) || isNaN(result.lat) ||
|
||||||
|
result.lng === 0 || result.lat === 0 ||
|
||||||
|
Math.abs(result.lng) > 180 || Math.abs(result.lat) > 90) {
|
||||||
|
console.error('坐标转换结果无效:', result, '原始响应:', response);
|
||||||
|
const fallback = this.wgs84ToBd09Fallback(wgs_lng, wgs_lat);
|
||||||
|
console.warn('使用备用算法:', fallback);
|
||||||
|
if (callback) callback(fallback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算偏移距离(用于调试)
|
||||||
|
const offsetLng = result.lng - wgs_lng;
|
||||||
|
const offsetLat = result.lat - wgs_lat;
|
||||||
console.log('Web API转换成功 - WGS84:', wgs_lng, wgs_lat, '-> BD09:', result.lng, result.lat);
|
console.log('Web API转换成功 - WGS84:', wgs_lng, wgs_lat, '-> BD09:', result.lng, result.lat);
|
||||||
|
console.log('坐标偏移:', '经度:', offsetLng.toFixed(6), '纬度:', offsetLat.toFixed(6));
|
||||||
|
|
||||||
if (callback) callback(result);
|
if (callback) callback(result);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
console.warn('Web API返回错误:', response);
|
console.error('Web API返回错误 - 状态码:', response.status, '错误信息:', response.message || JSON.stringify(response));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('Web API解析失败:', e);
|
console.error('Web API解析失败:', e, '响应文本:', xhr.responseText);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.error('Web API请求失败 - HTTP状态码:', xhr.status, '响应:', xhr.responseText);
|
||||||
}
|
}
|
||||||
// API调用失败,使用备用算法
|
// API调用失败,使用备用算法
|
||||||
|
console.warn('坐标转换API失败,使用备用算法');
|
||||||
const result = this.wgs84ToBd09Fallback(wgs_lng, wgs_lat);
|
const result = this.wgs84ToBd09Fallback(wgs_lng, wgs_lat);
|
||||||
console.log('使用备用算法转换 - WGS84:', wgs_lng, wgs_lat, '-> BD09:', result.lng, result.lat);
|
console.log('备用算法转换结果 - WGS84:', wgs_lng, wgs_lat, '-> BD09:', result.lng, result.lat);
|
||||||
if (callback) callback(result);
|
if (callback) callback(result);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhr.onerror = () => {
|
xhr.onerror = () => {
|
||||||
console.warn('Web API网络错误,使用备用算法');
|
console.error('Web API网络错误');
|
||||||
const result = this.wgs84ToBd09Fallback(wgs_lng, wgs_lat);
|
const result = this.wgs84ToBd09Fallback(wgs_lng, wgs_lat);
|
||||||
if (callback) callback(result);
|
if (callback) callback(result);
|
||||||
};
|
};
|
||||||
xhr.ontimeout = () => {
|
xhr.ontimeout = () => {
|
||||||
console.warn('Web API超时,使用备用算法');
|
console.error('Web API请求超时');
|
||||||
const result = this.wgs84ToBd09Fallback(wgs_lng, wgs_lat);
|
const result = this.wgs84ToBd09Fallback(wgs_lng, wgs_lat);
|
||||||
if (callback) callback(result);
|
if (callback) callback(result);
|
||||||
};
|
};
|
||||||
|
|
@ -750,8 +1247,14 @@
|
||||||
* 更新定位标记
|
* 更新定位标记
|
||||||
*/
|
*/
|
||||||
updateLocationMarker() {
|
updateLocationMarker() {
|
||||||
if (!this.map || !this.state.currentLocation) {
|
// 确保地图已加载完成且有位置信息
|
||||||
console.warn('无法更新定位标记:地图或位置信息缺失');
|
if (!this.map || !this.state.mapLoaded) {
|
||||||
|
console.warn('无法更新定位标记:地图未加载完成');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.state.currentLocation) {
|
||||||
|
console.warn('无法更新定位标记:位置信息缺失');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -781,8 +1284,8 @@
|
||||||
* 回到平板当前位置
|
* 回到平板当前位置
|
||||||
*/
|
*/
|
||||||
centerToLocation() {
|
centerToLocation() {
|
||||||
if (!this.map) {
|
if (!this.map || !this.state.mapLoaded) {
|
||||||
console.warn('地图未初始化');
|
console.warn('地图未加载完成');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1021,9 +1524,24 @@
|
||||||
* 停止定位跟踪
|
* 停止定位跟踪
|
||||||
*/
|
*/
|
||||||
stopLocationTracking() {
|
stopLocationTracking() {
|
||||||
|
// 停止定位定时器(包括uni-app和百度地图)
|
||||||
|
if (this.state.watchLocationTimer !== null) {
|
||||||
|
clearInterval(this.state.watchLocationTimer);
|
||||||
|
this.state.watchLocationTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理百度地图定位实例
|
||||||
|
if (this.baiduGeolocation) {
|
||||||
|
this.baiduGeolocation = null;
|
||||||
|
}
|
||||||
|
|
||||||
// 停止位置监听
|
// 停止位置监听
|
||||||
if (this.state.watchPositionId !== null) {
|
if (this.state.watchPositionId !== null) {
|
||||||
navigator.geolocation.clearWatch(this.state.watchPositionId);
|
if (navigator.geolocation) {
|
||||||
|
navigator.geolocation.clearWatch(this.state.watchPositionId);
|
||||||
|
} else if (typeof plus !== 'undefined' && plus.geolocation) {
|
||||||
|
plus.geolocation.clearWatch(this.state.watchPositionId);
|
||||||
|
}
|
||||||
this.state.watchPositionId = null;
|
this.state.watchPositionId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1034,7 +1552,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// 移除方向事件监听
|
// 移除方向事件监听
|
||||||
window.removeEventListener('deviceorientation', this.handleOrientation);
|
if (this.handleOrientation) {
|
||||||
|
window.removeEventListener('deviceorientation', this.handleOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
// 移除定位标记
|
// 移除定位标记
|
||||||
if (this.overlays.locationMarker && this.map) {
|
if (this.overlays.locationMarker && this.map) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue