1var side_bar_html = ""; 2var gmarkers = []; 3var gicons = []; 4var map = null; 5 6// NEW: lookup by stable key (id or name) 7var markerByKey = {}; 8 9var infowindow = new google.maps.InfoWindow({ 10 size: new google.maps.Size(150, 50), 11 maxWidth: 400 12}); 13 14gicons["red"] = new google.maps.MarkerImage( 15 "https://www.uwo.ca/about/maps/mapIcons/marker_red.png", 16 new google.maps.Size(32, 32), 17 new google.maps.Point(0, 0), 18 new google.maps.Point(9, 32) 19); 20 21var iconImage = new google.maps.MarkerImage( 22 "https://www.uwo.ca/about/maps/mapIcons/marker_red.png", 23 new google.maps.Size(32, 32), 24 new google.maps.Point(0, 0), 25 new google.maps.Point(9, 32) 26); 27var iconShadow = new google.maps.MarkerImage( 28 "https://www.uwo.ca/about/maps/mapIcons/msmarker.shadow.png", 29 new google.maps.Size(59, 32), 30 new google.maps.Point(0, 0), 31 new google.maps.Point(9, 32) 32); 33 34var iconShape = { 35 coord: [19,0,20,1,21,2,22,3,23,4,24,5,24,6,24,7,24,8,24,9,24,10,24,11,24,12,23,13,23,14,22,15,21,16,20,17,20,18,19,19,19,20,18,21,18,22,17,23,17,24,17,25,17,26,16,27,16,28,16,29,16,30,16,31,14,31,14,30,14,29,14,28,14,27,14,26,13,25,13,24,13,23,12,22,12,21,12,20,11,19,10,18,10,17,9,16,8,15,7,14,7,13,6,12,6,11,6,10,6,9,6,8,6,7,6,6,7,5,7,4,8,3,9,2,10,1,11,0,19,0], 36 type: "poly" 37}; 38 39function getMarkerImage(iconColor) { 40 if ((typeof iconColor === "undefined") || (iconColor == null)) { 41 iconColor = "red"; 42 } 43 if (!gicons[iconColor]) { 44 gicons[iconColor] = new google.maps.MarkerImage( 45 "https://www.uwo.ca/about/maps/mapIcons/marker_" + iconColor + ".png", 46 new google.maps.Size(32, 32), 47 new google.maps.Point(0, 0), 48 new google.maps.Point(9, 32) 49 ); 50 } 51 return gicons[iconColor]; 52} 53 54function category2color(category) { 55 var color = "red"; 56 switch (category) { 57 case "academic": color = "purple"; break; 58 case "perimeter": color = "grey"; break; 59 case "student": color = "green"; break; 60 case "arts": color = "yellow"; break; 61 case "core": color = "orange"; break; 62 case "residence": color = "red"; break; 63 case "visitor": color = "blue"; break; 64 case "services": color = "lightblue"; break; 65 default: color = "red"; break; 66 } 67 return color; 68} 69 70gicons["academic"] = getMarkerImage(category2color("academic")); 71gicons["residence"] = getMarkerImage(category2color("residence")); 72gicons["services"] = getMarkerImage(category2color("services")); 73gicons["visitor"] = getMarkerImage(category2color("visitor")); 74gicons["perimeter"] = getMarkerImage(category2color("perimeter")); 75gicons["core"] = getMarkerImage(category2color("core")); 76gicons["student"] = getMarkerImage(category2color("student")); 77gicons["arts"] = getMarkerImage(category2color("arts")); 78 79/* createMarker returns the marker, stores html on it, and sets a stable key */ 80function createMarker(latlng, name, html, category, key) { 81 const marker = new google.maps.Marker({ 82 position: latlng, 83 icon: gicons[category], 84 shadow: iconShadow, 85 map: map, 86 title: name, 87 zIndex: (Math.round(latlng.lat() * -100000) << 5) 88 }); 89 90 marker.mycategory = category; 91 marker.myname = name; 92 marker.key = key; // stable key (id or name) 93 marker.infoHtml = html; // bind THIS markerâs content 94 95 google.maps.event.addListener(marker, "click", function () { 96 infowindow.setContent(this.infoHtml); 97 infowindow.open(map, this); 98 }); 99 100 gmarkers.push(marker); 101 markerByKey[key] = marker; 102 return marker; 103} 104 105/* unchanged: show/hide/boxclick â continue using marker.mycategory */ 106function show(category) { 107 category = String(category || "").toLowerCase(); 108 for (var i = 0; i < gmarkers.length; i++) { 109 if (gmarkers[i].mycategory === category) { 110 gmarkers[i].setVisible(true); 111 } else { 112 gmarkers[i].setVisible(false); 113 } 114 } 115 infowindow.close(); 116 map.setZoom(15); 117 map.setCenter(new google.maps.LatLng(43.006103, -81.274978)); 118 var box = document.getElementById(category + "box"); 119 if (box) box.checked = true; 120 document.getElementById("result").innerHTML = ""; 121} 122 123function hide(category) { 124 category = String(category || "").toLowerCase(); 125 for (var i = 0; i < gmarkers.length; i++) { 126 if (gmarkers[i].mycategory === category) { 127 gmarkers[i].setVisible(false); 128 } 129 } 130 var box = document.getElementById(category + "box"); 131 if (box) box.checked = false; 132 infowindow.close(); 133} 134 135function boxclick(box, category) { 136 if (box.checked) { 137 show(category); 138 } else { 139 hide(category); 140 } 141 makeSidebar(); 142} 143 144/* index-based myclick -> key-based myclickByKey */ 145function myclickByKey(key) { 146 hide("academic"); 147 hide("residence"); 148 hide("services"); 149 hide("visitor"); 150 hide("core"); 151 hide("perimeter"); 152 hide("student"); 153 hide("arts");
154 const m = markerByKey[key]; 155 if (!m) return; 156 google.maps.event.trigger(m, "click"); 157 m.setVisible(true); 158 map.setCenter(m.getPosition()); 159 map.setZoom(17); 160} 161window.myclickByKey = myclickByKey; 162 163/* Sidebar links target myclickByKey with a stable key */ 164function makeSidebar() { 165 var html = ""; 166 for (var i = 0; i < gmarkers.length; i++) { 167 var m = gmarkers[i]; 168 if (m.getVisible()) { 169 html += '<li><a href="javascript:myclickByKey(' + JSON.stringify(m.key) + ')">' + 170 m.myname + "</a></li>"; 171 } 172 } 173 document.getElementById("side_bar").innerHTML = html; 174} 175 176function initialize() { 177 var myOptions = { 178 zoom: 15, 179 center: new google.maps.LatLng(43.006103, -81.274978), 180 mapTypeId: google.maps.MapTypeId.ROADMAP 181 }; 182 map = new google.maps.Map(document.getElementById("map"), myOptions); 183 184 google.maps.event.addListener(map, "click", function () { 185 infowindow.close(); 186 }); 187 188 // helper to trim safely 189 const raw = (v) => String(v || "").trim(); 190 191 // helper to detect placeholder/no-image values 192 function isNoImage(src) { 193 return /^https?:\/\/(?:www\.)?uwo\.ca\/about\/maps\/buildings\/no-image\.png(?:[?#].*)?$/i.test(raw(src)); 194 } 195 196 function normalizeMoreLink(url) { 197 const value = raw(url); 198 199 // Replace old parking map links like: 200 // https://www.uwo.ca/parking/find/map.html#westminster 201 // https://www.uwo.ca/parking/map.html#kent 202 // Hash value can be anything. 203 if (/^https?:\/\/(?:www\.)?uwo\.ca\/parking\/(?:find\/)?map\.html(?:\?[^#]*)?(?:#.*)?$/i.test(value)) { 204 return "https://www.uwo.ca/parking/find-parking/index.html"; 205 } 206 207 return value; 208} 209 210 // Add a cache-buster so you always fetch the latest XML after edits 211 downloadUrl("/about/maps/buildings.xml?v=20251030", function (doc) { 212 var xml = xmlParse(doc); 213 var markers = xml.documentElement.getElementsByTagName("marker"); 214 215 for (let i = 0; i < markers.length; i++) { 216 const hiddenAttr = raw(markers[i].getAttribute("hidden")).toLowerCase(); 217 if (hiddenAttr === "true" || hiddenAttr === "1" || hiddenAttr === "yes") { 218 // Respect the "hidden" attribute: skip rendering this marker entirely. 219 continue; 220 } 221 222 const lat = parseFloat(raw(markers[i].getAttribute("lat"))); 223 const lng = parseFloat(raw(markers[i].getAttribute("lng"))); 224 const point = new google.maps.LatLng(lat, lng); 225 226 const description = raw(markers[i].getAttribute("description")); 227 const image = raw(markers[i].getAttribute("image")); 228 const id = raw(markers[i].getAttribute("id")); // preferred stable key 229 const name = raw(markers[i].getAttribute("name")) || ("Building " + (i + 1)); 230 // const more = raw(markers[i].getAttribute("more")); // may be blank 231 const more = normalizeMoreLink(markers[i].getAttribute("more")); // may be blank 232 const read = raw(markers[i].getAttribute("read")) || "Read more"; 233 const category = (raw(markers[i].getAttribute("category")) || "academic").toLowerCase(); 234 235 // Build InfoWindow HTML â *omit* the link block if "more" is blank 236 let html = ''; 237 html += '<p style="margin-top:5px; color:#4E2583;"><strong>' + name + "</strong></p>"; 238 //if (image) { 239 // html += '<img style="float:right; display:block; margin:4px 10px 5px 15px;
239" src="' + image + '" alt="' + name + '"/>'; 240 // } 241 if (image && !isNoImage(image)) { 242 html += '<img style="float:right; display:block; margin:4px 10px 5px 15px;" src="' + image + '" alt="' + name + '"/>'; 243 } 244 if (description) { 245 html += "<p>" + description + "</p>"; 246 } 247 if (more) { 248 // Only render the link if `more` is non-empty 249 html += '<p><a href="' + more + '" target="_blank" rel="noopener noreferrer"><span style="font-weight:bold;">' + read + "</span></a></p>"; 250 } 251 252 // Prefer the XML id as the stable key; fall back to name if needed 253 const key = id || name; 254 255 createMarker(point, name, html, category, key); 256 } 257 258 // initial state (as you had it) 259 hide("academic"); 260 hide("residence"); 261 hide("services"); 262 hide("visitor"); 263 hide("core"); 264 hide("perimeter"); 265 hide("student"); 266 hide("arts"); 267 makeSidebar(); 268 }); 269}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.