2

我在地图中有三个 kml 层:多边形、线、点。该地图是根据 mobile-wms-vienna 示例修改的。我更改了图层,并更改了“标签”按钮以更改多边形图层上的不透明度。为了确保可以看到所有功能,我需要设置 z-indexing。

但是我也希望能够在多边形图层上显示一个弹出窗口,该图层设置为最低。我不想看到线或点的弹出窗口。(点可以有标签,线不需要标签)。我已经阅读了很多关于在多个图层上选择问题的帖子,但是找不到在设置 z-indexing 时如何使任何内容可选的解决方案。

有没有办法做到这一点?最好按照图层添加到地图的顺序绘制图层。还是随着地图移动和缩放变化的标签层?不幸的是,kml 多边形标签固定在一个点上,因此在移动或放大地图时可能会消失。

下面给出了整个地图代码,因为我不确定我的地图中是否还有其他东西会影响这种行为。

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, "&lt;");
            }
            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;
            }
        };

};

该地图可以在http://quartzspatial.net/act/map_v2.html看到

可能解决我的问题的最接近的答案是here,但我无法理解如何使用这些解决方案,并且在多次尝试将代码放在不同的地方之后,我放弃了。

4

1 回答 1

0

我之前一直在研究类似的问题。您现在可能已经自己弄清楚了,但我想分享我的jsFiddle,我在地图对象上使用事件侦听器而不是选择控件。

您不能将 OpenLayers 选择控件与图层索引一起使用。激活事件将始终将图层放在顶部,并且在图层上设置 z 索引将禁用选择控件。我也无法通过在激活事件中禁用 moveontop 来解决问题(在 jsFiddle 中)。

请看一下事件监听器解决方案:

var map = new OpenLayers.Map({
 div: "map",
 projection: new OpenLayers.Projection("EPSG:3857"),
 displayProjection: new OpenLayers.Projection("EPSG:4326"),
 layers: [
  new OpenLayers.Layer.OSM()],
 controls: [
  new OpenLayers.Control.Navigation(),
  new OpenLayers.Control.ArgParser() ],

 eventListeners: {

  featureover: function(e) { if (e.feature.layer != vectors2) {
   e.feature.renderIntent = "temporary";
   e.feature.layer.drawFeature(e.feature); }
  },

 featureout: function(e) { if (e.feature.layer != vectors2) {
  e.feature.renderIntent = "default";
  e.feature.layer.drawFeature(e.feature); }
 },

 featureclick: function(e) { if (e.feature.layer != vectors2) {
  e.feature.renderIntent = "select";
  e.feature.layer.drawFeature(e.feature); }
 }

}

});
于 2014-05-12T18:40:45.197 回答