OpenLayers OpenLayers

Ticket #1631 (closed bug: fixed)

Opened 2 years ago

Last modified 2 years ago

SVG viewbox problem with minScale

Reported by: openlayers Assigned to: elemoine
Priority: major Milestone: 2.7 Release
Component: Renderer.SVG Version: 2.6
Keywords: Cc:
State: Complete

Description

I use Firefox.

Of what I understand, each time I zoom in or out a map that has a vector layer, the left and top values of the rederer's viewbox are reseted to 0.

I have a WFS layer with a minScale: 49999 in my map. So, the first time I get inRange of my layer, left and top are reset to 0. If I pan, they change their value and if their value is 15000 pixels away from my original left-top, no feature will be drawn.

The problem is if I zoom out of my minScale: 49999, my layer becomes inactive. Zooming out don't reset the left-top values.

So, if I pan to somewhere else and then zoom in until I get inRange of my minScale, my WFS layer shows no features because it's as we didn't zoom at all ( the resolution is the same that the time we zoom out of range ) . But, if I zoom in again once, then the features appear (because the resolution has changed, and left-top are reseted to 0). If I zoom out once, the features are still there.

I think the main problem is at line 103 in Renderer.SVG when it checks if the resolution has changed. Since it didn't because the WFS layer was inactive ( because it was not inRange ) and the resolution didn't change when we zoomed out. After it checks the resolution, if it's the same, it should check if we are out of the 15000 pixel and if we are, it should reset our left and top values :

left = (this.left) - (-extent.left / resolution); 115 top = (this.top) - (extent.top / resolution);

Here's a code snippet that should allow to see the bug. The map will initially zoom in scale 27000 so we can see the WFS features. Zoom out to 0 using the pan zoom bar then zoom in to an other place far from the initial spot (like Montreal city should be enough). When the WFS layer swith to inRange, you'll see nothing. Zoom in again, you'll see it. Zoom out, you'll see it again.

var oMap; var olHydro, olRoads, olWFSRoads;

function loadmap() {

var nZoom = 9; // 1 = normal 3=1750000 6=218750 9=27000 var nLon = -188256; // Chicoutimi city longitude var nLat = 495208; // Chitoutimi city latitude var sHTML; var sMSURL = "http://127.0.0.1:8080/cgi-bin/mapserv"; var sMapPath = "/mypath/mymap.map"; var oMapOptions = {

controls: [], units: 'm', maxResolution: 156543.0339, maxExtent: new OpenLayers.Bounds(-1100000, -23500, 1100000, 2253500), projection: new OpenLayers.Projection("EPSG:32198")

}; var oBLParams = { // Base Layer common params

map: sMapPath, layers : "", // this value must be set for each layer format: "image/gif"

}; var oBLOptions = { // Base Layer common options

isBaseLayer: true, singleTile: true, minScale: 14000000

}; var oOvParams = { // Overlay common params

map: sMapPath, layers : "", // this value must be set for each layer transparent: "true", format: "image/gif"

}; var oOvOptions = { // Overlay common options

isBaseLayer: false, singleTile: true, minScale: 4000000 // init minScale value

};

oMap = new OpenLayers.Map( 'map', oMapOptions ); oBLParams.layers = "hydro"; olHydro = new OpenLayers.Layer.MapServer(

"Hydro", sMSURL, oBLParams, oBLOptions );

oOvOptions.minScale = 1000000; // for below overlay layers

oOvParams.layers = "roads"; olRoads = new OpenLayers.Layer.MapServer(

"Roads", sMSURL, oOvParams, oOvOptions );

olRoads.addOptions( {maxScale: 50000} );

olWFSRoads = new OpenLayers.Layer.WFS(

"Roads - WFS", sMSURL, { typename: "roads", map: sMapPath }, {

extractAttributes: true, minScale: 49999, typename: "roads"

}

);

// add layers oMap.addLayers([olHydro, olRoads, olWFSRoads]);

// add controls oMap.addControl(new OpenLayers.Control.Navigation()); oMap.addControl(new OpenLayers.Control.Scale($('scale'))); oMap.addControl(new OpenLayers.Control.LayerSwitcher()); oMap.addControl(new OpenLayers.Control.PanZoomBar());

// initial zoom oMap.zoomToMaxExtent(); oMap.setCenter(new OpenLayers.LonLat(nLon, nLat), nZoom);

}

Alexandre Dube Mapgears adube@mapgears.com

Attachments

patch-1631-A0.diff (3.8 kB) - added by elemoine on 07/29/08 13:07:46.
patch-1631-A1.diff (4.4 kB) - added by elemoine on 07/30/08 15:11:56.

Change History

07/29/08 13:07:46 changed by elemoine

  • attachment patch-1631-A0.diff added.

07/30/08 09:33:21 changed by adube

The boolean variable resolutionChanged is undefined in SVG.js in the setExtent function. It's called by Vector.js, line 292.

this.left and this.top are also undefined so the result looks like this : extentString : "NaN NaN 629.9999999999984 449.99999999999886" No more features are displayed.

Alexandre

07/30/08 15:11:56 changed by elemoine

  • attachment patch-1631-A1.diff added.

07/30/08 15:12:29 changed by elemoine

  • state set to Awaiting User Feedback.

Patch A0 was missing a file! Sorry about that.

07/31/08 07:51:56 changed by adube

First, I want to thank Eric for his hard work : thank you very much, Eric !

I tested the new patch. Here's the new results :

When I zoom in or out, everything works fine. Even if my layer is not inRange, as soon as it becomes inRange, my features are displayed.

But, when I pan, at some point the features become invisibles ( we reach the 15000px limit ). It's ok because users will want to zoom out a little before then zoom in again ( much more faster that way), but I have a list of cities that "onchange"-->go to selected city ( setCenter with cities coordinates ) and I can easily go out of our 15000px range that way.

Wouldn't it be possible to change the renderer's left and top values if the features are more than 10000px (for example) away from current left-top ? That way, we would always have features displayed. Or maybe that could be : as soon as a feature becomes out out the 15000px range, reset the left-top to 0 then recalculate every feature position.

Alexandre

07/31/08 08:19:40 changed by elemoine

  • milestone set to 2.7 Release.

Alexandre, do you confirm that my patch solves your first problem? It seems to me that the issue relating to the pixel limit is something different, that would deserve its own ticket and possibly patch.

07/31/08 08:32:05 changed by crschmidt

  • owner set to crschmidt.
  • priority changed from minor to major.
  • state changed from Awaiting User Feedback to Review.

The pixel limit is seperate, and has an existing ticket already. (#670)

I've reopened it since it seems that someone might actually care about working on it.

Alexandre's emails make it clear that this patch improves things. I'll try and look at it.

07/31/08 14:36:14 changed by crschmidt

  • owner changed from crschmidt to elemoine.
  • state changed from Review to Needs More Work.

Eric,

I like the patch in general, but dislike tossing optional booleans to the end of a call. Can we turn 'resolutionChanged' into an options hash, with 'resolutionChanged' as a key in it? that way, if we need other options (for example, for the VML layer) we can add them in without needing a 'blank' boolean spot?

Other than that, it looks pretty good.

08/12/08 05:43:12 changed by ahocevar

See #1675 for a fix.

09/02/08 12:21:03 changed by crschmidt

  • status changed from new to closed.
  • state changed from Needs More Work to Complete.
  • resolution set to fixed.

r7930 /trunk/openlayers/ (12 files in 7 dirs): New vector rendering for better performance and less renderer specific limitations. r=elemoine (closes #1675, closes #1656, closes #1631, closes #1431, closes #1709)