I have three kml layers in a map: polygons, lines, points. The map is modified from the mobile-wms-vienna example. I have changed the layers, and changed the "Labels" button to alter the opacity on the polygon layer. To ensure that all features can be seen I need set z-indexing.
However I would also like to be able to display a pop-up on the polygon layer, which is set as the lowest. I do not want to see popups from lines or points. (Points can have labels, lines do not need labeling). I have read many posts about the problems with select on multiple layers, but could not find a solution to how to make anything selectable when z-indexing is set.
Is there a way to do this? Preferably draw the layers in the order they are added to the map. Or a label layer that moves with the map and zoom changes? Unfortunately, kml polygon labels are fixed to a point and so might disappear when the map is moved or zoomed in.
The entire map code is given below, as I am not sure if there is something else in my map that is affecting this behaviour.
var map;
var linetyle = new OpenLayers.Style({'strokeWidth': 2, 'strokeColor':"red",});
function init() {
document.documentElement.lang = (navigator.userLanguage || navigator.language).split("-")[0];
var layerPanel = new OpenLayers.Control.Panel({
displayClass: "layerPanel",
autoActivate: true
});
var opButton = new OpenLayers.Control({
type: OpenLayers.Control.TYPE_TOGGLE,
displayClass: "opButton",
eventListeners: {
activate: function() {
if (polygon) {polygon.setOpacity(0.4);}
},
deactivate: function() {
if (polygon) {polygon.setOpacity(0.9);}
}
}
});
layerPanel.addControls([opButton]);
var zoomPanel = new OpenLayers.Control.ZoomPanel();
// Geolocate control for the Locate button - the locationupdated handler
// draws a cross at the location and a circle showing the accuracy radius.
var geolocate = new OpenLayers.Control.Geolocate({
type: OpenLayers.Control.TYPE_TOGGLE,
bind: false,
watch: true,
geolocationOptions: {
enableHighAccuracy: false,
maximumAge: 0,
timeout: 7000
},
eventListeners: {
activate: function() {
map.addLayer(vector);
},
deactivate: function() {
map.removeLayer(vector);
vector.removeAllFeatures();
},
locationupdated: function(e) {
vector.removeAllFeatures();
vector.addFeatures([
new OpenLayers.Feature.Vector(e.point, null, {
graphicName: 'cross',
strokeColor: '#f00',
strokeWidth: 2,
fillOpacity: 0,
pointRadius: 10
}),
new OpenLayers.Feature.Vector(
OpenLayers.Geometry.Polygon.createRegularPolygon(
new OpenLayers.Geometry.Point(e.point.x, e.point.y),
e.position.coords.accuracy / 2, 50, 0
), null, {
fillOpacity: 0.1,
fillColor: '#000',
strokeColor: '#f00',
strokeOpacity: 0.6
}
)
]);
map.zoomToExtent(vector.getDataExtent());
}
}
});
zoomPanel.addControls([geolocate]);
map = new OpenLayers.Map({
div: "map",
theme: null,
projection: new OpenLayers.Projection("EPSG:3857"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
layers: [new OpenLayers.Layer.Google( "Google Satellite", {type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22})],
center: new OpenLayers.LonLat(149.1, -35.3).transform('EPSG:4326', 'EPSG:3857'),
zoom: 10,
units: "m",
maxResolution: 38.21851413574219,
controls: [
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.Attribution(),
zoomPanel,
layerPanel
],
});
layerPanel.activateControl(opButton);
// Vector layer for the location cross and circle
var vector = new OpenLayers.Layer.Vector("Vector Layer");
var point = new OpenLayers.Layer.Vector("points", {
// rendererOptions: {zIndexing: 'true'},
projection: map.displayProjection,
strategies: [new OpenLayers.Strategy.BBOX()],
protocol: new OpenLayers.Protocol.HTTP({
url: "kml/point.kml",
format: new OpenLayers.Format.KML({
extractStyles: true,
extractAttributes: true
}) }) });
var line = new OpenLayers.Layer.Vector("line", {
// rendererOptions: {zIndexing: 'true'},
projection: map.displayProjection,
strategies: [new OpenLayers.Strategy.BBOX({resFactor: 1})],
styleMap: linetyle,
protocol: new OpenLayers.Protocol.HTTP({
url: "kml/line.kml",
format: new OpenLayers.Format.KML({ extractStyles: false,
extractAttributes: true
}) }) });
var polygon = new OpenLayers.Layer.Vector("Geology", {
// rendererOptions: {zIndexing: 'true'},
projection: map.displayProjection,
strategies: [new OpenLayers.Strategy.BBOX({resFactor: 1})],
protocol: new OpenLayers.Protocol.HTTP({
url: "kml/polygon.kml",
format: new OpenLayers.Format.KML({extractStyles: true,extractAttributes: true})
}) });
map.addLayers([point, line, polygon]);
polygon.setOpacity(0.5);
// point.setZIndex(1400);
// line.setZIndex(1300);
// polygon.setZIndex(1200);
// Select Features/Popup
select = new OpenLayers.Control.SelectFeature (polygon, line, point);
polygon.events.on({
"featureselected": onFeatureSelect,
"featureunselected": onFeatureUnselect
}),
line.events.on({
"featureselected": onFeatureSelect,
"featureunselected": onFeatureUnselect
}),
point.events.on({
"featureselected": onFeatureSelect,
"featureunselected": onFeatureUnselect
}),
map.addControl(select);
select.activate();
function onPopupClose(evt) {
select.unselectAll();
}
function onFeatureSelect(event) {
var feature = event.feature;
// Since KML is user-generated, do naive protection against
// Javascript.
var content = "<h2>"+feature.attributes.name + "</h2>" + feature.attributes.description;
if (content.search("<script") != -1) {
content = "Content contained Javascript! Escaped content below.<br>" + content.replace(/</g, "<");
}
popup = new OpenLayers.Popup.FramedCloud("chicken",
feature.geometry.getBounds().getCenterLonLat(),
new OpenLayers.Size(100,100),
content,
null, false, onPopupClose);
feature.popup = popup;
map.addPopup(popup);
}
function onFeatureUnselect(event) {
var feature = event.feature;
if(feature.popup) {
map.removePopup(feature.popup);
feature.popup.destroy();
delete feature.popup;
}
};
};
The map can be seen at http://quartzspatial.net/act/map_v2.html
The closest answer that may solve my problem is here, but I could not understand how to use the solutions, and after many attempts at putting code in different places, I gave up.