我正在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> | <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的新手,感谢任何帮助!
答案 0 :(得分:0)
错误是由错误引起的,这意味着只有最上层是可选的。这里描述:
https://github.com/getsmap/smap-responsive/issues/198
感谢Johan Lahti快速解决问题!