3liz / lizmap-javascript-scripts

Scripts for Lizmap Web Client
Mozilla Public License 2.0
19 stars 40 forks source link

zoom_to_feature_at_startup lizmap zooms to center of mapextends #27

Closed geomoes closed 2 weeks ago

geomoes commented 4 years ago

tried to implement the zoom_to_feature_at_startup script. LM 3.3, PlugIn: 3.2.17, QGIS 3.14-1, QGIS-server When I call the lizmap page with the appended #fid: string

https://xxx.xxx.xxx.xxx/lizmap/index.php/view/map/?repository=fn&project=lizmap#fid:v_parzellen_74ad241d_3f1e_4081_8e88_0d4031463c95.4642

Lizmap starts rendering the baselayer at the initial extend, then zooms to the center of the original extend at the closest zoom level. This behavior does not change when I pass another id. I left #fid: although I don't have an 'fid'-field. My pk_field in the table is 'id'. I also tried to change this to #id:, but this did not fix the problem. In the console jQuery complains about an empty string, that is passd to getElementById()? The script is loaded corectly. The project file is in EPSG:3857 and the layer data in EPSQ:2169, but layers show up on the right place.

Gustry commented 4 years ago

This script has been developed by @mdouchin, maybe you have idea?

geomoes commented 4 years ago

I changed now the project projection to EPSG:2169 (Luxembourg), updated the extend in the layer properties from the map canvas (showing the whole country) and did the same in the Lizmap-Plugin. The overlay-layers are in EPSG:2169 and the baselayers in EPSG:3857. In Lizmap all layers are displayed correct. When I activate the zoom_to_feature_at_startup script, I end up about 100km south-west from the feature. So defenitely outside the bounding box of the initial extend. I admit, that the title isn't correct anymore since the map doesn't zoom anymore to the center of the mapextend, but somewhere else (565137/6263080 in EPSG:2169 or 5,07663/48,93052 in EPSG:4326). (using QGIS 4.14-1 on macos, Lizmap 3.3).

I checked the values returned by the script. Everything is OK until I come to lizMap.zoomToFeature(featureType, fid, 'zoom'); since this returns 'undefined'.

One other strange thing is that lizMap.map.getProjection(); gives me EPSG:900913, which is a synonym of EPSG:3857. Although my whole project is in EPSG:2169. Could that be an issue do to a missing EPSG-definition for 2169 in proj4?

Bildschirmfoto 2020-08-25 um 20 53 36
geomoes commented 4 years ago

I've tried the script now with a new Lizmap project, that has only two layers. A PostGIS layer and an WMS baselayer. Both are in EPSG:3857 and the project projection is also set to EPSG:3857. The layers display fine in Lizmap. When I call the layer: https://map.xxxx.xx/lizmap/index.php/view/map/?repository=hfnlm&project=lm_test#fid:v_btk_s_3857_51c2ab28_ba0f_488d_aba5_c54f0578f1cc.518 the map opens and stays at the initial view. No zooming.

The lizmap-log shows the following entry:

warning 2020-08-28 10:50:34 [2] file_get_contents(http://map.xxxx.xx/cgi-bin/qgis_mapserv.fcgi?
service=WMS&request=GetCapabilitiesAtlas&map=/var/www/lizmap-web-client-3.3.3/lizmap/install/hfn_lm/lm_test.qgs): 
failed to open stream: HTTP request failed! HTTP/1.1 501 Not Implemented
    /var/www/lizmap-web-client-3.3.3/lizmap/modules/lizmap/classes/lizmapProxy.class.php    240

2020-08-28 10:50:34 95.90.255.241   error   ("gid" = 518)

Any idea?

johnzet39 commented 4 years ago

Same problem. And if I run lizMap.zoomToFeature(featureType, fid, 'zoom'); from browser console, it works correctly.

geomoes commented 4 years ago

OK, for me it works as well in the console even without issues concerning the projection. I was a bit confused, since my project is set up in EPSG:2169 (Luxembourg), the layer (v_parzellen) I try to adress is also in EPSG:2169, but lizmap.getProjection() returns EPSG:900913 which corresponds to EPSG:3857. When I use lizMap.zoomToFeature('v_parzellen', 518, 'zoom'); in the browser console I get exactly what I want. The map zooms to the feature with the id=518 on the layer v_parzellen. So at least I'm shure that it is not an issue with the projection. I don't understand, why this doesn't work with the script? I tried to declare first var featureType = ''; to be shure it will be a string, but this doesn't change anything.

johnzet39 commented 4 years ago

I tried to replacing the line of code

// Zoom to feature
//lizMap.zoomToFeature(featuretype.toString(), fid.toString(), 'zoom');

by

// Zoom to feature
setTimeout(() => {
  lizMap.zoomToFeature(featuretype, fid, 'zoom');
},2000);

and script works as we want. I don't know why, but maybe this will help to suggest some thoughts. If I set 1 second timeout, it don't work.

johnzet39 commented 4 years ago

By the way, this only works for me if I have enabled atlas for the layer in plugin Lizmap. Although it is not required to execute a line in the browser console.

geomoes commented 4 years ago

OK, I've tested that the way you described. For me it works when

johnzet39 commented 4 years ago
//file map.js
function zoomToFeature( featureType, fid, zoomAction ){
      zoomAction = typeof zoomAction !== 'undefined' ?  zoomAction : 'zoom';

      var layerConfig = config.layers[featureType];
      var featureId = featureType + '.' + fid;

      var proj = new OpenLayers.Projection(config.layers[featureType].crs);
      if( config.layers[featureType].featureCrs )
          proj = new OpenLayers.Projection(config.layers[featureType].featureCrs);
      getLayerFeature(featureType, fid, function(feat) {
          zoomToOlFeature( feat, proj, zoomAction );
      });
}

So, if you don't use a timer then the variable proj = new OpenLayers.Projection(lizMap.config.layers[featureType].featureCrs) in function "zoomToFeature" (file map.js) does not have time to receive data (?) after loading map. And then in function "localZoomToOlFeature" an incorrect transform occurs. Unfortunately, I dont understand yet why config.layers[featureType].crs and layers[featureType].featureCrs can/should be different. And does the layers[featureType].featureCrs always have to be 'EPSG:4326'. (If anyone can explain in a nutshell, I would appreciate it). At the moment I am compelled to extract this function into the file of plugin and hard-assign the value to var proj = new OpenLayers.Projection('EPSG:4326');. I think the timer method is unreliable and inconvenient.

Sorry if I am not clear, english and javascript are my not native languages :).

geomoes commented 4 years ago

Well both aren't my native languages too. I've tried to wrap the whole function (from the original script) in an

$(window).load(function(){
....
});  

to avoid, that code is executed before all elements of the DOM are loaded. But this didn't work neither. Your setTimeout works in conjunction with the atlas functionality, but as You said it's unreliable and inconvenient.

After all, my initial intention was to just address a feature at a given layer, highlight it and zoom to it (that what the atlas does) just I want it by calling lizmap and passing the layer and the id in the GET parameters. So zoom_to_feature_at_startup would be ideal if it would work. I'll look at the atlas.js, maybe I'll find a way to fiddle out a way to archieve this.

geomoes commented 3 years ago

Even tough I don't understand, why the script did not work in my environment under Lizmap 3.3.3, I finally managed it to upgrade to 3.4.0. Now the script works like expected. It would be good to habe two enhancemends:

Gustry commented 2 weeks ago

This is now native in Lizmap Web Client, no more JS needed.