未捕获的TypeError:无法读取属性'属性' Leaflet smap-responsive中未定义的

时间:2015-12-13 14:58:27

标签: javascript leaflet geojson

我正在Leaflet中构建一个包含多个geojsons的地图,它在正常尺寸的计算机屏幕上运行良好。但它并不适用于较小的屏幕或Apple产品,所以我正在努力将我的代码转移到Smap响应https://github.com/getsmap/smap-responsive

我按照给定的示例添加了一个geojson,并根据属性设置它,它看起来我想要它,弹出窗口按我想要的方式工作。当我尝试添加第二个geojson时会出现问题。当我点击第一层上的点时,它可以正常工作,但是当我关闭该层并打开第二层时,弹出窗口在第二层上不起作用。如果我刷新页面并首先尝试第二层,那些弹出窗口可以工作但是它们不能在第一层上工作。我得到的错误是:

“未捕获的TypeError:无法读取属性'属性'未定义的“

以下是代码:

        var config = {

    // These params are default and can be overridden by calling the map with e.g. http://mymap?center=13.1,55.6&zoom=17
    params: {
        // The map's centering from start. Coordinates should be in WGS 84 and given like [easting, northing] i.e. [longitude, latitude]
        center: [14.0, 55.52],

        // The initial zoom of the map, In this example I zoom out slightly if the screen is smaller than given number of pixels
        zoom: $(window).width() < 600 ? 11 : 11
    },

    // Optional configuration object for the Leaflet map object. You can use all options specified here: http://leafletjs.com/reference.html#map-class
    // mapConfig: {
    //  maxBounds: [    // Optional. Limit panning of the map. Given as [[north, west], [south, east]]
    //      [55.71628170645908, 12.6507568359375],
    //      [55.42589636057864, 13.34564208984375]
    //  ],  
    //  minZoom: 11,    // Optional. Limit how much you can zoom out. 0 is maximum zoomed out.
    //  maxZoom: 18     // Optional. Limit how much you can zoom in. 18 is usually the maximum zoom.
    // },

    smapOptions: {
        // The text of the <title>-tag
        title: "webbkartan",

        // The favicon to be used
        favIcon: "//assets-cdn.github.com/favicon.ico"
    },

    // -- Baselayers (background layers) --
    bl: [
        // -- An openstreetmap layer. Note that all layer types used as overlays can also be used as baselayers, and vice versa (see more layers below). --
        {
            init: "L.TileLayer",
            url: '//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
            options: {
                layerId: "osm",
                displayName: "OSM",
                attribution: '<span>© OpenStreetMap contributors</span>&nbsp;|&nbsp;<span>Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="//developer.mapquest.com/content/osm/mq_logo.png"></span>',
                maxZoom: 18
            }
        }

    ],

    // -- Overlays --
    ol: [

        {
            init: "L.GeoJSON.WFS",
            url: document.URL.search(/dev.html?/) > 0 ? "examples/data/recipient.geojson" : "../examples/data/recipient.geojson",

            options: {
                displayName: "Totalkväve halt",                 
                category: ["Status"],                       
                layerId: "kvave",               
                attribution: "",            
                inputCrs: "EPSG:4326",                      
                uniqueKey: "Nr",                            
                selectable: true,                           
                reverseAxis: false,                         
                reverseAxisBbox: true,                      
                geomType: "POINT",                          
                legend:"examples/data/legend/kvave_legend.jpg",




                popup:  
                    '<h4>Punkt ${Nr} </h4>'+
                    '<br><img src="examples/data/diagram/' + '${Ar_kvav}' + '"/ width=400>'+
                    '<img src="examples/data/diagram/' + '${Man_kvav}' + '"/ width=400>'+

                    '<p><font size=2>'+ '${Plats}'+
                    '<br><b> Frekvens: </b>${frekvens_g}/år'+
                    '<br><b> Senast provtagning: </b> ${sist_anv}'+
                    '<br><b> Nuvarande status: </b> ${Status_fos} status'+
                    '<br><b> Senaste uppdaterad: </b> ${uppdaterad}</p>',

                style:function(feature){
                    switch (feature.properties.Status_kva){

                        case "Extremt hög halt" : return {color: '#FF000D'};
                        case "Mycket hög halt": return {color: '#FFBB00'};
                        case null: return {color: '#8C8C89'};

                    };
                }

            }
        },


        {
            init: "L.GeoJSON.WFS",
            url: document.URL.search(/dev.html?/) > 0 ? "examples/data/recipient.geojson" : "../examples/data/recipient.geojson",

            options: {
                displayName: "Totalfosfor status",                  
                category: ["Status"],                       
                layerId: "fosfor",              
                attribution: "",            
                inputCrs: "EPSG:4326",                      
                uniqueKey: "OBJECTID",                          
                selectable: true,                           
                reverseAxis: false,                         
                reverseAxisBbox: true,                      
                geomType: "POINT",                          
                legend:"examples/data/legend/fos_legend.jpg",



                popup: 
                    '<h4>Punkt ${Nr} </h4>'+
                    '<br><img src="examples/data/diagram/' + '${Ar_fos}' + '"/ width=400>'+
                    '<img src="examples/data/diagram/' + '${Man_fos}' + '"/ width=400>'+

                    '<p><font size=2>'+ '${Plats}'+
                    '<br><b> Frekvens: </b>${frekvens_g}/år'+
                    '<br><b> Senast provtagning: </b> ${sist_anv}'+
                    '<br><b> Nuvarande status: </b> ${Status_fos} status'+
                    '<br><b> Senaste uppdaterad: </b> ${uppdaterad}</p>',

                style:function(feature){
                    switch (feature.properties.Status_fos){
                        case "Hög" : return {color:'#02A0F5', fillColor: '#02A0F5', fillOpacity:1};
                        case "God" : return {color:'#29D637', fillColor: '#29D637', fillOpacity:1};
                        case "Otillfredsställande" : return {color: '#F5AA07', fillColor: '#F5AA07', fillOpacity:1};
                        case "Dålig": return {color:'#FC0000', fillColor: '#FC0000', fillOpacity:1};
                        case null: return {color:'#8C8C89', fillColor: '#8C8C89',fillOpacity:1 };

                    };
                }



            }
        },



    ],

    // <><><><><><><><><><><><><><><><><><><><><><><><><><>
    // Plugins are Leaflet controls. The options of a control
    // given here, will override the options in the control.
    // Thereby, you can manage everything the control lets
    // you manage from this config file – without having to
    // edit the plugin itself.
    // <><><><><><><><><><><><><><><><><><><><><><><><><><>

    plugins: [
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // Scale is Leaflet's in-built scale bar control. See options: http://leafletjs.com/reference.html#control-scale
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init: "L.Control.Scale",
                    options: {
                        imperial: false
                    }
                },

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // LayerSwitcher is a responsive layer menu for both overlays and baselayers.
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init: "L.Control.LayerSwitcher",
                    options: {
                        toggleSubLayersOnClick: false,          // If true, all layers below this header will be turned on when expanding it.
                        unfoldOnClick: true,                    // If true, clicking anywhere on a header will unfold it. If false, user has to click on the icon next the header text.
                        unfoldAll: false,                       // If true, all subheaders will be unfolded when unfolding a header.
                        olFirst: false,                         // If true, the overlays panel is shown at the top
                        pxDesktop: 992,                         // Breakpoint for switching between mobile and desktop switcher
                        btnHide: true,                          // Show a hide button at the top header
                        catIconClass: "fa fa-chevron-right"     // Icon class for foldable headers
                    }
                },
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // Zoombar creates a custom zoombar with [+] and [-] buttons.
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init: "L.Control.Zoombar",
                    options: {}
                },

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // Geolocate shows the users position. Based on the HTML5 geolocation API.
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init: "L.Control.Geolocate",
                    options: {
                        position: 'bottomright',        // Button's position
                        locateOptions: {
                            maxZoom: 17,                // Maximum auto-zoom after finding location
                            enableHighAccuracy: true    // true: Will turn on GPS if installed (better accuracy but uses more battery)
                        }
                    }
                },

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // SelectVector is needed to make WMS layers selectable 
                // using getfeatureinfo requests.
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init: "L.Control.SelectWMS",
                    options: {
                        wmsVersion: "1.3.0",        // The WMS version to use in the getfeatureinfo request
                        info_format: "text/plain",  // The fallback info format to fetch from the WMS service. Overridden by layer's info_format in layer's selectOptions.
                        maxFeatures: 20,            // Max features to fetch on click
                        buffer: 12,                 // Buffer around click (a larger number makes it easier to click on lines and points)
                        useProxy: false             // If you want call the URL with a prepended proxy URL (defined in ws above)
                    }
                },

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // SelectVector is needed in order to make vector (e.g. WFS) layers selectable.
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init: "L.Control.SelectVector",
                    options: {
                        // The select style.
                        selectStyle: {
                            weight: 5,
                            color: '#00FFFF',
                            fillColor: '#00FFFF',
                            opacity: 1,
                            fillOpacity: .5
                        }
                    }
                },

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // Search connects to a autocomplete and geolocate service and places a marker
                // at the geolocated location.
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init: "L.Control.Search",
                    options: {
                        _lang: {
                            // Watermark/placeholder for text entry. Language dependent.
                            "en": {search: "Search address or place"},  // english
                            "sv": {search: "Sök adress eller plats"}    // swedish
                        },
                        gui: true,                  // If false, entry is not shown but the plugin can still take the POI URL parameter
                        whitespace: "%20",          // How to encode whitespace.
                        wsOrgProj: "EPSG:3008",     // The projection of the returned coordinates from the web service
                        useProxy: false,            // If you want call the URL with a prepended proxy URL (defined in ws above)
                        wsAcUrl: "//kartor.malmo.se/api/v1/addresses/autocomplete/", // Required. Autocomplete service.
                        wsLocateUrl: "//kartor.malmo.se/api/v1/addresses/geolocate/", // Required. Geolocate service.
                        acOptions: {                // typeahead options (Bootstrap's autocomplete library)
                            items: 100              // Number of options to display on autocomplete
                        }
                    }
                },

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // Print creates a downloadable image server-side. Requires Geoserver and the plugin "Mapfish print".
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // {
            //      init: "L.Control.Print",
            //      options: {
            //          printUrl: "//kartor.malmo.se/print-servlet/leaflet_print/",     // The print service URL
            //          position: "topright"                                            // Button's position
            //      }
            //  },

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // ShareLink adds a button which, on click, will create a
                // URL which recreates the map, more or less how it looked like.
                // It is up to other plugins to add and receive URL parameters by 
                // listening to the events:
                //      - Create params:    "smap.core.createparams"
                //      - Apply params:     "smap.core.beforeapplyparams" or "smap.core.applyparams"
                //  For instance:
                //  
                //  smap.event.on("smap.core.createparams", function(e, paramsObject) {
                //      paramsObject.myparameter = 3;
                //  });
                //  smap.event.on("smap.core.applyparams", function(e, paramsObject) {
                //      alert(paramsObject.myparameter);
                //  });
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init: "L.Control.ShareLink",
                    options: {
                        position: "topright",
                        root: location.protocol + "//malmo.se/karta?" // location.protocol + "//kartor.malmo.se/init/?appid=stadsatlas-v1&" // Link to malmo.se instead of directly to map
                    }
                },

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // RedirectClick opens a new browser tab when the user clicks on the map.
                // The easting ${x} and northing ${y} is sent along to the url. See example below.
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init : "L.Control.RedirectClick", // Pictometry
                    options: {
                        position: "topright",       // Button's position
                        url: "http://kartor.malmo.se/urbex/index.htm?p=true&xy=${x};${y}",  // Malmö pictometry
                        btnClass: "fa fa-plane",    // Button's icon class
                        cursor: "crosshair"         // Cursor shown in map before click
                    }
                },

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // Info simply creates a toggleable Bootstrap modal which you can fill with any info below.
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init: "L.Control.Info",
                    options: {
                        addToMenu: false,           // Create toggle button or not
                        position: "topright",       // Button's position (requires addToMenu == true)
                        autoActivate: false,        // Open from start

                        // Here follows the content of the modal – language dependent!
                        _lang: {
                            "en": {
                                titleInfo: "<h4>A header</h4>",
                                bodyContent:
                                    '<p>Some content</p>'
                            },
                            "sv": {
                                titleInfo: "<h4>En rubrik</h4>",
                                bodyContent:
                                    '<p>Lite innehåll</p>'
                            }
                        }
                    }
                },

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // MeasureDraw is a combined measure and drawing tool. The created
                // markers, lines or polygons can be shared with others 
                // (geometries and attributes sent along as a URL parameter).
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init: "L.Control.MeasureDraw",
                    options: {
                        position: "topright",       // Button's position
                        saveMode: "url",            // So far url is the only option
                        layerName: "measurelayer",  // The internal layerId for the draw layer

                        stylePolygon: {             // Draw style for polygons
                            color: '#0077e2',
                            weight: 3
                        },
                        stylePolyline: {            // Draw style for polylines
                            color: '#0077e2',
                            weight: 9
                        }
                    }
                },

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // ToolHandler takes care of making all buttons inside the top-right div responsive.
                // When the screen width is smaller than the defined breakpoint, the buttons are contained 
                // within a Bootstrap popover which can be toggled by a single button.
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                {
                    init: "L.Control.ToolHandler",
                    options: {
                        showPopoverTitle: false     // Show title (header) in the popover
                    }
                }

                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // Add2HomeScreen creates a popover on iOS devices supporting
                // "Add To Homescreen", which advices the user to add the website
                // to the homescreen, making it look almost like a native app.
                // <><><><><><><><><><><><><><><><><><><><><><><><><><>
                // {
                //  init: "L.Control.Add2HomeScreen",
                //  options: {}
                // }
    ]
};

错误指向&#34; feature.properties。&#34;在设置我打开的第一层颜色的功能中,当我点击以在我打开的第二层上弹出时,它就会出现。使用Leaflet时没有使用smap-resonsive我没有遇到过这个问题。

我尝试将该功能移到外部js。文件,使用&#34; var something =&#34;定义函数。我试过直接从一个属性调用颜色,但都给出了同样的错误。

我是Leaflet和Javascript的新手,感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

错误是由错误引起的,这意味着只有最上层是可选的。这里描述:

https://github.com/getsmap/smap-responsive/issues/198

感谢Johan Lahti快速解决问题!