I have a map where user from an admin panel can add many tiled layers to the map. Those layers will be added to the map in the form of loop. The user can switch the layer on and off based on their selection.
After adding the layers via the loop when I select the first layer the second layer renders but if I don’t add the layers via the loop but add them separately the layer selection works fine.
Here is my code
JavaScript
x
286
286
1
<!DOCTYPE html>
2
<html>
3
4
<head>
5
<meta charset="UTF-8">
6
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7
<title>Welcome- Land Cover Maps</title>
8
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
9
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
10
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
11
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
12
13
<style>
14
#over_map {
15
display: flex;
16
flex-direction: column;
17
position: absolute;
18
top: 20vh;
19
left: 10px;
20
z-index: 99;
21
}
22
23
body {
24
display: flex;
25
flex-direction: column;
26
min-height: 100vh;
27
}
28
29
.navbar {
30
flex-grow: 0;
31
}
32
33
#map {
34
flex-grow: 1;
35
}
36
37
38
.gm-ui-hover-effect {
39
width: 45px !important;
40
height: 45px !important;
41
}
42
43
.gm-ui-hover-effect>img {
44
width: 30px !important;
45
height: 30px !important;
46
}
47
48
.gm-style-iw {
49
height: 60vh;
50
}
51
52
.gm-style-iw-c {
53
height: 60vh;
54
}
55
56
.gm-style-iw {
57
max-height: 50vh !important;
58
overflow-y: auto;
59
display: flex;
60
}
61
62
.sidebar {
63
height: 50%;
64
/* 100% Full-height */
65
width: 0;
66
/* 0 width - change this with JavaScript */
67
position: fixed;
68
/* Stay in place */
69
z-index: 1;
70
/* Stay on top */
71
bottom: 0;
72
left: 0;
73
background-color: white;
74
/* Black*/
75
overflow-x: hidden;
76
/* Disable horizontal scroll */
77
padding-top: 90px;
78
/* Place content 60px from the top */
79
transition: 0.5s;
80
/* 0.5 second transition effect to slide in the sidebar */
81
82
}
83
84
/* The sidebar links */
85
.sidebar a {
86
padding: 8px 8px 8px 32px;
87
text-decoration: none;
88
font-size: 15px;
89
color: grey;
90
display: block;
91
transition: 0.3s;
92
}
93
94
/* When you mouse over the navigation links, change their color */
95
.sidebar a:hover {
96
color: #f1f1f1;
97
}
98
99
/* Position and style the close button (top right corner) */
100
.sidebar .closebtn {
101
position: absolute;
102
top: 0;
103
right: 25px;
104
font-size: 36px;
105
margin-left: 50px;
106
}
107
108
/* The button used to open the sidebar */
109
.openbtn {
110
top: 30px;
111
font-size: 20px;
112
cursor: pointer;
113
background-color: #111;
114
color: white;
115
padding: 10px 15px;
116
border: none;
117
}
118
119
.openbtn:hover {
120
background-color: #444;
121
}
122
123
/* Style page content - use this if you want to push the page content to the right when you open the side navigation */
124
#main {
125
transition: margin-left .5s;
126
/* If you want a transition effect */
127
padding: 20px;
128
}
129
130
/* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */
131
@media screen and (max-height: 450px) {
132
.sidebar {
133
padding-top: 15px;
134
}
135
136
.sidebar a {
137
font-size: 18px;
138
}
139
}
140
</style>
141
142
</head>
143
144
<body>
145
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
146
<a class="navbar-brand" href="#">
147
Try Test
148
149
</a>
150
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown"
151
aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
152
<span class="navbar-toggler-icon"></span>
153
</button>
154
<div class="collapse navbar-collapse" id="navbarNavDropdown">
155
<ul class="navbar-nav list-inline mx-auto justify-content-center">
156
157
158
<li class="nav-item dropdown">
159
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button"
160
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
161
Layers
162
</a>
163
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
164
<a href="#" class="btn btn-secondary" id="stamen" onclick="switchimagery('watercolor',0)"
165
style="padding:10px; width:90%;margin:10px;">Water Color</a>
166
<a href="#" class="btn btn-secondary" id="landcover2020" onclick="switchimagery('toner',1)"
167
style=" padding:10px; width:90%;margin:10px;">Background Toner</a>
168
169
</div>
170
</li>
171
</ul>
172
</div>
173
174
</nav>
175
176
177
<div id="map"></div>
178
179
<script>
180
var TILE_URL = 'http://c.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg';
181
var TILE_URL1 = 'http://tile.stamen.com/toner-background/{z}/{x}/{y}.png';
182
var layers = [{
183
"tile_id": "3",
184
"tile_name": "stamen_watercolor",
185
"tile_alias": "watercolor",
186
"tile_location": "http://c.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg",
187
"tile_status": "active",
188
"min_zoom": "1",
189
"max_zoom": "11"
190
}, {
191
"tile_id": "2",
192
"tile_name": "toner_background",
193
"tile_alias": "toner",
194
"tile_location": "http://tile.stamen.com/toner-background/{z}/{x}/{y}.png",
195
"tile_status": "active",
196
"min_zoom": "1",
197
"max_zoom": "11"
198
}];
199
var layerarray = [],
200
imagerylayer = [],
201
imagerylayerid = [];
202
203
var map;
204
var mapEl;
205
var layer;
206
var layerID = 'stamen';
207
208
window.initMap = function () {
209
// Select the element with id="map".
210
mapEl = document.querySelector('#map');
211
212
// Create a new map.
213
map = new google.maps.Map(mapEl, {
214
center: new google.maps.LatLng(39.8282, -98.5795),
215
zoom: 4
216
});
217
console.log({
218
layers
219
});
220
for (var i = 0; i < 2; i++) {
221
222
var path = "";
223
path = layers[i].tile_location;
224
225
var tname = layers[i].tile_alias;
226
var min = layers[i].min_zoom;
227
var max = layers[i].max_zoom;
228
var tempimagelayer = "";
229
230
console.log(path);
231
232
233
imagerylayer[i] = new google.maps.ImageMapType({
234
name: tname,
235
getTileUrl: function (coord, zoom) {
236
237
var url = path
238
.replace('{x}', coord.x)
239
.replace('{y}', coord.y)
240
.replace('{z}', zoom);
241
242
243
return url;
244
},
245
tileSize: new google.maps.Size(256, 256),
246
minZoom: min,
247
maxZoom: max
248
});
249
if(i==0)
250
{
251
map.overlayMapTypes.push(imagerylayer[i]);
252
}
253
}
254
};
255
256
function switchimagery(imgid, id) {
257
console.log("Imgid:"+imgid+" id:"+id);
258
console.log(imagerylayer[id].name, imagerylayer[id].getTileUrl);
259
map.overlayMapTypes.clear();
260
261
map.overlayMapTypes.push(imagerylayer[id]);
262
263
for (var j = 0; j < imagerylayer.length; j++) {
264
var buttonname = "#" + imagerylayer[j].name;
265
if (imagerylayer[j].name == imgid) {
266
267
268
$(buttonname).addClass("btn-success");
269
$(buttonname).removeClass("btn-secondary");
270
271
} else {
272
$(buttonname).removeClass("btn-success");
273
$(buttonname).addClass("btn-secondary");
274
}
275
//map.overlayMapTypes.pop(imagerylayer[i]);
276
}
277
}
278
</script>
279
280
<!-- NOTE: The 'key' parameter should be replaced with your Google Maps API Key. -->
281
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk">
282
</script>
283
284
</body>
285
286
</html>
Advertisement
Answer
To make your loop work (with modern browsers), use the let
keyword to define the path:
JavaScript
1
4
1
for (var i = 0; i < 2; i++) {
2
let path = layers[i].tile_location;
3
// ...
4
watercolor layer:
toner layer:
complete code:
JavaScript
1
284
284
1
<html>
2
3
<head>
4
<meta charset="UTF-8">
5
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6
<title>Welcome- Land Cover Maps</title>
7
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
8
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
9
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
10
11
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
12
13
<style>
14
#over_map {
15
display: flex;
16
flex-direction: column;
17
position: absolute;
18
top: 20vh;
19
left: 10px;
20
z-index: 99;
21
}
22
23
body {
24
display: flex;
25
flex-direction: column;
26
min-height: 100vh;
27
}
28
29
.navbar {
30
flex-grow: 0;
31
}
32
33
#map {
34
flex-grow: 1;
35
}
36
37
38
.gm-ui-hover-effect {
39
width: 45px !important;
40
height: 45px !important;
41
}
42
43
.gm-ui-hover-effect>img {
44
width: 30px !important;
45
height: 30px !important;
46
}
47
48
.gm-style-iw {
49
height: 60vh;
50
}
51
52
.gm-style-iw-c {
53
height: 60vh;
54
}
55
56
.gm-style-iw {
57
max-height: 50vh !important;
58
overflow-y: auto;
59
display: flex;
60
}
61
62
.sidebar {
63
height: 50%;
64
/* 100% Full-height */
65
width: 0;
66
/* 0 width - change this with JavaScript */
67
position: fixed;
68
/* Stay in place */
69
z-index: 1;
70
/* Stay on top */
71
bottom: 0;
72
left: 0;
73
background-color: white;
74
/* Black*/
75
overflow-x: hidden;
76
/* Disable horizontal scroll */
77
padding-top: 90px;
78
/* Place content 60px from the top */
79
transition: 0.5s;
80
/* 0.5 second transition effect to slide in the sidebar */
81
82
}
83
84
/* The sidebar links */
85
.sidebar a {
86
padding: 8px 8px 8px 32px;
87
text-decoration: none;
88
font-size: 15px;
89
color: grey;
90
display: block;
91
transition: 0.3s;
92
}
93
94
/* When you mouse over the navigation links, change their color */
95
.sidebar a:hover {
96
color: #f1f1f1;
97
}
98
99
/* Position and style the close button (top right corner) */
100
.sidebar .closebtn {
101
position: absolute;
102
top: 0;
103
right: 25px;
104
font-size: 36px;
105
margin-left: 50px;
106
}
107
108
/* The button used to open the sidebar */
109
.openbtn {
110
top: 30px;
111
font-size: 20px;
112
cursor: pointer;
113
background-color: #111;
114
color: white;
115
padding: 10px 15px;
116
border: none;
117
}
118
119
.openbtn:hover {
120
background-color: #444;
121
}
122
123
/* Style page content - use this if you want to push the page content to the right when you open the side navigation */
124
#main {
125
transition: margin-left .5s;
126
/* If you want a transition effect */
127
padding: 20px;
128
}
129
130
/* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */
131
@media screen and (max-height: 450px) {
132
.sidebar {
133
padding-top: 15px;
134
}
135
136
.sidebar a {
137
font-size: 18px;
138
}
139
}
140
</style>
141
142
</head>
143
144
<body>
145
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
146
<a class="navbar-brand" href="#">
147
Try Test
148
149
</a>
150
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown"
151
aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
152
<span class="navbar-toggler-icon"></span>
153
</button>
154
<div class="collapse navbar-collapse" id="navbarNavDropdown">
155
<ul class="navbar-nav list-inline mx-auto justify-content-center">
156
157
158
<li class="nav-item dropdown">
159
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button"
160
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
161
Layers
162
</a>
163
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
164
<a href="#" class="btn btn-secondary" id="stamen" onclick="switchimagery('watercolor',0)"
165
style="padding:10px; width:90%;margin:10px;">Water Color</a>
166
<a href="#" class="btn btn-secondary" id="landcover2020" onclick="switchimagery('toner',1)"
167
style=" padding:10px; width:90%;margin:10px;">Background Toner</a>
168
169
</div>
170
</li>
171
</ul>
172
</div>
173
174
</nav>
175
176
177
<div id="map"></div>
178
179
<script>
180
var TILE_URL = 'http://c.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg';
181
var TILE_URL1 = 'http://tile.stamen.com/toner-background/{z}/{x}/{y}.png';
182
var layers = [{
183
"tile_id": "3",
184
"tile_name": "stamen_watercolor",
185
"tile_alias": "watercolor",
186
"tile_location": "http://c.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg",
187
"tile_status": "active",
188
"min_zoom": "1",
189
"max_zoom": "11"
190
}, {
191
"tile_id": "2",
192
"tile_name": "toner_background",
193
"tile_alias": "toner",
194
"tile_location": "http://tile.stamen.com/toner-background/{z}/{x}/{y}.png",
195
"tile_status": "active",
196
"min_zoom": "1",
197
"max_zoom": "11"
198
}];
199
var layerarray = [],
200
imagerylayer = [],
201
imagerylayerid = [];
202
203
var map;
204
var mapEl;
205
var layer;
206
var layerID = 'stamen';
207
208
window.initMap = function () {
209
// Select the element with id="map".
210
mapEl = document.querySelector('#map');
211
212
// Create a new map.
213
map = new google.maps.Map(mapEl, {
214
center: new google.maps.LatLng(39.8282, -98.5795),
215
zoom: 4
216
});
217
console.log({
218
layers
219
});
220
for (var i = 0; i < 2; i++) {
221
222
let path = layers[i].tile_location;
223
224
var tname = layers[i].tile_alias;
225
var min = layers[i].min_zoom;
226
var max = layers[i].max_zoom;
227
var tempimagelayer = "";
228
console.log(path);
229
imagerylayer[i] = new google.maps.ImageMapType({
230
name: tname,
231
getTileUrl: function (coord, zoom) {
232
233
var url = path
234
.replace('{x}', coord.x)
235
.replace('{y}', coord.y)
236
.replace('{z}', zoom);
237
console.log(url);
238
239
return url;
240
},
241
tileSize: new google.maps.Size(256, 256),
242
minZoom: min,
243
maxZoom: max,
244
opacity: 0.5
245
});
246
if(i==0)
247
{
248
map.overlayMapTypes.push(imagerylayer[i]);
249
}
250
}
251
};
252
253
function switchimagery(imgid, id) {
254
console.log("Imgid:"+imgid+" id:"+id);
255
console.log(imagerylayer[id].name, imagerylayer[id].getTileUrl);
256
map.overlayMapTypes.clear();
257
258
map.overlayMapTypes.push(imagerylayer[id]);
259
260
for (var j = 0; j < imagerylayer.length; j++) {
261
var buttonname = "#" + imagerylayer[j].name;
262
if (imagerylayer[j].name == imgid) {
263
264
265
$(buttonname).addClass("btn-success");
266
$(buttonname).removeClass("btn-secondary");
267
268
} else {
269
$(buttonname).removeClass("btn-success");
270
$(buttonname).addClass("btn-secondary");
271
}
272
//map.overlayMapTypes.pop(imagerylayer[i]);
273
}
274
}
275
</script>
276
277
<!-- NOTE: The 'key' parameter should be replaced with your Google Maps API Key. -->
278
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap&key=API_KEY">
279
</script>
280
281
</body>
282
283
</html>
284