Reputation: 768
Because of conflicts between some libraries (prototype.js and pro4js) i need to rewrite a function of OpenLayers. But even when i try to use the exact same code than on their github, the result differs from the one i get without rewriting the function.
In my case the function in want to recode is register()
from ol/proj/proj4
Here is a reprojection example using this function :
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>
But then if i recode this function (according to this source : https://github.com/openlayers/openlayers/blob/master/src/ol/proj/proj4.js), the projection i defined does not have any effect on the ol map except totaly blurring the map ( but i guess this is a side effect of my main problem since blurry maps are most of the time du to reprojection issue ) :
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>
Can someone explain to me where i am wrong ? And of course if you have a better idea for rewriting a function from a library i would enjoy it also !
BTW : For curious, the conflict i try to face is because prototype.js adds extra properties to objects. I don't know a lot about this framework and I don't have the hand on it or the choice to remove it. Since the function ol.proj.proj4.register()
retrieves projection codes with Object.keys()
, it actually retrieves much more than those codes because of prototype.js. And of course generates an error.
Upvotes: 0
Views: 726
Reputation: 17897
ol.proj.getTransform
is not the same as {get as getTransform} from './transforms.js'
(which would be ol.proj.transforms.get
if it was part of the API). Since it isn't listed in the public API it isn't available via the full build so you would need to use an alternative test for a transform being defined, or simply don't bother to test and always redefine.
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>
Upvotes: 1