[GIS] Openlayers – how to display base layer before overlays and display overlays as they are being loaded

loadingopenlayers-2

This is my first question here. I already found a lot of good information here about openlayers so I guess it is the right place to ask. I am not a programer, I just usually adapt what I can find to suit my needs for my personnal website.

I am using openlayers to display about 20 gpx files over a basemap. Each gpx file is about 600ko,each is displayed in its own overlay.

As it was, everytime I added one more gpx overlay, it took longer before anything is displayed on my webpage. So I guess Openlayers is loading everything before displaying anything.
So I am looking for a way to display the base layer first and then load and display one gpx overlay at a time so that the user does not have to wait for too long before he sees anything happening on his screen.

Here is my webpage with the map underwork at the bottom of the page :
http://www.untourenvelo.ch/carnet-de-voyage/suisse/apres-

And here is what I tried to do but does not work. I put a "loadend" event on the last created overlay so that the next overlay is not created before the previous is not completely added to the map. But this does not work : The first one shows correctly (of course) but the second one does not show because the (i-1) is "undefined" according to console log. The third one is displayed and … that's it 🙁
If anyone can help.

Here is my initOSM function :

    function initOSM() {

map= new OpenLayers.Map("CarteOSM");
var mapnik = new OpenLayers.Layer.OSM();
var fromProjection = new OpenLayers.Projection("EPSG:4326"); // Transform from WGS 1984
var toProjection = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
var position = new OpenLayers.LonLat(13.41,52.52).transform( fromProjection, toProjection);
var zoom = 2; 
map.addLayer(mapnik);
//map.zoomToMaxExtent();

map.setCenter([25,45],zoom);


var cyclemap = new OpenLayers.Layer.OSM("cyclemap","http://tile.opencyclemap.org/cycle/${z}/${x}/${y}.png",
{'sphericalMercator': true, isBaseLayer:true}
);
map.addLayer(cyclemap); 

StyleGPX = new OpenLayers.StyleMap({
"default": new OpenLayers.Style({
//Icone en fonction du type de waypoint, le nom du fichier png doit être identique au texte dans la balise sym du fichier gpx
externalGraphic: "../../images/GPS/${sym}.png",
pointRadius: 2,
//graphicHeight: 60,
graphicYOffset: -32,
graphicXOffset: -5,
label: "${name}", 
labelAlign: 'rb',
fontSize: 11,
fontFamily: "Arial",
fontColor: "black",
labelYOffset: 0,
labelXOffset: -10,
fillColor: "ffcc66",
strokeColor: "#ffe400",
strokeWidth: 1.5, 
strokeOpacity: 1
}),
"select": new OpenLayers.Style({
externalGraphic: "../../images/GPS/${sym}.png",
graphicYOffset: -32,
graphicXOffset: -5,
pointRadius: 20,
fillColor: "#66ccff",
strokeColor: "#3399ff",
graphicZIndex: 2,
label: "${name}",
labelAlign: 'rb',
fontSize: 11,
fontFamily: "Arial",
fontColor: "black",
labelYOffset: 0,
labelXOffset: -10
})
});


StyleGPX.styles["default"].defaultStyle.externalGraphic = "";
StyleGPX.styles["default"].defaultStyle.pointRadius = 2;
StyleGPX.styles["default"].defaultStyle.label = "";


//Tableau des fichiers gpx a afficher
FichiersGPX = ["Europe","Turquie","Iran","Asie Centrale","Bolivie","Chine", "Chili_Argentine", "Indonesie"];

//Create layers from array of files' names
CalquesGPX[0] = new OpenLayers.Layer.Vector(FichiersGPX[0], {
protocol: new OpenLayers.Protocol.HTTP({
            url: "../../images/GPS/"+FichiersGPX[0]+".gpx",
            format: new OpenLayers.Format.GPX({extractWaypoints: true, extractRoutes: false, extractAttributes: true})
}),
strategies: [new OpenLayers.Strategy.Fixed()],
visibility: true,
styleMap: StyleGPX,
projection: new OpenLayers.Projection("EPSG:4326"),
eventListeners: {"featureselected": onFeatureSelect, "featureunselected": onFeatureUnselect},
'displayInLayerSwitcher':false
 });
map.addLayers([CalquesGPX[0]]);


for (var i=1; i<=FichiersGPX.length-1; ++i) {
CalquesGPX[i-1].events.register('loadend',CalquesGPX[i-1],function() {
CalquesGPX[i] = new OpenLayers.Layer.Vector(FichiersGPX[i], {
protocol: new OpenLayers.Protocol.HTTP({
            url: "../../images/GPS/"+FichiersGPX[i]+".gpx",
            format: new OpenLayers.Format.GPX({extractWaypoints: true, extractRoutes: false, extractAttributes: true})
}),
strategies: [new OpenLayers.Strategy.Fixed()],
visibility: true,
styleMap: StyleGPX,
projection: new OpenLayers.Projection("EPSG:4326"),
eventListeners: {"featureselected": onFeatureSelect, "featureunselected": onFeatureUnselect},
'displayInLayerSwitcher':false
 });
map.addLayers([CalquesGPX[i]]);

});
}


//Selection des elements pour affichage de pop up dans un overlay On declare le tableau complet des calques
selectionElement = new OpenLayers.Control.SelectFeature(CalquesGPX,{
clickout: true, toggle: false,
multiple: false, hover: false,
toggleKey: "ctrlKey", // ctrl key removes from selection
multipleKey: "shiftKey" // shift key adds to selection
});
map.addControl(selectionElement);
selectionElement.activate();

//Affichage de l'echelle de la carte
var echelle = new OpenLayers.Control.ScaleLine({ topInUnits: 'km', bottomInUnits: 'm'});
map.addControl(echelle); 

//Affichage du selecteur de calque
var layer_switcher = new OpenLayers.Control.LayerSwitcher();
map.addControl(layer_switcher);
layer_switcher.maximizeControl(); 

}

Best Answer

Ok I worked things around. Now I initially load a unique lightweight gpx file summing up all the detailed ones. Then I load the detailed files on demand by giving the "addLayer" method only when the corresponding box is checked.