我有一个
.json
的点文件要放在 Leaflet 地图上,并且我使用 proj4js
将它们从 EPSG 3946 投影转换为 WGS84 EPSG 4326 投影。所有这些都有效,但这些点并未位于应有的位置:它们的纬度大约偏南 8 度,偏东一点。相同的点在 QGIS 上看起来很好,它们位于应该在的位置。
这是
.js
脚本:
var pTransfo;
$.getJSON('transfo.json',function(data){
proj4.defs("EPSG:3946", "+proj=lcc +lat_1=43 +lat_2=49 +lat_0=46.5 +lon_0=6 +x_0=1700000 +y_0=6200000 +datum=RGF93 +units=m +no_defs +towgs84=0,0,0");
var fromProj = proj4('EPSG:3946');
var toProj = proj4('EPSG:4326');
function convertCoordinates(coordinates) {
var convertedCoords = proj4(fromProj, toProj, [coordinates[0], coordinates[1]]);
console.log('Coordonnées originales :', coordinates);
console.log('Coordonnées converties :', convertedCoords);
return [convertedCoords[0], convertedCoords[1]];
}
data.features.forEach(function(feature) {
if (feature.geometry.type === "Point") {
feature.geometry.coordinates = convertCoordinates(feature.geometry.coordinates);
}
});
我已经在 html 中添加了这一行:
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.0/proj4-src.js"></script>
在 jquery 和 leaflet 行之后。
为什么定位会延迟?
问题很可能是 EPSG:3946 坐标的顺序。由于我没有你的数据可供测试,所以我只能猜测。但是,我使用
1124390.4605155424, 5490541.680680278
(x, y) 为布雷斯特的 Le Conquet 编写了一个示例。
对话输出为
-4.773869999999995, 48.36004666665183
(lng, lat)。如果我以相反的顺序传递 EPSG:3946 坐标 (y, x),那么我也会得到一个偏离的坐标。
此外,我正在使用 Jaromanda X 在他的评论中建议的投影。
// x, y
const leConquetEPSG3946 = [1124390.4605155424, 5490541.680680278];
proj4.defs('EPSG:3946', '+proj=lcc +lat_0=46 +lon_0=3 +lat_1=45.25 +lat_2=46.75 +x_0=1700000 +y_0=5200000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs');
const proj3946 = proj4('EPSG:3946');
const proj4326 = proj4('EPSG:4326');
const result = proj4(proj3946, proj4326, leConquetEPSG3946);
// -4.773869999999995, 48.36004666665183
console.log(result);
这是一个工作示例(从 spatialreference.org 动态加载投影定义):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>StackOverflow Question 79049517</title>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.12.1/proj4.js"></script>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<style>
body {
margin: 0;
}
#map {
height: 100vh;
}
.reference-marker .circle {
background-color: #f07819;
border-radius: 50%;
height: 20px; width: 20px;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
// x, y
const leConquetEPSG3946 = [1124390.4605155424, 5490541.680680278];
// lat, lng
const leConquetEPSG4326 = [48.36004669356216, -4.773869943507622];
const map = L.map('map')
.setView(leConquetEPSG4326, 16);
map.attributionControl
.setPrefix('<a href="https://leafletjs.com/">Leaflet</a>');
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
// add link to attribution, omitted in this code example
// due to width limit, i.e., avoid horizontal scrolling
attribution: '© OpenStreetMap',
}).addTo(map);
L.marker(leConquetEPSG4326, {
icon: L.divIcon({
className: 'reference-marker',
iconSize: [20, 20],
html: '<div class="circle"></div>',
}),
}).addTo(map);
async function loadDefs(...epsgCodes) {
const projs = {};
for (const code of epsgCodes) {
if (code != 4326) {
const url = `https://spatialreference.org/ref/epsg/${code}/esriwkt.txt`;
const response = await fetch(url);
const wkt = await response.text();
proj4.defs(`EPSG:${code}`, wkt);
}
projs[code] = proj4(`EPSG:${code}`);
}
return projs;
}
loadDefs(3946, 4326)
.then(projs => {
// lng, lat
const conversionResult = proj4(projs[3946], projs[4326], leConquetEPSG3946);
// lat, lng
const result = conversionResult.reverse();
console.log(leConquetEPSG4326);
console.log(result);
L.marker(result).addTo(map);
});
</script>
</body>
</html>