I am working on Openlayers to dynamically load KML tracks on map. I want it to load filtered KML everytime map is moved or zoomed based on viewport and zoom level.
I got it working with code below, but for some reason Permalink doesn't work anymore. When pressing permalink link Debug console gives error: Uncaught TypeError: Cannot set property 'loaded' of undefined
on line 108. That is the line layer.loaded = false;
on UpdateKmlLayer() function.
Could someone help on what I am missing here?
// Start position for the map (hardcoded here for simplicity)
var lat = 65.37371
var lon = 24.49389
var zoom = 6;
var map; //complex object of type OpenLayers.Map
var KMLlayer;
//Initialise the 'map' object
function init() {
map = new OpenLayers.Map("map", {
controls: [],
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
maxResolution: 156543.0339,
numZoomLevels: 16,
units: 'm',
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
eventListeners: {
"moveend": moveEnd,
},
});
// Controls
map.addControl(new OpenLayers.Control.Navigation());
map.addControl(new OpenLayers.Control.PanZoomBar(), new OpenLayers.Pixel(0, 15));
map.addControl(new OpenLayers.Control.Permalink());
map.addControl(new OpenLayers.Control.ScaleLine({geodesic: true}));
map.addControl(new OpenLayers.Control.MousePosition());
map.addControl(new OpenLayers.Control.Attribution());
// Osmarender
layerTilesAtHome = new OpenLayers.Layer.OSM.Osmarender("Osmarender", {
numZoomLevels: 18
});
map.addLayer(layerTilesAtHome);
// Local KML
KMLlayer = new OpenLayers.Layer.Vector("KMLlayer", {
projection: map.displayProjection,
strategies: [
new OpenLayers.Strategy.BBOX(),
],
protocol: new OpenLayers.Protocol.HTTP({
url: "kml.php",
format: new OpenLayers.Format.KML({
extractStyles: true,
extractAttributes: true
})
})
});
map.addLayer(KMLlayer);
var switcherControl = new OpenLayers.Control.LayerSwitcher();
map.addControl(switcherControl);
switcherControl.maximizeControl();
if (!map.getCenter()) {
var lonLat = new OpenLayers.LonLat(lon, lat).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
);
map.setCenter(lonLat, zoom);
}
} //init()
function moveEnd(event) {
console.log(event.type);
UpdateKmlLayer(KMLlayer);
}
function UpdateKmlLayer(layer) {
console.log("updateKML");
console.log(layer);
layer.loaded = false; // setting loaded to false unloads the layer
layer.setVisibility(true); // setting visibility to true forces a reload of the layer
layer.refresh({ force: true, params: { 'zoom': map.getZoom()} }); // force new KML data
}
Best Answer
Cause:
When the permalink control is added to the map it registers for notification of the following events:
When you add the layerTilesAtHome layer to the map the changelayer or changebaselayer event if triggered and dispatched to the permalink control. The permalink control in turn recenters the map and set layer visibility accordingly to the permalink.
But by moving the map the permalink control triggers the moveend event which is dispatched to the moveEnd function. Unfortunately at this time the kmlLayer has not been created yet hence the error.
Solution 1 (recommended):
register the controls after all the layers have been added to the map.
Solution 2:
add a not-null check in the UpdateKmlLayer function: