Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing an OpenLayers 3 map in a hidden element

I am writing a page where you can view both details about an area and a map. The details are on one tab and the map on another. The relevant portion of the HTML is below and the classes are from Bootstrap.

<div class="col-xs-8">
    <ul class="nav nav-tabs">
        <li class="active"><a href="#tab-details" data-toggle="tab">Details</a></li>
        <li><a href="#tab-map" data-toggle="tab">Map</a></li>
    </ul>
    <div class="tab-content">
        <div id="tab-details" class="tab-pane fade in active"></div>
        <div id="tab-map" class="tab-pane fade">
            <div id="map-container" class="map"></div>
        </div>
    </div>
</div>

The tile layer is from OSM and the vector layer is loaded via a URL serving a KML file. It does this using OpenLayers 3.0.0 as follows:

function ShowMap() {
    var area = $('#AreaCode').val();
    $('#map-container').empty();
    if (area != null && area != '') {
        var kmlUrl = '/kml?code=' + area;
        var tile = new ol.layer.Tile({ source: new ol.source.OSM() });
        var vectorSource = new ol.source.KML({ url: kmlUrl, projection: 'EPSG:3857' });
        var vector = new ol.layer.Vector({ source: vectorSource });
        vector.setOpacity(.3);
        var map = new ol.Map({
            target: 'map-container',
            layers: [tile, vector],
            view: new ol.View({
                center: [0, 0],
                zoom: 2
            })
        });

        vector.addEventListener("change", function(event) {
            map.getView().fitExtent(vectorSource.getExtent(), map.getSize());
        });
    }
}

$('#tab-map-link').on('shown.bs.tab', function(event) {
    ShowMap();
});

This renders the map when the map tab is clicked causing a small delay. Is there any way of loading it even when the tab is not selected? If I try that and don't redraw when the map tab is selected then the canvas is blank when I switch to the map tab and only the zoom in and out buttons are shown.

Is there any way to render the map in an element which is not visible?

like image 548
Andy Nichols Avatar asked Sep 25 '14 09:09

Andy Nichols


2 Answers

You can initialize the map in a hidden container and then, when the tab is activated, you can call updateSize on the map:

map.updateSize()
like image 106
tsauerwein Avatar answered Oct 06 '22 00:10

tsauerwein


In my case the solution was to use the timeout to wait for the div to be displayed.

setTimeout(function() {
    map.updateSize();
}, 100);
like image 31
DanniFilth Avatar answered Oct 06 '22 01:10

DanniFilth