admin管理员组文章数量:1430681
I am developing a map via Mapbox GL JS that display coordinate data as a geojson, and displays a variety of environmental layers as either Mapbox Studio layers, or a WMS layer.
I have however just run into an issue. All my points and layers display properly upon load. But when I click "satellite" to change the basemap, the Wetlands, Aquifers and Floodzone layers stop working. The buttons do not function whatsoever and the error I get is:
style.js:788 Uncaught TypeError: Cannot read property 'getLayoutProperty' of undefined
at i.getLayoutProperty (style.js:788)
at o.getLayoutProperty (map.js:1315)
at HTMLAnchorElement.link.onclick ((index):1309)
i.getLayoutProperty @ style.js:788
o.getLayoutProperty @ map.js:1315
link.onclick @ (index):1309
You can see a functioning demo here. /
And all code is below:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='.50.0/mapbox-gl.js'></script>
<link href='.50.0/mapbox-gl.css' rel='stylesheet' />
<script src='.2.0/mapbox-gl-geocoder.min.js'></script>
<link rel='stylesheet' href='.2.0/mapbox-gl-geocoder.css' type='text/css' />
<link href="+Sans" rel="stylesheet">
<link href="" rel="stylesheet">
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<style>
.marker {
background-image: url('data/marker.svg');
background-size: cover;
width:20px;
height: 20px;
cursor: pointer;
padding: 0px;
}
.markerUnit {
background-image: url('.svg');
background-size: cover;
width:20px;
height: 20px;
cursor: pointer;
padding: 0px;
}
.mapboxgl-popup {
max-width: 300px;
}
.mapboxgl-popup-content {
text-align: center;
font-family: 'Open Sans', sans-serif;
}
#infoButton {
position: fixed;
right:10px;
top: 10px;
width: 30px;
height: 20px;
box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
border: none;
border-radius: 3px;
font-size: 12px;
font-family: 'Inconsolata';
color: #fff;
background: #ee8a65;
cursor:pointer;
}
#centerMap {
position: fixed;
right: 45px;
top: 10px;
width: 80px;
height: 20px;
box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
border: none;
border-radius: 3px;
font-size: 12px;
font-family: 'Inconsolata';
text-align: center;
color: #fff;
background: #ee8a65;
cursor:pointer;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
/* Modal Content/Box */
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border-radius: 4px;
width: 60%;
font-family: 'Open Sans', sans-serif;
font-size: 14px;
animation-name: animatetop;
animation-duration: 0.4s;
}
@keyframes animatetop {
from {top: -300px; opacity: 0}
to {top: 0; opacity: 1}
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
#menu {
background: #fff;
position: absolute;
z-index: 1;
top: 60px;
left: 10px;
width: 120px;
box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
border-radius: 3px;
font-size: 12px;
font-family: 'Inconsolata';
color: #fff;
cursor:pointer;
}
#menu a {
font-size: 13px;
color: #404040;
display: block;
margin: 0;
padding: 0;
padding: 10px;
text-decoration: none;
border-bottom: 1px solid rgba(0,0,0,0.25);
text-align: center;
}
#menu a:last-child {
border: none;
}
#menu a:hover {
background-color: #f8f8f8;
color: #404040;
}
#menu a.active {
background-color: #3887be;
color: #ffffff;
}
#menu a.active:hover {
background: #3074a4;
}
#menuLayer {
position: fixed;
bottom:10px;
right:45px;
height: 15px;
width: 140px;
box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
border-radius: 3px;
background: #fff;
padding: 10px;
font-family: 'Inconsolata';
font-size: 12px;
text-align: center;
}
</style>
<div id='map'></div>
<div id='menuLayer'>
<input id='cjneuzsr492wx2tqw6ngm0zug' type='radio' name='rtoggle' value='light' checked='checked'>
<label for='light'>light</label>
<input id='cjnxbj1503m302sp7bkpcxt4w' type='radio' name='rtoggle' value='satellite'>
<label for='satellite'>satellite</label>
</div>
<nav id="menu"></nav>
<div class='map-overlay top'>
<div class='map-overlay-inner'>
</div>
</div>
<button id="centerMap">Center Map</button>
<button id="infoButton">i</button>
<div id="myModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<h4>Insert text </h4>
</div>
</div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiZHlhdnJvbSIsImEiOiJjamZsZGl0dnIwMHUwMnhvNDB4N2o0cnB6In0.AqxOgFJXuLgFMiwkPutaLA';
var bounds = [
[-137.3,14.3], // west-south coordinates
[-41.6, 67.4] // Northeast coordinates
];
if (!mapboxgl.supported()) {
alert('Your browser does not support Mapbox GL. Please try and different browser.');
} else {
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/dyavrom/cjneuzsr492wx2tqw6ngm0zug',
center: [-105, 47],
zoom: 2.75,
// maxBounds: bounds,
attributionControl:false
});
}
//add second layer of data
map.on('load', function() {
// Floodzome Mapbox Studio layer
map.addLayer({
"id": "Floodzones",
"type": "fill",
"source": {
type: 'vector',
url: 'mapbox://dyavrom.d7g97071'
},
'source-layer': 'selected_layer',
'minzoom':8,
'layout': {
'visibility': 'none'
},
"paint": {
"fill-color": "#2ee6da",
"fill-opacity": .5
}
});
//Aquifer Mapbox Studio layer
map.addLayer({
"id": "Aquifers",
"type": "fill",
"source": {
type: 'vector',
url: 'mapbox://dyavrom.6i5kjh12'
},
'source-layer': 'aquifersSingleColor-9baxdg',
'minzoom':5,
'layout': {
'visibility': 'none'
},
"paint": {
"fill-color": "#7e5cee",
"fill-opacity": .25
}
});
// wetlands WMS layer
map.addLayer({
'id': 'Wetlands',
'type': 'raster',
'source': {
'type': 'raster',
'tiles': [
'={bbox-epsg-3857}&bboxSR=EPSG%3A3857&layers=28&layerDefs=&size=256%2c256&imageSR=&format=png&transparent=true&dpi=&time=&layerTimeOptions=&dynamicLayers=&gdbVersion=&mapScale=&f=image'
],
'tileSize': 256,
},
'minzoom':5,
'layout': {
'visibility': 'none'
}
});
});
var layerList = document.getElementById('menuLayer');
var inputs = layerList.getElementsByTagName('input');
function switchLayer(layer) {
var layerId = layer.target.id;
map.setStyle('mapbox://styles/dyavrom/' + layerId);
}
for (var i = 0; i < inputs.length; i++) {
inputs[i].onclick = switchLayer;
}
//fit to center button
document.getElementById('centerMap').addEventListener('click', function() {
map.fitBounds([[
-167.3,14.3
], [
-41.6,67.4
]]);
});
var geojsonUnit = {
"type": "FeatureCollection",
"name": "latlon2",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "Code": -999, "Name": "Place", "address": "xxx", "city": "xxx", "state": "xx", "zip": 12345, "lat": 38.79381, "lon": -91.9854, "unitType": "xxx" }, "geometry": { "type": "Point", "coordinates": [ -91.9854, 38.79381 ] } }
]
}
//add markers to map
geojsonUnit.features.forEach(function(markerUnit) {
// create a HTML element for each feature
var el = document.createElement('div');
el.className = 'markerUnit';
// make a marker for each feature and add to the map
new mapboxgl.Marker(el)
.setLngLat(markerUnit.geometry.coordinates)
.addTo(map);
//add popups
new mapboxgl.Marker(el)
.setLngLat(markerUnit.geometry.coordinates)
.setPopup(new mapboxgl.Popup({ offset: 25,
closeButton: (true) })
.setHTML('<h3>' + markerUnit.properties.plantName + '</h3><h5>' +
markerUnit.properties.address +
', ' +
markerUnit.properties.city +
' ' +
markerUnit.properties.state +
', ' +
markerUnit.properties.zip +
'</h5><h5>'+
'Type: '+
markerUnit.properties.unitType +
'</h5>'))
.addTo(map);
});
// Add Geocoder and buttons
map.addControl(new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
}), 'top-left');
// Add zoom and rotation controls to the map.
map.addControl(new mapboxgl.NavigationControl({
showCompass: (false),
}), 'bottom-right');
// Add geolocate control to the map.
map.addControl(new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true,
fitBoundsOptions: {maxZoom:11},
}), 'bottom-right');
// Info button
var modal = document.getElementById('myModal');
// Get the button that opens the modal
var btn = document.getElementById("infoButton");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on the button, open the modal
btn.onclick = function() {
modal.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
//toggle layers
var toggleableLayerIds = [ 'Wetlands', 'Floodzones', 'Aquifers' ];
for (var i = 0; i < toggleableLayerIds.length; i++) {
var id = toggleableLayerIds[i];
var link = document.createElement('a');
link.href = '#';
link.className = '';
link.textContent = id;
link.onclick = function (e) {
var clickedLayer = this.textContent;
e.preventDefault();
e.stopPropagation();
var visibility = map.getLayoutProperty(clickedLayer, 'visibility');
if (visibility === 'visible') {
map.setLayoutProperty(clickedLayer, 'visibility', 'none');
this.className = '';
} else {
this.className = 'active';
map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
}
};
var layers = document.getElementById('menu');
layers.appendChild(link);
}
</script>
</body>
</html>
I am developing a map via Mapbox GL JS that display coordinate data as a geojson, and displays a variety of environmental layers as either Mapbox Studio layers, or a WMS layer.
I have however just run into an issue. All my points and layers display properly upon load. But when I click "satellite" to change the basemap, the Wetlands, Aquifers and Floodzone layers stop working. The buttons do not function whatsoever and the error I get is:
style.js:788 Uncaught TypeError: Cannot read property 'getLayoutProperty' of undefined
at i.getLayoutProperty (style.js:788)
at o.getLayoutProperty (map.js:1315)
at HTMLAnchorElement.link.onclick ((index):1309)
i.getLayoutProperty @ style.js:788
o.getLayoutProperty @ map.js:1315
link.onclick @ (index):1309
You can see a functioning demo here. https://bl.ocks/dyavromEPA/raw/4576726c459e654ff5e2664f096aaba1/
And all code is below:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox./mapbox-gl-js/v0.50.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox./mapbox-gl-js/v0.50.0/mapbox-gl.css' rel='stylesheet' />
<script src='https://api.mapbox./mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.2.0/mapbox-gl-geocoder.min.js'></script>
<link rel='stylesheet' href='https://api.mapbox./mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.2.0/mapbox-gl-geocoder.css' type='text/css' />
<link href="https://fonts.googleapis./css?family=Open+Sans" rel="stylesheet">
<link href="https://fonts.googleapis./css?family=Inconsolata" rel="stylesheet">
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<style>
.marker {
background-image: url('data/marker.svg');
background-size: cover;
width:20px;
height: 20px;
cursor: pointer;
padding: 0px;
}
.markerUnit {
background-image: url('https://cdn.rawgit./dyavromEPA/a71f02aca7cade0d26a90344e61738f4/raw/aca54e7f1f8eb8c87c6719feb23c8fe2198baea3/map.svg');
background-size: cover;
width:20px;
height: 20px;
cursor: pointer;
padding: 0px;
}
.mapboxgl-popup {
max-width: 300px;
}
.mapboxgl-popup-content {
text-align: center;
font-family: 'Open Sans', sans-serif;
}
#infoButton {
position: fixed;
right:10px;
top: 10px;
width: 30px;
height: 20px;
box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
border: none;
border-radius: 3px;
font-size: 12px;
font-family: 'Inconsolata';
color: #fff;
background: #ee8a65;
cursor:pointer;
}
#centerMap {
position: fixed;
right: 45px;
top: 10px;
width: 80px;
height: 20px;
box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
border: none;
border-radius: 3px;
font-size: 12px;
font-family: 'Inconsolata';
text-align: center;
color: #fff;
background: #ee8a65;
cursor:pointer;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
/* Modal Content/Box */
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border-radius: 4px;
width: 60%;
font-family: 'Open Sans', sans-serif;
font-size: 14px;
animation-name: animatetop;
animation-duration: 0.4s;
}
@keyframes animatetop {
from {top: -300px; opacity: 0}
to {top: 0; opacity: 1}
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
#menu {
background: #fff;
position: absolute;
z-index: 1;
top: 60px;
left: 10px;
width: 120px;
box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
border-radius: 3px;
font-size: 12px;
font-family: 'Inconsolata';
color: #fff;
cursor:pointer;
}
#menu a {
font-size: 13px;
color: #404040;
display: block;
margin: 0;
padding: 0;
padding: 10px;
text-decoration: none;
border-bottom: 1px solid rgba(0,0,0,0.25);
text-align: center;
}
#menu a:last-child {
border: none;
}
#menu a:hover {
background-color: #f8f8f8;
color: #404040;
}
#menu a.active {
background-color: #3887be;
color: #ffffff;
}
#menu a.active:hover {
background: #3074a4;
}
#menuLayer {
position: fixed;
bottom:10px;
right:45px;
height: 15px;
width: 140px;
box-shadow:0px 0px 3px rgba(0, 0, 0, 0.10);
border-radius: 3px;
background: #fff;
padding: 10px;
font-family: 'Inconsolata';
font-size: 12px;
text-align: center;
}
</style>
<div id='map'></div>
<div id='menuLayer'>
<input id='cjneuzsr492wx2tqw6ngm0zug' type='radio' name='rtoggle' value='light' checked='checked'>
<label for='light'>light</label>
<input id='cjnxbj1503m302sp7bkpcxt4w' type='radio' name='rtoggle' value='satellite'>
<label for='satellite'>satellite</label>
</div>
<nav id="menu"></nav>
<div class='map-overlay top'>
<div class='map-overlay-inner'>
</div>
</div>
<button id="centerMap">Center Map</button>
<button id="infoButton">i</button>
<div id="myModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<h4>Insert text </h4>
</div>
</div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiZHlhdnJvbSIsImEiOiJjamZsZGl0dnIwMHUwMnhvNDB4N2o0cnB6In0.AqxOgFJXuLgFMiwkPutaLA';
var bounds = [
[-137.3,14.3], // west-south coordinates
[-41.6, 67.4] // Northeast coordinates
];
if (!mapboxgl.supported()) {
alert('Your browser does not support Mapbox GL. Please try and different browser.');
} else {
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/dyavrom/cjneuzsr492wx2tqw6ngm0zug',
center: [-105, 47],
zoom: 2.75,
// maxBounds: bounds,
attributionControl:false
});
}
//add second layer of data
map.on('load', function() {
// Floodzome Mapbox Studio layer
map.addLayer({
"id": "Floodzones",
"type": "fill",
"source": {
type: 'vector',
url: 'mapbox://dyavrom.d7g97071'
},
'source-layer': 'selected_layer',
'minzoom':8,
'layout': {
'visibility': 'none'
},
"paint": {
"fill-color": "#2ee6da",
"fill-opacity": .5
}
});
//Aquifer Mapbox Studio layer
map.addLayer({
"id": "Aquifers",
"type": "fill",
"source": {
type: 'vector',
url: 'mapbox://dyavrom.6i5kjh12'
},
'source-layer': 'aquifersSingleColor-9baxdg',
'minzoom':5,
'layout': {
'visibility': 'none'
},
"paint": {
"fill-color": "#7e5cee",
"fill-opacity": .25
}
});
// wetlands WMS layer
map.addLayer({
'id': 'Wetlands',
'type': 'raster',
'source': {
'type': 'raster',
'tiles': [
'https://www.fws.gov/wetlands/arcgis/rest/services/Wetlands/MapServer/export?bbox={bbox-epsg-3857}&bboxSR=EPSG%3A3857&layers=28&layerDefs=&size=256%2c256&imageSR=&format=png&transparent=true&dpi=&time=&layerTimeOptions=&dynamicLayers=&gdbVersion=&mapScale=&f=image'
],
'tileSize': 256,
},
'minzoom':5,
'layout': {
'visibility': 'none'
}
});
});
var layerList = document.getElementById('menuLayer');
var inputs = layerList.getElementsByTagName('input');
function switchLayer(layer) {
var layerId = layer.target.id;
map.setStyle('mapbox://styles/dyavrom/' + layerId);
}
for (var i = 0; i < inputs.length; i++) {
inputs[i].onclick = switchLayer;
}
//fit to center button
document.getElementById('centerMap').addEventListener('click', function() {
map.fitBounds([[
-167.3,14.3
], [
-41.6,67.4
]]);
});
var geojsonUnit = {
"type": "FeatureCollection",
"name": "latlon2",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "Code": -999, "Name": "Place", "address": "xxx", "city": "xxx", "state": "xx", "zip": 12345, "lat": 38.79381, "lon": -91.9854, "unitType": "xxx" }, "geometry": { "type": "Point", "coordinates": [ -91.9854, 38.79381 ] } }
]
}
//add markers to map
geojsonUnit.features.forEach(function(markerUnit) {
// create a HTML element for each feature
var el = document.createElement('div');
el.className = 'markerUnit';
// make a marker for each feature and add to the map
new mapboxgl.Marker(el)
.setLngLat(markerUnit.geometry.coordinates)
.addTo(map);
//add popups
new mapboxgl.Marker(el)
.setLngLat(markerUnit.geometry.coordinates)
.setPopup(new mapboxgl.Popup({ offset: 25,
closeButton: (true) })
.setHTML('<h3>' + markerUnit.properties.plantName + '</h3><h5>' +
markerUnit.properties.address +
', ' +
markerUnit.properties.city +
' ' +
markerUnit.properties.state +
', ' +
markerUnit.properties.zip +
'</h5><h5>'+
'Type: '+
markerUnit.properties.unitType +
'</h5>'))
.addTo(map);
});
// Add Geocoder and buttons
map.addControl(new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
}), 'top-left');
// Add zoom and rotation controls to the map.
map.addControl(new mapboxgl.NavigationControl({
showCompass: (false),
}), 'bottom-right');
// Add geolocate control to the map.
map.addControl(new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true,
fitBoundsOptions: {maxZoom:11},
}), 'bottom-right');
// Info button
var modal = document.getElementById('myModal');
// Get the button that opens the modal
var btn = document.getElementById("infoButton");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on the button, open the modal
btn.onclick = function() {
modal.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
//toggle layers
var toggleableLayerIds = [ 'Wetlands', 'Floodzones', 'Aquifers' ];
for (var i = 0; i < toggleableLayerIds.length; i++) {
var id = toggleableLayerIds[i];
var link = document.createElement('a');
link.href = '#';
link.className = '';
link.textContent = id;
link.onclick = function (e) {
var clickedLayer = this.textContent;
e.preventDefault();
e.stopPropagation();
var visibility = map.getLayoutProperty(clickedLayer, 'visibility');
if (visibility === 'visible') {
map.setLayoutProperty(clickedLayer, 'visibility', 'none');
this.className = '';
} else {
this.className = 'active';
map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
}
};
var layers = document.getElementById('menu');
layers.appendChild(link);
}
</script>
</body>
</html>
Share
Improve this question
asked Oct 31, 2018 at 18:11
Deeba YavromDeeba Yavrom
911 silver badge12 bronze badges
1
- You need to demonstrate that you have tried to solve the problem yourself, not just paste your entire application here. – Steve Bennett Commented Nov 12, 2018 at 12:43
1 Answer
Reset to default 5When you change the map style, all your layer is removed. This is due to the fact all you layer is create on the map style https://docs.mapbox./mapbox-gl-js/style-spec/. You just have to recreate them all.
本文标签: javascriptMapbox layers not showing with style changesStack Overflow
版权声明:本文标题:javascript - Mapbox layers not showing with style changes - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745562224a2663541.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论