Ticket #1782 (closed bug: fixed)

Opened 5 years ago

Last modified 4 years ago

Multipoly rendering skips 2nd - Nth poly when first poly is outside extents.

Reported by: dzwarg Owned by: ahocevar
Priority: major Milestone: 2.8 Release
Component: Renderer.Elements Version: 2.7
Keywords: Cc:
State: Complete

Description

OpenLayers.Geometry.MultiPolygons* are not rendered properly when the first polygon is outside the extent of the map.

In OpenLayers.Renderer.Elements, line 466-467 (at time of reporting), the drawGeometry command is short-circuited with: rendered = rendered && drawGeometry(geometry.components[i], style, featureId); and the polygons of index 1 ... geometry.components.length - 1 are never drawn if the first one was removed from the map.

Consider this case:

  1. a MultiPolygon is rendered on a Vector layer
  2. said MultiPolygon geometry has more than one component
  3. client is zooming in to an extent where the entire MultiPolygon is outside the map extent

The first time through this loop (the first Polygon of the MultiPolygon), the drawGeometry method is called, and the first polygon is un-rendered/removed. The rendered state is set to false, and all subsequent attempts to call drawGeometry() are short-circuited by the fact that rendered is false, so the second part of rendered && drawGeometry(...) is never evaluated.

* probably for OpenLayers.Geometry.Collection, OpenLayers.Geometry.MultiPoint, OpenLayers.Geometry.MultiLineString, too.

Attachments

multipolybug.html Download (21.4 KB) - added by dzwarg 5 years ago.
A demo of the multi-polygon rendering bug. Copy into the examples directory, and witness said bug.
multipolygonrender.patch Download (0.5 KB) - added by dzwarg 5 years ago.
Set the rendering flag to true if a geometry was removed from the document.
Elements.js.patch Download (0.8 KB) - added by igrcic 5 years ago.
patch for eric's solution

Change History

Changed 5 years ago by dzwarg

A demo of the multi-polygon rendering bug. Copy into the examples directory, and witness said bug.

Changed 5 years ago by dzwarg

Set the rendering flag to true if a geometry was removed from the document.

  Changed 5 years ago by dzwarg

  • state set to Review
  • type changed from feature to bug
  • milestone set to 2.8 Release

Added patch that sets the rendered state of the geometry to true. This only affects geometries that have fallen outside the extent, and are being removed the from the document for the first time. If the geometry is outside the extent, and the element doesn't exist on the page, there is no change.

follow-up: ↓ 7   Changed 5 years ago by elemoine

  • state changed from Review to Needs More Work

thanks for the example showing the bug and for pinpointing where the issue is in the code.

Now I don't think your patch does the right thing. Because in the case of non-multi geometries drawFeature would always return true even when it should return false. To me the right fix involves doing rendered = this.drawGeometry() && rendered in place of rendered = rendered && this.drawGeometry(). What do you think?

  Changed 5 years ago by ahocevar

  • owner set to ahocevar

I'll have a look at this, but it may take a while.

  Changed 5 years ago by igrcic

Hi, I have the similar (if not the same problem). Im loading my vector feature from gml file, containing 21 features that are all MultiPolygons and Polygons . When you zoom in, lets say on north part of map, features from south are sometimes also shown, under correctly rendered features on top..

You can check out the example here (it is also possible to add/remove SelectFeature control)  http://dev.openlayers.org/sandbox/igrcic/playground/

  Changed 5 years ago by crschmidt

igric, did you try the patch? Did it fix the problem?

  Changed 5 years ago by crschmidt

Oh. Wait. igrcic, ignore my coment, I was thinking of a different ticket.

Changed 5 years ago by igrcic

patch for eric's solution

in reply to: ↑ 2   Changed 5 years ago by igrcic

Replying to elemoine:

thanks for the example showing the bug and for pinpointing where the issue is in the code. Now I don't think your patch does the right thing. Because in the case of non-multi geometries drawFeature would always return true even when it should return false. To me the right fix involves doing rendered = this.drawGeometry() && rendered in place of rendered = rendered && this.drawGeometry(). What do you think?

For me it does the trick! When i change this line features are rendered correctly. I attached the patch (hope its ok) and you can see working example with patch added:  http://dev.openlayers.org/sandbox/igrcic/playground/

  Changed 4 years ago by tcoulter

  • state changed from Needs More Work to Review

I tried this patch on TOPP's Alachua project, and it worked great. I'm setting to review as requested by ahocevar.

  Changed 4 years ago by ahocevar

  • status changed from new to closed
  • state changed from Review to Complete
  • resolution set to fixed

(In [8411]) modified logic to determine when a multipart geometry is fully rendered. Thanks to elemoine for the suggestion how to resolve the issue, thanks to igrcic for testing and turning it into a patch, and thanks to tcoulter for additional testing. r=me (closes #1782)

Note: See TracTickets for help on using tickets.