尝试重新编码 OpenLayers 函数时出现重投影问题
Reprojection issue while trying to recode an OpenLayers function
由于某些库(prototype.js 和 pro4js)之间的冲突,我需要重写 OpenLayers 的一个函数。但即使我尝试使用与他们 github 完全相同的代码,结果也与我没有重写函数得到的结果不同。
在我的例子中,想要重新编码的函数是 register()
来自 ol/proj/proj4
这是一个使用此函数的重投影示例:
proj4.defs('EPSG:27572', "+title=NTF (Paris) / Lambert zone II +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs");
ol.proj.proj4.register(proj4);
proj = ol.proj.get('EPSG:27572');
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
],
target: 'map',
view: new ol.View({
projection: proj,
center: [0, 0],
zoom: 1
})
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>Reprojection</title>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css">
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>
<style>
.map {
width: 600px;
height:400px;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
</body>
</html>
但是如果我重新编码这个函数(根据这个来源:https://github.com/openlayers/openlayers/blob/master/src/ol/proj/proj4.js),我定义的投影对 ol 地图没有任何影响,除了完全模糊地图(但我想这是一个我的主要问题的副作用,因为模糊地图大部分时间都是由于重投影问题):
ol.proj.proj4.register = function(proj4) {
const projCodes = Object.keys(proj4.defs);
const len = projCodes.length;
let i, j;
for (i = 0; i < len; ++i) {
const code = projCodes[i];
if (!ol.proj.get(code)) {
const def = proj4.defs(code);
ol.proj.addProjection(new ol.proj.Projection({
code: code,
axisOrientation: def.axis,
metersPerUnit: def.to_meter,
units: def.units
}));
}
}
for (i = 0; i < len; ++i) {
const code1 = projCodes[i];
const proj1 = ol.proj.get(code1);
for (j = 0; j < len; ++j) {
const code2 = projCodes[j];
const proj2 = ol.proj.get(code2);
if (!ol.proj.getTransform(code1, code2)) {
if (proj4.defs[code1] === proj4.defs[code2]) {
ol.proj.addEquivalentProjections([proj1, proj2]);
} else {
const transform = proj4(code1, code2);
ol.proj.addCoordinateTransforms(proj1, proj2, transform.forward, transform.inverse);
}
}
}
}
}
proj4.defs('EPSG:27572', "+title=NTF (Paris) / Lambert zone II +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs");
ol.proj.proj4.register(proj4);
proj = ol.proj.get('EPSG:27572');
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
],
target: 'map',
view: new ol.View({
projection: proj,
center: [0, 0],
zoom: 1
})
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>Reprojection</title>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css">
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>
<style>
.map {
width: 600px;
height:400px;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
</body>
</html>
有人可以向我解释我错在哪里吗?当然,如果您对从库中重写函数有更好的想法,我也会喜欢它!
顺便说一句:出于好奇,我试图面对的冲突是因为 prototype.js 向对象添加了额外的属性。我对这个框架知之甚少,也没有手头或选择删除它。由于函数 ol.proj.proj4.register()
检索带有 Object.keys()
的投影代码,它实际上检索了比 prototype.js 的那些代码更多的代码。当然会产生错误。
ol.proj.getTransform
与 {get as getTransform} from './transforms.js'
不同(如果它是 API 的一部分,则为 ol.proj.transforms.get
)。由于它未在 public API 中列出,因此无法通过完整构建使用它,因此您需要对正在定义的转换使用替代测试,或者干脆不去测试并且总是重新定义。
ol.proj.proj4.register = function(proj4) {
const projCodes = Object.keys(proj4.defs);
const len = projCodes.length;
let i, j;
for (i = 0; i < len; ++i) {
const code = projCodes[i];
if (!ol.proj.get(code)) {
const def = proj4.defs(code);
ol.proj.addProjection(new ol.proj.Projection({
code: code,
axisOrientation: def.axis,
metersPerUnit: def.to_meter,
units: def.units
}));
}
}
for (i = 0; i < len; ++i) {
const code1 = projCodes[i];
const proj1 = ol.proj.get(code1);
for (j = 0; j < len; ++j) {
const code2 = projCodes[j];
const proj2 = ol.proj.get(code2);
//if (!ol.proj.getTransform(code1, code2)) {
if (proj4.defs[code1] === proj4.defs[code2]) {
ol.proj.addEquivalentProjections([proj1, proj2]);
} else {
const transform = proj4(code1, code2);
ol.proj.addCoordinateTransforms(proj1, proj2, transform.forward, transform.inverse);
}
//}
}
}
}
proj4.defs('EPSG:27572', "+title=NTF (Paris) / Lambert zone II +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs");
ol.proj.proj4.register(proj4);
proj = ol.proj.get('EPSG:27572');
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
],
target: 'map',
view: new ol.View({
projection: proj,
center: [0, 0],
zoom: 1
})
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>Reprojection</title>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css">
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>
<style>
.map {
width: 600px;
height:400px;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
</body>
</html>
由于某些库(prototype.js 和 pro4js)之间的冲突,我需要重写 OpenLayers 的一个函数。但即使我尝试使用与他们 github 完全相同的代码,结果也与我没有重写函数得到的结果不同。
在我的例子中,想要重新编码的函数是 register()
来自 ol/proj/proj4
这是一个使用此函数的重投影示例:
proj4.defs('EPSG:27572', "+title=NTF (Paris) / Lambert zone II +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs");
ol.proj.proj4.register(proj4);
proj = ol.proj.get('EPSG:27572');
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
],
target: 'map',
view: new ol.View({
projection: proj,
center: [0, 0],
zoom: 1
})
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>Reprojection</title>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css">
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>
<style>
.map {
width: 600px;
height:400px;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
</body>
</html>
但是如果我重新编码这个函数(根据这个来源:https://github.com/openlayers/openlayers/blob/master/src/ol/proj/proj4.js),我定义的投影对 ol 地图没有任何影响,除了完全模糊地图(但我想这是一个我的主要问题的副作用,因为模糊地图大部分时间都是由于重投影问题):
ol.proj.proj4.register = function(proj4) {
const projCodes = Object.keys(proj4.defs);
const len = projCodes.length;
let i, j;
for (i = 0; i < len; ++i) {
const code = projCodes[i];
if (!ol.proj.get(code)) {
const def = proj4.defs(code);
ol.proj.addProjection(new ol.proj.Projection({
code: code,
axisOrientation: def.axis,
metersPerUnit: def.to_meter,
units: def.units
}));
}
}
for (i = 0; i < len; ++i) {
const code1 = projCodes[i];
const proj1 = ol.proj.get(code1);
for (j = 0; j < len; ++j) {
const code2 = projCodes[j];
const proj2 = ol.proj.get(code2);
if (!ol.proj.getTransform(code1, code2)) {
if (proj4.defs[code1] === proj4.defs[code2]) {
ol.proj.addEquivalentProjections([proj1, proj2]);
} else {
const transform = proj4(code1, code2);
ol.proj.addCoordinateTransforms(proj1, proj2, transform.forward, transform.inverse);
}
}
}
}
}
proj4.defs('EPSG:27572', "+title=NTF (Paris) / Lambert zone II +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs");
ol.proj.proj4.register(proj4);
proj = ol.proj.get('EPSG:27572');
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
],
target: 'map',
view: new ol.View({
projection: proj,
center: [0, 0],
zoom: 1
})
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>Reprojection</title>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css">
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>
<style>
.map {
width: 600px;
height:400px;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
</body>
</html>
有人可以向我解释我错在哪里吗?当然,如果您对从库中重写函数有更好的想法,我也会喜欢它!
顺便说一句:出于好奇,我试图面对的冲突是因为 prototype.js 向对象添加了额外的属性。我对这个框架知之甚少,也没有手头或选择删除它。由于函数 ol.proj.proj4.register()
检索带有 Object.keys()
的投影代码,它实际上检索了比 prototype.js 的那些代码更多的代码。当然会产生错误。
ol.proj.getTransform
与 {get as getTransform} from './transforms.js'
不同(如果它是 API 的一部分,则为 ol.proj.transforms.get
)。由于它未在 public API 中列出,因此无法通过完整构建使用它,因此您需要对正在定义的转换使用替代测试,或者干脆不去测试并且总是重新定义。
ol.proj.proj4.register = function(proj4) {
const projCodes = Object.keys(proj4.defs);
const len = projCodes.length;
let i, j;
for (i = 0; i < len; ++i) {
const code = projCodes[i];
if (!ol.proj.get(code)) {
const def = proj4.defs(code);
ol.proj.addProjection(new ol.proj.Projection({
code: code,
axisOrientation: def.axis,
metersPerUnit: def.to_meter,
units: def.units
}));
}
}
for (i = 0; i < len; ++i) {
const code1 = projCodes[i];
const proj1 = ol.proj.get(code1);
for (j = 0; j < len; ++j) {
const code2 = projCodes[j];
const proj2 = ol.proj.get(code2);
//if (!ol.proj.getTransform(code1, code2)) {
if (proj4.defs[code1] === proj4.defs[code2]) {
ol.proj.addEquivalentProjections([proj1, proj2]);
} else {
const transform = proj4(code1, code2);
ol.proj.addCoordinateTransforms(proj1, proj2, transform.forward, transform.inverse);
}
//}
}
}
}
proj4.defs('EPSG:27572', "+title=NTF (Paris) / Lambert zone II +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs");
ol.proj.proj4.register(proj4);
proj = ol.proj.get('EPSG:27572');
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
],
target: 'map',
view: new ol.View({
projection: proj,
center: [0, 0],
zoom: 1
})
});
<!DOCTYPE html>
<html lang="en">
<head>
<title>Reprojection</title>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css">
<script type="text/javascript" src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>
<style>
.map {
width: 600px;
height:400px;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
</body>
</html>