Search code examples
openlayersopenlayers-5

OLv5 vector layer with dynamic source not rendering


I'm brand new to OL as of last week, so I apologize if I've missed something obvious. It's mostly cobbled together from examples, but I'm pretty sure I understand what's going on at this point. You can see my code in action here: https://fleur.github.io/dist/index.html, or more conventionally, here: https://github.com/fleur/olexample.

If I create a map with a vector layer whos source is a static file (via the 'url' property), the features show up as expected. If I create a map with the same code, where the only difference is the source is a loader function making an xhr call, the features don't show up.

I've put listeners on both the source and layer in both cases and get these events fired:

static:

precompose
postcompose
addfeature
addfeature
addfeature
change
precompose
render
postcompose

dynamic:

precompose
postcompose
addfeature
addfeature
addfeature
change
precompose
postcompose

Note there is no 'render' event in the dynamic sequence of events. I even do a synchronous HTTP call. I am at a complete loss. The dynamic source loader function is doing slightly tricky stuff with closures, so maybe that has something to do with it? The code was taken from an example on openlayers.org, though, and only modified with console.log and a different url.

So, my question is: how can I get the dynamically retrieved features, which do get added to the source, to render?


Solution

  • When consuming data using URL with GeoJSON, GPX, KML or OSMXML formats, the OpenLayers library automatically do reprojection from EPSG:4326 to EPSG:3857 whereas when you do a manual Ajax call, it's your responsibility to do this transformation. Render does not happen as you features are outside the extent to draw them.

    To fix your issue, after,

    const f = dynamic_source.getFormat().readFeatures(xhr.responseText);
    

    Add

    // Return at the moment geometry with longitude-latitude / WGS 84 / EPSG:4326
    // like [-122.3563599, 37.5793804]
    // Only here for learning purpose, you can remove it after understanding my point
    console.log(f[0].getGeometry().getCoordinates());
    
    // Reproject coordinates manually by mutating the current geometry in place
    f.forEach(feature => feature.getGeometry().transform('EPSG:4326', 'EPSG:3857'));
    

    PS: tested