1/** 2* @param {google.maps.LatLng} newLatLng 3* @returns {number} 4*/ 5google.maps.LatLng.prototype.distanceFrom = function(newLatLng) { 6 // setup our variables 7 var lat1 = this.lat(); 8 var radianLat1 = lat1 * ( Math.PI / 180 ); 9 var lng1 = this.lng(); 10 var radianLng1 = lng1 * ( Math.PI / 180 ); 11 var lat2 = newLatLng.lat(); 12 var radianLat2 = lat2 * ( Math.PI / 180 ); 13 var lng2 = newLatLng.lng(); 14 var radianLng2 = lng2 * ( Math.PI / 180 ); 15 // sort out the radius, MILES or KM? 16 var earth_radius = 3959; // (km = 6378.1) OR (miles = 3959) - radius of the earth 17 18 // sort our the differences 19 var diffLat = ( radianLat1 - radianLat2 ); 20 var diffLng = ( radianLng1 - radianLng2 ); 21 // put on a wave (hey the earth is round after all) 22 var sinLat = Math.sin( diffLat / 2 ); 23 var sinLng = Math.sin( diffLng / 2 ); 24 25 // maths - borrowed from http://www.opensourceconnections.com/wp-content/uploads/2009/02/clientsidehaversinecalculation.html 26 var a = Math.pow(sinLat, 2.0) + Math.cos(radianLat1) * Math.cos(radianLat2) * Math.pow(sinLng, 2.0); 27 28 // work out the distance 29 var distance = earth_radius * 2 * Math.asin(Math.min(1, Math.sqrt(a))); 30 31 // return the distance 32 return distance; 33} 34 35/* 36function createIcons() 37{ 38 icon00 = new GIcon(); 39 icon00.image = "http://schoolperformancemaps.com/images/00.png"; 40 icon00.shadow = "http://schoolperformancemaps.com/images/shadow.png"; 41 icon00.iconSize = new GSize(12, 20); 42 icon00.shadowSize = new GSize(22, 20); 43 icon00.iconAnchor = new GPoint(6, 20); 44 icon00.infoWindowAnchor = new GPoint(5, 1); 45 46 icon01 = new GIcon(); 47 icon01.image = "http://schoolperformancemaps.com/images/01.png"; 48 icon01.shadow = "http://schoolperformancemaps.com/images/shadow.png"; 49 icon01.iconSize = new GSize(12, 20); 50 icon01.shadowSize = new GSize(22, 20); 51 icon01.iconAnchor = new GPoint(6, 20); 52 icon01.infoWindowAnchor = new GPoint(5, 1); 53 54 icon02 = new GIcon(); 55 icon02.image = "http://schoolperformancemaps.com/images/02.png"; 56 icon02.shadow = "http://schoolperformancemaps.com/images/shadow.png"; 57 icon02.iconSize = new GSize(12, 20); 58 icon02.shadowSize = new GSize(22, 20); 59 icon02.iconAnchor = new GPoint(6, 20); 60 icon02.infoWindowAnchor = new GPoint(5, 1); 61 62 icon03 = new GIcon(); 63 icon03.image = "http://schoolperformancemaps.com/images/03.png"; 64 icon03.shadow = "http://schoolperformancemaps.com/images/shadow.png"; 65 icon03.iconSize = new GSize(12, 20); 66 icon03.shadowSize = new GSize(22, 20); 67 icon03.iconAnchor = new GPoint(6, 20); 68 icon03.infoWindowAnchor = new GPoint(5, 1); 69 70 icon04 = new GIcon(); 71 icon04.image = "http://schoolperformancemaps.com/images/04.png";
72 icon04.shadow = "http://schoolperformancemaps.com/images/shadow.png"; 73 icon04.iconSize = new GSize(12, 20); 74 icon04.shadowSize = new GSize(22, 20); 75 icon04.iconAnchor = new GPoint(6, 20); 76 icon04.infoWindowAnchor = new GPoint(5, 1); 77 78 icon05 = new GIcon(); 79 icon05.image = "http://schoolperformancemaps.com/images/05.png"; 80 icon05.shadow = "http://schoolperformancemaps.com/images/shadow.png"; 81 icon05.iconSize = new GSize(12, 20); 82 icon05.shadowSize = new GSize(22, 20); 83 icon05.iconAnchor = new GPoint(6, 20); 84 icon05.infoWindowAnchor = new GPoint(5, 1); 85 86 icon06 = new GIcon(); 87 icon06.image = "http://schoolperformancemaps.com/images/06.png"; 88 icon06.shadow = "http://schoolperformancemaps.com/images/shadow.png"; 89 icon06.iconSize = new GSize(12, 20); 90 icon06.shadowSize = new GSize(22, 20); 91 icon06.iconAnchor = new GPoint(6, 20); 92 icon06.infoWindowAnchor = new GPoint(5, 1); 93 94 icon07 = new GIcon(); 95 icon07.image = "http://schoolperformancemaps.com/images/07.png"; 96 icon07.shadow = "http://schoolperformancemaps.com/images/shadow.png"; 97 icon07.iconSize = new GSize(12, 20); 98 icon07.shadowSize = new GSize(22, 20); 99 icon07.iconAnchor = new GPoint(6, 20); 100 icon07.infoWindowAnchor = new GPoint(5, 1); 101 102 icon08 = new GIcon(); 103 icon08.image = "http://schoolperformancemaps.com/images/08.png"; 104 icon08.shadow = "http://schoolperformancemaps.com/images/shadow.png"; 105 icon08.iconSize = new GSize(12, 20); 106 icon08.shadowSize = new GSize(22, 20); 107 icon08.iconAnchor = new GPoint(6, 20); 108 icon08.infoWindowAnchor = new GPoint(5, 1); 109 110 icon09 = new GIcon(); 111 icon09.image = "http://schoolperformancemaps.com/images/09.png"; 112 icon09.shadow = "http://schoolperformancemaps.com/images/shadow.png"; 113 icon09.iconSize = new GSize(12, 20); 114 icon09.shadowSize = new GSize(22, 20); 115 icon09.iconAnchor = new GPoint(6, 20); 116 icon09.infoWindowAnchor = new GPoint(5, 1); 117 118 icon10 = new GIcon(); 119 icon10.image = "http://schoolperformancemaps.com/images/10.png"; 120 icon10.shadow = "http://schoolperformancemaps.com/images/shadow.png"; 121 icon10.iconSize = new GSize(12, 20); 122 icon10.shadowSize = new GSize(22, 20); 123 icon10.iconAnchor = new GPoint(6, 20); 124 icon10.infoWindowAnchor = new GPoint(5, 1); 125 126} 127*/ 128 129function getHeight() 130{ 131 var y = 600; 132 if (self.innerHeight) // all except Explorer 133 { 134 y = self.innerHeight; 135 } 136 else if (document.documentElement && document.documentElement.clientHeight) 137 // Explorer 6 Strict Mode 138 { 139 y = document.documentElement.clientHeight; 140 } 141 else if (document.body) // other Explorers 142 { 143 y = document.body.clientHeight; 144 } 145 return y; 146} 147 148function getWidth() 149{ 150 var x = 700; 151 if (self.innerWidth) // all except Explorer 152 { 153 x = self.innerWidth; 154 } 155 else if (document.documentElement && document.documentElement.clientWidth) 156 // Explorer 6 Strict Mode 157 { 158 x = document.documentElement.clientWidth; 159 } 160 else if (document.body) // other Explorers 161 { 162 x = document.body.clientWidth; 163 } 164 return x; 165} 166 167function checkHeight() 168{ 169 var newHeight = getHeight() - 191; 170 document.getElementById("map").style.height = newHeight + "px"; 171 var newHeight2 = newHeight - 24; 172 document.getElementById("about").style.height = newHeight2 + "px"; 173 document.getElementById("contact").style.height = newHeight2 + "px"; 174 175 var newWidth = getWidth() - 196; 176 document.getElementById("about").style.width = newWidth + "px"; 177 document.getElementById("contact").style.width = newWidth + "px"; 178} 179 180function resetMap() 181{ 182 // redraw map in most browsers, reload page in Safari 183 if (document.getElementById("maplink")) 184 { 185 document.getElementById("maplink").innerHTML = ""; 186 } 187 /* if (navigator.userAgent.indexOf("Safari") == -1) 188 { */ 189 mapState(); 190 /* } 191 else 192 { 193 window.location.reload(true); 194 } */ 195 return; 196} 197 198function setCenterZoom(newLatLng, newZoom) 199{ 200 map.setCenter(newLatLng); 201 map.setZoom(newZoom); 202} 203 204function preUpdate() 205{ 206 if (document.getElementById("maplink")) 207 { 208 document.getElementById("maplink").innerHTML = ""; 209 } 210 document.getElementById("info").innerHTML = "<strong>Updating map -- please wait...</strong>"; 211 document.getElementById("progress").innerHTML = "Checking database..."; 212 // if (navigator.userAgent.indexOf("Safari") == -1) 213 // { 214 window.setTimeout("updateMarkers();", 200); 215 // } 216 // else 217 // { 218 // updateMarkers(); 219 // } 220} 221 222function updateMarkers() 223{ 224 // timeLog = "start update markers: " + ((new Date())/1000); 225 226 // hide the about and contact info 227 document.getElementById("contact").style.display = "none"; 228 document.getElementById("about").style.display = "none"; 229 230 var bounds = map.getBounds(); 231 232 // state-specific function 233 var schTypeCode = getSchoolTypeCode(); 234 235 // if schooltypes change, get rid of all markers 236 if (schTypeCode != oldSchTypeCode) 237 { 238 // map.clearOverlays(); 239 // markers = []; 240 while(markers[0]) { 241 markers.pop().setMap(null); 242 } 243 } 244 /* 245 else if (!bounds.equals(oldBounds)) 246 // if bounds change, kill markers outside outerBounds 247 { 248 var osw = new GLatLng(
249 (bounds.getSouthWest().lat() - (bounds.getCenter().lat() - bounds.getSouthWest().lat())), 250 (bounds.getSouthWest().lng() - (bounds.getCenter().lng() - bounds.getSouthWest().lng())) 251 ); 252 var one = new GLatLng( 253 (bounds.getNorthEast().lat() + (bounds.getNorthEast().lat() - bounds.getCenter().lat())), 254 (bounds.getNorthEast().lng() + (bounds.getNorthEast().lng() - bounds.getCenter().lng())) 255 ); 256 outerBounds = bounds; 257 outerBounds.extend(osw); 258 outerBounds.extend(one); 259 for (theMarker in markers) 260 { 261 if (!outerBounds.contains(theMarker.getPoint())) 262 { 263 map.removeOverlay(theMarker); 264 delete markers[theMarker]; 265 } 266 } 267 } 268 */ 269 270 // see if we should map if there is a change in bounds or school types selected 271 if (!bounds.equals(oldBounds) || schTypeCode != oldSchTypeCode) 272 { 273 274 oldSchTypeCode = schTypeCode; 275 oldBounds = bounds; 276 277 /* if (bounds.minX != oldBounds.minX || bounds.minY != oldBounds.minY || bounds.maxX != oldBounds.maxX || bounds.maxY != oldBounds.maxY) 278 { 279 oldBounds.minX = bounds.minX; 280 oldBounds.minY = bounds.minY; 281 oldBounds.maxX = bounds.maxX; 282 oldBounds.maxY = bounds.maxY; 283 } */ 284 285 if (map.getZoom() >= minPlotZoom && schTypeCode != "0") 286 // only map schools if we are zoomed in sufficiently and school type(s) are selected 287 { 288 var requestUrl = "getschoolinfo.php?limit=" + markerLimit + "&minlon=" + bounds.getSouthWest
288().lng() + "&maxlon=" + bounds.getNorthEast().lng() + "&minlat=" + bounds.getSouthWest().lat() + "&maxlat=" + bounds.getNorthEast().lat() + "&schtypecode=" + schTypeCode; 289 290 291 292 new Ajax.Request(requestUrl, { 293 method:'get', 294 onSuccess: function(transport) { 295 var xmlDoc = transport.responseXML; 296 scount = xmlDoc.documentElement.getElementsByTagName("schoolcount")[0].firstChild.data; 297 298 var tcArray = xmlDoc.documentElement.getElementsByTagName("topcity"); 299 if (tcArray.length && tcArray[0].firstChild) 300 { 301 topCity = tcArray[0].firstChild.data; 302 } 303 else 304 { 305 topCity = ""; 306 } 307 308 schools = xmlDoc.documentElement.getElementsByTagName("schoolinfo"); 309 schoolsAA = new Object(); 310 for (i = 0; i < schools.length; i++) 311 { 312 schoolsAA['cds' + schools[i].getElementsByTagName("cds_code")[0].firstChild.data] = -1; 313 } 314 315 if (scount > markerLimit) 316 { 317 document.getElementById("progress").innerHTML = "Mapping " + markerLimit + " schools of " + scount + " found..."; 318 } 319 else if (scount == 1) 320 { 321 document.getElementById("progress").innerHTML = "Mapping 1 school..."; 322 } 323 else 324 { 325 document.getElementById("progress").innerHTML = "Mapping " + scount + " schools..."; 326 } 327 328 updateAds(); 329 330 // async call to actually change markers, so progress info can show first 331 window.setTimeout("mapSchools();", 200); 332 333 }, 334 onFailure: function() { 335 document.getElementById("progress").innerHTML = ""; 336 resetText(); 337 alert('Error retrieving school markers.'); 338 } 339 }); 340 341 342 343 // set up hash if maplink exists 344 if (document.getElementById("maplink")) 345 { 346 // alert(map.getCenter().lat() + "%2C" + map.getCenter().lng() + "%2C" + map.getZoom() + "%2C" + schTypeCode.replace(/\,/g, "%2C")); 347 document.getElementById("maplink").innerHTML = '<a href="#' + (Math.round(1000000 * map.getCenter().lat())/1000000) + '%2C' + (Math.round(1000000 * map.getCenter().lng())/1000000) + '%2C' + map.getZoom() + '%2C' + schTypeCode.replace(/\,/g, '%2C') + '">Link to this map</a>'; 348 } 349 } 350 else 351 { 352 document.getElementById("progress").innerHTML = ""; 353 resetText(); 354 } 355 } 356 else 357 { 358 document.getElementById("progress").innerHTML = ""; 359 resetText(); 360 } 361} 362 363 364function mapSchools() { 365 366 if (markers[0]) 367 { 368 // use oldMarkers to hold them temporarily, create new ones only as needed 369 var oldMarkers = markers; 370 var alreadyMapped = false; 371 markers = []; 372 while (oldMarkers[0]) 373 { 374 // loop through old markers 375 // if oldMarker is in schools[] (search result) then add to markers[] else delete marker 376 var oldMarker = oldMarkers.pop(); 377 alreadyMapped = false; 378 for (var i = 0; i < schools.length; i++) 379 { 380 if (oldMarker.cdscode == schools[i].getElementsByTagName("cds_code")[0].firstChild.data) 381 { 382 alreadyMapped = true; 383 break; 384 } 385 }
386 if (alreadyMapped) 387 { 388 markers.push(oldMarker); 389 } 390 else 391 { 392 oldMarker.setMap(null); 393 } 394 } 395 396 // loop through search result 397 // if not already in markers[] then make a merker and add to markers[] 398 for (var i = 0; i < schools.length; i++) 399 { 400 alreadyMapped = false; 401 for (var k = 0; k < markers.length; k++) 402 { 403 if (markers[k].cdscode == schools[i].getElementsByTagName("cds_code")[0].firstChild.data) 404 { 405 alreadyMapped = true; 406 break; 407 } 408 } 409 if (!alreadyMapped) 410 { 411 // map this school 412 var marker = createSchoolMarker(new google.maps.LatLng(parseFloat(schools[i].getElementsByTagName("lat")[0].firstChild.data), parseFloat(schools[i].getElementsByTagName("lon")[0].firstChild.data)), schools[i].getElementsByTagName("cds_code")[0].firstChild.data, schools[i].getElementsByTagName("nces")[0].firstChild.data, schools[i].getElementsByTagName("district")[0].firstChild.data, schools[i].getElementsByTagName("school")[0].firstChild.data, schools[i].getElementsByTagName("rankinfo")[0].firstChild.data, schools[i].getElementsByTagName("avg_rank")[0].firstChild.data); 413 414 marker.setMap(map); 415 markers.push(marker); 416 } 417 } 418 } 419 else 420 { 421 // make markers from scratch 422 for (j = 0; j < scount && j < markerLimit; j++) 423 { 424 // loop through results to map 425 var marker = createSchoolMarker(new google.maps.LatLng(parseFloat(schools[j].getElementsByTagName("lat")[0].firstChild.data), parseFloat(schools[j].getElementsByTagName("lon")[0].firstChild.data)), schools[j].getElementsByTagName("cds_code")[0].firstChild.data, schools[j].getElementsByTagName("nces")[0].firstChild.data, schools[j].getElementsByTagName("district")[0].firstChild.data, schools[j].getElementsByTagName("school")[0].firstChild.data, schools[j].getElementsByTagName("rankinfo")[0].firstChild.data, schools[j].getElementsByTagName("avg_rank")[0].firstChild.data); 426 427 marker.setMap(map); 428 markers.push(marker); 429 } 430 } 431 432 if (document.getElementById("progress").innerHTML != "") document.getElementById("progress").innerHTML += " done"; 433 resetText(); 434 435} 436 437 438function resetText() { 439 440 if (map.getZoom() < minPlotZoom) 441 { 442 document.getElementById("info").innerHTML = "Click the map to zoom in to an area and map nearby schools."; 443 } 444 else 445 { 446 document.getElementById("info").innerHTML = "Click and drag inside the map to recenter."; 447 if (document.getElementById("checkboxes")) 448 { 449 // alert("reset hash"); 450 var newhash = map.getCenterLatLng().y + "," + map.getCenterLatLng().x + "," + map.getZoom(); 451 // alert(document.getElementById("checkboxes").elements.length); 452 for (var box = 0; box < document.getElementById("checkboxes").elements.length; box++) 453 { 454 // alert(document.getElementById("checkboxes").elements[box].checked); 455 if (document.getElementById("checkboxes").elements[box].checked == true) 456 { 457 newhash += ("," + document.getElementById("checkboxes").elements[box].id); 458 } 459 } 460 // location.hash = encode64(newhash); 461 document.getElementById("maplink").innerHTML = '<a href="#' + encode64(newhash) + '">Link to this map</a>'; 462 } 463 } 464 if (oldSchTypeCode == "0") document.getElementById("info").innerHTML += "<br /><strong>Select at least one school type</strong> at the top."; 465 466} 467 468function about() 469{ 470 document.getElementById("about").style.display = "block"; 471 document.getElementById("contact").style.display = "none"; 472} 473 474function closeAbout() 475{ 476 document.getElementById("about").style.display = "none"; 477} 478 479function contact() 480{ 481 document.getElementById("contact").style.display = "block"; 482 document.getElementById("about").style.display = "none"; 483} 484 485function closeContact() 486{ 487 document.getElementById("contact").style.display = "none"; 488} 489 490function ahah(url,target) 491{ 492 // native XMLHttpRequest object 493 document.getElementById(target).innerHTML = '...'; 494 if (window.XMLHttpRequest) { 495 req = new XMLHttpRequest(); 496 req.onreadystatechange = function() {ahahDone(target);}; 497 req.open("GET", url, true); 498 req.send(null); 499 // IE/Windows ActiveX version 500 } else if (window.ActiveXObject) { 501 req = new ActiveXObject("Microsoft.XMLHTTP"); 502 if (req) { 503 req.onreadystatechange = function() {ahahDone(target);}; 504 req.open("GET", url, true); 505 req.send(); 506 } 507 } 508} 509 510function ahahDone(target) 511{ 512 // only if req is "loaded" 513 if (req.readyState == 4) { 514 // only if "OK" 515 if (req.status == 200 || req.status == 304) { 516 results = req.responseText; 517 document.getElementById(target).innerHTML = results; 518 } else { 519 document.getElementById(target).innerHTML="ahah error:\n" + 520 req.statusText; 521 } 522 } 523} 524 525function encode64(input) { 526 var output = ""; 527 var chr1, chr2, chr3 = ""; 528 var enc1, enc2, enc3, enc4 = ""; 529 var i = 0; 530 var keyStr = "ABCDEFGHIJKLMNOP" + 531 "QRSTUVWXYZabcdef" + 532 "ghijklmnopqrstuv" +
533 "wxyz0123456789+/" + 534 "="; 535 536 537 do { 538 chr1 = input.charCodeAt(i++); 539 chr2 = input.charCodeAt(i++); 540 chr3 = input.charCodeAt(i++); 541 542 enc1 = chr1 >> 2; 543 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); 544 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); 545 enc4 = chr3 & 63; 546 547 if (isNaN(chr2)) { 548 enc3 = enc4 = 64; 549 } else if (isNaN(chr3)) { 550 enc4 = 64; 551 } 552 553 output = output + 554 keyStr.charAt(enc1) + 555 keyStr.charAt(enc2) + 556 keyStr.charAt(enc3) + 557 keyStr.charAt(enc4); 558 chr1 = chr2 = chr3 = ""; 559 enc1 = enc2 = enc3 = enc4 = ""; 560 } while (i < input.length); 561 562 return output; 563} 564 565function decode64(input) { 566 var output = ""; 567 var chr1, chr2, chr3 = ""; 568 var enc1, enc2, enc3, enc4 = ""; 569 var i = 0; 570 var keyStr = "ABCDEFGHIJKLMNOP" + 571 "QRSTUVWXYZabcdef" + 572 "ghijklmnopqrstuv" + 573 "wxyz0123456789+/" + 574 "="; 575 576 // remove all characters that are not A-Z, a-z, 0-9, +, /, or = 577 var base64test = /[^A-Za-z0-9\+\/\=]/g; 578 if (base64test.exec(input)) { 579 alert("There were invalid base64 characters in the input text.\n" + 580 "Valid base64 characters are A-Z, a-z, 0-9, '+', '/', and '='\n" + 581 "Expect errors in decoding."); 582 } 583 input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); 584 585 do { 586 enc1 = keyStr.indexOf(input.charAt(i++)); 587 enc2 = keyStr.indexOf(input.charAt(i++)); 588 enc3 = keyStr.indexOf(input.charAt(i++)); 589 enc4 = keyStr.indexOf(input.charAt(i++)); 590 591 chr1 = (enc1 << 2) | (enc2 >> 4); 592 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); 593 chr3 = ((enc3 & 3) << 6) | enc4; 594 595 output = output + String.fromCharCode(chr1); 596 597 if (enc3 != 64) { 598 output = output + String.fromCharCode(chr2); 599 } 600 if (enc4 != 64) { 601 output = output + String.fromCharCode(chr3); 602 } 603 604 chr1 = chr2 = chr3 = ""; 605 enc1 = enc2 = enc3 = enc4 = ""; 606 607 } while (i < input.length); 608 609 return output; 610} 611
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.