Using the OpenLayers Javascript from the OpenLayers module can present some problems with rendering vector layers in IE.

The root cause of the issue:

Internet Explorer has a thing called VML: Vector Markup Language, which it uses to draw graphics. VML is what you use in IE: canvas4ie is way slow, google maps uses VML to draw routes, and OpenLayers uses it to draw vectors.

VML elements are styled by creating CSS-like styles in a namespace. OpenLayers creates an ol: namespace and then creates styles like ol:line ol:circle, etc.

To do this, it has to access document.namespaces. Document.namespaces is not always around: notably, you can't depend on it being around before document.ready.

But, sometimes document.namespaces *is* around before document.ready and that's the thing that messed up my worldview. So, the theory was, there are modes. Something in HTML can prevent document.namespaces being filled in before document.ready.

Here's how it goes.

$( or $(document).ready()

  • If there is a broken image on the page, then namespaces is not filled in.
  • If the page has no broken images, then document.namespaces is accessible

document.load()

  • document.namespaces is always filled in.

31 stylesheets

IE cannot handle more than 31 stylesheets on a page at a time. This is clearly the
devil's work, but it persists beyond IE8. If there are 31 stylesheets and you run an
OpenLayers map, it cannot add another stylesheet to initialize its VML namespace.
Therefore, the map breaks. You must aggregate your CSS.

The Fix

We can't move openlayers to document.load() because it is dependent on the Drupal behaviors stack, that runs on document.ready(). We need to just define document.namespaces before OpenLayers asks its VML renderer whether the current browser is capable of rendering VML (a task it tries to complete by calling !!(document.namespaces))

Other Fixes

Adding a tag <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> will allow IE8 to render vectors if it doesn't render them correctly on a normal pageload. Note that this must be the first element inside the header tag.

Comments

mearns’s picture

do you mean document.onload?

tmcw’s picture

This is using jQuery terminology - I should have been more clear.

tmcw’s picture

Please post on the OpenLayers Issue queue with any bug reports and support requests. We cannot provide support on Book Pages.

castawaybcn’s picture

You may also get around the 31 stylesheets limitation by using either http://drupal.org/project/ie_css_optimizer or http://drupal.org/project/unlimited_css modules.