Google Maps API, Part 1
When I returned to Binghamton University at the beginning of this semester, I was immediately confronted by large amounts of construction in the middle of campus. Binghamton has been doing construction for the past 2 years, so this wasn’t that much of a surprise. However, with the construction being directly in the area of what used to be highly traveled walking paths, students and faculty were being forced to walk through other buildings to get to certain parts of campus. I’ll be honest, it took me a few days to figure out how to get around, even after being here for 4 years.
On Tuesdays and Thursdays, I have class from 2:50-5:50, a quick 10 minute break, and then another class at 6. By the time I get out of the first classes, I’m usually pretty hungry and make a run for the dining hall. In the first 2 weeks of the semester, this quick run to the dining hall meant showing up 5-10 minutes late to my 6:00 class. While making the move to get food 2 weeks ago, I was discussing with a friend in my class the quickest way to get to our next class. After quickly thinking about our options, we ended up picking a route and hoping for the best. At the same time, we joked about how nice it would be to have a website that would provide you with the quickest way to get from Point A to Point B on campus.
The next day I decided to give it a shot – I mean, the worst thing that could have happened was I tried to implement something and it wouldn’t work. Best case scenario, I develop a great new tool for Binghamton University students. I looked up the Google Maps API and quickly plugged in the latitude/longitude coordinates for several buildings on campus. I put all of the necessary code in place, selected my start point and end point, and was immediately disappointed with the results. Google only indexed the roads around campus – there were no paths on their map to go through the walkways in the middle. This meant that every route the map returned required you to walk around the edge of campus, even if the buildings were located in the middle.
After explaining to my friend Alex what I was trying to do, he helped me put together a rough idea of what would need to be done to get the map working the way I wanted it to. In short, I would need to index the middle of campus myself, and then use an algorithm to create the shortest path. Ultimately, I would only be using the Google Maps API for the picture of the map.
To make the process of indexing the middle of campus easier, I had to put together another page using the API. This page would have to have drastically different options than my first page that was just going to show the map. The basic functionality is as follows:
- Click on the map to place a marker – either a building, entrance/exit, or walkway via point – and at the same time add this location into a javascript object with an array attached to it. For instance, A[point1] = new Array(). This was necessary for creating a mapping of connected points, which was to come later.
- Each marker also had to have a click event attached to it. If it was clicked while in mode 0, the marker would have to be removed, as well as any references to it in the data structures. If it was clicked while in mode 1, it would have to be stored in memory until a second marker was clicked, at which point a connection was made between them, and again the necessary data structures were updated.
With the basic modes in place, I began putting everything together. Below you’ll find the javascript necessary to perform the operations as outlined above. If you don’t really care about the code, check out the live demo here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'> <html> <head> <!-- Information --> <meta http-equiv='Content-Type' content='text/html; charset=ISO-8859-1' /> <!-- Stylesheets --> <link href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css" rel="stylesheet" type="text/css" /> <style> .left { float: right; width: 120px; } .clear { clear: both; } </style> <!-- Javascript --> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="jquery.iphone-switch.js"></script> <script type="text/javascript" src="json2.js"></script> <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> <script type="text/javascript"> var map; var markers = []; var A = {}; var cnt = 0; var mode = 0; // 0 for Entering Points, 1 for Creating Graph var startPt = -1; var endPt = -1; var first = true; var polyCoordinates = []; var polyLine; var buildings = new Array(); function initialize() { var binghamtonU = new google.maps.LatLng(42.088889,-75.966929); var myOptions = { zoom:17, mapTypeId: google.maps.MapTypeId.HYBRID, center: binghamtonU } map = new google.maps.Map(document.getElementById('map_canvas'), myOptions); google.maps.event.addListener(map,'click',function(event) { var title = event.latLng.toString(); var pos = new google.maps.LatLng(event.latLng.lat(), event.latLng.lng()); markers.push(new google.maps.Marker({ position: pos, map: map, draggable: false, title: title })); A[title] = new Array(); google.maps.event.addListener(markers[cnt],'click', (function(cnt) { return function() { if (mode == 0) { var foo = markers[cnt].getTitle(); // Remove Marker markers[cnt].setMap(null); // Delete array in A delete A[markers[cnt].getTitle()]; // Delete entries in A and polyCoordinates, if any for (var baz = 0; baz < polyCoordinates.length; baz++) { if (polyCoordinates[baz] == foo) { polyCoordinates.splice(baz, 1); baz = 0; } } for (var qux in A) { for (var baz = 0; baz < A[qux].length; baz++) { if (A[qux][baz] == foo) { A[qux].splice(baz, 1); baz = 0; } } } // Update Polyline if (polyLine != undefined) polyLine.setMap(null); polyLine = new google.maps.Polyline({ path: polyCoordinates, strokeColor: "#FF0000", strokeOpacity: 1.0, strokeWeight: 2 }); polyLine.setMap(map); } else { // If Marker already selected, remove selection if (markers[cnt].getIcon() == "blue-dot.png") { markers[cnt].setIcon(null); first ? endPt = -1 : startPt = -1; first = first ? false : true; } else { // Select Marker markers[cnt].setIcon("blue-dot.png"); first ? startPt = cnt : endPt = cnt; first = first ? false : true; } // If 2 Markers selected, add to A and update Polyline if (startPt != -1 && endPt != -1) { // Check if relation has already been entered if ($.inArray(markers[endPt].getTitle(), A[markers[startPt].getTitle()]) == -1) { // Add to A in appropriate locations A[markers[startPt].getTitle()].push(markers[endPt].getTitle()); A[markers[endPt].getTitle()].push(markers[startPt].getTitle()); // Create Polyline var foo = new google.maps.LatLng(markers[startPt].getPosition().lat(), markers[startPt].getPosition().lng()); if ($.inArray(markers[startPt].getTitle(), polyCoordinates) == -1) polyCoordinates.push(foo); var bar = new google.maps.LatLng(markers[endPt].getPosition().lat(), markers[endPt].getPosition().lng()); if ($.inArray(markers[endPt].getTitle(), polyCoordinates) == -1) polyCoordinates.push(bar); if (polyLine != undefined) polyLine.setMap(null); polyLine = new google.maps.Polyline({ path: polyCoordinates, strokeColor: "#FF0000", strokeOpacity: 1.0, strokeWeight: 2 }); polyLine.setMap(map); } // Reset Markers to Default markers[startPt].setIcon(null); markers[endPt].setIcon(null); // Reset Variables startPt = -1; endPt = -1; } } }; })(cnt)); cnt++; }); } </script> </head> <body onload="initialize()"> <span style='font-size: 28px; font-family: Verdana,sans-serif; margin-left: 20px;'><a href='#' id='showA' style='color: #000;'>Done?</a></span> <div id='containerA' style='display: none; position: absolute; left: 50%; top: 100px; width: 800px; margin-left: -400px; z-index: 10000; background: #FFF; border: 3px solid #000; -moz-border-radius: 8px; -webkit-border-radius: 8px;'> <div id='returnA' style='margin-left: 20px;'></div> </div> <div class="left" id="opMode"></div> <div class="clear"></div> <script type="text/javascript"> $('#opMode').iphoneSwitch("off", function() { mode = 1; }, function() { mode = 0; }, { switch_on_container_path: 'iphone_switch_container_off.png' }); $('#showA').click(function() { $('#containerA').hide(); var retA = JSON.stringify(A); retA += "<br><br><center><a href='#' onClick=\"$('#containerA').hide();\" style='color: #000;'>Close</a></center>"; $('#returnA').html(retA); $('#containerA').show(); }); </script> <div id="map_canvas" style='top: 30px;'></div> </body> </html> |
After mapping out Binghamton using this page, I quickly realized that I had left out some crucial options necessary to use the data I was generating. Most importantly, I had no ability to save/load my data which meant that I would never be able to leave the page if I was still in the middle of finishing the map. This lead to version 2 of the code, which I’ll save for the next post. Any questions/comments, leave a message below.
[...] RSS Feed « Google Maps API, Part 1 [...]