diff --git a/4190.pdf b/4190.pdf new file mode 100644 index 0000000..bf045f5 Binary files /dev/null and b/4190.pdf differ diff --git a/4191.pdf b/4191.pdf new file mode 100644 index 0000000..a9591b0 Binary files /dev/null and b/4191.pdf differ diff --git a/9781430216209.jpg b/9781430216209.jpg new file mode 100644 index 0000000..04aef2a Binary files /dev/null and b/9781430216209.jpg differ diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..9f45335 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,27 @@ +Freeware License, some rights reserved + +Copyright (c) 2009 Jon Udell + +Permission is hereby granted, free of charge, to anyone obtaining a copy +of this software and associated documentation files (the "Software"), +to work with the Software within the limits of freeware distribution and fair use. +This includes the rights to use, copy, and modify the Software for personal use. +Users are also allowed and encouraged to submit corrections and modifications +to the Software for the benefit of other users. + +It is not allowed to reuse, modify, or redistribute the Software for +commercial use in any way, or for a user’s educational materials such as books +or blog articles without prior permission from the copyright holder. + +The above copyright notice and this permission notice need to be included +in all copies or substantial portions of the software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..fce6516 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +#Apress Source Code + +This repository accompanies [*Beginning Google Maps Mashups with Mapplets, KML, and GeoRSS*](http://www.apress.com/9781430216209) by Jon Udell (Apress, 2009). + +![Cover image](9781430216209.jpg) + +Download the files as a zip using the green button, or clone the repository to your machine using Git. + +##Releases + +Release v1.0 corresponds to the code in the published book, without corrections or updates. + +##Contributions + +See the file Contributing.md for more information on how you can contribute to this repository. diff --git a/appendix_a/listing_a_01.js b/appendix_a/listing_a_01.js new file mode 100644 index 0000000..dbda302 --- /dev/null +++ b/appendix_a/listing_a_01.js @@ -0,0 +1,22 @@ +function dms2decimal(deg, min, sec) +{ + // dms2decimal: converts degrees/minutes/seconds to decimal degrees + + if (sec == null) + sec = 0; + + if (deg >= 0) + return deg + (min / 60) + (sec / 3600); + else + return deg - ((min / 60) + (sec / 3600)); +}; + +function decimal2dms(degrees) +{ + // decimal2dms: converts decimal degrees to degrees/minutes/seconds + var minutes = (Math.abs(degrees) - Math.floor(Math.abs(degrees))) * 60; + var seconds = Number(((minutes - Math.floor(minutes)) * 60).toFixed(2)); + var minutes = Math.floor(minutes); + var degrees = Math.floor(degrees); + return {deg: degrees, min: minutes, sec: seconds}; +}; diff --git a/appendix_a/listing_a_02.php b/appendix_a/listing_a_02.php new file mode 100644 index 0000000..afcc393 --- /dev/null +++ b/appendix_a/listing_a_02.php @@ -0,0 +1,13 @@ + diff --git a/appendix_b/listing_b_01.js b/appendix_b/listing_b_01.js new file mode 100644 index 0000000..f1a52ff --- /dev/null +++ b/appendix_b/listing_b_01.js @@ -0,0 +1,10 @@ +if (a == b) +{ + // Statements here execute if a is equal to b + ... +} +else +{ + // Statements here execute if a is not equal to b + ... +} diff --git a/appendix_b/listing_b_02.js b/appendix_b/listing_b_02.js new file mode 100644 index 0000000..e91d149 --- /dev/null +++ b/appendix_b/listing_b_02.js @@ -0,0 +1,15 @@ +if (a == b) +{ + // Statements here execute if a is equal to b + ... +} +else if (a == c) +{ + // Statements here execute if a is equal to c + ... +} +else +{ + // Statements here execute if a is not equal to b or c + ... +} diff --git a/appendix_b/listing_b_03.js b/appendix_b/listing_b_03.js new file mode 100644 index 0000000..f31a14d --- /dev/null +++ b/appendix_b/listing_b_03.js @@ -0,0 +1,5 @@ +for (a = 0; a < 5; a++) +{ + // Statements here will execute five times + ... +} diff --git a/appendix_b/listing_b_04.js b/appendix_b/listing_b_04.js new file mode 100644 index 0000000..4f77cb8 --- /dev/null +++ b/appendix_b/listing_b_04.js @@ -0,0 +1,5 @@ +for (var a = 0; a < array.length; a++) +{ + // Actions can be performed here on array[a] + ... +} diff --git a/appendix_b/listing_b_05.js b/appendix_b/listing_b_05.js new file mode 100644 index 0000000..65b57ef --- /dev/null +++ b/appendix_b/listing_b_05.js @@ -0,0 +1,7 @@ +for (var a = array.length ? 1; a >= 0; a--) +{ + // Actions can be performed here on array[a], before deletion + ... + + array.splice(a, 1); +} diff --git a/appendix_b/listing_b_06.js b/appendix_b/listing_b_06.js new file mode 100644 index 0000000..a823ada --- /dev/null +++ b/appendix_b/listing_b_06.js @@ -0,0 +1,5 @@ +while (a == b) +{ + // Statements here will execute until a is no longer equal to b + ... +} diff --git a/appendix_b/listing_b_07.js b/appendix_b/listing_b_07.js new file mode 100644 index 0000000..c6494a4 --- /dev/null +++ b/appendix_b/listing_b_07.js @@ -0,0 +1,12 @@ +var found = -1; +for (var a = 0; a < array.length; a++) +{ + if (array[a] == 'banana') + { + found = a; + break; + } +} + +if (found > -1) + alert('banana found at element ' + found); diff --git a/appendix_b/listing_b_08.js b/appendix_b/listing_b_08.js new file mode 100644 index 0000000..d432493 --- /dev/null +++ b/appendix_b/listing_b_08.js @@ -0,0 +1,16 @@ +switch (a) +{ + case b: + // Statements here execute if a is equal to b + ... + break + + case c: + // Statements here execute if a is equal to c + ... + break; + + default: + // Statements here execute if a is not equal to b or c + ... +} diff --git a/appendix_b/listing_b_09.js b/appendix_b/listing_b_09.js new file mode 100644 index 0000000..1c9a65c --- /dev/null +++ b/appendix_b/listing_b_09.js @@ -0,0 +1,19 @@ +switch (currencyCode) +{ + case 'AUD': + case 'CAD': + case 'USD': + var symbol = '$'; + break; + + case 'GBP': + var symbol = '£'; + break; + + case 'JPY': + var symbol = 'Â¥'; + break; + + default: + var symbol = currencyCode; +} diff --git a/appendix_b/listing_b_10.js b/appendix_b/listing_b_10.js new file mode 100644 index 0000000..ed444b5 --- /dev/null +++ b/appendix_b/listing_b_10.js @@ -0,0 +1,12 @@ +function doSomething(a) +{ + var b; + // Actions can be performed here on the parameter, a + ... + + return b; +}; + +... +// Later in the code, we can invoke those actions: +var c = doSomething(d); diff --git a/appendix_b/listing_b_11.js b/appendix_b/listing_b_11.js new file mode 100644 index 0000000..6771364 --- /dev/null +++ b/appendix_b/listing_b_11.js @@ -0,0 +1,8 @@ +function square (x) +{ + var sqr = x * x; + return sqr; +}; + +var nine = square(3); +var thirtySix = square(6); diff --git a/appendix_b/listing_b_12.js b/appendix_b/listing_b_12.js new file mode 100644 index 0000000..65b8ce1 --- /dev/null +++ b/appendix_b/listing_b_12.js @@ -0,0 +1,5 @@ +var x = {length: 6, width: 4, color: 'gray'}; +x.area = function () +{ + return this.length * this.width; +}; diff --git a/appendix_b/listing_b_13.js b/appendix_b/listing_b_13.js new file mode 100644 index 0000000..d98c9bd --- /dev/null +++ b/appendix_b/listing_b_13.js @@ -0,0 +1,10 @@ +var a; + +function doSomething() +{ + var b; + var c = a + b; + ... +}; +... +var d = a + b; // This statement will produce an error! \ No newline at end of file diff --git a/appendix_b/listing_b_14.js b/appendix_b/listing_b_14.js new file mode 100644 index 0000000..bb8127a --- /dev/null +++ b/appendix_b/listing_b_14.js @@ -0,0 +1,6 @@ +GEvent.addListener(map, 'zoomend', + function (oldZoom, newZoom) + { + // Perform actions here, after the map zooms, using the old and new zoom levels + ... + }); diff --git a/appendix_b/listing_b_15.js b/appendix_b/listing_b_15.js new file mode 100644 index 0000000..567b421 --- /dev/null +++ b/appendix_b/listing_b_15.js @@ -0,0 +1,13 @@ +function addDataPoint(coordinates, name, description, style) +{ + var thisMarker = new GMarker(coordinates, options); + ... + var sidebarRow = document.createElement('div'); + ... + sidebarRow.onclick = + function () + { + // A click on the sidebar entry triggers a click on its associated marker + GEvent.trigger(thisMarker, 'click') + }; +}; diff --git a/appendix_b/readme.txt b/appendix_b/readme.txt new file mode 100644 index 0000000..8e7ed8c --- /dev/null +++ b/appendix_b/readme.txt @@ -0,0 +1,2 @@ +Note: Most of the listings in this chapter are example code snippets to illustrate + structure, not complete (nor syntactically valid) JavaScript. \ No newline at end of file diff --git a/appendix_c/listing_c_01.js b/appendix_c/listing_c_01.js new file mode 100644 index 0000000..baa2d1a --- /dev/null +++ b/appendix_c/listing_c_01.js @@ -0,0 +1,21 @@ +var map; + +function loadMap() +{ + var mapDiv = document.getElementById('map'); + + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + map = new GMap2(mapDiv); + map.setCenter(new GLatLng(39.8, -98.5), 4); + + GEvent.addListener(map, 'moveend', mapMoveEnd); + } +}; + +function mapMoveEnd() +{ + GLog.write(map.getCenter().toUrlValue()); +}; diff --git a/appendix_c/listing_c_02.js b/appendix_c/listing_c_02.js new file mode 100644 index 0000000..a93d327 --- /dev/null +++ b/appendix_c/listing_c_02.js @@ -0,0 +1,17 @@ +var map; + +GEvent.addDomListener(window, 'load', loadMap); +GEvent.addDomListener(window, 'unload', GUnload); + +function loadMap() +{ + var mapDiv = document.getElementById('map'); + + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + map = new GMap2(mapDiv); + map.setCenter(new GLatLng(39.8, -98.5), 4); + } +}; diff --git a/appendix_c/listing_c_03.html b/appendix_c/listing_c_03.html new file mode 100644 index 0000000..7040e94 --- /dev/null +++ b/appendix_c/listing_c_03.html @@ -0,0 +1,15 @@ + + + + + Better Event Listeners + + + + + +
+ + \ No newline at end of file diff --git a/appendix_c/listing_c_04.html b/appendix_c/listing_c_04.html new file mode 100644 index 0000000..e18a79a --- /dev/null +++ b/appendix_c/listing_c_04.html @@ -0,0 +1,14 @@ + + + + + Multiple API Keys + + + + + +
+ + \ No newline at end of file diff --git a/appendix_c/listing_c_05.js b/appendix_c/listing_c_05.js new file mode 100644 index 0000000..0e5b469 --- /dev/null +++ b/appendix_c/listing_c_05.js @@ -0,0 +1,12 @@ +// Set Google maps API key + +var scriptUrl = 'http://maps.google.com/maps?file=api&v=2.124&key='; + +if (location.host == 'www.somedomain.com') + // Live server + scriptUrl = scriptUrl + 'ABQIAAAA5wG_Upp3E2E2FvbwfSzPchQEMNwiYNXG5Xk21FzWxftqhFg'; +else + // Development server + scriptUrl = scriptUrl + 'ABQIAAAAN_IKAOv-fz9s2G9ZOihkhRQRiYyMmFOXXgCIe1BMmHtWUkP'; + +document.write(''); diff --git a/appendix_c/listing_c_06.xml b/appendix_c/listing_c_06.xml new file mode 100644 index 0000000..5c14298 --- /dev/null +++ b/appendix_c/listing_c_06.xml @@ -0,0 +1,61 @@ + + + + + + + + p { + font-size: 90%; + } + + +

+ + + ]]>
+
\ No newline at end of file diff --git a/async.js b/async.js new file mode 100644 index 0000000..c5a3e7b --- /dev/null +++ b/async.js @@ -0,0 +1,46 @@ +// GAsync v2 by Michael Geary +// Commented version and description at: +// http://mg.to/2007/06/22/write-the-same-code-for-google-mapplets-and-maps-api +// Free beer and free speech license. Enjoy! + +function GAsync( obj ) { + + function callback() { + args[nArgs].apply( null, results ); + } + + function queue( iResult, name, next ) { + + function ready( value ) { + results[iResult] = value; + if( ! --nCalls ) + callback(); + } + + var a = []; + if( next.join ) + a = a.concat(next), ++iArg; + if( mapplet ) { + a.push( ready ); + obj[ name+'Async' ].apply( obj, a ); + } + else { + results[iResult] = obj[name].apply( obj, a ); + } + } + + var mapplet = ! window.GBrowserIsCompatible; + var args = arguments, nArgs = args.length - 1; + var results = [], nCalls = 0; + + for( var iArg = 1; iArg < nArgs; ++iArg ) { + var name = args[iArg]; + if( typeof name == 'object' ) + obj = name; + else + queue( nCalls++, name, args[iArg+1] ); + } + + if( ! mapplet ) + callback(); +} \ No newline at end of file diff --git a/chapter_01/listing_01_01.kml b/chapter_01/listing_01_01.kml new file mode 100644 index 0000000..babdaa8 --- /dev/null +++ b/chapter_01/listing_01_01.kml @@ -0,0 +1,10 @@ + + + + Crater Lake + A deep blue lake in the Cascade Mountains. + + -122.1089,42.9413,0 + + + diff --git a/chapter_01/listing_01_02.xml b/chapter_01/listing_01_02.xml new file mode 100644 index 0000000..ef42e9b --- /dev/null +++ b/chapter_01/listing_01_02.xml @@ -0,0 +1,12 @@ + + + National Park Tour + 2008-05-19T19:41:10Z + + Crater Lake + A deep blue lake in the Cascade Mountains. + 2008-05-19T19:41:10Z + 42.9413 -122.1089 + + diff --git a/chapter_01/listing_01_03.xml b/chapter_01/listing_01_03.xml new file mode 100644 index 0000000..c398a0d --- /dev/null +++ b/chapter_01/listing_01_03.xml @@ -0,0 +1,14 @@ + + + + National Park Tour + http://sterlingudell.com/bgmm/ + Simple RSS feed with geodata + + Crater Lake + http://sterlingudell.com/bgmm/chapter_01/listing_01_03.xml + A deep blue lake in the Cascade Mountains. + 42.9413 -122.1089 + + + diff --git a/chapter_02/listing_02_01.html b/chapter_02/listing_02_01.html new file mode 100644 index 0000000..da4e26a --- /dev/null +++ b/chapter_02/listing_02_01.html @@ -0,0 +1,12 @@ + + + + + Google Maps API Basic Example + + + +
+ + diff --git a/chapter_02/listing_02_02.css b/chapter_02/listing_02_02.css new file mode 100644 index 0000000..977f742 --- /dev/null +++ b/chapter_02/listing_02_02.css @@ -0,0 +1,14 @@ +html { + height: 100%; +} + +body { + height: 100%; + margin: 0; +} + +#map { + width: 100%; + height: 100%; +} + diff --git a/chapter_02/listing_02_03.html b/chapter_02/listing_02_03.html new file mode 100644 index 0000000..53bc3db --- /dev/null +++ b/chapter_02/listing_02_03.html @@ -0,0 +1,15 @@ + + + + + Google Maps API Basic Example + + + + + +
+ + diff --git a/chapter_02/listing_02_04.js b/chapter_02/listing_02_04.js new file mode 100644 index 0000000..4a850be --- /dev/null +++ b/chapter_02/listing_02_04.js @@ -0,0 +1,16 @@ +var map; + +function loadMap() +{ + var mapDiv = document.getElementById('map'); + + if (!GBrowserIsCompatible()) + { + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + } + else + { + map = new GMap2(mapDiv); + map.setCenter(new GLatLng(39.9, -105.2), 10); + } +}; diff --git a/chapter_02/listing_02_05.js b/chapter_02/listing_02_05.js new file mode 100644 index 0000000..c26f909 --- /dev/null +++ b/chapter_02/listing_02_05.js @@ -0,0 +1,21 @@ +var map; + +function loadMap() +{ + var mapDiv = document.getElementById('map'); + + if (!GBrowserIsCompatible()) + { + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + } + else + { + map = new GMap2(mapDiv); + var coordinates = new GLatLng(39.9, -105.2); + map.setCenter(coordinates, 10); + + var marker = new GMarker(coordinates); + marker.bindInfoWindowHtml('

Hello, World!

'); + map.addOverlay(marker); + } +}; diff --git a/chapter_02/listing_02_06.js b/chapter_02/listing_02_06.js new file mode 100644 index 0000000..9eb5200 --- /dev/null +++ b/chapter_02/listing_02_06.js @@ -0,0 +1,27 @@ +var map; + +function loadMap() +{ + var mapDiv = document.getElementById('map'); + + if (!GBrowserIsCompatible()) + { + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + } + else + { + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_PHYSICAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP]}); + var coordinates = new GLatLng(39.9, -105.2); + map.setCenter(coordinates, 10, G_PHYSICAL_MAP); + + var marker = new GMarker(coordinates); + marker.bindInfoWindowHtml('

Hello, World!

'); + map.addOverlay(marker); + + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + map.addControl(new GLargeMapControl()); + } +}; diff --git a/chapter_03/listing_03_01.js b/chapter_03/listing_03_01.js new file mode 100644 index 0000000..4eff657 --- /dev/null +++ b/chapter_03/listing_03_01.js @@ -0,0 +1,27 @@ +var map; +var geoXml; + +function loadMap() +{ + var mapDiv = document.getElementById('map'); + + if (!GBrowserIsCompatible()) + { + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + } + else + { + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + var coordinates = new GLatLng(39.8, -98.5); + map.setCenter(coordinates, 4); + + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + geoXml = new GGeoXml('http://www.placeopedia.com/cgi-bin/kml.cgi'); + map.addOverlay(geoXml); + } +}; diff --git a/chapter_03/listing_03_02.js b/chapter_03/listing_03_02.js new file mode 100644 index 0000000..a2d5a88 --- /dev/null +++ b/chapter_03/listing_03_02.js @@ -0,0 +1,33 @@ +var map; +var geoXml; + +function loadMap() +{ + var mapDiv = document.getElementById('map'); + + if (!GBrowserIsCompatible()) + { + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + } + else + { + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + var coordinates = new GLatLng(39.8, -98.5); + map.setCenter(coordinates, 4); + + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + geoXml = new GGeoXml( + 'http://www.placeopedia.com/cgi-bin/rss.cgi?num_results=5', xmlLoaded); + map.addOverlay(geoXml); + } +}; + +function xmlLoaded() +{ + geoXml.gotoDefaultViewport(map); +}; \ No newline at end of file diff --git a/chapter_03/listing_03_03.js b/chapter_03/listing_03_03.js new file mode 100644 index 0000000..d3ec56c --- /dev/null +++ b/chapter_03/listing_03_03.js @@ -0,0 +1,33 @@ +var map; +var geoXml; + +function loadMap() +{ + var mapDiv = document.getElementById('map'); + + if (!GBrowserIsCompatible()) + { + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + } + else + { + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + var coordinates = new GLatLng(49.186416, -122.842911); + map.setCenter(coordinates, 15); + + var marker = new GMarker(coordinates); + marker.bindInfoWindowHtml('

Our Office

' + + '10100 E Whalley Ring Rd
Vancouver, BC
'); + map.addOverlay(marker); + GEvent.trigger(marker, 'click'); + + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + geoXml = new GGeoXml('http://bbs.keyhole.com/ubb/download.php?Number=921371'); + map.addOverlay(geoXml); + } +}; diff --git a/chapter_03/listing_03_04.css b/chapter_03/listing_03_04.css new file mode 100644 index 0000000..9803c8c --- /dev/null +++ b/chapter_03/listing_03_04.css @@ -0,0 +1,18 @@ +html { + height: 100%; +} + +body { + height: 100%; + margin: 0; +} + +#map { + width: 100%; + height: 100%; +} + +#map h3 { + margin: 0; +} + \ No newline at end of file diff --git a/chapter_04/delicate_arch.jpg b/chapter_04/delicate_arch.jpg new file mode 100644 index 0000000..d441b51 Binary files /dev/null and b/chapter_04/delicate_arch.jpg differ diff --git a/chapter_04/listing_04_01.html b/chapter_04/listing_04_01.html new file mode 100644 index 0000000..4266256 --- /dev/null +++ b/chapter_04/listing_04_01.html @@ -0,0 +1,19 @@ + + + + + Building Out Your Map Page + + + + + +
+ + + \ No newline at end of file diff --git a/chapter_04/listing_04_02.css b/chapter_04/listing_04_02.css new file mode 100644 index 0000000..b07cba6 --- /dev/null +++ b/chapter_04/listing_04_02.css @@ -0,0 +1,34 @@ +html { + height: 100%; +} + +body { + height: 100%; + margin: 0; + font-family: sans-serif; + font-size: 90%; +} + +#map { + width: 75%; + height: 100%; +} + +#sidebar { + position: absolute; + left: 75%; + top: 0; + right: 0; + bottom: 0; + overflow: auto; + padding: 1em; +} + +h1 { + margin: 0; + font-size: 220%; +} +h2 { + margin: 0; + font-size: 125%; +} diff --git a/chapter_04/listing_04_03.js b/chapter_04/listing_04_03.js new file mode 100644 index 0000000..4cdf0d5 --- /dev/null +++ b/chapter_04/listing_04_03.js @@ -0,0 +1,30 @@ +// Declare variables for later use +var map; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(38.661, -109.534); + map.setCenter(coordinates, 11, G_PHYSICAL_MAP); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + } +}; diff --git a/chapter_04/listing_04_04.js b/chapter_04/listing_04_04.js new file mode 100644 index 0000000..fa70e37 --- /dev/null +++ b/chapter_04/listing_04_04.js @@ -0,0 +1,55 @@ +// Declare variables for later use +var map; +var whiteIcon, blackIcon; +var entranceMarker, delicateArchMarker, windowsMarker; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(38.661, -109.534); + map.setCenter(coordinates, 11, G_PHYSICAL_MAP); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize a new icon, based on the GMaps default but in white + whiteIcon = new GIcon(G_DEFAULT_ICON); + whiteIcon.image = '../markers/white.png'; + + // Add a marker to the map for the park entrance, using the white icon + coordinates = new GLatLng(38.6168, -109.61986); + entranceMarker = new GMarker(coordinates, {icon: whiteIcon}); + map.addOverlay(entranceMarker); + + // Another new icon, also based on the GMaps default but this time in black + blackIcon = new GIcon(G_DEFAULT_ICON); + blackIcon.image = '../markers/black.png'; + + // Add two markers to the map for hiking trails, using the black icon + + coordinates = new GLatLng(38.73561, -109.52073); + delicateArchMarker = new GMarker(coordinates, {icon: blackIcon}); + map.addOverlay(delicateArchMarker); + + coordinates = new GLatLng(38.68725, -109.53712); + windowsMarker = new GMarker(coordinates, {icon: blackIcon}); + map.addOverlay(windowsMarker); + } +}; diff --git a/chapter_04/listing_04_05.html b/chapter_04/listing_04_05.html new file mode 100644 index 0000000..4cf95e2 --- /dev/null +++ b/chapter_04/listing_04_05.html @@ -0,0 +1,34 @@ + + + + + Building Out Your Map Page + + + + + +
+ + + \ No newline at end of file diff --git a/chapter_04/listing_04_06.css b/chapter_04/listing_04_06.css new file mode 100644 index 0000000..9232a98 --- /dev/null +++ b/chapter_04/listing_04_06.css @@ -0,0 +1,47 @@ +html { + height: 100%; +} + +body { + height: 100%; + margin: 0; + font-family: sans-serif; + font-size: 90%; +} + +#map { + width: 75%; + height: 100%; +} + +#sidebar { + position: absolute; + left: 75%; + top: 0; + right: 0; + bottom: 0; + overflow: auto; + padding: 1em; +} +#sidebar img { + vertical-align: middle; + border: none; +} + +h1 { + margin: 0; + font-size: 220%; +} +h2 { + margin: 0; + font-size: 125%; +} + +ul, li { + list-style: none; + padding: 0; + margin-top: 0; +} +li { + margin-top: 2px; +} diff --git a/chapter_04/listing_04_07.js b/chapter_04/listing_04_07.js new file mode 100644 index 0000000..ed0dd63 --- /dev/null +++ b/chapter_04/listing_04_07.js @@ -0,0 +1,62 @@ +// Declare variables for later use +var map; +var whiteIcon, blackIcon; +var entranceMarker, delicateArchMarker, windowsMarker; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(38.661, -109.534); + map.setCenter(coordinates, 11, G_PHYSICAL_MAP); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize a new icon, based on the GMaps default but in white + whiteIcon = new GIcon(G_DEFAULT_ICON); + whiteIcon.image = '../markers/white.png'; + + // Add a marker to the map for the park entrance, using the white icon + coordinates = new GLatLng(38.6168, -109.61986); + entranceMarker = new GMarker(coordinates, {icon: whiteIcon}); + map.addOverlay(entranceMarker); + GEvent.addListener(entranceMarker, 'click', entranceClick); + + // Another new icon, also based on the GMaps default but this time in black + blackIcon = new GIcon(G_DEFAULT_ICON); + blackIcon.image = '../markers/black.png'; + + // Add two markers to the map for hiking trails, using the black icon + + coordinates = new GLatLng(38.73561, -109.52073); + delicateArchMarker = new GMarker(coordinates, {icon: blackIcon}); + map.addOverlay(delicateArchMarker); + + coordinates = new GLatLng(38.68725, -109.53712); + windowsMarker = new GMarker(coordinates, {icon: blackIcon}); + map.addOverlay(windowsMarker); + } +}; + +function entranceClick() +{ + // entranceClick: Open a map detail infowindow showing the park entrance area + entranceMarker.showMapBlowup({mapType: G_NORMAL_MAP, zoomLevel: 14}); +}; diff --git a/chapter_04/listing_04_08.html b/chapter_04/listing_04_08.html new file mode 100644 index 0000000..158f44d --- /dev/null +++ b/chapter_04/listing_04_08.html @@ -0,0 +1,80 @@ + + + + + Building Out Your Map Page + + + + + +
+ + +
+
+

Delicate Arch trail

+
+
Distance
3 miles (4.8 km) round trip
+
Time
2 to 3 hours
+
Difficulty
Moderate
+
+

+ One of the classic hikes of any national park, this scramble across + exposed slickrock leads to an open sandstone bowl with stunning views of + the freestanding Delicate Arch and the La Sal Mountains beyond. + Especially fabulous at sunset! +

+

+ Carry at least 1 quart of water per person. Good balance is a plus as + much of the hike is on sloping sandstone. +

+
+
+

Delicate Arch at Sunset

+ Delicate Arch +
+ +
+

The Windows trail

+
+
Distance
1 mile (1.6 km) round trip
+
Time
½ to 1 hour
+
Difficulty
Easy
+
+

+ A fairly short, level walk that takes in several major arches, also + providing good views across the singular landscape of the park. The same + parking area gives access to the short trail to Double Arch. +

+

+ Suitable for all abilities. Initial section is wheelchair-accessible. +

+
+
+

North Window Arch

+ North Window +
+
+ + \ No newline at end of file diff --git a/chapter_04/listing_04_09.css b/chapter_04/listing_04_09.css new file mode 100644 index 0000000..e4c2887 --- /dev/null +++ b/chapter_04/listing_04_09.css @@ -0,0 +1,67 @@ +html { + height: 100%; +} + +body { + height: 100%; + margin: 0; + font-family: sans-serif; + font-size: 90%; +} + +#map { + width: 75%; + height: 100%; +} + +#sidebar { + position: absolute; + left: 75%; + top: 0; + right: 0; + bottom: 0; + overflow: auto; + padding: 1em; +} +#sidebar img { + vertical-align: middle; + border: none; +} + +h1 { + margin: 0; + font-size: 220%; +} +h2 { + margin: 0; + font-size: 125%; +} + +ul, li { + list-style: none; + padding: 0; + margin-top: 0; +} +li { + margin-top: 2px; +} + +#infowindow_content { + display: none; +} +.details_tab { + font-size: 80%; +} +h3 { + margin: 0; +} +dt { + width: 5em; + float: left; + clear: left; + font-weight: bold; + line-height: 1em; +} +dd { + line-height: 1em; +} diff --git a/chapter_04/listing_04_10.js b/chapter_04/listing_04_10.js new file mode 100644 index 0000000..fd82034 --- /dev/null +++ b/chapter_04/listing_04_10.js @@ -0,0 +1,76 @@ +// Declare variables for later use +var map; +var whiteIcon, blackIcon; +var entranceMarker, delicateArchMarker, windowsMarker; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(38.661, -109.534); + map.setCenter(coordinates, 11, G_PHYSICAL_MAP); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize a new icon, based on the GMaps default but in white + whiteIcon = new GIcon(G_DEFAULT_ICON); + whiteIcon.image = '../markers/white.png'; + + // Add a marker to the map for the park entrance, using the white icon + coordinates = new GLatLng(38.6168, -109.61986); + entranceMarker = new GMarker(coordinates, {icon: whiteIcon}); + map.addOverlay(entranceMarker); + GEvent.addListener(entranceMarker, 'click', entranceClick); + + // Another new icon, also based on the GMaps default but this time in black + blackIcon = new GIcon(G_DEFAULT_ICON); + blackIcon.image = '../markers/black.png'; + + // Create two infowindow tabs for Delicate Arch using content from the XHTML + var tabs = [new GInfoWindowTab('Details', + document.getElementById('delicate_tab_details')), + new GInfoWindowTab('Photo', + document.getElementById('delicate_tab_photo'))]; + + // Add a map marker for the Delicate Arch trail using the tabs and black icon + coordinates = new GLatLng(38.73561, -109.52073); + delicateArchMarker = new GMarker(coordinates, {icon: blackIcon}); + delicateArchMarker.bindInfoWindowTabs(tabs, {maxWidth: 300}); + map.addOverlay(delicateArchMarker); + + // Two more infowindow tabs, for the Windows trail... + tabs = [new GInfoWindowTab('Details', + document.getElementById('windows_tab_details')), + new GInfoWindowTab('Photo', + document.getElementById('windows_tab_photo'))]; + + // ...and a map marker for the Windows trail as well, again using the black icon + coordinates = new GLatLng(38.68725, -109.53712); + windowsMarker = new GMarker(coordinates, {icon: blackIcon}); + windowsMarker.bindInfoWindowTabs(tabs, {maxWidth: 300}); + map.addOverlay(windowsMarker); + } +}; + +function entranceClick() +{ + // entranceClick: Open a map detail infowindow showing the park entrance area + entranceMarker.showMapBlowup({mapType: G_NORMAL_MAP, zoomLevel: 14}); +}; diff --git a/chapter_04/listing_04_11.html b/chapter_04/listing_04_11.html new file mode 100644 index 0000000..a71141c --- /dev/null +++ b/chapter_04/listing_04_11.html @@ -0,0 +1,88 @@ + + + + + Building Out Your Map Page + + + + + +
+ + +
+
+

Delicate Arch trail

+
+
Distance
3 miles (4.8 km) round trip
+
Time
2 to 3 hours
+
Difficulty
Moderate
+
+

+ One of the classic hikes of any national park, this scramble across + exposed slickrock leads to an open sandstone bowl with stunning views of + the freestanding Delicate Arch and the La Sal Mountains beyond. + Especially fabulous at sunset! +

+

+ Carry at least 1 quart of water per person. Good balance is a plus as + much of the hike is on sloping sandstone. +

+
+
+

Delicate Arch at Sunset

+ Delicate Arch +
+ +
+

The Windows trail

+
+
Distance
1 mile (1.6 km) round trip
+
Time
½ to 1 hour
+
Difficulty
Easy
+
+

+ A fairly short, level walk that takes in several major arches, also + providing good views across the singular landscape of the park. The same + parking area gives access to the short trail to Double Arch. +

+

+ Suitable for all abilities. Initial section is wheelchair-accessible. +

+
+
+

North Window Arch

+ North Window +
+
+ + \ No newline at end of file diff --git a/chapter_04/listing_04_12.js b/chapter_04/listing_04_12.js new file mode 100644 index 0000000..20de9e9 --- /dev/null +++ b/chapter_04/listing_04_12.js @@ -0,0 +1,91 @@ +// Declare variables for later use +var map; +var whiteIcon, blackIcon; +var entranceMarker, delicateArchMarker, windowsMarker; +var geoXml; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(38.661, -109.534); + map.setCenter(coordinates, 11, G_PHYSICAL_MAP); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize a new icon, based on the GMaps default but in white + whiteIcon = new GIcon(G_DEFAULT_ICON); + whiteIcon.image = '../markers/white.png'; + + // Add a marker to the map for the park entrance, using the white icon + coordinates = new GLatLng(38.6168, -109.61986); + entranceMarker = new GMarker(coordinates, {icon: whiteIcon}); + map.addOverlay(entranceMarker); + GEvent.addListener(entranceMarker, 'click', entranceClick); + + // Another new icon, also based on the GMaps default but this time in black + blackIcon = new GIcon(G_DEFAULT_ICON); + blackIcon.image = '../markers/black.png'; + + // Create two infowindow tabs for Delicate Arch using content from the XHTML + var tabs = [new GInfoWindowTab('Details', + document.getElementById('delicate_tab_details')), + new GInfoWindowTab('Photo', + document.getElementById('delicate_tab_photo'))]; + + // Add a map marker for the Delicate Arch trail using the tabs and black icon + coordinates = new GLatLng(38.73561, -109.52073); + delicateArchMarker = new GMarker(coordinates, {icon: blackIcon}); + delicateArchMarker.bindInfoWindowTabs(tabs, {maxWidth: 300}); + map.addOverlay(delicateArchMarker); + + // Two more infowindow tabs, for the Windows trail... + tabs = [new GInfoWindowTab('Details', + document.getElementById('windows_tab_details')), + new GInfoWindowTab('Photo', + document.getElementById('windows_tab_photo'))]; + + // ...and a map marker for the Windows trail as well, again using the black icon + coordinates = new GLatLng(38.68725, -109.53712); + windowsMarker = new GMarker(coordinates, {icon: blackIcon}); + windowsMarker.bindInfoWindowTabs(tabs, {maxWidth: 300}); + map.addOverlay(windowsMarker); + + // Create a geodata overlay for nearby campgrounds and add it to the map + geoXml = new GGeoXml( + 'http://www.satellitefriendly.com/services/popular_network.kml'); + map.addOverlay(geoXml); + } +}; + +function entranceClick() +{ + // entranceClick: Open a map detail infowindow showing the park entrance area + entranceMarker.showMapBlowup({mapType: G_NORMAL_MAP, zoomLevel: 14}); +}; + +function toggleCampgrounds() +{ + // toggleCampgrounds: Turn the campground geodata overlay on or off + if (document.getElementById('show_campgrounds').checked) + geoXml.show(); + else + geoXml.hide(); +}; diff --git a/chapter_04/listing_04_13.html b/chapter_04/listing_04_13.html new file mode 100644 index 0000000..799872b --- /dev/null +++ b/chapter_04/listing_04_13.html @@ -0,0 +1,93 @@ + + + + + Building Out Your Map Page + + + + + +
+ + +
+
+

Delicate Arch trail

+
+
Distance
3 miles (4.8 km) round trip
+
Time
2 to 3 hours
+
Difficulty
Moderate
+
+

+ One of the classic hikes of any national park, this scramble across + exposed slickrock leads to an open sandstone bowl with stunning views of + the freestanding Delicate Arch and the La Sal Mountains beyond. + Especially fabulous at sunset! +

+

+ Carry at least 1 quart of water per person. Good balance is a plus as + much of the hike is on sloping sandstone. +

+
+
+

Delicate Arch at Sunset

+ Delicate Arch +
+ +
+

The Windows trail

+
+
Distance
1 mile (1.6 km) round trip
+
Time
½ to 1 hour
+
Difficulty
Easy
+
+

+ A fairly short, level walk that takes in several major arches, also + providing good views across the singular landscape of the park. The same + parking area gives access to the short trail to Double Arch. +

+

+ Suitable for all abilities. Initial section is wheelchair-accessible. +

+
+
+

North Window Arch

+ North Window +
+
+ + \ No newline at end of file diff --git a/chapter_04/listing_04_14.js b/chapter_04/listing_04_14.js new file mode 100644 index 0000000..a17bbd1 --- /dev/null +++ b/chapter_04/listing_04_14.js @@ -0,0 +1,93 @@ +// Declare variables for later use +var map; +var whiteIcon, blackIcon; +var entranceMarker, delicateArchMarker, windowsMarker; +var geoXml; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object, including the Google Earth maptype + map = new GMap2(mapDiv, {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, + G_HYBRID_MAP, G_PHYSICAL_MAP, G_SATELLITE_3D_MAP]}); + var coordinates = new GLatLng(38.661, -109.534); + map.setCenter(coordinates, 11, G_PHYSICAL_MAP); + + // Add the standard map controls, moving the scale control to the upper-right + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl(), + new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(6, 31))); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Also add a local search control to the map + map.enableGoogleBar(); + + // Initialize a new icon, based on the GMaps default but in white + whiteIcon = new GIcon(G_DEFAULT_ICON); + whiteIcon.image = '../markers/white.png'; + + // Add a marker to the map for the park entrance, using the white icon + coordinates = new GLatLng(38.6168, -109.61986); + entranceMarker = new GMarker(coordinates, {icon: whiteIcon}); + map.addOverlay(entranceMarker); + GEvent.addListener(entranceMarker, 'click', entranceClick); + + // Another new icon, also based on the GMaps default but this time in black + blackIcon = new GIcon(G_DEFAULT_ICON); + blackIcon.image = '../markers/black.png'; + + // Create two infowindow tabs for Delicate Arch using content from the XHTML + var tabs = [new GInfoWindowTab('Details', + document.getElementById('delicate_tab_details')), + new GInfoWindowTab('Photo', + document.getElementById('delicate_tab_photo'))]; + + // Add a map marker for the Delicate Arch trail using the tabs and black icon + coordinates = new GLatLng(38.73561, -109.52073); + delicateArchMarker = new GMarker(coordinates, {icon: blackIcon}); + delicateArchMarker.bindInfoWindowTabs(tabs, {maxWidth: 300}); + map.addOverlay(delicateArchMarker); + + // Two more infowindow tabs, for the Windows trail... + tabs = [new GInfoWindowTab('Details', + document.getElementById('windows_tab_details')), + new GInfoWindowTab('Photo', + document.getElementById('windows_tab_photo'))]; + + // ...and a map marker for the Windows trail as well, again using the black icon + coordinates = new GLatLng(38.68725, -109.53712); + windowsMarker = new GMarker(coordinates, {icon: blackIcon}); + windowsMarker.bindInfoWindowTabs(tabs, {maxWidth: 300}); + map.addOverlay(windowsMarker); + + // Create a geodata overlay for nearby campgrounds and add it to the map + geoXml = new GGeoXml( + 'http://www.satellitefriendly.com/services/popular_network.kml'); + map.addOverlay(geoXml); + } +}; + +function entranceClick() +{ + // entranceClick: Open a map detail infowindow showing the park entrance area + entranceMarker.showMapBlowup({mapType: G_NORMAL_MAP, zoomLevel: 14}); +}; + +function toggleCampgrounds() +{ + // toggleCampgrounds: Turn the campground geodata overlay on or off + if (document.getElementById('show_campgrounds').checked) + geoXml.show(); + else + geoXml.hide(); +}; diff --git a/chapter_04/window_arch.jpg b/chapter_04/window_arch.jpg new file mode 100644 index 0000000..c85e0ff Binary files /dev/null and b/chapter_04/window_arch.jpg differ diff --git a/chapter_05/listing_05_01.html b/chapter_05/listing_05_01.html new file mode 100644 index 0000000..813cc5e --- /dev/null +++ b/chapter_05/listing_05_01.html @@ -0,0 +1,23 @@ + + + + + Your Map and the Real World + + + + + +
+ + + \ No newline at end of file diff --git a/chapter_05/listing_05_02.js b/chapter_05/listing_05_02.js new file mode 100644 index 0000000..e9015ca --- /dev/null +++ b/chapter_05/listing_05_02.js @@ -0,0 +1,50 @@ +// Declare variables for later use +var map; +var geocoder; +var startMarker; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(37.75, -122.44); + map.setCenter(coordinates, 12); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize the geocoder object and tie it to the current map view + geocoder = new GClientGeocoder(); + geocoder.setViewport(map.getBounds()); + } +}; + +function geocode() +{ + // geocode: Call the Google geocoder with the address supplied by the user + var address = document.getElementById('start').value; + geocoder.getLatLng(address, afterGeocode); +}; + +function afterGeocode(coordinates) +{ + // afterGeocode: Callback function for the geocoder, showing the coords on the map + startMarker = new GMarker(coordinates); + map.addOverlay(startMarker); +}; diff --git a/chapter_05/listing_05_03.js b/chapter_05/listing_05_03.js new file mode 100644 index 0000000..1951b92 --- /dev/null +++ b/chapter_05/listing_05_03.js @@ -0,0 +1,68 @@ +// Declare variables for later use +var map; +var geocoder; +var startMarker; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(37.75, -122.44); + map.setCenter(coordinates, 12); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize the geocoder object and tie it to the current map view + geocoder = new GClientGeocoder(); + geocoder.setViewport(map.getBounds()); + } +}; + +function geocode() +{ + // geocode: Call the Google geocoder with the address supplied by the user + var address = document.getElementById('start').value; + geocoder.getLatLng(address, afterGeocode); +}; + +function afterGeocode(coordinates) +{ + // afterGeocode: Callback function for the geocoder, showing the coords on the map + if (coordinates == null) + alert('Address not found. Please try again.'); + else if (!map.getBounds().contains(coordinates)) + alert('Address not found in map area. Please try again.'); + else + { + // Address was found + if (startMarker == null) + { + // This is the first time we've geocoded an address, so create the marker + startMarker = new GMarker(coordinates); + map.addOverlay(startMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + startMarker.setPoint(coordinates); + } + } +}; + diff --git a/chapter_05/listing_05_04.html b/chapter_05/listing_05_04.html new file mode 100644 index 0000000..3099288 --- /dev/null +++ b/chapter_05/listing_05_04.html @@ -0,0 +1,34 @@ + + + + + Your Map and the Real World + + + + + +
+ + + \ No newline at end of file diff --git a/chapter_05/listing_05_05.js b/chapter_05/listing_05_05.js new file mode 100644 index 0000000..6b8b4dd --- /dev/null +++ b/chapter_05/listing_05_05.js @@ -0,0 +1,98 @@ +// Declare variables for later use +var map; +var geocoder; +var startMarker; +var finishMarker; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(37.75, -122.44); + map.setCenter(coordinates, 12); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize the geocoder object and tie it to the current map view + geocoder = new GClientGeocoder(); + geocoder.setViewport(map.getBounds()); + } +}; + +function geocode() +{ + // geocode: Call the Google geocoder with the address supplied by the user + var address = document.getElementById('start').value; + geocoder.getLatLng(address, afterGeocode); +}; + +function afterGeocode(coordinates) +{ + // afterGeocode: Callback function for the geocoder, showing the coords on the map + if (coordinates == null) + alert('Address not found. Please try again.'); + else if (!map.getBounds().contains(coordinates)) + alert('Address not found in map area. Please try again.'); + else + { + // Address was found + if (startMarker == null) + { + // This is the first time we've geocoded an address, so create the marker + startMarker = new GMarker(coordinates); + map.addOverlay(startMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + startMarker.setPoint(coordinates); + } + } +}; + +function destinationChange() +{ + // destinationChange: Update destination marker from the drop-down list + + // Extract the new destination from the drop-down + var finish = document.getElementById('finish'); + var value = finish.options[finish.selectedIndex].value; + if (value != '') + { + // Valid destination: create a coordinates object from it + var coordinates = eval('new GLatLng(' + value + ')'); + + if (finishMarker == null) + { + // This is the first time the user has selected a destination + finishMarker = new GMarker(coordinates); + map.addOverlay(finishMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + finishMarker.setPoint(coordinates); + } + + // Ensure that the destination point is visible on the map + if (!map.getBounds().contains(coordinates)) + map.panTo(coordinates); + } +}; diff --git a/chapter_05/listing_05_06.html b/chapter_05/listing_05_06.html new file mode 100644 index 0000000..da1e09f --- /dev/null +++ b/chapter_05/listing_05_06.html @@ -0,0 +1,36 @@ + + + + + Your Map and the Real World + + + + + +
+ + + \ No newline at end of file diff --git a/chapter_05/listing_05_07.js b/chapter_05/listing_05_07.js new file mode 100644 index 0000000..469277c --- /dev/null +++ b/chapter_05/listing_05_07.js @@ -0,0 +1,120 @@ +// Declare variables for later use +var map; +var geocoder; +var startMarker; +var finishMarker; +var directions; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(37.75, -122.44); + map.setCenter(coordinates, 12); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize the geocoder object and tie it to the current map view + geocoder = new GClientGeocoder(); + geocoder.setViewport(map.getBounds()); + + // Initialize the driving directions object + var panel = document.getElementById('directions'); + directions = new GDirections(map, panel); + } +}; + +function geocode() +{ + // geocode: Call the Google geocoder with the address supplied by the user + var address = document.getElementById('start').value; + geocoder.getLatLng(address, afterGeocode); +}; + +function afterGeocode(coordinates) +{ + // afterGeocode: Callback function for the geocoder, showing the coords on the map + if (coordinates == null) + alert('Address not found. Please try again.'); + else if (!map.getBounds().contains(coordinates)) + alert('Address not found in map area. Please try again.'); + else + { + // Address was found + if (startMarker == null) + { + // This is the first time we've geocoded an address, so create the marker + startMarker = new GMarker(coordinates); + map.addOverlay(startMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + startMarker.setPoint(coordinates); + } + } +}; + +function destinationChange() +{ + // destinationChange: Update destination marker from the drop-down list + + // Extract the new destination from the drop-down + var finish = document.getElementById('finish'); + var value = finish.options[finish.selectedIndex].value; + if (value != '') + { + // Valid destination: create a coordinates object from it + var coordinates = eval('new GLatLng(' + value + ')'); + + if (finishMarker == null) + { + // This is the first time the user has selected a destination + finishMarker = new GMarker(coordinates); + map.addOverlay(finishMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + finishMarker.setPoint(coordinates); + } + + // Ensure that the destination point is visible on the map + if (!map.getBounds().contains(coordinates)) + map.panTo(coordinates); + } +}; + +function getDirections() +{ + // getDirections: Request driving directions from start to destination + + if ((startMarker == null) || (finishMarker == null)) + alert('Please select a starting address and destination for directions.'); + else + { + // Collect the start and finish points as 'lat,lon' strings + var waypoints = [startMarker.getPoint().toUrlValue(), + finishMarker.getPoint().toUrlValue()]; + + // Load driving directions for those points + directions.loadFromWaypoints(waypoints); + } +}; diff --git a/chapter_05/listing_05_08.html b/chapter_05/listing_05_08.html new file mode 100644 index 0000000..df07f93 --- /dev/null +++ b/chapter_05/listing_05_08.html @@ -0,0 +1,41 @@ + + + + + Your Map and the Real World + + + + + +
+ + + \ No newline at end of file diff --git a/chapter_05/listing_05_09.js b/chapter_05/listing_05_09.js new file mode 100644 index 0000000..dfcc4c2 --- /dev/null +++ b/chapter_05/listing_05_09.js @@ -0,0 +1,134 @@ +// Declare variables for later use +var map; +var geocoder; +var startMarker; +var finishMarker; +var directions; +var traffic; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(37.75, -122.44); + map.setCenter(coordinates, 12); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize the geocoder object and tie it to the current map view + geocoder = new GClientGeocoder(); + geocoder.setViewport(map.getBounds()); + + // Initialize the driving directions object + var panel = document.getElementById('directions'); + directions = new GDirections(map, panel); + + // Initialize the traffic object + traffic = new GTrafficOverlay(); + map.addOverlay(traffic); + } +}; + +function geocode() +{ + // geocode: Call the Google geocoder with the address supplied by the user + var address = document.getElementById('start').value; + geocoder.getLatLng(address, afterGeocode); +}; + +function afterGeocode(coordinates) +{ + // afterGeocode: Callback function for the geocoder, showing the coords on the map + if (coordinates == null) + alert('Address not found. Please try again.'); + else if (!map.getBounds().contains(coordinates)) + alert('Address not found in map area. Please try again.'); + else + { + // Address was found + if (startMarker == null) + { + // This is the first time we've geocoded an address, so create the marker + startMarker = new GMarker(coordinates); + map.addOverlay(startMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + startMarker.setPoint(coordinates); + } + } +}; + +function destinationChange() +{ + // destinationChange: Update destination marker from the drop-down list + + // Extract the new destination from the drop-down + var finish = document.getElementById('finish'); + var value = finish.options[finish.selectedIndex].value; + if (value != '') + { + // Valid destination: create a coordinates object from it + var coordinates = eval('new GLatLng(' + value + ')'); + + if (finishMarker == null) + { + // This is the first time the user has selected a destination + finishMarker = new GMarker(coordinates); + map.addOverlay(finishMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + finishMarker.setPoint(coordinates); + } + + // Ensure that the destination point is visible on the map + if (!map.getBounds().contains(coordinates)) + map.panTo(coordinates); + } +}; + +function getDirections() +{ + // getDirections: Request driving directions from start to destination + + if ((startMarker == null) || (finishMarker == null)) + alert('Please select a starting address and destination for directions.'); + else + { + // Collect the start and finish points as 'lat,lon' strings + var waypoints = [startMarker.getPoint().toUrlValue(), + finishMarker.getPoint().toUrlValue()]; + + // Load driving directions for those points + directions.loadFromWaypoints(waypoints); + } +}; + +function toggleTraffic() +{ + // toggleTraffic: Turn the traffic overlay on or off + if (document.getElementById('show_traffic').checked) + traffic.show(); + else + traffic.hide(); +}; diff --git a/chapter_05/listing_05_10.html b/chapter_05/listing_05_10.html new file mode 100644 index 0000000..1f4d556 --- /dev/null +++ b/chapter_05/listing_05_10.html @@ -0,0 +1,42 @@ + + + + + Your Map and the Real World + + + + + +
+ + + \ No newline at end of file diff --git a/chapter_05/listing_05_11.js b/chapter_05/listing_05_11.js new file mode 100644 index 0000000..b5d9745 --- /dev/null +++ b/chapter_05/listing_05_11.js @@ -0,0 +1,152 @@ +// Declare variables for later use +var map; +var geocoder; +var startMarker; +var finishMarker; +var directions; +var traffic; +var streetviewClient; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(37.75, -122.44); + map.setCenter(coordinates, 12); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize the geocoder object and tie it to the current map view + geocoder = new GClientGeocoder(); + geocoder.setViewport(map.getBounds()); + + // Initialize the driving directions object + var panel = document.getElementById('directions'); + directions = new GDirections(map, panel); + + // Initialize the traffic object + traffic = new GTrafficOverlay(); + map.addOverlay(traffic); + + // Initialize the Street View controller object + streetviewClient = new GStreetviewClient(); + } +}; + +function geocode() +{ + // geocode: Call the Google geocoder with the address supplied by the user + var address = document.getElementById('start').value; + geocoder.getLatLng(address, afterGeocode); +}; + +function afterGeocode(coordinates) +{ + // afterGeocode: Callback function for the geocoder, showing the coords on the map + if (coordinates == null) + alert('Address not found. Please try again.'); + else if (!map.getBounds().contains(coordinates)) + alert('Address not found in map area. Please try again.'); + else + { + // Address was found + if (startMarker == null) + { + // This is the first time we've geocoded an address, so create the marker + startMarker = new GMarker(coordinates); + map.addOverlay(startMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + startMarker.setPoint(coordinates); + } + } +}; + +function destinationChange() +{ + // destinationChange: Update destination marker from the drop-down list + + // Extract the new destination from the drop-down + var finish = document.getElementById('finish'); + var value = finish.options[finish.selectedIndex].value; + if (value != '') + { + // Valid destination: create a coordinates object from it + var coordinates = eval('new GLatLng(' + value + ')'); + + if (finishMarker == null) + { + // This is the first time the user has selected a destination + finishMarker = new GMarker(coordinates); + map.addOverlay(finishMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + finishMarker.setPoint(coordinates); + } + + // Ensure that the destination point is visible on the map + if (!map.getBounds().contains(coordinates)) + map.panTo(coordinates); + } +}; + +function getDirections() +{ + // getDirections: Request driving directions from start to destination + + if ((startMarker == null) || (finishMarker == null)) + alert('Please select a starting address and destination for directions.'); + else + { + // Collect the start and finish points as 'lat,lon' strings + var waypoints = [startMarker.getPoint().toUrlValue(), + finishMarker.getPoint().toUrlValue()]; + + // Load driving directions for those points + directions.loadFromWaypoints(waypoints); + } +}; + +function toggleTraffic() +{ + // toggleTraffic: Turn the traffic overlay on or off + if (document.getElementById('show_traffic').checked) + traffic.show(); + else + traffic.hide(); +}; + +function getView() +{ + // getView: Retrieve a Street View panorama for the selected destination + + if (finishMarker == null) + alert('Please select a destination.'); + else + { + // Retrieve the Street View panorama for the coordinates of the marker + var coordinates = finishMarker.getPoint(); + streetviewClient.getNearestPanorama(coordinates, afterView); + } +}; diff --git a/chapter_05/listing_05_12.js b/chapter_05/listing_05_12.js new file mode 100644 index 0000000..abdcfc4 --- /dev/null +++ b/chapter_05/listing_05_12.js @@ -0,0 +1,177 @@ +// Declare variables for later use +var map; +var geocoder; +var startMarker; +var finishMarker; +var directions; +var traffic; +var streetviewClient; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(37.75, -122.44); + map.setCenter(coordinates, 12); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize the geocoder object and tie it to the current map view + geocoder = new GClientGeocoder(); + geocoder.setViewport(map.getBounds()); + + // Initialize the driving directions object + var panel = document.getElementById('directions'); + directions = new GDirections(map, panel); + + // Initialize the traffic object + traffic = new GTrafficOverlay(); + map.addOverlay(traffic); + + // Initialize the Street View controller object + streetviewClient = new GStreetviewClient(); + } +}; + +function geocode() +{ + // geocode: Call the Google geocoder with the address supplied by the user + var address = document.getElementById('start').value; + geocoder.getLatLng(address, afterGeocode); +}; + +function afterGeocode(coordinates) +{ + // afterGeocode: Callback function for the geocoder, showing the coords on the map + if (coordinates == null) + alert('Address not found. Please try again.'); + else if (!map.getBounds().contains(coordinates)) + alert('Address not found in map area. Please try again.'); + else + { + // Address was found + if (startMarker == null) + { + // This is the first time we've geocoded an address, so create the marker + startMarker = new GMarker(coordinates); + map.addOverlay(startMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + startMarker.setPoint(coordinates); + } + } +}; + +function destinationChange() +{ + // destinationChange: Update destination marker from the drop-down list + + // Extract the new destination from the drop-down + var finish = document.getElementById('finish'); + var value = finish.options[finish.selectedIndex].value; + if (value != '') + { + // Valid destination: create a coordinates object from it + var coordinates = eval('new GLatLng(' + value + ')'); + + if (finishMarker == null) + { + // This is the first time the user has selected a destination + finishMarker = new GMarker(coordinates); + map.addOverlay(finishMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + finishMarker.setPoint(coordinates); + } + + // Ensure that the destination point is visible on the map + if (!map.getBounds().contains(coordinates)) + map.panTo(coordinates); + } +}; + +function getDirections() +{ + // getDirections: Request driving directions from start to destination + + if ((startMarker == null) || (finishMarker == null)) + alert('Please select a starting address and destination for directions.'); + else + { + // Collect the start and finish points as 'lat,lon' strings + var waypoints = [startMarker.getPoint().toUrlValue(), + finishMarker.getPoint().toUrlValue()]; + + // Load driving directions for those points + directions.loadFromWaypoints(waypoints); + } +}; + +function toggleTraffic() +{ + // toggleTraffic: Turn the traffic overlay on or off + if (document.getElementById('show_traffic').checked) + traffic.show(); + else + traffic.hide(); +}; + +function getView() +{ + // getView: Retrieve a Street View panorama for the selected destination + + if (finishMarker == null) + alert('Please select a destination.'); + else + { + // Retrieve the Street View panorama for the coordinates of the marker + var coordinates = finishMarker.getPoint(); + streetviewClient.getNearestPanorama(coordinates, afterView); + } +}; + +function afterView(streetviewData) +{ + // afterView: Callback function for Street View panorama retrieval + + if (streetviewData.code == G_GEO_SUCCESS) + { + // Create a DHTML element to contain the panorama + var streetViewer = document.createElement('div'); + + // Create the Street View panorama object + var panorama = new GStreetviewPanorama(streetViewer); + + // Extract the precise lat/lon coordinates from the Street View data object + var coordinates = new GLatLng(streetviewData.location.lat, + streetviewData.location.lng); + + // Tell the panorama object to display view for those coordinates + panorama.setLocationAndPOV(coordinates, streetviewData.location.pov); + + // Open an infowindow with the panorama container element + streetViewer.className = 'streetViewer'; + finishMarker.openInfoWindow(streetViewer); + } +}; diff --git a/chapter_05/listing_05_13.css b/chapter_05/listing_05_13.css new file mode 100644 index 0000000..ee76947 --- /dev/null +++ b/chapter_05/listing_05_13.css @@ -0,0 +1,39 @@ +html { + height: 100%; +} + +body { + height: 100%; + margin: 0; + font-family: sans-serif; + font-size: 90%; +} + +#map { + width: 74%; + height: 100%; +} + +#sidebar { + position: absolute; + left: 74%; + top: 0; + right: 0; + bottom: 0; + overflow: auto; + padding: 1em; +} + +h1 { + margin: 0; + font-size: 220%; +} +h2 { + margin: 0; + font-size: 125%; +} + +.streetViewer { + width: 350px; + height: 250px; +} diff --git a/chapter_05/listing_05_14.js b/chapter_05/listing_05_14.js new file mode 100644 index 0000000..b273d22 --- /dev/null +++ b/chapter_05/listing_05_14.js @@ -0,0 +1,182 @@ +// Declare variables for later use +var map; +var geocoder; +var startMarker; +var finishMarker; +var directions; +var traffic; +var streetviewClient; +var ads; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport, based on center coordinates and zoom level + var coordinates = new GLatLng(37.75, -122.44); + map.setCenter(coordinates, 12); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize the geocoder object and tie it to the current map view + geocoder = new GClientGeocoder(); + geocoder.setViewport(map.getBounds()); + + // Initialize the driving directions object + var panel = document.getElementById('directions'); + directions = new GDirections(map, panel); + + // Initialize the traffic object + traffic = new GTrafficOverlay(); + map.addOverlay(traffic); + + // Initialize the Street View controller object + streetviewClient = new GStreetviewClient(); + + // Initialize the map advertising object + ads = new GAdsManager(map, 'google', {maxAdsOnMap: 10}); + ads.enable(); + } +}; + +function geocode() +{ + // geocode: Call the Google geocoder with the address supplied by the user + var address = document.getElementById('start').value; + geocoder.getLatLng(address, afterGeocode); +}; + +function afterGeocode(coordinates) +{ + // afterGeocode: Callback function for the geocoder, showing the coords on the map + if (coordinates == null) + alert('Address not found. Please try again.'); + else if (!map.getBounds().contains(coordinates)) + alert('Address not found in map area. Please try again.'); + else + { + // Address was found + if (startMarker == null) + { + // This is the first time we've geocoded an address, so create the marker + startMarker = new GMarker(coordinates); + map.addOverlay(startMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + startMarker.setPoint(coordinates); + } + } +}; + +function destinationChange() +{ + // destinationChange: Update destination marker from the drop-down list + + // Extract the new destination from the drop-down + var finish = document.getElementById('finish'); + var value = finish.options[finish.selectedIndex].value; + if (value != '') + { + // Valid destination: create a coordinates object from it + var coordinates = eval('new GLatLng(' + value + ')'); + + if (finishMarker == null) + { + // This is the first time the user has selected a destination + finishMarker = new GMarker(coordinates); + map.addOverlay(finishMarker); + } + else + { + // The marker already exists, just move it to the new coordinates + finishMarker.setPoint(coordinates); + } + + // Ensure that the destination point is visible on the map + if (!map.getBounds().contains(coordinates)) + map.panTo(coordinates); + } +}; + +function getDirections() +{ + // getDirections: Request driving directions from start to destination + + if ((startMarker == null) || (finishMarker == null)) + alert('Please select a starting address and destination for directions.'); + else + { + // Collect the start and finish points as 'lat,lon' strings + var waypoints = [startMarker.getPoint().toUrlValue(), + finishMarker.getPoint().toUrlValue()]; + + // Load driving directions for those points + directions.loadFromWaypoints(waypoints); + } +}; + +function toggleTraffic() +{ + // toggleTraffic: Turn the traffic overlay on or off + if (document.getElementById('show_traffic').checked) + traffic.show(); + else + traffic.hide(); +}; + +function getView() +{ + // getView: Retrieve a Street View panorama for the selected destination + + if (finishMarker == null) + alert('Please select a destination.'); + else + { + // Retrieve the Street View panorama for the coordinates of the marker + var coordinates = finishMarker.getPoint(); + streetviewClient.getNearestPanorama(coordinates, afterView); + } +}; + +function afterView(streetviewData) +{ + // afterView: Callback function for Street View panorama retrieval + + if (streetviewData.code == G_GEO_SUCCESS) + { + // Create a DHTML element to contain the panorama + var streetViewer = document.createElement('div'); + + // Create the Street View panorama object + var panorama = new GStreetviewPanorama(streetViewer); + + // Extract the precise lat/lon coordinates from the Street View data object + var coordinates = new GLatLng(streetviewData.location.lat, + streetviewData.location.lng); + + // Tell the panorama object to display view for those coordinates + panorama.setLocationAndPOV(coordinates, streetviewData.location.pov); + + // Open an infowindow with the panorama container element + streetViewer.className = 'streetViewer'; + finishMarker.openInfoWindow(streetViewer); + } +}; diff --git a/chapter_07/listing_07_01.xml b/chapter_07/listing_07_01.xml new file mode 100644 index 0000000..fdf4c58 --- /dev/null +++ b/chapter_07/listing_07_01.xml @@ -0,0 +1,28 @@ + + + + + + + h1 { + font-size: 120%; + } + + +

New York City

+

Hello, World!

+ + + ]]>
+
\ No newline at end of file diff --git a/chapter_07/listing_07_02.xml b/chapter_07/listing_07_02.xml new file mode 100644 index 0000000..aa556c8 --- /dev/null +++ b/chapter_07/listing_07_02.xml @@ -0,0 +1,36 @@ + + + + + + + + p { + font-size: 90%; + } + + +

+ The latest 50 Wikipedia entries with locations, from + placeopedia.com. +

+ + + ]]>
+
\ No newline at end of file diff --git a/chapter_07/screenshot.png b/chapter_07/screenshot.png new file mode 100644 index 0000000..4cc072c Binary files /dev/null and b/chapter_07/screenshot.png differ diff --git a/chapter_07/thumbnail.png b/chapter_07/thumbnail.png new file mode 100644 index 0000000..19ada37 Binary files /dev/null and b/chapter_07/thumbnail.png differ diff --git a/chapter_08/center_scr.png b/chapter_08/center_scr.png new file mode 100644 index 0000000..05f6216 Binary files /dev/null and b/chapter_08/center_scr.png differ diff --git a/chapter_08/center_thm.png b/chapter_08/center_thm.png new file mode 100644 index 0000000..a2015da Binary files /dev/null and b/chapter_08/center_thm.png differ diff --git a/chapter_08/geoname_scr.png b/chapter_08/geoname_scr.png new file mode 100644 index 0000000..242485c Binary files /dev/null and b/chapter_08/geoname_scr.png differ diff --git a/chapter_08/geoname_thm.png b/chapter_08/geoname_thm.png new file mode 100644 index 0000000..bd42fea Binary files /dev/null and b/chapter_08/geoname_thm.png differ diff --git a/chapter_08/listing_08_01.xml b/chapter_08/listing_08_01.xml new file mode 100644 index 0000000..2401ee7 --- /dev/null +++ b/chapter_08/listing_08_01.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + p { + font-size: 90%; + } + + +

+ The latest Wikipedia entries with locations, from + placeopedia.com. +

+ + + +

This mapplet is an example from the book:

+ + ]]>
+
\ No newline at end of file diff --git a/chapter_08/listing_08_02.js b/chapter_08/listing_08_02.js new file mode 100644 index 0000000..855ca61 --- /dev/null +++ b/chapter_08/listing_08_02.js @@ -0,0 +1,22 @@ +var timeout; +var clickCoords; + +function mapClick(overlay, coordinates) +{ + if (overlay != null) + // Click wasn't on "empty" map space, so don't go any further + return; + + if (timeout == null) + { + // The first click we've had recently => start a timeout for the lookup + clickCoords = coordinates; + timeout = setTimeout('placeMarker()', 500); + } + else + { + // Second click means it's a double-click, so cancel the lookup timeout + clearTimeout(timeout) + timeout = null; + } +}; \ No newline at end of file diff --git a/chapter_08/listing_08_03.js b/chapter_08/listing_08_03.js new file mode 100644 index 0000000..784f01b --- /dev/null +++ b/chapter_08/listing_08_03.js @@ -0,0 +1,15 @@ +function placeMarker() +{ + if (marker == null) + { + // Marker doesn't exist yet, so create it now + marker = new GMarker(clickCoords); + map.addOverlay(marker); + } + else + // Move the marker to the new coordinates + marker.setPoint(clickCoords); + + // Prepare for the next click + timeout = null; +}; diff --git a/chapter_08/listing_08_04.js b/chapter_08/listing_08_04.js new file mode 100644 index 0000000..fbeaf0d --- /dev/null +++ b/chapter_08/listing_08_04.js @@ -0,0 +1,20 @@ +function placeMarker() +{ + if (marker == null) + { + // Marker doesn't exist yet, so create it now + marker = new GMarker(clickCoords); + map.addOverlay(marker); + } + else + // Move the marker to the new coordinates + marker.setPoint(clickCoords); + + // Build and retrieve the placename lookup URL from the clicked coordinates + var url = 'http://ws.geonames.org/findNearbyPlaceNameJSON?lat=' + + clickCoords.lat() + '&lng=' + clickCoords.lng(); + _IG_FetchContent(url, afterGeoname); + + // Prepare for the next click + timeout = null; +}; diff --git a/chapter_08/listing_08_05.js b/chapter_08/listing_08_05.js new file mode 100644 index 0000000..17270bd --- /dev/null +++ b/chapter_08/listing_08_05.js @@ -0,0 +1,23 @@ +function afterGeoname(responseText) +{ + // Evaluate the JSON response to extract the data from it + var responseData = json_parse(responseText); + + if (responseData.geonames.length == 0) + { + // No place name found; let the user know with a simple message + var content = 'No nearby place name found.'; + } + else + { + // Place name found succesfully; build it into an infowindow + var place = responseData.geonames[0]; + var miles = parseFloat(place.distance) / 1.61; + var content = miles.toFixed(2) + ' miles from ' + place.name + ',
' + + place.adminName1 + ', ' + place.countryName; + } + + // Attach the infowindow content to the marker, and also show it now + marker.openInfoWindow(content); + marker.bindInfoWindow(content); +}; diff --git a/chapter_08/listing_08_06.xml b/chapter_08/listing_08_06.xml new file mode 100644 index 0000000..bfc6a35 --- /dev/null +++ b/chapter_08/listing_08_06.xml @@ -0,0 +1,131 @@ + + + + + + + + p { + font-size: 90%; + } + + +

+ Click anywhere on the map to get the name of the nearest populated place. + Lookup services provided by GeoNames.org. +

+ + + + +

This mapplet is an example from the book:

+ + ]]>
+
diff --git a/chapter_08/listing_08_07.js b/chapter_08/listing_08_07.js new file mode 100644 index 0000000..c8fad3c --- /dev/null +++ b/chapter_08/listing_08_07.js @@ -0,0 +1,26 @@ +// Declare variables for later use +var moving = false; +var lastCenter = new GLatLng(90, 0); + +// Initialize the map +var map = new GMap2(); + +// Create the center "crosshair" overlay +var crosshair = new GScreenOverlay( + 'http://sterlingudell.com/bgmm/markers/crosshair.png', // image URL + new GScreenPoint(0.5, 0.5, 'fraction', 'fraction'), // screen offset + new GScreenPoint(11, 12, 'pixel', 'pixel'), // overlay offset + new GScreenSize(24, 24, 'pixel', 'pixel') // overlay size +); +map.addOverlay(crosshair); + +// Attach several events to be called when the map moves +GEvent.addListener(map, 'movestart', mapMoveStart); +GEvent.addListener(map, 'moveend', mapMoveEnd); +GEvent.addListener(map, 'zoomend', mapZoomEnd); + +// Initialize the center display +map.getCenterAsync(afterGetCenter); + +// Adjust the height of the sidebar display +_IG_AdjustIFrameHeight(); diff --git a/chapter_08/listing_08_08.js b/chapter_08/listing_08_08.js new file mode 100644 index 0000000..5119160 --- /dev/null +++ b/chapter_08/listing_08_08.js @@ -0,0 +1,15 @@ +function mapMoveStart() +{ + moving = true; + map.getCenterAsync(afterGetCenter); +}; + +function mapMoveEnd() +{ + moving = false; +}; + +function mapZoomEnd() +{ + map.getCenterAsync(afterGetCenter); +}; diff --git a/chapter_08/listing_08_09.js b/chapter_08/listing_08_09.js new file mode 100644 index 0000000..90fc556 --- /dev/null +++ b/chapter_08/listing_08_09.js @@ -0,0 +1,41 @@ +function afterGetCenter(coordinates) +{ + if (!coordinates.equals(lastCenter)) + { + // Map has moved since the last time we checked + + // Save the new coordinates, so we can tell next time if it's moved + lastCenter = coordinates; + + // Reformat the map center latitude as a more readable string + + var latitude = Math.abs(coordinates.lat()); + latitude = latitude.toFixed(5); + latitude = latitude + '? '; + + if (coordinates.lat() > 0) + latitude = latitude + 'N'; + else if (coordinates.lat() < 0) + latitude = latitude + 'S'; + + // Ditto for longitude + + var longitude = Math.abs(coordinates.lng()); + longitude = longitude.toFixed(5); + longitude = longitude + '? '; + + if (coordinates.lng() > 0) + longitude = longitude + 'E'; + else if (coordinates.lng() < 0) + longitude = longitude + 'W'; + + var centerDisplay = 'Map center: ' + latitude + ', ' + longitude; + + // Set the mapplet's title to include the formatted center coordinates + _IG_SetTitle(centerDisplay); + } + + if (moving) + // Map is still moving, so carry on updating the center display + map.getCenterAsync(afterGetCenter); +}; diff --git a/chapter_08/listing_08_10.xml b/chapter_08/listing_08_10.xml new file mode 100644 index 0000000..4271684 --- /dev/null +++ b/chapter_08/listing_08_10.xml @@ -0,0 +1,112 @@ + + + + + + + + + function mapMoveStart() + { + // mapMoveStart: event handler to initiate the recentering process + moving = true; + map.getCenterAsync(afterGetCenter); + }; + + function mapMoveEnd() + { + // mapMoveEnd: event handler to stop recentering when map stops moving + moving = false; + }; + + function mapZoomEnd() + { + // mapZoomEnd: also trigger the recentering code when the map is zoomed + map.getCenterAsync(afterGetCenter); + }; + + function afterGetCenter(coordinates) + { + // afterGetCenter: callback to update title with current map center coords + + if (coordinates.toUrlValue() != lastCenter.toUrlValue()) + { + // Map has moved since the last time we checked + + // Save the new coordinates, so we can tell next time if it's moved + lastCenter = coordinates; + + // Reformat the map center latitude as a more readable string + + var latitude = Math.abs(coordinates.lat()); + latitude = latitude.toFixed(5); + latitude = latitude + '� '; + + if (coordinates.lat() > 0) + latitude = latitude + 'N'; + else if (coordinates.lat() < 0) + latitude = latitude + 'S'; + + // Ditto for longitude + + var longitude = Math.abs(coordinates.lng()); + longitude = longitude.toFixed(5); + longitude = longitude + '� '; + + if (coordinates.lng() > 0) + longitude = longitude + 'E'; + else if (coordinates.lng() < 0) + longitude = longitude + 'W'; + + var centerDisplay = 'Map center: ' + latitude + ', ' + longitude; + + // Set the mapplet's title to include the formatted center coordinates + _IG_SetTitle(centerDisplay); + } + + if (moving) + // Map is still moving, so carry on updating the center display + map.getCenterAsync(afterGetCenter); + }; + + // END FUNCTION DECLARATIONS - BEGIN MAIN MAPPLET CODE + + // Declare variables for later use + var moving = false; + var lastCenter = new GLatLng(90, 0); + var timeout; + + // Initialize the map + var map = new GMap2(); + + // Create the center "crosshair" overlay + var crosshair = new GScreenOverlay( + 'http://sterlingudell.com/bgmm/markers/crosshair.png', // image URL + new GScreenPoint(0.5, 0.5, 'fraction', 'fraction'), // screen offset + new GScreenPoint(11, 12, 'pixel', 'pixel'), // overlay offset + new GScreenSize(24, 24, 'pixel', 'pixel') // overlay size + ); + map.addOverlay(crosshair); + + // Attach several events to be called when the map moves + GEvent.addListener(map, 'movestart', mapMoveStart); + GEvent.addListener(map, 'moveend', mapMoveEnd); + GEvent.addListener(map, 'zoomend', mapZoomEnd); + + // Initialize the center display + map.getCenterAsync(afterGetCenter); + + // Adjust the height of the sidebar display + _IG_AdjustIFrameHeight(); + + +

This mapplet is an example from the book:

+ + ]]>
+
\ No newline at end of file diff --git a/chapter_09/brewery_scr.png b/chapter_09/brewery_scr.png new file mode 100644 index 0000000..192b706 Binary files /dev/null and b/chapter_09/brewery_scr.png differ diff --git a/chapter_09/brewery_thm.png b/chapter_09/brewery_thm.png new file mode 100644 index 0000000..37f40e6 Binary files /dev/null and b/chapter_09/brewery_thm.png differ diff --git a/chapter_09/listing_09_01.js b/chapter_09/listing_09_01.js new file mode 100644 index 0000000..054381b --- /dev/null +++ b/chapter_09/listing_09_01.js @@ -0,0 +1,7 @@ +var myIcon = new GIcon(G_DEFAULT_ICON); +myIcon.image = 'http://sterlingudell.com/bgmm/markers/music.png'; +myIcon.iconSize = new GSize(25, 40); +myIcon.iconAnchor = new GPoint(12, 40); +myIcon.infoWindowAnchor = new GPoint(12, 1); +myIcon.shadow = 'http://sterlingudell.com/bgmm/markers/shadow.png'; +myIcon.shadowSize = new GSize(41, 40); diff --git a/chapter_09/listing_09_02.html b/chapter_09/listing_09_02.html new file mode 100644 index 0000000..04980ff --- /dev/null +++ b/chapter_09/listing_09_02.html @@ -0,0 +1,35 @@ + + + + + Geocoding Revisted + + + + + + +
+

+ Find Your Location +

+
+

+ + +

+

+ +

+

+ + + +

+
+ + diff --git a/chapter_09/listing_09_03.css b/chapter_09/listing_09_03.css new file mode 100644 index 0000000..3da2b34 --- /dev/null +++ b/chapter_09/listing_09_03.css @@ -0,0 +1,17 @@ +label { + float: left; + width: 5em; +} + +p { + clear: left; +} + +#map { + float: right; + width: 400px; + height: 400px; + border: 1px solid; + overflow: none; +} + diff --git a/chapter_09/listing_09_04.js b/chapter_09/listing_09_04.js new file mode 100644 index 0000000..7838c6a --- /dev/null +++ b/chapter_09/listing_09_04.js @@ -0,0 +1,30 @@ +function afterGeocode(coordinates) +{ + if (coordinates == null) + alert('Address not found. Please try again.'); + else + { + // Address was found + if (marker == null) + { + // This is the first time we've geocoded an address, so create the marker + var iconOptions = {width: 24, height: 24, primaryColor: "#fffc1b"}; + var myIcon = MapIconMaker.createMarkerIcon(iconOptions); + marker = new GMarker(coordinates, {icon: myIcon, draggable: true}); + map.addOverlay(marker); + + GEvent.addListener(marker, 'dragend', markerDragEnd); + GEvent.addListener(marker, 'dragstart', markerDragStart); + } + else + { + // The marker already exists, just move it to the new coordinates + marker.setPoint(coordinates); + } + + map.setCenter(coordinates, 14); + + marker.openInfoWindowHtml('Drag marker to exact location, then click Save.'); + updatesaveCoordinates(); + } +}; diff --git a/chapter_09/listing_09_05.js b/chapter_09/listing_09_05.js new file mode 100644 index 0000000..1492c37 --- /dev/null +++ b/chapter_09/listing_09_05.js @@ -0,0 +1,13 @@ +function markerDragStart() +{ + map.closeInfoWindow(); +}; + +function markerDragEnd() +{ + saveCoordinates(); + + var content = 'Zoom in' + + ' if needed to place marker
exactly, or click Save when done.'; + marker.openInfoWindow(content); +}; diff --git a/chapter_09/listing_09_06.js b/chapter_09/listing_09_06.js new file mode 100644 index 0000000..9c8cf60 --- /dev/null +++ b/chapter_09/listing_09_06.js @@ -0,0 +1,100 @@ +// Declare variables for later use +var map; +var geocoder; +var marker; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport + var coordinates = new GLatLng(39.8, -98.5); + map.setCenter(coordinates, 3, G_HYBRID_MAP); + + // Add the standard map controls + map.addControl(new GSmallMapControl()); + map.addControl(new GScaleControl(), + new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(6, 18))); + map.addControl(new GMapTypeControl(true)); + + // Initialize the geocoder object + geocoder = new GClientGeocoder(); + } +}; + +function geocode() +{ + // geocode: Call the Google geocoder with the address supplied by the user + var address = document.getElementById('address').value; + geocoder.getLatLng(address, afterGeocode); +}; + +function afterGeocode(coordinates) +{ + // afterGeocode: Callback function for the geocoder, showing the coords on the map + if (coordinates == null) + alert('Address not found. Please try again.'); + else + { + // Address was found + if (marker == null) + { + // This is the first time we've geocoded an address, so create the marker + var iconOptions = {width: 24, height: 24, primaryColor: "#fffc1b"}; + var myIcon = MapIconMaker.createMarkerIcon(iconOptions); + marker = new GMarker(coordinates, {icon: myIcon, draggable: true}); + map.addOverlay(marker); + + GEvent.addListener(marker, 'dragend', markerDragEnd); + GEvent.addListener(marker, 'dragstart', markerDragStart); + } + else + { + // The marker already exists, just move it to the new coordinates + marker.setPoint(coordinates); + } + + map.setCenter(coordinates, 14); + + marker.openInfoWindowHtml('Drag marker to exact location, then click Save.'); + saveCoordinates(); + } +}; + +function markerDragStart() +{ + // markerDragStart: Close the infowindow when the marker is being dragged + map.closeInfoWindow(); +}; + +function markerDragEnd() +{ + // markerDragEnd: Update the form coordinates and show more instructions + + saveCoordinates(); + + var content = 'Zoom in' + + ' if needed to place marker
exactly, or click Save when done.'; + marker.openInfoWindow(content); +}; + +function saveCoordinates() +{ + // saveCoordinates: Copy the current marker coordinates into the form fields + var coordinates = marker.getPoint(); + document.getElementById('latitude').value = coordinates.lat().toFixed(6); + document.getElementById('longitude').value = coordinates.lng().toFixed(6); +}; + diff --git a/chapter_09/listing_09_07.html b/chapter_09/listing_09_07.html new file mode 100644 index 0000000..0cf3385 --- /dev/null +++ b/chapter_09/listing_09_07.html @@ -0,0 +1,20 @@ + + + + + US State Capitals + + + + + + +
+ + + diff --git a/chapter_09/listing_09_08.js b/chapter_09/listing_09_08.js new file mode 100644 index 0000000..feed136 --- /dev/null +++ b/chapter_09/listing_09_08.js @@ -0,0 +1,47 @@ +// Declare variables for later use +var map; +var geoXml; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport + var coordinates = new GLatLng(39.8, -98.5); + map.setCenter(coordinates, 4); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize a custom marker icon + var starIcon = new GIcon(); + starIcon.image = '../markers/star.png'; + starIcon.iconSize = new GSize(17, 17); + starIcon.iconAnchor = new GPoint(8, 8); + starIcon.infoWindowAnchor = new GPoint(12, 4); + + // Initialize the KML processor + var url = 'state_capitals.kml'; + var options = {sidebarid: 'list', + markeroptions: {icon: starIcon}}; + geoXml = new EGeoXml(map, url, options); + + // Load the KML + geoXml.parse(); + } +}; diff --git a/chapter_09/listing_09_09.xml b/chapter_09/listing_09_09.xml new file mode 100644 index 0000000..8ec6d17 --- /dev/null +++ b/chapter_09/listing_09_09.xml @@ -0,0 +1,59 @@ + + + + + + + + p { + font-size: 90%; + } + + +

+ + + + +

This mapplet is an example from the book:

+ + ]]>
+
\ No newline at end of file diff --git a/chapter_09/listing_09_10.html b/chapter_09/listing_09_10.html new file mode 100644 index 0000000..1fdec17 --- /dev/null +++ b/chapter_09/listing_09_10.html @@ -0,0 +1,21 @@ + + + + + British Breweries + + + + + + + +
+ + + diff --git a/chapter_09/listing_09_11.css b/chapter_09/listing_09_11.css new file mode 100644 index 0000000..2cf39d6 --- /dev/null +++ b/chapter_09/listing_09_11.css @@ -0,0 +1,38 @@ +html { + height: 100%; +} + +body { + height: 100%; + margin: 0; + font-family: sans-serif; + font-size: 90%; +} + +#map { + width: 70%; + height: 100%; +} + +#sidebar { + position: absolute; + left: 70%; + top: 0; + right: 0; + bottom: 0; + overflow: auto; + padding: 1em; +} + +h1 { + margin: 0; + font-size: 100%; +} + +ul { + padding-left: 1em; +} +li { + padding-left: 0em; +} + diff --git a/chapter_09/listing_09_12.js b/chapter_09/listing_09_12.js new file mode 100644 index 0000000..a0ffa67 --- /dev/null +++ b/chapter_09/listing_09_12.js @@ -0,0 +1,60 @@ +// Declare variables for later use +var map; +var geoXml; +var data = new Array(); +var markers = new Array(); + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport + var coordinates = new GLatLng(53.6, -4.3); + map.setCenter(coordinates, 6); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize the KML processor + var url = 'uk_breweries.kml'; + var options = {sidebarid: 'list', createmarker: addDataPoint, nozoom: true}; + geoXml = new EGeoXml(map, url, options); + + // Attach an event handler for after the KML is processed + GEvent.addListener(geoXml, 'parsed', xmlParsed); + + // Load the KML + geoXml.parse(); + + // Attach an event to refresh the marker display whenever the map moves + GEvent.addListener(map, 'moveend', mapMoveEnd); + } +}; + +function addDataPoint(coordinates, name, description) +{ + // addDataPoint: save the data for a placemark found by the KML processor + var d = data.length; + data[d] = {coords: coordinates, title: name, details: description}; +}; + +function xmlParsed() +{ + // xmlParsed: after KML processing, initialize the marker display + mapMoveEnd(); +}; \ No newline at end of file diff --git a/chapter_09/listing_09_13.js b/chapter_09/listing_09_13.js new file mode 100644 index 0000000..d1e8b60 --- /dev/null +++ b/chapter_09/listing_09_13.js @@ -0,0 +1,156 @@ +// Declare variables for later use +var map; +var geoXml; +var data = new Array(); +var markers = new Array(); +var clicked; +var current; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport + var coordinates = new GLatLng(53.6, -4.3); + map.setCenter(coordinates, 6); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize the KML processor + var url = 'uk_breweries.kml'; + var options = {createmarker: addDataPoint, nozoom: true}; + geoXml = new EGeoXml(map, url, options); + + // Attach an event handler for after the KML is processed + GEvent.addListener(geoXml, 'parsed', xmlParsed); + + // Load the KML + geoXml.parse(); + + // Attach an event to refresh the marker display whenever the map moves + GEvent.addListener(map, 'moveend', mapMoveEnd); + GEvent.addListener(map, 'infowindowopen', mapInfoWindowOpen); + GEvent.addListener(map, 'infowindowclose', mapInfoWindowClose); + } +}; + +function addDataPoint(coordinates, name, description) +{ + // addDataPoint: save the data for a placemark found by the KML processor + var d = data.length; + data[d] = {coords: coordinates, title: name, details: description}; +}; + +function xmlParsed() +{ + // xmlParsed: after KML processing, initialize the marker display + mapMoveEnd(); +}; + +function mapMoveEnd() +{ + // mapMoveEnd: refresh the marker display after the map has moved + + // Get the map boundary coordinates + var mapBounds = map.getBounds(); + + // Don't refresh if the currently-selected marker is still in view + if (current != null) + { + if (mapBounds.contains(current)) + return; + else + map.closeInfoWindow(); + } + + // Prepare to build new sidebar content by starting with a clean slate + var sidebarContent = ''; + + // Remove previous set of markers from the map and the array + for (var m = markers.length - 1; m >= 0; m--) + { + map.removeOverlay(markers[m]); + markers.splice(m, 1); + } + + // Create a base icon + var numberIcon = new GIcon(G_DEFAULT_ICON); + + // Look for data in the new map area + for (var d = 0; d < data.length; d++) + { + if (mapBounds.contains(data[d].coords)) + { + // Map does contain this data point; create a marker and add it to the map + m = markers.length; + numberIcon.image = + 'http://gmaps-samples.googlecode.com/svn/trunk/markers/orange/marker' + + (m + 1) + '.png'; + markers[m] = new GMarker(data[d].coords, {icon: numberIcon}); + markers[m].data = data[d]; + map.addOverlay(markers[m]); + + // Also attach an event handler to show infowindow when marker is clicked + GEvent.addListener(markers[m], 'click', + new Function('showDetail(' + m + ')')); + + // Create sidebar content for this data point, including click event handler + sidebarContent = sidebarContent + + '
  • ' + + data[d].title + '
  • '; + + if (m >= 19) + { + // We've reached 20 markers, so break out of the loop + sidebarContent = sidebarContent + + '
  • zoom in for more...
  • '; + break; + } + } + } + + if (markers.length == 0) + // No data points found in map boundaries + sidebarContent = '
  • No results found in map area. ' + + 'Try zooming out or moving the map.
  • '; + + // Move the new content into the sidebar + document.getElementById('list').innerHTML = sidebarContent; +}; + +function showDetail(m) +{ + // showDetail: open the infowindow for the given map marker + current = clicked = markers[m].data.coords; + markers[m].openInfoWindow( + '

    ' + markers[m].data.title + '

    ' + + '

    ' + markers[m].data.details + '

    '); +}; + +function mapInfoWindowOpen() +{ + // mapInfoWindowOpen: set the variable that keeps track of the selected coords + current = clicked; +}; + +function mapInfoWindowClose() +{ + // mapInfoWindowClose: clear the variable that keeps track of the selected coords + current = null; +}; diff --git a/chapter_09/listing_09_14.xml b/chapter_09/listing_09_14.xml new file mode 100644 index 0000000..16bc68b --- /dev/null +++ b/chapter_09/listing_09_14.xml @@ -0,0 +1,54 @@ + + + + + + + + ul { + font-size: 90%; + padding-left: 1em; + } + li { + padding-left: 0em; + } + + +
      + + + + + +

      This mapplet is an example from the book:

      + + ]]>
      +
      \ No newline at end of file diff --git a/chapter_09/listing_09_15.js b/chapter_09/listing_09_15.js new file mode 100644 index 0000000..1bb381f --- /dev/null +++ b/chapter_09/listing_09_15.js @@ -0,0 +1,159 @@ +// Declare variables for later use +var map; +var geoXml; +var data = new Array(); +var markers = new Array(); +var clicked; +var current; + +function loadMap() +{ + // loadMap: initialize the API and load the map onto the page + + // Get the map container div + var mapDiv = document.getElementById('map'); + + // Confirm browser compatibility with the Maps API + if (!GBrowserIsCompatible()) + mapDiv.innerHTML = 'Sorry, your browser isn\'t compatible with Google Maps.'; + else + { + // Initialize the core map object + map = new GMap2(mapDiv, + {mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}); + + // Set the starting map viewport + var coordinates = new GLatLng(53.6, -4.3); + map.setCenter(coordinates, 6); + + // Add the standard map controls + map.addControl(new GLargeMapControl()); + map.addControl(new GScaleControl()); + map.addControl(new GOverviewMapControl()); + map.addControl(new GMapTypeControl()); + + // Initialize the KML processor + var url = 'uk_breweries.kml'; + var options = {createmarker: addDataPoint, nozoom: true}; + geoXml = new EGeoXml(map, url, options); + + // Attach an event handler for after the KML is processed + GEvent.addListener(geoXml, 'parsed', xmlParsed); + + // Load the KML + geoXml.parse(); + + // Attach an event to refresh the marker display whenever the map moves + GEvent.addListener(map, 'moveend', mapMoveEnd); + GEvent.addListener(map, 'infowindowopen', mapInfoWindowOpen); + GEvent.addListener(map, 'infowindowclose', mapInfoWindowClose); + } +}; + +function addDataPoint(coordinates, name, description) +{ + // addDataPoint: save the data for a placemark found by the KML processor + var d = data.length; + data[d] = {coords: coordinates, title: name, details: description}; +}; + +function xmlParsed() +{ + // xmlParsed: after KML processing, initialize the marker display + mapMoveEnd(); +}; + +function mapMoveEnd() +{ + // mapMoveEnd: get the new map boundary coordinates for use in marker display + GAsync(map, 'getBounds', afterGetBounds); +}; + +function afterGetBounds(mapBounds) +{ + // afterGetBounds: refresh the marker display + + // Don't refresh if the currently-selected marker is still in view + if (current != null) + { + if (mapBounds.contains(current)) + return; + else + map.closeInfoWindow(); + } + + // Prepare to build new sidebar content by starting with a clean slate + var sidebarContent = ''; + + // Remove previous set of markers from the map and the array + for (var m = markers.length - 1; m >= 0; m--) + { + map.removeOverlay(markers[m]); + markers.splice(m, 1); + } + + // Create a base icon + var numberIcon = new GIcon(G_DEFAULT_ICON); + + // Look for data in the new map area + for (var d = 0; d < data.length; d++) + { + if (mapBounds.contains(data[d].coords)) + { + // Map does contain this data point; create a marker and add it to the map + m = markers.length; + numberIcon.image = + 'http://gmaps-samples.googlecode.com/svn/trunk/markers/orange/marker' + + (m + 1) + '.png'; + markers[m] = new GMarker(data[d].coords, {icon: numberIcon}); + markers[m].data = data[d]; + map.addOverlay(markers[m]); + + // Also attach an event handler to show infowindow when marker is clicked + GEvent.addListener(markers[m], 'click', + new Function('showDetail(' + m + ')')); + + // Create sidebar content for this data point, including click event handler + sidebarContent = sidebarContent + + '
    1. ' + + data[d].title + '
    2. '; + + if (m >= 19) + { + // We've reached 20 markers, so break out of the loop + sidebarContent = sidebarContent + + '
    3. zoom in for more...
    4. '; + break; + } + } + } + + if (markers.length == 0) + // No data points found in map boundaries + sidebarContent = '
    5. No results found in map area. ' + + 'Try zooming out or moving the map.
    6. '; + + // Move the new content into the sidebar + document.getElementById('list').innerHTML = sidebarContent; +}; + +function showDetail(m) +{ + // showDetail: open the infowindow for the given map marker + current = clicked = markers[m].data.coords; + markers[m].openInfoWindow( + '

      ' + markers[m].data.title + '

      ' + + '

      ' + markers[m].data.details + '

      '); +}; + +function mapInfoWindowOpen() +{ + // mapInfoWindowOpen: set the variable that keeps track of the selected coords + current = clicked; +}; + +function mapInfoWindowClose() +{ + // mapInfoWindowClose: clear the variable that keeps track of the selected coords + current = null; +}; diff --git a/chapter_09/state_capitals.kml b/chapter_09/state_capitals.kml new file mode 100644 index 0000000..edabd17 --- /dev/null +++ b/chapter_09/state_capitals.kml @@ -0,0 +1,357 @@ + + + + US State Capitals + + + Alabama + + + -86.300568,32.377716,0.000000 + + + + Alaska + + + -134.420212,58.301598,0.000000 + + + + Arizona + + + -112.096962,33.448143,0.000000 + + + + Arkansas + + + -92.288986,34.746613,0.000000 + + + + California + + + -121.493629,38.576668,0.000000 + + + + Colorado + + + -104.984856,39.739227,0.000000 + + + + Connecticut + ]]> + + -72.682198,41.764046,0.000000 + + + + Delaware + + + -75.519722,39.157307,0.000000 + + + + Hawaii + + + -157.857376,21.307442,0.000000 + + + + Florida + + + -84.281296,30.438118,0.000000 + + + + Georgia + ]]> + + -84.388229,33.749027,0.000000 + + + + Idaho + + + -116.199722,43.617775,0.000000 + + + + Illinois + + + -89.654961,39.798363,0.000000 + + + + Indiana + + + -86.162643,39.768623,0.000000 + + + + Iowa + + + -93.603729,41.591087,0.000000 + + + + Kansas + + + -95.677956,39.048191,0.000000 + + + + Kentucky + + + -84.875374,38.186722,0.000000 + + + + Louisiana + + + -91.187393,30.457069,0.000000 + + + + Maine + + + -69.781693,44.307167,0.000000 + + + + Maryland + + + -76.490936,38.978764,0.000000 + + + + Massachusetts + + + -71.063698,42.358162,0.000000 + + + + Michigan + + + -84.555328,42.733635,0.000000 + + + + Minnesota + + + -93.102211,44.955097,0.000000 + + + + Mississippi + + + -90.182106,32.303848,0.000000 + + + + Missouri + + + -92.172935,38.579201,0.000000 + + + + Montana + + + -112.018417,46.585709,0.000000 + + + + Nebraska + + + -96.699654,40.808075,0.000000 + + + + Nevada + + + -119.766121,39.163914,0.000000 + + + + New Hampshire + + + -71.537994,43.206898,0.000000 + + + + New Jersey + + + -74.769913,40.220596,0.000000 + + + + New Mexico + + + -105.939728,35.682240,0.000000 + + + + North Carolina + + + -78.639099,35.780430,0.000000 + + + + North Dakota + + + -100.783318,46.820850,0.000000 + + + + New York + + + -73.757874,42.652843,0.000000 + + + + Ohio + + + -82.999069,39.961346,0.000000 + + + + Oklahoma + + + -97.503342,35.492207,0.000000 + + + + Oregon + + + -123.030403,44.938461,0.000000 + + + + Pennsylvania + + + -76.883598,40.264378,0.000000 + + + + Rhode Island + + + -71.414963,41.830914,0.000000 + + + + South Carolina + + + -81.033211,34.000343,0.000000 + + + + South Dakota + + + -100.346405,44.367031,0.000000 + + + + Tennessee + + + -86.784241,36.165810,0.000000 + + + + Texas + + + -97.740349,30.274670,0.000000 + + + + Utah + + + -111.888237,40.777477,0.000000 + + + + Vermont + + + -72.580536,44.262436,0.000000 + + + + Virginia + + + -77.433640,37.538857,0.000000 + + + + Washington + + + -122.905014,47.035805,0.000000 + + + + West Virginia + + + -81.612328,38.336246,0.000000 + + + + Wisconsin + + + -89.384445,43.074684,0.000000 + + + + Wyoming + + + -104.820236,41.140259,0.000000 + + + + diff --git a/chapter_09/state_scr.png b/chapter_09/state_scr.png new file mode 100644 index 0000000..c42bc22 Binary files /dev/null and b/chapter_09/state_scr.png differ diff --git a/chapter_09/state_thm.png b/chapter_09/state_thm.png new file mode 100644 index 0000000..8287912 Binary files /dev/null and b/chapter_09/state_thm.png differ diff --git a/chapter_09/uk_breweries.kml b/chapter_09/uk_breweries.kml new file mode 100644 index 0000000..24ac413 --- /dev/null +++ b/chapter_09/uk_breweries.kml @@ -0,0 +1,7336 @@ + + + + uk_breweries.kml + + + + + + + United Kingdom + + Avon + + Bristol Beer Factory + Bristol, Avon + +Southville
      +Bristol
      +Avon
      +United Kingdom
      +(0117) 902 6317
      +[Email]
      +www.bristolbeerfactory.co.uk/
      +
      ]]>
      + #6 + + -2.612473,51.442732,0 + +
      +
      + + Bedford + + Charles Wells Ltd. + Bedford, Bedford + +Bedford
      +Bedford
      +United Kingdom
      +(01234) 272766
      +[Email]
      +www.charleswells.co.uk/
      +
      ]]>
      + #6 + + -0.481493,52.13206,0 + +
      + + Whitbread Beer Company + Luton, Bedford + +Capability Green
      +Luton
      +Bedford
      +United Kingdom
      +(01582) 391166
      +[Email]
      +www.whitbread.co.uk/
      +
      ]]>
      + #4 + + -0.417558,51.879652,0 + +
      + + Old Stables Brewing Company + Sandy, Bedford + +Sandy
      +Bedford
      +United Kingdom
      +(01767) 692151
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -0.286154,52.127847,0 + +
      + + Potton Brewery + Sandy, Bedford + +Potton
      +Sandy
      +Bedford
      +United Kingdom
      +(01767) 261042
      +[Email]
      +www.potton-brewery.co.uk/
      +
      ]]>
      + #6 + + -0.21938,52.12906,0 + +
      + + B & T Brewery + Shefford, Bedford + +Bedford
      +United Kingdom
      +(01462) 815080
      ]]>
      + #4 + + -0.332827,52.038585,0 + +
      +
      + + Berkshire + + West Berkshire Brewery + Frilsham, Berkshire + +Frilsham
      +Berkshire
      +United Kingdom
      +(01635) 202638
      +[Email]
      +www.wbbrew.co.uk/
      +
      ]]>
      + #4 + + -1.216626,51.454605,0 + +
      + + Butts Brewery Ltd. + Hungerford, Berkshire + +Great Shefford
      +Hungerford
      +Berkshire
      +United Kingdom
      +01488 648133
      ]]>
      + #4 + + -1.515729,51.414637,0 + +
      +
      + + Buckingham + + Chiltern Brewery + Aylesbury, Buckingham + +Terrick
      +Aylesbury
      +Buckingham
      +United Kingdom
      +(01296) 613647
      +[Email]
      +www.chilternbrewery.co.uk/
      +
      ]]>
      + #6 + + -0.799338,51.759307,0 + +
      + + Stag and Griffin Brewery + Gerrards Cross, Buckingham + +Tatling End
      +Gerrards Cross
      +Buckingham
      +United Kingdom
      +(01753) 883100
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -0.561138,51.585427,0 + +
      + + Vale Brewery Company + Haddenham, Buckingham + +Haddenham
      +Buckingham
      +United Kingdom
      +(01844) 290008
      +[Email]
      +www.valebrewery.co.uk/
      +
      ]]>
      + #6 + + -0.9463140000000001,51.76941200000001,0 + +
      + + Rebellion Beer Company + Marlow Bottom, Buckingham + +Bencombe Farm
      +Marlow Bottom
      +Buckingham
      +United Kingdom
      +(01628) 476617
      +[Email]
      +www.rebellionbeer.co.uk/
      +
      +Bar/Tasting RoomMerchandiseBeer to Go / Off-LicenseTours]]>
      + #4 + + -0.7879509999999999,51.58762600000001,0 + +
      +
      + + Cambridge + + City of Cambridge Brewery + Chittering, Cambridge + +Chittering
      +Cambridge
      +United Kingdom
      +(01223) 864864
      +[Email]
      +www.cambridge-brewery.co.uk/
      +
      ]]>
      + #6 + + 0.182013,52.29606299999999,0 + +
      + + Fenland Brewery + Ely, Cambridge + +Little Downham
      +Ely
      +Cambridge
      +United Kingdom
      +(01353) 699966
      +[Email]
      +www.elybeer.co.uk/
      +
      ]]>
      + #4 + + 0.259786,52.399449,0 + +
      + + Milton Brewery, Cambridge Ltd. + Milton, Cambridge + +Cambridge Road
      +Milton
      +Cambridge
      +United Kingdom
      +(01223) 226198
      +[Email]
      +www.miltonbrewery.co.uk/
      +
      ]]>
      + #4 + + 0.161516,52.243454,0 + +
      + + Oakham Ales + Peterborough, Cambridge + +Peterborough
      +Cambridge
      +United Kingdom
      +(01733) 358300
      +[Email]
      ]]>
      + #8 + + -0.248,52.575761,0 + +
      + + Elgood & Sons + Wisbech, Cambridge + +Cambridge
      +United Kingdom
      +(01945) 583160
      +[Email]
      +www.elgoods-brewery.co.uk/
      +
      +Bar/Tasting RoomBeer GardenRestaurantMerchandiseBeer to Go / Off-LicenseTours]]>
      + #4 + + 0.159401,52.666216,0 + +
      +
      + + Cheshire + + Beartown Brewery + Congleton, Cheshire + +Congleton
      +Cheshire
      +United Kingdom
      +(01260) 299964
      +[Email]
      +www.beartownbrewery.co.uk/
      +
      ]]>
      + #6 + + -2.205051,53.16384599999999,0 + +
      + + Paradise Brewery + Nantwich, Cheshire + +Wrenbury
      +Nantwich
      +Cheshire
      +United Kingdom
      +(01270) 780916
      +[Email]
      ]]>
      + #4 + + -2.520013,53.06426800000001,0 + +
      + + Frederic Robinson Ltd. + Stockport, Cheshire + +Lower Hillgate
      +Stockport
      +Cheshire
      +United Kingdom
      +(0161) 480 6571
      +[Email]
      +www.frederic-robinson.com/
      +
      ]]>
      + #4 + + -2.149293,53.408488,0 + +
      + + Weetwood Ales Ltd. + Tarporley, Cheshire + +Weetwood
      +Tarporley
      +Cheshire
      +United Kingdom
      +(01829) 752377
      +[Email]
      +www.weetwoodales.co.uk/
      +
      ]]>
      + #4 + + -2.667582,53.157554,0 + +
      + + Burtonwood Brewery + Warrington, Cheshire + +Burtonwood
      +Warrington
      +Cheshire
      +United Kingdom
      +(01925) 225131
      +[Email]
      +www.burtonwood.co.uk/
      +
      ]]>
      + #4 + + -2.586989,53.39263,0 + +
      + + Coach House Brewing + Warrington, Cheshire + +Cheshire
      +United Kingdom
      +[Email]
      +www.beer.u-net.com/
      +
      ]]>
      + #4 + + -2.586989,53.39263,0 + +
      +
      + + Cleveland + + Camerons Brewery Company + Hartlepool, Cleveland + +Hartlepool
      +Cleveland
      +United Kingdom
      +(01429) 266 666
      +[Email]
      +www.cameronsbrewery.com/
      +www.castleedenbrewery.com/
      +
      ]]>
      + #8 + + -1.212733,54.681636,0 + +
      +
      + + Cornwall + + Wheal Ale Brewery + Hayle, Cornwall + +Trelissick Road
      +Hayle
      +Cornwall
      +United Kingdom
      +(01736) 753974
      ]]>
      + #4 + + -5.420574,50.18810299999999,0 + +
      + + Blue Anchor + Helston, Cornwall + +Helston
      +Cornwall
      +United Kingdom
      +(01326) 562821
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -5.276998,50.100501,0 + +
      + + Lizard Ales + Helston, Cornwall + +St Keverne
      +Helston
      +Cornwall
      +United Kingdom
      +(01326) 281135
      +[Email]
      +www.lizardales.co.uk/
      +
      ]]>
      + #4 + + -5.272275,50.107364,0 + +
      + + Organic Brewhouse + Helston, Cornwall + +Cury Cross Lanes
      +Helston
      +Cornwall
      +United Kingdom
      +01326 241555
      ]]>
      + #5 + + -5.220135,50.040851,0 + +
      + + Ales Of Scilly + Isles of Scilly, Cornwall + +St Mary's
      +Isles of Scilly
      +Cornwall
      +United Kingdom
      +(01720) 422419
      +[Email]
      ]]>
      + #4 + + -6.303396,49.930712,0 + +
      + + Ring O Bells + Launceston, Cornwall + +Pennygillam Way
      +Launceston
      +Cornwall
      +United Kingdom
      +(01566) 77787
      ]]>
      + #4 + + -4.37529,50.627853,0 + +
      + + Blackawton Brewery + Saltash, Cornwall + +Moorlands Trading Estate
      +Saltash
      +Cornwall
      +United Kingdom
      +(01752) 848777
      +[Email]
      +www.blackawtonbrewery.com/
      +
      ]]>
      + #4 + + -4.212217,50.40872499999999,0 + +
      + + Driftwood Brewery + St Agnes, Cornwall + +Trevaunance Cove
      +St Agnes
      +Cornwall
      +United Kingdom
      +(01872) 552428
      +[Email]
      +www.driftwoodspars.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -5.20214,50.315215,0 + +
      + + St Austell Brewery + St Austell, Cornwall + +St Austell
      +Cornwall
      +United Kingdom
      +(01726) 7444
      +[Email]
      +www.staustellbrewery.co.uk/
      +
      ]]>
      + #6 + + -4.789178,50.341365,0 + +
      + + Skinner's Brewery + Truro, Cornwall + +Newham
      +Truro
      +Cornwall
      +United Kingdom
      +(01872) 271885
      +[Email]
      +www.skinnersbrewery.com/
      +
      ]]>
      + #6 + + -5.042508,50.258085,0 + +
      + + Wooden Hand Brewery + Truro, Cornwall + +Truro
      +Cornwall
      +United Kingdom
      +(01726) 884596
      +[Email]
      +www.woodenhand.co.uk/
      +
      +MerchandiseBeer to Go / Off-LicenseTours]]>
      + #4 + + -5.050702,50.262952,0 + +
      + + Sharp's Brewery + Wadebridge, Cornwall + +Rock
      +Wadebridge
      +Cornwall
      +United Kingdom
      +(01208) 862121
      ]]>
      + #4 + + -4.836286,50.51625299999999,0 + +
      +
      + + Cumbria + + Barngates Brewery + Ambleside, Cumbria + +Ambleside
      +Cumbria
      +United Kingdom
      +(01539) 436347
      +[Email]
      +www.drunkenduckinn.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -2.9623,54.428376,0 + +
      + + Yates Brewery + Aspatria, Cumbria + +Westnewton
      +Aspatria
      +Cumbria
      +United Kingdom
      +(016973) 21081
      +[Email]
      ]]>
      + #4 + + -3.325289,54.764538,0 + +
      + + Foxfield Brewery + Broughton-in-Furness, Cumbria + +Broughton-in-Furness
      +Cumbria
      +United Kingdom
      +(01229) 716238
      +[Email]
      +www.princeofwalesfoxfield.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -3.213904,54.277147,0 + +
      + + Bitter End + Cockermouth, Cumbria + +Cockermouth
      +Cumbria
      +United Kingdom
      +(01900) 828993
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -3.359775,54.663877,0 + +
      + + Jennings Brewery + Cockermouth, Cumbria + +Cumbria
      +United Kingdom
      +(0845) 1297185
      +[Email]
      +www.jenningsbrewery.co.uk/
      +
      +Bar/Tasting RoomMerchandiseBeer to Go / Off-LicenseTours]]>
      + #4 + + -3.367228,54.663587,0 + +
      + + Coniston Brewing + Coniston, Cumbria + +Coniston
      +Cumbria
      +United Kingdom
      +(01539) 441133
      +[Email]
      +www.conistonbrewery.com/
      +
      ]]>
      + #4 + + -3.075738,54.368965,0 + +
      + + Dent Brewery + Dent, Cumbria + +Cowgill
      +Dent
      +Cumbria
      +United Kingdom
      +(01539) 625326
      +[Email]
      +www.dentbrewery.co.uk/
      +
      ]]>
      + #4 + + -2.454389,54.27769399999999,0 + +
      + + Hawkshead Brewery + Hawkshead, Cumbria + +Hawkshead
      +Cumbria
      +United Kingdom
      +(01539) 436111
      +[Email]
      +www.hawksheadbrewery.co.uk/
      +
      ]]>
      + #4 + + -2.997472,54.373245,0 + +
      + + Hesket Newmarket Brewery + Hesket-Newmarket, Cumbria + +Back Green
      +Hesket-Newmarket
      +Cumbria
      +United Kingdom
      +(016974) 78066
      +[Email]
      +www.hesketbrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -3.026736,54.737864,0 + +
      + + Hardknott Brewery + Holmrook, Cumbria + +Holmrook
      +Cumbria
      +United Kingdom
      +(019467) 23230
      +[Email]
      +www.woolpack.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -3.420384,54.383432,0 + +
      + + The Personal Beer Company Ltd + Keswick, Cumbria + +St. John Street
      +Keswick
      +Cumbria
      +United Kingdom
      +(017687) 80356
      +[Email]
      +www.personalbeer.co.uk/
      +
      ]]>
      + #4 + + -3.136258,54.60038,0 + +
      + + Loweswater Brewery + Loweswater, Cumbria + +Cumbria
      +United Kingdom
      +(01900) 85219
      +[Email]
      +www.kirkstile.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -3.327021,54.577911,0 + +
      + + Tirril Brewery + Penrith, Cumbria + +Penrith
      +Cumbria
      +United Kingdom
      +(01768) 863219
      +[Email]
      +www.queensheadinn.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -2.754948,54.666686,0 + +
      +
      + + Derby + + Leatherbritches Brewery + Ashbourne, Derby + +Fenny Bentley
      +Ashbourne
      +Derby
      +United Kingdom
      +(01335) 350278
      +[Email]
      +www.bentleybrookinn.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -1.729405,53.01413600000001,0 + +
      + + Whim Ales + Buxton, Derby + +Buxton
      +Derby
      +United Kingdom
      +(01298) 84991
      ]]>
      + #5 + + -1.913402,53.26102600000001,0 + +
      + + Townes Brewery + Chesterfield, Derby + +Staveley
      +Chesterfield
      +Derby
      +United Kingdom
      +(01246) 472252
      +[Email]
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -1.341933,53.269393,0 + +
      + + Brunswick Brewing + Derby, Derby + +Derby
      +Derby
      +United Kingdom
      +(01332) 290677
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.464012,52.91871,0 + +
      + + High Peak Brewery + Derby, Derby + +Derby
      +United Kingdom
      ]]>
      + #4 + + -1.475642,52.921899,0 + +
      + + John Thompson Brewery + Derby, Derby + +Derby
      +Derby
      +United Kingdom
      +(01332) 862469
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -1.484836,52.83982000000001,0 + +
      + + Edale Brewery + Edale, Derby + +Derby
      +United Kingdom
      +[Email]
      ]]>
      + #4 + + -1.815763,53.364218,0 + +
      + + Lloyds Country Beers Ltd. + Melbourne, Derby + +Melbourne
      +Derby
      +United Kingdom
      +(01332) 863426
      ]]>
      + #6 + + -1.437273,52.831179,0 + +
      +
      + + Devon + + Barum Brewery + Barnstaple, Devon + +Pilton
      +Barnstaple
      +Devon
      +United Kingdom
      +(01271) 329994
      +[Email]
      +www.barumbrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -4.060553,51.08079099999999,0 + +
      + + Tarka Ales + Barnstaple, Devon + +Fremington
      +Barnstaple
      +Devon
      +United Kingdom
      +(01837) 811030
      +[Email]
      ]]>
      + #4 + + -4.058228,51.080582,0 + +
      + + Country Life Brewery + Bideford, Devon + +Bideford
      +Devon
      +United Kingdom
      +(01237) 420808
      +[Email]
      +www.countrylifebrewery.com/
      +
      +Bar/Tasting RoomBeer GardenRestaurantMerchandiseBeer to Go / Off-LicenseTours]]>
      + #6 + + -4.219824,51.016978,0 + +
      + + Jollyboat Brewery + Bideford, Devon + +Bideford
      +Devon
      +United Kingdom
      +(01237) 424343
      ]]>
      + #4 + + -4.206919,51.019651,0 + +
      + + Gargoyles Brewery + Dawlish, Devon + +Holcombe
      +Dawlish
      +Devon
      +United Kingdom
      ]]>
      + #6 + + -3.474344,50.574119,0 + +
      + + Beer Engine + Exeter, Devon + +Exeter
      +Devon
      +United Kingdom
      +(01392) 851282
      +[Email]
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -3.592342,50.765888,0 + +
      + + Exe Valley Brewery + Exeter, Devon + +Silverton
      +Exeter
      +Devon
      +United Kingdom
      +(01392) 860406
      +[Email]
      +www.quaffale.org.uk/php/brewery/59
      +
      ]]>
      + #4 + + -3.533617,50.7218,0 + +
      + + Exeter Brewery + Exeter, Devon + +Station Road, Exminster
      +Exeter
      +Devon
      +United Kingdom
      +(01392) 823013
      +www.theexeterbrewery.co.uk/
      +
      ]]>
      + #4 + + -3.533617,50.7218,0 + +
      + + O'Hanlon's Brewing Company Ltd. + Exeter, Devon + +Whimple
      +Exeter
      +Devon
      +United Kingdom
      +(01404) 822412
      +[Email]
      +www.ohanlons.co.uk/
      +www.thomashardyale.com/
      +
      ]]>
      + #4 + + -3.533617,50.7218,0 + +
      + + Scattor Rock Brewery + Exeter, Devon + +Christow
      +Exeter
      +Devon
      +United Kingdom
      +(01647) 252120
      +[Email]
      +www.scattorrockbrewery.com/
      +
      ]]>
      + #4 + + -3.533617,50.7218,0 + +
      + + Warrior Brewing Company + Exeter, Devon + +Matford
      +Exeter
      +Devon
      +United Kingdom
      +(01392) 221451
      +[Email]
      ]]>
      + #4 + + -3.533617,50.7218,0 + +
      + + Blackdown Brewery + Honiton, Devon + +Honiton
      +Devon
      +United Kingdom
      +(01404) 890096
      +[Email]
      +www.blackdownbrewery.co.uk/
      +
      ]]>
      + #4 + + -3.188925,50.799586,0 + +
      + + Otter Brewery + Honiton, Devon + +Luppitt
      +Honiton
      +Devon
      +United Kingdom
      +(01404) 891285
      +[Email]
      +www.otterbrewery.com/
      +
      ]]>
      + #4 + + -3.188925,50.799586,0 + +
      + + Combe Martin Brewery + Ilfracombe, Devon + +Combe Martin
      +Ilfracombe
      +Devon
      +United Kingdom
      +[Email]
      +combemartinbrewery.prizaar.com/
      +
      ]]>
      + #8 + + -4.122301,51.20690599999999,0 + +
      + + Quercus Brewery + Kingsbridge, Devon + +Churchstow
      +Kingsbridge
      +Devon
      +United Kingdom
      +(01548) 854888
      +[Email]
      +www.quercusbrewery.co.uk/
      +
      +Beer to Go / Off-License]]>
      + #4 + + -3.809971,50.298771,0 + +
      + + South Hams Brewing Company + Kingsbridge, Devon + +Stokenham
      +Kingsbridge
      +Devon
      +United Kingdom
      +(01548) 581151
      +[Email]
      +www.southhamsbrewery.co.uk/
      +
      ]]>
      + #4 + + -3.777402,50.28314900000001,0 + +
      + + Dartmouth Inn Brewery + Newton Abbot, Devon + +Newton Abbot
      +Devon
      +United Kingdom
      +(01626) 353451
      +Bar/Tasting RoomBeer Garden]]>
      + #8 + + -3.609675,50.528981,0 + +
      + + Red Rock Brewery Ltd + Newton Abbot, Devon + +Bishopsteignton
      +Newton Abbot
      +Devon
      +United Kingdom
      +[Email]
      +www.redrockbrewery.co.uk/
      +
      ]]>
      + #4 + + -3.608712,50.531921,0 + +
      + + Teignworthy Brewery + Newton Abbot, Devon + +Teign Road
      +Newton Abbot
      +Devon
      +United Kingdom
      +(01626) 332066
      +[Email]
      +www.teignworthybrewery.com/
      +
      ]]>
      + #4 + + -3.608712,50.531921,0 + +
      + + Bays Brewery + Paignton, Devon + +Paignton
      +Devon
      +United Kingdom
      +(01803) 555004
      +[Email]
      +www.baysbrewery.co.uk/
      +
      ]]>
      + #6 + + -3.596948,50.42406,0 + +
      + + Summerskills Brewery + Plymouth, Devon + +Billacombe
      +Plymouth
      +Devon
      +United Kingdom
      +(01752) 481283
      +[Email]
      +www.summerskills.co.uk/
      +
      ]]>
      + #6 + + -4.096303,50.367797,0 + +
      + + Union Brewery + Plymouth, Devon + +Holbeaton
      +Plymouth
      +Devon
      +United Kingdom
      +(01752) 830288
      +[Email]
      +www.dartmoorunion.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -4.000652,50.34844500000001,0 + +
      + + Princetown Breweries Ltd. + Princetown, Devon + +Tavistock Road
      +Princetown
      +Devon
      +United Kingdom
      +(01822) 890798
      +[Email]
      +www.princetownbreweries.co.uk/
      +
      ]]>
      + #4 + + -3.990432,50.544119,0 + +
      + + Branscombe Vale Brewery + Seaton, Devon + +Branscombe
      +Seaton
      +Devon
      +United Kingdom
      +(01297) 680511
      +[Email]
      ]]>
      + #4 + + -3.069375,50.70938999999999,0 + +
      + + Ringmore Craft Brewery Ltd + Teignmouth, Devon + +Shaldon
      +Teignmouth
      +Devon
      +United Kingdom
      +[Email]
      +ringmorecraftbrewery.co.uk/
      +
      ]]>
      + #6 + + -3.517515,50.535323,0 + +
      + + Clearwater Brewery + Torrington, Devon + +Hatchmoor Industrial Estate
      +Torrington
      +Devon
      +United Kingdom
      +(01805) 625242
      ]]>
      + #4 + + -4.136852,50.95209700000001,0 + +
      +
      + + Dorset + + Badger Brewery + Blandford St Mary, Dorset + +Dorset
      +United Kingdom
      +(01258) 452141
      +[Email]
      +www.badgerbrewery.com/
      +
      ]]>
      + #4 + + -2.176305,50.837488,0 + +
      + + Palmers Brewery + Bridport, Dorset + +Bridport
      +Dorset
      +United Kingdom
      +(01308) 422396
      +[Email]
      +www.palmersbrewery.com/
      +
      ]]>
      + #6 + + -2.758253,50.71976100000001,0 + +
      + + Goldfinch Brewery + Dorchester, Dorset + +Dorchester
      +Dorset
      +United Kingdom
      +(01305) 264020
      +[Email]
      +www.goldfinchbrewery.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -2.433685,50.71567900000001,0 + +
      + + Lapin Noir Ltd. + Weymouth, Dorset + +Weymouth
      +Dorset
      +United Kingdom
      +(01305) 777622
      ]]>
      + #4 + + -2.454146,50.60879400000001,0 + +
      +
      + + Durham + + High Force Hotel Brewery + Barnard Castle, Durham + +Barnard Castle
      +Durham
      +United Kingdom
      +(01833) 622222
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -1.927437,54.54454,0 + +
      + + Middleton Brewery + Barnard Castle, Durham + +Durham
      +United Kingdom
      ]]>
      + #4 + + -1.927437,54.54454,0 + +
      + + Durham Brewery + Bowburn, Durham + +Bowburn
      +Durham
      +United Kingdom
      +(0191) 3771991
      +[Email]
      +www.durham-brewery.co.uk/
      +
      ]]>
      + #4 + + -1.528844,54.739341,0 + +
      + + Derwentrose Brewery + Consett, Durham + +Consett
      +Durham
      +United Kingdom
      +(01207) 502585
      +[Email]
      +www.thegreyhorse.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -1.826863,54.853371,0 + +
      + + Lanchester Brewing + Durham, Durham + +Durham
      +United Kingdom
      ]]>
      + #4 + + -1.559605,54.778692,0 + +
      +
      + + East Sussex + + White Brewing Company + Bexhill-on-Sea, East Sussex + +Pebsham Lane
      +Bexhill-on-Sea
      +East Sussex
      +United Kingdom
      +(01424) 731066
      +[Email]
      +www.white-brewing.co.uk/
      +
      +MerchandiseBeer to Go / Off-LicenseTours]]>
      + #4 + + 0.470544,50.849895,0 + +
      + + Kemptown Brewery + Brighton, East Sussex + +Kemptown
      +Brighton
      +East Sussex
      +United Kingdom
      +(01273) 699595
      +[Email]
      +www.kemptownbreweryltc.co.uk
      +
      ]]>
      + #4 + + -0.167831,50.830219,0 + +
      + + FILO Brewery + Hastings, East Sussex + +Old Town
      +Hastings
      +East Sussex
      +United Kingdom
      +(01424) 425079
      +[Email]
      +www.thefilo.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + 0.593673,50.85935,0 + +
      + + Beards of Sussex Ltd. + Herstmonceux, East Sussex + +East Sussex
      +United Kingdom
      ]]>
      + #4 + + 0.324097,50.889496,0 + +
      + + 1648 Brewing Co. + Lewes, East Sussex + +East Hoathly
      +Lewes
      +East Sussex
      +United Kingdom
      +(01825) 840830
      +[Email]
      +www.1648brewing.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + 0.00856,50.982655,0 + +
      + + Harvey & Son (Lewes) + Lewes, East Sussex + +Lewes
      +East Sussex
      +United Kingdom
      +(01273) 480209
      +[Email]
      +www.harveys.org.uk/
      +
      ]]>
      + #8 + + 0.016656,50.874168,0 + +
      + + Rectory Ales Ltd. + Lewes, East Sussex + +Plumpton Green
      +Lewes
      +East Sussex
      +United Kingdom
      +(01273) 890570
      +[Email]
      +www.rectory-ales.co.uk/
      +
      ]]>
      + #6 + + 0.011096,50.870535,0 + +
      + + Rother Valley Brewing Company + Northiam, East Sussex + +Northiam
      +East Sussex
      +United Kingdom
      +(01797) 252922
      ]]>
      + #4 + + 0.600366,50.99399,0 + +
      +
      + + East Yorkshire + + Old Mill Brewery Ltd. + Goole, East Yorkshire + +Snaith
      +Goole
      +East Yorkshire
      +United Kingdom
      +(01405) 861813
      ]]>
      + #6 + + -0.865348,53.704321,0 + +
      +
      + + Essex + + Crouch Vale Brewery + Chelmsford, Essex + +South Woodham Ferrers
      +Chelmsford
      +Essex
      +United Kingdom
      +(01245) 322744
      +[Email]
      +www.crouch-vale.co.uk/
      +
      ]]>
      + #8 + + 0.622435,51.650567,0 + +
      + + Beer Shop + Colchester, Essex + +Great Horkesley
      +Colchester
      +Essex
      +United Kingdom
      +(0845) 833 1492
      +[Email]
      +www.pitfieldbeershop.co.uk/
      +
      ]]>
      + #6 + + 0.850924,51.889653,0 + +
      + + Mersea Island Vineyard + Colchester, Essex + +East Mersea
      +Colchester
      +Essex
      +United Kingdom
      +(01206) 385900
      +[Email]
      +www.merseawine.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + 0.901235,51.88980399999999,0 + +
      + + Nethergate Brewery Co Ltd + Pentlow, Essex + +Pentlow
      +Essex
      +United Kingdom
      +(01787) 283220
      +[Email]
      +www.nethergate.co.uk/
      +www.partybeers.com/
      +
      +Beer to Go / Off-License]]>
      + #6 + + 0.6559350000000001,52.08097,0 + +
      + + Blanchfield's Brewery + Rochford, Essex + +Purdeys Industrial Estate
      +Rochford
      +Essex
      +United Kingdom
      +(01702) 530053
      +[Email]
      ]]>
      + #8 + + 0.716299,51.575503,0 + +
      +
      + + Gloucestershire + + Battledown Brewery + Cheltenham, Gloucestershire + +Keynsham Street
      +Cheltenham
      +Gloucestershire
      +United Kingdom
      +(07734) 834104
      +[Email]
      +www.BattledownBrewery.com/
      +
      ]]>
      + #4 + + -2.071308,51.89799100000001,0 + +
      + + Stanway Brewery + Cheltenham, Gloucestershire + +Cheltenham
      +Gloucestershire
      +United Kingdom
      +(01386) 584320
      +www.stanwaybrewery.co.uk/
      +
      ]]>
      + #6 + + -2.119865,51.89596,0 + +
      + + Freeminer Brewery + Cinderford, Gloucestershire + +Steam Mills
      +Cinderford
      +Gloucestershire
      +United Kingdom
      +(01594) 827989
      +[Email]
      +www.freeminer.com/
      +
      ]]>
      + #6 + + -2.511597,51.83250000000001,0 + +
      + + Uley Brewery Ltd. + Dursley, Gloucestershire + +Uley
      +Dursley
      +Gloucestershire
      +United Kingdom
      +(01453) 860120
      ]]>
      + #4 + + -2.36041,51.688037,0 + +
      + + Donnington Brewery + Gloucester, Gloucestershire + +Gloucestershire
      +United Kingdom
      +(01451) 830603
      ]]>
      + #4 + + -2.24867,51.866742,0 + +
      + + Mayhem's Brewery + Gloucester, Gloucestershire + +Gloucester
      +Gloucestershire
      +United Kingdom
      +(01452) 780172
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -2.24867,51.866742,0 + +
      + + Bath Ales Ltd + Warmley, Gloucestershire + +Caxton Business Estate, Tower Road North
      +Warmley
      +Gloucestershire
      +United Kingdom
      +(0117) 9474797
      +[Email]
      +www.bathales.com/
      +
      +Bar/Tasting RoomMerchandiseBeer to Go / Off-LicenseTours]]>
      + #8 + + -2.47621,51.45502999999999,0 + +
      + + Wickwar Brewing + Wickwar, Gloucestershire + +Station Road
      +Wickwar
      +Gloucestershire
      +United Kingdom
      +(01454) 294168
      +[Email]
      +www.wickwarbrewing.co.uk/
      +
      ]]>
      + #4 + + -2.399917,51.59523000000001,0 + +
      + + Goff's Brewery + Winchcombe, Gloucestershire + +Winchcombe
      +Gloucestershire
      +United Kingdom
      +(01242) 603383
      +[Email]
      +www.goffs.biz/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.956347,51.964412,0 + +
      +
      + + Guernsey + + Guernsey Brewery Co. (1920) Ltd. + Saint Peter Port, Guernsey + +Saint Peter Port
      +Guernsey
      +United Kingdom
      +(01481) 720143
      ]]>
      + #4 + + -2.539592,49.458763,0 + +
      + + RW Randall Vauxlaurens Brewery + Saint Peter Port, Guernsey + +Saint Peter Port
      +Guernsey
      +United Kingdom
      +(01481) 720134
      ]]>
      + #4 + + -2.539592,49.458763,0 + +
      +
      + + Hampshire + + Cheriton Brewhouse + Alresford, Hampshire + +Hampshire
      +United Kingdom
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -1.165786,51.090113,0 + +
      + + Itchen Valley Brewery + Alresford, Hampshire + +New Farm Road
      +Alresford
      +Hampshire
      +United Kingdom
      +(01962) 735111
      +[Email]
      +www.itchenvalley.com/
      +
      ]]>
      + #4 + + -1.165786,51.090113,0 + +
      + + Triple fff Brewing Company + Alton, Hampshire + +Station Approach, Four Marks
      +Alton
      +Hampshire
      +United Kingdom
      +(01420) 561422
      +[Email]
      +www.triplefff.com/
      +
      ]]>
      + #4 + + -0.975245,51.150822,0 + +
      + + Newale Brewing Company Ltd. + Andover, Hampshire + +Walworth Industrial Estate
      +Andover
      +Hampshire
      +United Kingdom
      +(01264) 336336
      ]]>
      + #6 + + -1.480471,51.203684,0 + +
      + + Portchester Brewery + Fareham, Hampshire + +Portchester
      +Fareham
      +Hampshire
      +United Kingdom
      +(01329) 512918
      +[Email]
      +www.portchesterbrewery.co.uk/
      +
      ]]>
      + #8 + + -1.139092,50.839906,0 + +
      + + Oakleaf Brewing Co Ltd + Gosport, Hampshire + +Gosport
      +Hampshire
      +United Kingdom
      +(02392) 513222
      +[Email]
      +www.oakleafbrewing.co.uk/
      +
      ]]>
      + #4 + + -1.12907,50.794664,0 + +
      + + Wingfield's Brewery + Portsmouth, Hampshire + +Portsmouth
      +Hampshire
      +United Kingdom
      +(01705) 829079
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -1.090291,50.79392800000001,0 + +
      + + Ringwood Brewery + Ringwood, Hampshire + +Ringwood
      +Hampshire
      +United Kingdom
      +(01425) 471177
      +[Email]
      +www.ringwoodbrewery.co.uk/
      +
      ]]>
      + #8 + + -1.786956,50.841032,0 + +
      + + Hampshire Brewery + Romsey, Hampshire + +Greatbridge Road
      +Romsey
      +Hampshire
      +United Kingdom
      +(01794) 830529
      +[Email]
      +www.hampshirebrewery.com/
      +
      +Tours]]>
      + #4 + + -1.498872,50.988902,0 + +
      + + Winchester Brewery + Southampton, Hampshire + +Hampshire
      +United Kingdom
      +[Email]
      +www.winchesterbrewery.com/
      +
      ]]>
      + #4 + + -1.395606,50.899837,0 + +
      + + Spikes Brewery + Southsea, Hampshire + +Hampshire
      +United Kingdom
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -1.088216,50.78649099999999,0 + +
      +
      + + Hereford and Worcester + + Red Cross Brewery + Bromsgrove, Hereford and Worcester + +Bromsgrove
      +Hereford and Worcester
      +United Kingdom
      +(01527) 871409
      ]]>
      + #6 + + -2.073708,52.345602,0 + +
      + + Queen's Head & Fat God's Brewery + Evesham, Hereford and Worcester + +Evesham
      +Hereford and Worcester
      +United Kingdom
      +(01386) 871012
      +[Email]
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -1.916994,52.165854,0 + +
      + + Spinning Dog Brewery + Hereford, Hereford and Worcester + +Hereford
      +Hereford and Worcester
      +United Kingdom
      +(01432) 342125
      +[Email]
      +www.spinningdogbrewery.co.uk/
      +
      ]]>
      + #6 + + -2.706212,52.05250900000001,0 + +
      + + Hobson's Brewery and Co. + Kidderminster, Hereford and Worcester + +Cleobury Mortimer
      +Kidderminster
      +Hereford and Worcester
      +United Kingdom
      +(01299) 270837
      +www.hobsons-brewery.co.uk/
      +
      ]]>
      + #4 + + -2.246896,52.38606000000001,0 + +
      + + Dunn Plowman Brewery + Kington, Hereford and Worcester + +Kington
      +Hereford and Worcester
      +United Kingdom
      +(01544) 231106
      +[Email]
      +Bar/Tasting RoomRestaurantTours]]>
      + #6 + + -3.027956,52.202773,0 + +
      + + Teme Valley Brewery + Knightwick, Hereford and Worcester + +Hereford and Worcester
      +United Kingdom
      +(01886) 821235 x209
      +[Email]
      +www.temevalleybrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -2.394475,52.199641,0 + +
      + + Cannon Royall Brewery + Ombersley, Hereford and Worcester + +Ombersley
      +Hereford and Worcester
      +United Kingdom
      +(01905) 621161
      +[Email]
      +www.cannonroyall.co.uk/
      +
      ]]>
      + #4 + + -2.228711,52.271302,0 + +
      + + Brandy Cask Brewing Company + Pershore, Hereford and Worcester + +Pershore
      +Hereford and Worcester
      +United Kingdom
      +(01386) 555338
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -2.073662,52.10861100000001,0 + +
      + + Wyre Piddle Brewery + Pershore, Hereford and Worcester + +Pinvin
      +Pershore
      +Hereford and Worcester
      +United Kingdom
      +(01386) 841853
      +[Email]
      ]]>
      + #4 + + -2.080596,52.114194,0 + +
      + + Wye Valley Brewery + Stoke Lacy, Hereford and Worcester + +Hereford and Worcester
      +United Kingdom
      +(01885) 490505
      +[Email]
      +www.wyevalleybrewery.com/
      +
      ]]>
      + #4 + + -2.556404,52.14210599999999,0 + +
      +
      + + Hertfordshire + + Harpenden Brewery + Harpenden, Hertfordshire + +Harpenden
      +Hertfordshire
      +United Kingdom
      +(01582) 460156
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -0.347949,51.83037499999999,0 + +
      + + McMullen & Sons + Hertford, Hertfordshire + +Hertford
      +Hertfordshire
      +United Kingdom
      +(01992) 584911
      ]]>
      + #8 + + -0.080647,51.797456,0 + +
      + + Abel Brown's Brewery + Hitchin, Hertfordshire + +Stotford
      +Hitchin
      +Hertfordshire
      +United Kingdom
      +(01462) 730261
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -0.233236,52.013941,0 + +
      + + Green Tye Brewery + Much Hadham, Hertfordshire + +Hertfordshire
      +United Kingdom
      +(01279) 841041
      +[Email]
      +www.gtbrewery.co.uk/
      +
      ]]>
      + #4 + + 0.071753,51.854102,0 + +
      + + Buntingford Brewery Company Ltd. + Royston, Hertfordshire + +Therfield Road
      +Royston
      +Hertfordshire
      +United Kingdom
      +(01763) 250749
      +[Email]
      +www.buntingford-brewery.co.uk/
      +
      ]]>
      + #4 + + -0.024068,52.04817700000001,0 + +
      + + Verulam Brewery + Saint Albans, Hertfordshire + +Saint Albans
      +Hertfordshire
      +United Kingdom
      ]]>
      + #6 + + -0.320852,51.741552,0 + +
      + + Supermalt UK Ltd. + St. Albans, Hertfordshire + +Victoria Street
      +St. Albans
      +Hertfordshire
      +United Kingdom
      +(01727) 884960
      ]]>
      + #4 + + -0.333892,51.75153,0 + +
      +
      + + Isle of Man + + Mount Murray Brewing Co. Ltd. + Braddan, Isle of Man + +Isle of Man
      +United Kingdom
      ]]>
      + #4 + + -4.569692,54.23073000000001,0 + +
      + + Okell & Son Ltd. + Douglas, Isle of Man + +Kewaigue
      +Douglas
      +Isle of Man
      +United Kingdom
      +(01624) 661120
      +[Email]
      +www.okells.co.uk/
      +
      ]]>
      + #4 + + -4.479282,54.15085700000001,0 + +
      + + Shore Hotel + Laxey, Isle of Man + +Isle of Man
      +United Kingdom
      +(01624) 861509
      +[Email]
      +www.welcome.to/shorehotel/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -4.569692,54.23073000000001,0 + +
      +
      + + Isle of Wight + + Goddards Brewery + Ryde, Isle of Wight + +Bullen Road
      +Ryde
      +Isle of Wight
      +United Kingdom
      +(01983) 611011
      +[Email]
      +www.goddards-brewery.co.uk/
      +
      ]]>
      + #4 + + -1.168697,50.728289,0 + +
      + + St Lawrence Brewery + St Lawrence, Isle of Wight + +Isle of Wight
      +United Kingdom
      ]]>
      + #4 + + -1.235184,50.58859,0 + +
      + + Ventnor Brewery + Ventnor, Isle of Wight + +Ventnor
      +Isle of Wight
      +United Kingdom
      +(01983) 856161
      +[Email]
      +www.ventnorbrewery.co.uk/
      +
      ]]>
      + #6 + + -1.202356,50.595879,0 + +
      +
      + + Jersey + + Jersey Brewery + Saint Helier, Jersey + +Saint Helier
      +Jersey
      +United Kingdom
      +(01534) 31561
      ]]>
      + #4 + + -2.107453,49.187183,0 + +
      + + Tipsy Toad Brewery + Saint Peter, Jersey + +Jersey
      +United Kingdom
      +(01534) 485556
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -2.131237,49.21416900000001,0 + +
      +
      + + Kent + + Royal Harbour Brewhouse and Bakers + Broadstairs, Kent + +Pysons Road Industrial Estate
      +Broadstairs
      +Kent
      +United Kingdom
      +(01843) 868453
      +[Email]
      +www.ramsgatebrewery.co.uk/
      +
      +Bar/Tasting RoomMerchandiseBeer to Go / Off-LicenseTours]]>
      + #6 + + 1.412214,51.356264,0 + +
      + + Nelson Brewing Company + Chatham, Kent + +The Historic Dockyard
      +Chatham
      +Kent
      +United Kingdom
      +(01634) 832828
      ]]>
      + #6 + + 0.12103,51.30752799999999,0 + +
      + + Larkins Brewery Ltd. + Edenbridge, Kent + +Kent
      +United Kingdom
      ]]>
      + #4 + + 0.066265,51.19288199999999,0 + +
      + + Shepherd Neame + Faversham, Kent + +Faversham
      +Kent
      +United Kingdom
      +(01795) 532206
      +[Email]
      +www.shepherd-neame.co.uk/
      +
      ]]>
      + #6 + + 0.892106,51.316752,0 + +
      + + P and DJ Goacher + Maidstone, Kent + +Kent
      +United Kingdom
      ]]>
      + #4 + + 0.523841,51.270337,0 + +
      + + Whitstable Brewery + Maidstone, Kent + +Grafty Green
      +Maidstone
      +Kent
      +United Kingdom
      +(01622) 851007
      ]]>
      + #4 + + 0.523841,51.270337,0 + +
      + + Hopdaemon Brewery + Newnham, Kent + +Seed Road
      +Newnham
      +Kent
      +United Kingdom
      +(01795) 892078
      +[Email]
      +www.hopdaemon.com/
      +
      ]]>
      + #4 + + 0.801268,51.28450800000001,0 + +
      +
      + + Lancashire + + Daniel Thwaites Brewery + Blackburn, Lancashire + +Star Brewery
      +Blackburn
      +Lancashire
      +United Kingdom
      +[Email]
      +www.thwaites.co.uk/
      +www.thwaitesbeers.co.uk/
      +
      ]]>
      + #8 + + -2.477267,53.74896499999999,0 + +
      + + Moonstone Brewery + Burnley, Lancashire + +Burnley
      +Lancashire
      +United Kingdom
      +(01282) 830909
      ]]>
      + #6 + + -2.252059,53.78827700000001,0 + +
      + + Moorhouse's Brewery (Burnley) + Burnley, Lancashire + +Burnley
      +Lancashire
      +United Kingdom
      +(01282) 422864
      +www.moorhouses.co.uk/
      +
      ]]>
      + #8 + + -2.269379,53.78641399999999,0 + +
      + + Leyden Brewery + Bury, Lancashire + +Nangreaves
      +Bury
      +Lancashire
      +United Kingdom
      +(0161) 7646680
      +[Email]
      +www.leydenbrewery.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -2.332157,53.567289,0 + +
      + + Bowland Brewery + Clitheroe, Lancashire + +Clitheroe
      +Lancashire
      +United Kingdom
      +(07952) 639465
      +[Email]
      +www.bowlandbrewery.com/
      +
      ]]>
      + #4 + + -2.390725,53.872821,0 + +
      + + Hopstar + Darwen, Lancashire + +Darwen
      +Lancashire
      +United Kingdom
      +[Email]
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -2.463645,53.6927,0 + +
      + + Porter Brewing Co. Ltd. + Haslingden, Lancashire + +Haslingden
      +Lancashire
      +United Kingdom
      +(01706) 214021
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -2.326004,53.69856100000001,0 + +
      + + Brysons Brews + Heysham, Lancashire + +25 Oxcliffe Road
      +Heysham
      +Lancashire
      +United Kingdom
      +(01524) 852150
      ]]>
      + #4 + + -2.894587,54.041125,0 + +
      + + Hart Brewery + Little Eccleston, Lancashire + +Little Eccleston
      +Lancashire
      +United Kingdom
      +(01995) 671686
      +[Email]
      ]]>
      + #6 + + -2.881964,53.858616,0 + +
      + + Ramsbottom Brewery + Manchester, Lancashire + +Manchester
      +Lancashire
      +United Kingdom
      +(07739) 507416
      +[Email]
      ]]>
      + #6 + + -2.318299,53.64807699999999,0 + +
      + + Owl Brewing + Oldham, Lancashire + +Oldham
      +Lancashire
      +United Kingdom
      +(07889) 631366
      +[Email]
      +www.owlbrew.co.uk/
      +
      +Bar/Tasting RoomRestaurantTours]]>
      + #6 + + -2.245538,53.783995,0 + +
      + + Pictish Brewing + Rochdale, Lancashire + +Woodbine Street East
      +Rochdale
      +Lancashire
      +United Kingdom
      +(01706) 522227
      +[Email]
      +www.pictish-brewing.co.uk/
      +
      ]]>
      + #4 + + -2.15871,53.616352,0 + +
      +
      + + Leicester + + Dowbridge Brewery + Catthorpe, Leicester + +Catthorpe
      +Leicester
      +United Kingdom
      +(01788) 869121
      ]]>
      + #6 + + -1.185545,52.387325,0 + +
      + + Langton Brewery + East Langton, Leicester + +East Langton
      +Leicester
      +United Kingdom
      +(01858) 545483
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -0.930325,52.526813,0 + +
      + + Wicked Hathern Brewery + Hathern, Leicester + +46 Derby Road
      +Hathern
      +Leicester
      +United Kingdom
      +(01509) 842585
      +[Email]
      +www.hathern.com/brewery.htm
      +
      ]]>
      + #4 + + -1.255868,52.796064,0 + +
      + + Hoskins Brothers + Leicester, Leicester + +Leicester
      +Leicester
      +United Kingdom
      +(0116) 262 3330
      +[Email]
      +www.alewagon.co.uk/
      +
      ]]>
      + #8 + + -1.128969,52.634256,0 + +
      + + Bells Brewery + Lutterworth, Leicester + +Bitteswell
      +Lutterworth
      +Leicester
      +United Kingdom
      +www.bellsbrewery.co.uk/
      +
      ]]>
      + #4 + + -1.210815,52.458564,0 + +
      + + Brewsters Brewing + Melton Mowbray, Leicester + +Stathern
      +Melton Mowbray
      +Leicester
      +United Kingdom
      +(01949) 861868
      +[Email]
      +www.brewsters.co.uk/
      +
      ]]>
      + #4 + + -0.8856500000000001,52.764251,0 + +
      + + Parish Brewery + Melton Mowbray, Leicester + +Burrough-On-The-Hill
      +Melton Mowbray
      +Leicester
      +United Kingdom
      +(01664) 454801
      +www.quaffale.org.uk/php/brewery/33
      +
      ]]>
      + #6 + + -0.906793,52.804802,0 + +
      + + Everards Brewery + Narborough, Leicester + +Narborough
      +Leicester
      +United Kingdom
      +(0116) 201 4100
      +[Email]
      +www.everards.co.uk/
      +
      ]]>
      + #4 + + -1.21085,52.572136,0 + +
      + + Steamin' Billy Brewing Company + Oadby, Leicester + +Oadby
      +Leicester
      +United Kingdom
      +(0116) 2712616
      +[Email]
      +www.steamin-billy.co.uk/
      +
      ]]>
      + #8 + + -1.083175,52.598621,0 + +
      + + Belvoir Brewery + Old Dalby, Leicester + +Nottingham Lane
      +Old Dalby
      +Leicester
      +United Kingdom
      +(01664) 823455
      +[Email]
      +www.belvoirbrewery.co.uk/
      +
      ]]>
      + #4 + + -1.001222,52.80757700000001,0 + +
      + + Shardlow Brewery Ltd. + Shardlow, Leicester + +Cavendish Bridge
      +Shardlow
      +Leicester
      +United Kingdom
      +(01322) 799188
      ]]>
      + #4 + + -1.356132,52.86959499999999,0 + +
      +
      + + Lincoln + + Highwood Products + Brigg, Lincoln + +Brigg
      +Lincoln
      +United Kingdom
      +(01652) 654514
      +[Email]
      +www.tomwood.iriswaypoint.com/
      +
      ]]>
      + #4 + + -0.490918,53.553693,0 + +
      + + Willy's Pub and Brewery + Cleethorpes, Lincoln + +Cleethorpes
      +Lincoln
      +United Kingdom
      +(01472) 602145
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -0.023447,53.556924,0 + +
      + + Oldershaw Brewery + Grantham, Lincoln + +Grantham
      +Lincoln
      +United Kingdom
      +(01476) 572135
      +[Email]
      +www.oldershawbrewery.co.uk/
      +
      ]]>
      + #4 + + -0.640277,52.915423,0 + +
      + + Blue Bell Brewery + Holbeach, Lincoln + +Whaplode St Catherine
      +Holbeach
      +Lincoln
      +United Kingdom
      +(01406) 701000
      +[Email]
      +www.bluebellbrewery.co.uk/
      +
      ]]>
      + #6 + + -0.02153,52.748822,0 + +
      + + Donoghue Brewing + Louth, Lincoln + +Grainthorpe
      +Louth
      +Lincoln
      +United Kingdom
      +01472 388229
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -0.005272,53.371956,0 + +
      + + George Bateman and Son Ltd. + Skegness, Lincoln + +Wainfleet
      +Skegness
      +Lincoln
      +United Kingdom
      +(01754) 880317
      +[Email]
      +www.bateman.co.uk/
      +
      ]]>
      + #6 + + 0.316904,53.168803,0 + +
      + + Melbourn Brothers Brewery + Stamford, Lincoln + +Stamford
      +Lincoln
      +United Kingdom
      +(01780) 752186
      +[Email]
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -0.481699,52.651933,0 + +
      +
      + + London + + Zerodegrees Restaurant and Microbrewery — Blackheath + Blackheath, London + +Blackheath
      +London
      +United Kingdom
      +(020) 8852 5619
      +[Email]
      +zerodegrees.co.uk/
      +
      ]]>
      + #7 + + 0.008475999999999999,51.467256,0 + +
      + + Bunker Bar + Covent Garden, London + +Covent Garden
      +London
      +United Kingdom
      +(020) 740 0606
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -0.125494,51.513935,0 + +
      + + Meantime Brewing + Greenwich, London + +Greenwich
      +London
      +United Kingdom
      +(020) 8293 1111
      +[Email]
      ]]>
      + #4 + + -0.010705,51.478768,0 + +
      + + Sweet William Brewery + Leyton, London + +Leyton
      +London
      +United Kingdom
      +(020) 8556 2460
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + 0.0091,51.562232,0 + +
      + + Cobra Beer + London, London + +14-16 Peterborough Road
      +London
      +London
      +United Kingdom
      +(020) 7731 6200
      +[Email]
      +www.cobrabeer.com/
      +
      ]]>
      + #4 + + -0.08894699999999998,51.51333000000001,0 + +
      + + Fuller, Smith & Turner + London, London + +London
      +London
      +United Kingdom
      +(0208) 996 2000
      +[Email]
      +www.fullers.co.uk/
      +
      ]]>
      + #6 + + -0.248885,51.487681,0 + +
      + + J Sainsbury plc + London, London + +London
      +London
      +United Kingdom
      ]]>
      + #8 + + -0.106317,51.51756799999999,0 + +
      + + The Davy Group + London, London + +London
      +London
      +United Kingdom
      +(0171) 4079670
      ]]>
      + #8 + + -0.08216,51.501555,0 + +
      + + Youngs & Company Brewery + Wandsworth, London + +Wandsworth
      +London
      +United Kingdom
      +(020) 8875 7000
      +[Email]
      +www.youngs.co.uk/
      +
      ]]>
      + #6 + + -0.154245,51.44182399999999,0 + +
      +
      + + Manchester + + Joseph Holt Ltd + Cheetham, Manchester + +Cheetham
      +Manchester
      +United Kingdom
      +(0161) 834 3285
      +[Email]
      +www.joseph-holt.com/
      +
      ]]>
      + #6 + + -2.243109,53.493447,0 + +
      + + Oak Brewing Company Ltd. + Heywood, Manchester + +Manchester
      +United Kingdom
      ]]>
      + #4 + + -2.217415,53.593485,0 + +
      + + Phoenix Brewery Ltd. + Heywood, Manchester + +Heywood
      +Manchester
      +United Kingdom
      +(01706) 627009
      ]]>
      + #6 + + -2.20791,53.586388,0 + +
      + + Bank Top Brewery Limited + Manchester, Manchester + +Bolton
      +Manchester
      +Manchester
      +United Kingdom
      +(01204) 595800
      +[Email]
      +www.banktopbrewery.co.uk/
      +
      ]]>
      + #4 + + -2.234507,53.480732,0 + +
      + + Hyde's Brewery + Manchester, Manchester + +Manchester
      +Manchester
      +United Kingdom
      +(0161) 226 1317
      +[Email]
      +www.hydesbrewery.co.uk/
      +
      ]]>
      + #8 + + -2.254382,53.459821,0 + +
      + + JW Lees and Co (Brewers) Ltd. + Manchester, Manchester + +Manchester
      +Manchester
      +United Kingdom
      +(0161) 6432487
      +[Email]
      +www.jwlees.co.uk/
      +
      ]]>
      + #6 + + -2.24704,53.527914,0 + +
      + + Marble Brewery + Manchester, Manchester + +Manchester
      +Manchester
      +United Kingdom
      +(0161) 819 2694
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -2.21686,53.50888799999999,0 + +
      + + Thomas McGuinness Brewing Company + Manchester, Manchester + +Manchester
      +United Kingdom
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -2.234507,53.480732,0 + +
      + + Boggart Hole Clough Brewing + Moston, Manchester + +Clough Road
      +Moston
      +Manchester
      +United Kingdom
      +(0161) 277 9666
      +[Email]
      +www.boggart-brewery.co.uk/
      +
      ]]>
      + #4 + + -2.181948,53.510372,0 + +
      + + Bazens' Brewery + Salford, Manchester + +Knoll Street
      +Salford
      +Manchester
      +United Kingdom
      +(0161) 7080247
      +[Email]
      +www.bazensbrewery.co.uk/
      +
      ]]>
      + #4 + + -2.308077,53.48473300000001,0 + +
      +
      + + Merseyside + + Cambrinus Craft Brewery + Knowsley, Merseyside + +Knowsley Park
      +Knowsley
      +Merseyside
      +United Kingdom
      +0150 546 2226
      ]]>
      + #6 + + -2.852336,53.44742,0 + +
      + + Robert Cain Brewery + Liverpool, Merseyside + +Liverpool
      +Merseyside
      +United Kingdom
      +(0151) 709 8734
      +[Email]
      +www.cainsbeers.com/
      +
      ]]>
      + #6 + + -2.978908,53.393164,0 + +
      + + Wapping Beers + Liverpool, Merseyside + +Liverpool
      +Merseyside
      +United Kingdom
      +(0151) 709 3116
      +[Email]
      +www.wappingbeers.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -2.986851,53.398458,0 + +
      + + George Wright Brewing Company + Rainford, Merseyside + +Sandwash Close
      +Rainford
      +Merseyside
      +United Kingdom
      +(01744) 886686
      +[Email]
      +www.georgewrightbrewing.co.uk/
      +
      ]]>
      + #4 + + -2.783703,53.50266299999999,0 + +
      +
      + + Norfolk + + Wolf Brewery + Attleborough, Norfolk + +Attleborough
      +Norfolk
      +United Kingdom
      +(01953) 457775
      +[Email]
      ]]>
      + #8 + + 1.020382,52.51148499999999,0 + +
      + + Fox Brewery Norfolk + Heacham, Norfolk + +Heacham
      +Norfolk
      +United Kingdom
      +(01485) 570345
      +[Email]
      +www.foxbrewery.co.uk/
      +
      ]]>
      + #6 + + 0.488279,52.909175,0 + +
      + + Iceni Brewery + Ickburgh, Norfolk + +Ickburgh
      +Norfolk
      +United Kingdom
      +(01842) 878922
      +[Email]
      +Tours]]>
      + #6 + + 0.659988,52.521739,0 + +
      + + Blue Moon Brewery + Norwich, Norfolk + +Barford
      +Norwich
      +Norfolk
      +United Kingdom
      +(01603) 757646
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + 1.231954,52.627599,0 + +
      + + Buffy's Brewery + Norwich, Norfolk + +Tivetshall St Mary
      +Norwich
      +Norfolk
      +United Kingdom
      +(01379) 676523
      +[Email]
      +www.buffys.co.uk/
      +
      ]]>
      + #4 + + 1.299349,52.62810099999999,0 + +
      + + Chalk Hill Brewery + Norwich, Norfolk + +Thorpe Hamlet
      +Norwich
      +Norfolk
      +United Kingdom
      +(01603) 477078
      ]]>
      + #6 + + 1.308945,52.62913099999999,0 + +
      + + Fat Cat Brewing + Norwich, Norfolk + +Norwich
      +Norfolk
      +United Kingdom
      +(01603) 788508
      +www.fatcatbrewery.co.uk/
      +
      ]]>
      + #8 + + 1.300608,52.643645,0 + +
      + + Spectrum Brewery + Norwich, Norfolk + +Barford
      +Norwich
      +Norfolk
      +United Kingdom
      +(07949) 254383
      +[Email]
      +www.spectrumbrewery.co.uk/
      +
      ]]>
      + #6 + + 1.231954,52.627599,0 + +
      + + Woodforde's Norfolk Ales + Norwich, Norfolk + +Norwich
      +Norfolk
      +United Kingdom
      +(01603) 720353
      +[Email]
      +www.woodfordes.co.uk/
      +
      ]]>
      + #4 + + 1.299349,52.62810099999999,0 + +
      + + Reepham Brewery + Reepham, Norfolk + +Collers Way
      +Reepham
      +Norfolk
      +United Kingdom
      +(01603) 871091
      ]]>
      + #8 + + 1.064099,52.843916,0 + +
      + + Alewife Brewery + Starston, Norfolk + +Norfolk
      +United Kingdom
      +(01379) 855267
      +[Email]
      ]]>
      + #4 + + 1.28414,52.411151,0 + +
      + + Wissey Valley Brewery + Stoke Ferry, Norfolk + +Stoke Ferry
      +Norfolk
      +United Kingdom
      +(01366) 500767
      +[Email]
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + 0.50433,52.57529499999999,0 + +
      + + Brandon Brewing Company + Thetford, Norfolk + +Brandon
      +Thetford
      +Norfolk
      +United Kingdom
      +(01842) 878496
      +[Email]
      +www.brandonbrewery.co.uk/
      +
      ]]>
      + #4 + + 0.752958,52.41456899999999,0 + +
      +
      + + North Yorkshire + + Wold Top Brewery + Driffield, North Yorkshire + +Wold Newton
      +Driffield
      +North Yorkshire
      +United Kingdom
      +(01723) 892222
      +[Email]
      +www.woldtopbrewery.co.uk/
      +
      ]]>
      + #6 + + -0.442862,54.009574,0 + +
      + + Daleside Brewery + Harrogate, North Yorkshire + +Harrogate
      +North Yorkshire
      +United Kingdom
      +(01423) 880022
      +[Email]
      +www.dalesidebrewery.co.uk/
      +
      ]]>
      + #6 + + -1.500981,53.999907,0 + +
      + + Franklins Brewery + Harrogate, North Yorkshire + +Bilton
      +Harrogate
      +North Yorkshire
      +United Kingdom
      +(01423) 322345
      +[Email]
      ]]>
      + #6 + + -1.517931,54.014347,0 + +
      + + Rooster's Brewing Company Ltd + Knaresborough, North Yorkshire + +Grimbald Park
      +Knaresborough
      +North Yorkshire
      +United Kingdom
      +(01423) 865959
      ]]>
      + #8 + + -1.402581,53.95714600000001,0 + +
      + + Wensleydale Brewery + Leyburn, North Yorkshire + +Bellerey
      +Leyburn
      +North Yorkshire
      +United Kingdom
      +(01969) 625250
      +[Email]
      +wensleydalebrewery.com/
      +
      ]]>
      + #4 + + -1.82857,54.309738,0 + +
      + + Suddaby's Crown Hotel + Malton, North Yorkshire + +Malton
      +North Yorkshire
      +United Kingdom
      +(01653) 697580
      +[Email]
      +www.suddabys.co.uk/
      +
      ]]>
      + #8 + + -0.796727,54.135316,0 + +
      + + Hambleton Ales + Melmerby, North Yorkshire + +Melmerby
      +North Yorkshire
      +United Kingdom
      +(01765) 640108
      +[Email]
      +www.hambletonales.co.uk/
      +
      +Beer to Go / Off-LicenseTours]]>
      + #6 + + -1.484186,54.174363,0 + +
      + + Cropton Brewery + Pickering, North Yorkshire + +Pickering
      +North Yorkshire
      +United Kingdom
      +(01751) 417330
      +[Email]
      +croptonbrewery.co.uk/
      +
      ]]>
      + #4 + + -0.7821410000000001,54.246356,0 + +
      + + North Yorkshire Brewing Co. + Pinchinthorpe, North Yorkshire + +Pinchinthorpe
      +North Yorkshire
      +United Kingdom
      +(01642) 226224
      ]]>
      + #5 + + -1.104529,54.52589,0 + +
      + + Swaled Ale + Richmond, North Yorkshire + +Gunnerside
      +Richmond
      +North Yorkshire
      +United Kingdom
      +(01748) 886441
      ]]>
      + #4 + + -1.736623,54.40518299999999,0 + +
      + + Black Sheep Brewery + Ripon, North Yorkshire + +Masham
      +Ripon
      +North Yorkshire
      +United Kingdom
      +(01765) 689227
      +[Email]
      +www.blacksheep.co.uk/
      +
      ]]>
      + #4 + + -1.524212,54.13878,0 + +
      + + T&R Theakston + Ripon, North Yorkshire + +Masham
      +Ripon
      +North Yorkshire
      +United Kingdom
      +(01765) 689544
      +[Email]
      +www.theakstons.co.uk/
      +
      ]]>
      + #6 + + -1.522759,54.13245400000001,0 + +
      + + Brown Cow Brewery + Selby, North Yorkshire + +Barlow
      +Selby
      +North Yorkshire
      +United Kingdom
      +(01757) 681947
      ]]>
      + #6 + + -1.024465,53.75513300000001,0 + +
      + + Selby (Middlesbrough) Brewery Ltd. + Selby, North Yorkshire + +Selby
      +North Yorkshire
      +United Kingdom
      +(01757) 702826
      ]]>
      + #8 + + -1.071416,53.787201,0 + +
      + + Copper Dragon Brewery + Skipton, North Yorkshire + +Keighley Road
      +Skipton
      +North Yorkshire
      +United Kingdom
      +(01756) 702130
      +[Email]
      +www.copperdragon.uk.com/
      +
      ]]>
      + #4 + + -2.011944,53.960978,0 + +
      + + Captain Cook Brewery + Stokesley, North Yorkshire + +Stokesley
      +North Yorkshire
      +United Kingdom
      +(01642) 710263
      +www.thecaptaincookbrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.195551,54.46812799999999,0 + +
      + + Courage Brewery + Tadcaster, North Yorkshire + +North Yorkshire
      +United Kingdom
      +(01937) 832091
      ]]>
      + #4 + + -1.263848,53.88303400000001,0 + +
      + + Samuel Smith Old Brewery (Tadcaster) + Tadcaster, North Yorkshire + +Tadcaster
      +North Yorkshire
      +United Kingdom
      +(01937) 839201
      +www.merchantduvin.com/pages/5_breweries/samsmith.html
      +
      ]]>
      + #6 + + -1.262536,53.883412,0 + +
      + + Rudgate Brewery + Tockwith, North Yorkshire + +Rudgate
      +Tockwith
      +North Yorkshire
      +United Kingdom
      +(01423) 358382
      +[Email]
      +www.rudgate-beers.co.uk/
      +
      ]]>
      + #4 + + -1.286819,53.965211,0 + +
      + + Black Dog Brewery + Whitby, North Yorkshire + +The Ropery
      +Whitby
      +North Yorkshire
      +United Kingdom
      +(01947) 821467
      +[Email]
      ]]>
      + #4 + + -0.617072,54.485082,0 + +
      + + Whitby's Own Brewery Ltd. + Whitby, North Yorkshire + +The Ropery
      +Whitby
      +North Yorkshire
      +United Kingdom
      +(01947) 605914
      ]]>
      + #6 + + -0.619012,54.486526,0 + +
      + + Marston Moor Brewery + York, North Yorkshire + +North Yorkshire
      +United Kingdom
      ]]>
      + #4 + + -1.082285,53.957702,0 + +
      + + York Brewery + York, North Yorkshire + +Micklegate
      +York
      +North Yorkshire
      +United Kingdom
      +(01904) 621162
      +[Email]
      +www.yorkbrew.demon.co.uk/
      +
      ]]>
      + #8 + + -1.090615,53.956994,0 + +
      +
      + + Northampton + + Hop House Brewery + Kingsthorpe, Northampton + +Kingsthorpe
      +Northampton
      +United Kingdom
      +(01604) 715221
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -0.9001629999999999,52.267749,0 + +
      + + Frog Island Brewery + Northampton, Northampton + +James Road
      +Northampton
      +Northampton
      +United Kingdom
      +(01604) 587772
      +[Email]
      +www.frogislandbrewery.co.uk/
      +
      ]]>
      + #4 + + -0.8973910000000001,52.23687399999999,0 + +
      +
      + + Northern Ireland + + Bass Ireland Ulster Brewery + Belfast, Northern Ireland + +Belfast
      +Northern Ireland
      +United Kingdom
      +www.inbev.com/
      +
      ]]>
      + #6 + + -6.006265000000001,54.578335,0 + +
      + + Strangford Lough Brewing Company Ltd + Killyleagh, Northern Ireland + +Killyleagh
      +Northern Ireland
      +United Kingdom
      +(028) 4428 1461
      +[Email]
      +www.slbc.ie/
      +
      ]]>
      + #4 + + -5.649401,54.401305,0 + +
      + + Hilden Brewery + Lisburn, Northern Ireland + +Hilden
      +Lisburn
      +Northern Ireland
      +United Kingdom
      +(028) 9266 0800
      +[Email]
      +www.festival.hilden-taproom.com/
      +www.hildenbrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -5.982570000000001,54.57570000000001,0 + +
      + + Whitewater Brewing Co. + Newry, Northern Ireland + +Kilkeel
      +Newry
      +Northern Ireland
      +United Kingdom
      +(028) 41769449
      +[Email]
      ]]>
      + #8 + + -6.074805,54.08780699999999,0 + +
      +
      + + Northumberland + + Northumberland Brewery + Bedlington, Northumberland + +Bomarsund
      +Bedlington
      +Northumberland
      +United Kingdom
      +(01670) 822112
      +[Email]
      +www.northumberlandbrewery.co.uk/
      +
      ]]>
      + #6 + + -1.553523,55.126685,0 + +
      + + Border Brewing Company + Berwick-upon-Tweed, Northumberland + +Northumberland
      +United Kingdom
      ]]>
      + #4 + + -2.005266,55.77042099999999,0 + +
      + + Haltwhistle Brewery + Haltwhistle, Northumberland + +Haltwhistle
      +Northumberland
      +United Kingdom
      +(01434) 320463
      ]]>
      + #4 + + -2.45723,54.970871,0 + +
      + + Wylam Brewery + Heddon-on-the-Wall, Northumberland + +Heddon-on-the-Wall
      +Northumberland
      +United Kingdom
      +(01661) 853377
      +[Email]
      +www.wylambrew.co.uk/
      +
      ]]>
      + #4 + + -1.793512,54.99727500000001,0 + +
      + + Hexhamshire Brewery + Hexham, Northumberland + +Ordley
      +Hexham
      +Northumberland
      +United Kingdom
      +(01434) 673031
      ]]>
      + #4 + + -2.097919,54.970216,0 + +
      + + Big Lamp Brewers + Newcastle upon Tyne, Northumberland + +Northumberland
      +United Kingdom
      ]]>
      + #4 + + -1.629195,54.970885,0 + +
      + + Scottish & Newcastle Breweries + Newcastle-upon-Tyne, Northumberland + +Newcastle-upon-Tyne
      +Northumberland
      +United Kingdom
      +(0191) 2325092
      +[Email]
      +www.newcastlebrown.com/
      +www.scottish-newcastle.com/
      +
      ]]>
      + #4 + + -1.619744,54.973639,0 + +
      +
      + + Nottingham + + Mallard Brewery + Carlton, Nottingham + +Carlton
      +Nottingham
      +United Kingdom
      +(0115) 9521289
      ]]>
      + #8 + + -1.149153,52.98346,0 + +
      + + Caythorpe Brewery + Caythorpe, near Lowdham, Nottingham + +Nottingham
      +United Kingdom
      +(0115) 966 4376
      ]]>
      + #4 + + -1.149309,52.955107,0 + +
      + + Hardys & Hansons + Kimberley, Nottingham + +Kimberley
      +Nottingham
      +United Kingdom
      +(0115) 9383611
      +[Email]
      +www.hardysandhansons.plc.uk/
      +
      ]]>
      + #6 + + -1.261538,53.00145199999999,0 + +
      + + Holland Brewery + Kimberley, Nottingham + +Kimberley
      +Nottingham
      +United Kingdom
      +(0115) 938 2685
      ]]>
      + #4 + + -1.270536,52.999938,0 + +
      + + Maypole Brewery + Newark, Nottingham + +Eakring
      +Newark
      +Nottingham
      +United Kingdom
      +(01623) 871690
      ]]>
      + #4 + + -0.811946,53.07622700000001,0 + +
      + + Springhead Brewery + Newark, Nottingham + +Sutton-on-Trent
      +Newark
      +Nottingham
      +United Kingdom
      +(01636) 821000
      +[Email]
      +www.springhead.co.uk/
      +
      ]]>
      + #6 + + -0.817087,53.185465,0 + +
      + + Castle Rock Brewery + Nottingham, Nottingham + +Nottingham
      +Nottingham
      +United Kingdom
      +(0115) 985 1615
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -1.148012,52.945813,0 + +
      + + Alcazar Brewing + Old Basford, Nottingham + +Old Basford
      +Nottingham
      +United Kingdom
      +(0115) 978 2282
      +[Email]
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.180716,52.98093400000001,0 + +
      + + Nottingham Brewery + Radford, Nottingham + +Radford
      +Nottingham
      +United Kingdom
      +(0781) 5073447
      +[Email]
      +www.nottinghambrewery.com/
      +
      ]]>
      + #4 + + -1.176209,52.96040500000001,0 + +
      + + Broadstone Brewing + Retford, Nottingham + +Retford
      +Nottingham
      +United Kingdom
      +(01777) 719797
      +[Email]
      +www.broadstonebrewery.com/
      +
      ]]>
      + #6 + + -0.943224,53.31959,0 + +
      +
      + + Oxford + + Bodicote Brewery + Banbury, Oxford + +Banbury
      +Oxford
      +United Kingdom
      +(01295) 262327
      +[Email]
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -1.340449,52.06002,0 + +
      + + Oxfordshire Ales + Bicester, Oxford + +Marsh Gibbon
      +Bicester
      +Oxford
      +United Kingdom
      +(01869) 278765
      +[Email]
      ]]>
      + #4 + + -1.060032,51.9029,0 + +
      + + Henry's Butchers Yard Brewery + Chipping Norton, Oxford + +Chipping Norton
      +Oxford
      +United Kingdom
      ]]>
      + #6 + + -1.545254,51.941831,0 + +
      + + Chiltern Valley Winery and Brewery + Henley-on-Thames, Oxford + +Henley-on-Thames
      +Oxford
      +United Kingdom
      +(01491) 638330
      +[Email]
      +www.chilternvalley.co.uk/
      +
      +Bar/Tasting RoomBeer to Go / Off-LicenseTours]]>
      + #5 + + -0.899633,51.533865,0 + +
      + + Hook Norton Brewery + Hook Norton, Oxford + +Hook Norton
      +Oxford
      +United Kingdom
      +(01608) 730384
      +[Email]
      +www.hook-norton-brewery.co.uk/
      +www.hooknortonbrewery.co.uk/
      +
      ]]>
      + #6 + + -1.492203,51.996625,0 + +
      + + Loddon Brewery + Reading, Oxford + +Dunsden
      +Reading
      +Oxford
      +United Kingdom
      +(0118) 948 1111
      +[Email]
      +www.loddonbrewery.co.uk/
      +
      ]]>
      + #4 + + -0.9690880000000001,51.45504099999999,0 + +
      + + Ridgeway Brewing + South Stoke, Oxford + +South Stoke
      +Oxford
      +United Kingdom
      +(01491) 873474
      +[Email]
      +www.sheltonbrothers.com/beers/breweryProfile.asp?BreweryID=40
      +
      ]]>
      + #8 + + -1.135492,51.546171,0 + +
      + + Wychwood Brewery + Witney, Oxford + +The Crofts, Corn Street
      +Witney
      +Oxford
      +United Kingdom
      +(01993) 890800
      +[Email]
      +www.wychwood.co.uk/
      +
      ]]>
      + #4 + + -1.485517,51.783711,0 + +
      +
      + + Rutland + + Blencowe Brewing + Barrowden, Rutland + +Barrowden
      +Rutland
      +United Kingdom
      +(01572) 747247
      +www.exeterarms.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -0.603745,52.59042400000001,0 + +
      + + Davis'es Brewing Company Ltd + Oakham, Rutland + +Oakham
      +Rutland
      +United Kingdom
      +(01572) 770065
      +[Email]
      +www.grainstorebrewery.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -0.7338710000000001,52.67224699999999,0 + +
      +
      + + Scotland + + Williams Brothers Brewing Company + Alloa, Scotland + +Kelliebank
      +Alloa
      +Scotland
      +United Kingdom
      +(01259) 725511
      +[Email]
      +www.fraoch.com/
      +www.heatherale.co.uk/
      +
      ]]>
      + #5 + + -3.795365,56.116288,0 + +
      + + Harviestoun Brewery + Alva, Scotland + +Alval Industrial Estate
      +Alva
      +Scotland
      +United Kingdom
      +(01259) 769100
      +[Email]
      +www.harviestoun-brewery.co.uk/
      +
      ]]>
      + #5 + + -3.800559,56.153056,0 + +
      + + Atlas Brewery + Argyll, Scotland + +Kinlochleven
      +Argyll
      +Scotland
      +United Kingdom
      +(01855) 831111
      +[Email]
      +www.atlasbrewery.com/
      +
      ]]>
      + #4 + + -5.238366,56.429411,0 + +
      + + Fyne Ales + Argyll, Scotland + +Loch Fyne
      +Argyll
      +Scotland
      +United Kingdom
      +(01499) 600238
      +[Email]
      +www.fyneales.com/
      +
      ]]>
      + #4 + + -4.939297,56.253374,0 + +
      + + Cairngorm Brewery Co Ltd + Aviemore, Scotland + +Aviemore
      +Scotland
      +United Kingdom
      +(01479) 812222
      +[Email]
      +www.cairngormbrewery.com/
      +
      ]]>
      + #5 + + -3.828824,57.194369,0 + +
      + + Valhalla Brewery + Baltasound, Scotland + +Scotland
      +United Kingdom
      +(01957) 711658
      +[Email]
      +www.valhallabrewery.co.uk/
      +
      ]]>
      + #4 + + -0.861137,60.758463,0 + +
      + + Kelburn Brewing + Barrhead, Scotland + +Barrhead
      +Scotland
      +United Kingdom
      +(0141) 881 2138
      +[Email]
      +www.kelburnbrewery.com/
      +
      ]]>
      + #6 + + -4.392648,55.80428800000001,0 + +
      + + Bridge of Allan Brewery + Bridge of Allan, Scotland + +Queens Lane
      +Bridge of Allan
      +Scotland
      +United Kingdom
      +(01786) 834555
      +[Email]
      +www.bridgeofallan.co.uk/
      +
      ]]>
      + #4 + + -3.945913,56.15448599999999,0 + +
      + + Sulwath Brewery + Castle Douglas, Scotland + +Castle Douglas
      +Scotland
      +United Kingdom
      +(01556) 504525
      +[Email]
      +www.sulwathbrewers.co.uk/
      +
      ]]>
      + #8 + + -3.929584999999999,54.940873,0 + +
      + + Devon Ales + Clackmannan, Scotland + +Sauchie, by Alloa
      +Clackmannan
      +Scotland
      +United Kingdom
      +(01259) 722020
      +[Email]
      +www.devonales.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -3.782321,56.12745699999999,0 + +
      + + Forth Brewing + Clackmannan, Scotland + +Alloa
      +Clackmannan
      +Scotland
      +United Kingdom
      +(01259) 72511
      +[Email]
      ]]>
      + #5 + + -3.75275,56.107275,0 + +
      + + Belhaven Brewery + East Lothian, Scotland + +Dunbar
      +East Lothian
      +Scotland
      +United Kingdom
      +(0)1368 862734
      +[Email]
      +www.belhaven.co.uk/
      +
      ]]>
      + #6 + + -2.5098,55.99696,0 + +
      + + Caledonian Brewing + Edinburgh, Scotland + +Edinburgh
      +Scotland
      +United Kingdom
      +(0131) 337 1286
      +[Email]
      +www.caledonian-brewery.co.uk/
      +
      ]]>
      + #6 + + -3.237789,55.931282,0 + +
      + + Innis & Gunn + Edinburgh, Scotland + +Scotland
      +United Kingdom
      ]]>
      + #4 + + -3.187606,55.95025400000001,0 + +
      + + Scottish & Newcastle PLC + Edinburgh, Scotland + +Edinburgh
      +Scotland
      +United Kingdom
      +(0131) 528 2000
      +[Email]
      +www.scottish-newcastle.com/
      +
      ]]>
      + #6 + + -3.249304,55.946396,0 + +
      + + Backdykes Brewing Company + Fife, Scotland + +Thornton
      +Fife
      +Scotland
      +United Kingdom
      +(01529) 775303
      ]]>
      + #4 + + -3.143625000000001,56.23393900000001,0 + +
      + + BrewDog Ltd. + Fraserburgh, Scotland + +Fraserburgh
      +Scotland
      +United Kingdom
      +(01346) 519009
      +[Email]
      +www.brewdog.com/
      +
      ]]>
      + #8 + + -2.006545,57.689992,0 + +
      + + Tennent Caledonian Brewery + Glasgow, Scotland + +Dennistoun
      +Glasgow
      +Scotland
      +United Kingdom
      +(0141) 552 6552
      +www.inbev.com/
      +
      ]]>
      + #6 + + -4.218676,55.85848600000001,0 + +
      + + The Clockwork Beer Company + Glasgow, Scotland + +Glasgow
      +Scotland
      +United Kingdom
      +(0141) 649 0184
      +www.clockworkbeerco.com/
      +
      +Bar/Tasting RoomBeer GardenRestaurantBeer to Go / Off-LicenseToursPublic Internet Access]]>
      + #6 + + -4.256869,55.83584,0 + +
      + + West Brewing Company + Glasgow, Scotland + +Glasgow Green
      +Glasgow
      +Scotland
      +United Kingdom
      +(0141) 5500135
      +www.westbeer.com/
      +
      +Bar/Tasting RoomBeer GardenRestaurantMerchandiseBeer to Go / Off-LicenseToursPublic Internet Access]]>
      + #6 + + -4.23395,55.85136799999999,0 + +
      + + Traquair House Brewery + Innerleithen, Scotland + +Scotland
      +United Kingdom
      +(01896) 830323
      +[Email]
      +www.aboutscotland.com/traquair/
      +www.traquair.co.uk/
      +
      +Hotel Rooms]]>
      + #5 + + -3.062823,55.619311,0 + +
      + + Isle of Arran Brewery + Isle of Arran, Scotland + +Brodick
      +Isle of Arran
      +Scotland
      +United Kingdom
      +(01770) 302353
      +[Email]
      +www.arranbrewery.co.uk/
      +www.arranbrewery.com/
      +
      ]]>
      + #5 + + -5.230248,55.574981,0 + +
      + + Isle of Skye Brewing Company + Isle of Skye, Scotland + +Uig
      +Isle of Skye
      +Scotland
      +United Kingdom
      +(01470) 542477
      +[Email]
      +www.skyebrewery.co.uk/
      +
      +Bar/Tasting RoomMerchandiseBeer to Go / Off-LicenseTours]]>
      + #4 + + -6.218579,57.313623,0 + +
      + + Fyfe Brewing Company + Kirkcaldy, Scotland + +Kirkcaldy
      +Scotland
      +United Kingdom
      +01592 264270
      +[Email]
      +www.fyfebrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -3.155939000000001,56.112519,0 + +
      + + Tryst Brewery + Larbet, Scotland + +Larbet
      +Scotland
      +United Kingdom
      +(01324) 554000
      +[Email]
      +www.trystbrewery.co.uk/
      +
      ]]>
      + #8 + + -3.82807,56.024267,0 + +
      + + Borve Brew House + Moray, Scotland + +Huntly
      +Moray
      +Scotland
      +United Kingdom
      +(01466) 760343
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -2.824784,57.510386,0 + +
      + + Black Isle Brewery + Munlochy, Scotland + +Munlochy
      +Scotland
      +United Kingdom
      +(01463) 811871
      +[Email]
      +www.blackislebrewery.com/
      +
      ]]>
      + #6 + + -4.265876,57.50447,0 + +
      + + Orkney Brewery + Orkney, Scotland + +Sandwick
      +Orkney
      +Scotland
      +United Kingdom
      +(01856) 841802
      +[Email]
      +www.orkneybrewery.co.uk/
      +
      ]]>
      + #4 + + -3.313501,59.069698,0 + +
      + + Inveralmond Brewery + Perth, Scotland + +Perth
      +Scotland
      +United Kingdom
      +(01738) 449448
      +[Email]
      +www.inveralmond-brewery.co.uk/
      +
      ]]>
      + #6 + + -3.477675,56.417439,0 + +
      + + Moulin Brewery + Perthshire and Kinross, Scotland + +Pitlochry
      +Perthshire and Kinross
      +Scotland
      +United Kingdom
      +(01796) 472196
      +[Email]
      ]]>
      + #6 + + -3.728122,56.71398299999999,0 + +
      + + Houston Brewing + Renfrewshire, Scotland + +Houston
      +Renfrewshire
      +Scotland
      +United Kingdom
      +(01505) 614528
      +[Email]
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -4.552344,55.868639,0 + +
      + + Cuillin Brewery + Sligachan, Scotland + +Sligachan
      +Scotland
      +United Kingdom
      +(01478) 650204
      +[Email]
      +www.cuillinbrewery.co.uk/
      +
      +Bar/Tasting RoomBeer GardenRestaurantMerchandiseHotel RoomsBeer to Go / Off-LicenseToursPublic Internet Access]]>
      + #4 + + -6.175137,57.287992,0 + +
      + + Hebridean Brewing + Stornoway, Scotland + +Stornoway
      +Scotland
      +United Kingdom
      +(01851) 700123
      +[Email]
      +www.hebridean-brewery.co.uk/
      +
      ]]>
      + #8 + + -6.38103,58.206777,0 + +
      + + Broughton Ales + The Borders, Scotland + +Biggar
      +The Borders
      +Scotland
      +United Kingdom
      +(01899) 830345
      +[Email]
      +www.broughtonales.co.uk/
      +
      ]]>
      + #4 + + -3.410744,55.614468,0 + +
      +
      + + Shropshire + + John Roberts Brewing Company + Bishops Castle, Shropshire + +Bishops Castle
      +Shropshire
      +United Kingdom
      +(01588) 638797
      ]]>
      + #6 + + -2.997427,52.49479,0 + +
      + + Six Bells Brewery + Bishops Castle, Shropshire + +Bishops Castle
      +Shropshire
      +United Kingdom
      +(01588) 630144
      +www.bishops-castle.co.uk/SixBells/brewery.htm
      +
      +Bar/Tasting RoomRestaurant]]>
      + #7 + + -2.998094,52.49062900000001,0 + +
      + + Corvedale Brewery + Craven Arms, Shropshire + +Craven Arms
      +Shropshire
      +United Kingdom
      +(01584) 861239
      +[Email]
      +thesuninn.netfirms.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -2.833799,52.44042,0 + +
      + + Wood Brewery + Craven Arms, Shropshire + +Craven Arms
      +Shropshire
      +United Kingdom
      +(01588) 672523
      +[Email]
      +www.woodbrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -2.833799,52.44042,0 + +
      + + Marches Ales + Ludlow, Shropshire + +Ludlow
      +Shropshire
      +United Kingdom
      +(01584) 878999
      +[Email]
      ]]>
      + #6 + + -2.715657,52.366254,0 + +
      + + Worfield Brewery + Madeley, Shropshire + +Madeley
      +Shropshire
      +United Kingdom
      +(01746) 769606
      +www.worfieldbrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -2.472642,52.60958000000001,0 + +
      + + Stonehouse Brewery + Oswestry, Shropshire + +Weston
      +Oswestry
      +Shropshire
      +United Kingdom
      +(01691) 676457
      +[Email]
      +www.stonehousebrewery.co.uk/
      +
      +MerchandiseBeer to Go / Off-LicenseTours]]>
      + #4 + + -3.053678,52.859916,0 + +
      + + Dolphin Brewery + Shrewsbury, Shropshire + +Shrewsbury
      +Shropshire
      +United Kingdom
      +(01743) 350419
      ]]>
      + #6 + + -2.746698,52.717803,0 + +
      + + Salopian Brewery + Shrewsbury, Shropshire + +Shrewsbury
      +Shropshire
      +United Kingdom
      +(01743) 248414
      +www.salopianbrewery.co.uk/
      +
      ]]>
      + #8 + + -2.787049,52.706875,0 + +
      + + Ironbridge Brewery Ltd + Telford, Shropshire + +Ironbridge
      +Telford
      +Shropshire
      +United Kingdom
      +(01952) 433910
      +www.ironbridgebrewery.co.uk/
      +
      +Tours]]>
      + #8 + + -2.494315,52.629644,0 + +
      + + Hanby Ales Ltd. + Wem, Shropshire + +Soulton Road
      +Wem
      +Shropshire
      +United Kingdom
      +(01939) 232432
      ]]>
      + #6 + + -2.721092,52.857151,0 + +
      +
      + + Somerset + + Moor Beer Company + Ashcott, Somerset + +Ashcott
      +Somerset
      +United Kingdom
      +(01458) 210050
      +[Email]
      +www.moorbeer.co.uk/
      +
      +MerchandiseTours]]>
      + #4 + + -2.811409,51.129305,0 + +
      + + Abbey Ales Limited + Bath, Somerset + +Bath
      +Somerset
      +United Kingdom
      +(01225) 444437
      +[Email]
      +www.abbeyales.co.uk/
      +
      ]]>
      + #6 + + -2.361918,51.389364,0 + +
      + + Butcombe Brewery Ltd. + Bristol, Somerset + +Wrington
      +Bristol
      +Somerset
      +United Kingdom
      +(01934) 863963
      +[Email]
      +www.butcombe.com/
      +
      ]]>
      + #8 + + -2.76177,51.35631,0 + +
      + + Berrow Brewery + Burnham-on-Sea, Somerset + +Somerset
      +United Kingdom
      ]]>
      + #4 + + -2.996978,51.237961,0 + +
      + + Fox Brothers and Co. Ltd. + Somerset, Somerset + +Somerset
      +United Kingdom
      ]]>
      + #6 + + -3.090291999999999,51.018167,0 + +
      + + Cottage Brewing Company + West Lydford, Somerset + +Somerset
      +United Kingdom
      ]]>
      + #4 + + -2.622101,51.081986,0 + +
      + + RCH Brewery + Weston-super-Mare, Somerset + +Weston-super-Mare
      +Somerset
      +United Kingdom
      +(01934) 834447
      +[Email]
      +www.rchbrewery.com/
      +
      +Merchandise]]>
      + #4 + + -2.88177,51.372915,0 + +
      + + Cotleigh Brewery + Wiveliscombe, Somerset + +Wiveliscombe
      +Somerset
      +United Kingdom
      +(01984) 624086
      +[Email]
      +www.cotleighbrewery.com/
      +
      ]]>
      + #6 + + -3.306827,51.042942,0 + +
      + + Exmoor Ales + Wiveliscombe, Somerset + +Somerset
      +United Kingdom
      +(01984) 623798
      +[Email]
      +www.exmoorales.co.uk/
      +
      ]]>
      + #4 + + -3.311753,51.041031,0 + +
      +
      + + South Yorkshire + + Acorn Brewery + Barnsley, South Yorkshire + +Wombwell
      +Barnsley
      +South Yorkshire
      +United Kingdom
      +(01226) 270734
      +[Email]
      +www.acornbrewery.net/
      +
      ]]>
      + #6 + + -1.412732,53.53302,0 + +
      + + Oakwell Brewery + Barnsley, South Yorkshire + +Barnsley
      +South Yorkshire
      +United Kingdom
      +(01226) 296161
      ]]>
      + #4 + + -1.481272,53.552933,0 + +
      + + Glentworth Brewery + Doncaster, South Yorkshire + +Skellow
      +Doncaster
      +South Yorkshire
      +United Kingdom
      +(01302) 725555
      ]]>
      + #6 + + -1.195566,53.589625,0 + +
      + + Concertina Brewery + Mexborough, South Yorkshire + +Mexborough
      +South Yorkshire
      +United Kingdom
      +(01709) 580841
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.293599,53.495522,0 + +
      + + Wentworth Brewery + Rotherham, South Yorkshire + +Wentworth
      +Rotherham
      +South Yorkshire
      +United Kingdom
      +(01226) 747070
      +[Email]
      +www.wentworth-brewery.co.uk/
      +
      +Tours]]>
      + #4 + + -1.41429,53.477067,0 + +
      + + Abbeydale Brewery + Sheffield, South Yorkshire + +Sheffield
      +South Yorkshire
      +United Kingdom
      +(0114) 281 2712
      +[Email]
      +www.abbeydalebrewery.co.uk/
      +
      ]]>
      + #4 + + -1.464795,53.383055,0 + +
      + + Crown Brewery + Sheffield, South Yorkshire + +Sheffield
      +South Yorkshire
      +United Kingdom
      +(0114) 232 2100
      +[Email]
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.488953,53.39483300000001,0 + +
      + + Frog and Parrot + Sheffield, South Yorkshire + +Sheffield
      +South Yorkshire
      +United Kingdom
      +(0114) 272 1280
      +[Email]
      ]]>
      + #8 + + -1.47622,53.379642,0 + +
      + + Kelham Island Brewery + Sheffield, South Yorkshire + +Sheffield
      +South Yorkshire
      +United Kingdom
      +(0114) 249 4804
      +[Email]
      +www.kelhambrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.471583,53.388533,0 + +
      + + Port Mahon + Sheffield, South Yorkshire + +Sheffield
      +South Yorkshire
      +United Kingdom
      +(0114) 249 2295
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.479431,53.388756,0 + +
      +
      + + Staffordshire + + Beowulf Brewing + Brownhills, Staffordshire + +Chasewater Country Park, Pool Road
      +Brownhills
      +Staffordshire
      +United Kingdom
      +(01543) 454067
      +[Email]
      ]]>
      + #4 + + -1.933403,52.647358,0 + +
      + + Bass Brewers + Burton-upon-Trent, Staffordshire + +Burton-upon-Trent
      +Staffordshire
      +United Kingdom
      +(01283) 513347
      +[Email]
      +www.bassale.com/
      +www.caffreys.com/
      +www.coorsbrewers.com/
      +www.worthingtons-whiteshield.com/
      +
      ]]>
      + #8 + + -1.628154,52.804591,0 + +
      + + Burton Bridge Brewery + Burton-upon-Trent, Staffordshire + +Burton-upon-Trent
      +Staffordshire
      +United Kingdom
      +(01283) 510573
      +[Email]
      +www.burtonbridgebrewery.co.uk/
      +
      +Beer to Go / Off-License]]>
      + #6 + + -1.62252,52.806496,0 + +
      + + Coors Brewers Limited + Burton-upon-Trent, Staffordshire + +Staffordshire
      +United Kingdom
      +www.carling.com/
      +
      ]]>
      + #4 + + -1.643034,52.806875,0 + +
      + + Marston, Thompson & Evershed + Burton-upon-Trent, Staffordshire + +Shobnall Road
      +Burton-upon-Trent
      +Staffordshire
      +United Kingdom
      +(01283) 531131
      ]]>
      + #4 + + -1.643034,52.806875,0 + +
      + + Museum Brewing + Burton-upon-Trent, Staffordshire + +Burton-upon-Trent
      +Staffordshire
      +United Kingdom
      +(01283) 511000
      +[Email]
      +www.bass-museum.com/
      +
      ]]>
      + #6 + + -1.633265,52.80904,0 + +
      + + Old Cottage Beer Company + Burton-upon-Trent, Staffordshire + +Hawkins Lane
      +Burton-upon-Trent
      +Staffordshire
      +United Kingdom
      +(07780) 900006
      +[Email]
      ]]>
      + #4 + + -1.643034,52.806875,0 + +
      + + Tower Brewery + Burton-upon-Trent, Staffordshire + +Glensyl Way
      +Burton-upon-Trent
      +Staffordshire
      +United Kingdom
      +(07771) 926323
      ]]>
      + #4 + + -1.643034,52.806875,0 + +
      + + Slaters' Brewery + Eccleshall, Staffordshire + +Eccleshall
      +Staffordshire
      +United Kingdom
      +(01785) 850300
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -2.252083,52.861166,0 + +
      + + Blythe Brewery + Hamstall Ridware, Staffordshire + +Hamstall Ridware
      +Staffordshire
      +United Kingdom
      +(07773) 747724
      +[Email]
      +www.blythebrewery.co.uk/
      +
      ]]>
      + #4 + + -1.843305,52.769395,0 + +
      + + Quartz Brewing Ltd + Kings Bromley, Staffordshire + +Alrewas Road
      +Kings Bromley
      +Staffordshire
      +United Kingdom
      +(01543) 473965
      +[Email]
      +www.quartzbrewing.co.uk/
      +
      +Tours]]>
      + #4 + + -1.821076,52.748998,0 + +
      + + Lichfield Brewery + Lichfield, Staffordshire + +Boley Park
      +Lichfield
      +Staffordshire
      +United Kingdom
      +(01543) 419919
      ]]>
      + #8 + + -1.797546,52.68458200000001,0 + +
      + + Titanic Brewery + Stoke-on-Trent, Staffordshire + +Burslem
      +Stoke-on-Trent
      +Staffordshire
      +United Kingdom
      +(01782) 823447
      +[Email]
      +www.titanicbrewery.co.uk/
      +
      ]]>
      + #4 + + -2.180053,53.003038,0 + +
      +
      + + Suffolk + + Kings Head Brewing + Bildeston, Suffolk + +Bildeston
      +Suffolk
      +United Kingdom
      +(01449) 741434
      +[Email]
      +www.bildestonkingshead.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + 0.908139,52.10799000000001,0 + +
      + + Brandon Brewery + Brandon, Suffolk + +Brandon
      +Suffolk
      +United Kingdom
      +(07876) 234689
      +[Email]
      +www.brandonbrewery.co.uk/
      +
      ]]>
      + #8 + + 0.623461,52.450239,0 + +
      + + Green Dragon Free House and Brewery + Bungay, Suffolk + +Bungay
      +Suffolk
      +United Kingdom
      +(01986) 892681
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + 1.435139,52.457917,0 + +
      + + St Peter's Brewery + Bungay, Suffolk + +St Peter South Elmham
      +Bungay
      +Suffolk
      +United Kingdom
      +(01986) 782322
      +[Email]
      +www.stpetersbrewery.co.uk/
      +
      +Merchandise]]>
      + #6 + + 1.438162,52.451302,0 + +
      + + Bartrams Brewery + Bury St Edmunds, Suffolk + +Rougham
      +Bury St Edmunds
      +Suffolk
      +United Kingdom
      +(01449) 737655
      ]]>
      + #6 + + 0.723633,52.24799500000001,0 + +
      + + Greene King + Bury St. Edmunds, Suffolk + +Bury St. Edmunds
      +Suffolk
      +United Kingdom
      +(01284) 763222
      +[Email]
      +www.greeneking.co.uk/
      +www.ruddles.co.uk/
      +
      ]]>
      + #6 + + 0.715964,52.241001,0 + +
      + + Old Cannon Brewery + Bury St. Edmunds, Suffolk + +Bury St. Edmunds
      +Suffolk
      +United Kingdom
      +(01284) 768769
      +Bar/Tasting RoomRestaurantHotel Rooms]]>
      + #8 + + 0.714564,52.249597,0 + +
      + + Old Chimneys Brewery + Diss, Suffolk + +Market Weston
      +Diss
      +Suffolk
      +United Kingdom
      +(01359) 221411
      ]]>
      + #6 + + 1.154451,52.34690199999999,0 + +
      + + Earl Soham Brewery + Earl Soham, Suffolk + +The Street
      +Earl Soham
      +Suffolk
      +United Kingdom
      +(01728) 684097
      +[Email]
      +www.EarlSohamBrewery.co.uk/
      +
      ]]>
      + #4 + + 1.265357,52.22026200000001,0 + +
      + + Greenjack Brewery + Lowestoft, Suffolk + +Lowestoft
      +Suffolk
      +United Kingdom
      +(01502) 582711
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.755155,52.48018999999999,0 + +
      + + Oulton Ales + Lowestoft, Suffolk + +Oulton Broad
      +Lowestoft
      +Suffolk
      +United Kingdom
      +(01502) 587905
      ]]>
      + #4 + + 1.753642,52.474739,0 + +
      + + Adnams & Co. + Southwold, Suffolk + +Suffolk
      +United Kingdom
      +(01502) 727200
      +[Email]
      +www.adnams.co.uk/
      +
      ]]>
      + #4 + + 1.679138,52.326182,0 + +
      + + Hektors Brewery + Southwold, Suffolk + +Henham Park
      +Southwold
      +Suffolk
      +United Kingdom
      +(07900) 553 426
      +[Email]
      +www.hektorsbrewery.com/
      +
      ]]>
      + #4 + + 1.679138,52.326182,0 + +
      + + Cox & Hobrook + Stowmarket, Suffolk + +Buxhall
      +Stowmarket
      +Suffolk
      +United Kingdom
      +(01449) 73623
      ]]>
      + #4 + + 0.993414,52.188429,0 + +
      + + Mauldons Brewery + Sudbury, Suffolk + +Chilton Industrial Estate
      +Sudbury
      +Suffolk
      +United Kingdom
      +(01787) 311055
      +[Email]
      +www.mauldons.co.uk/
      +
      ]]>
      + #8 + + 0.749253,52.04413499999999,0 + +
      + + Elveden Ales + Thetford, Suffolk + +Elveden Estate
      +Thetford
      +Suffolk
      +United Kingdom
      +(01842) 878922
      ]]>
      + #4 + + 0.752958,52.41456899999999,0 + +
      +
      + + Surrey + + Weltons Brewery + Dorking, Surrey + +Vincent Lane
      +Dorking
      +Surrey
      +United Kingdom
      +(01306) 888655
      +[Email]
      +www.weltons.co.uk/
      +
      ]]>
      + #4 + + -0.329744,51.23291,0 + +
      + + Pilgrim Brewery + Reigate, Surrey + +Reigate
      +Surrey
      +United Kingdom
      +(01737) 222651
      +[Email]
      +www.pilgrim.co.uk/
      +
      ]]>
      + #8 + + -0.210724,51.23836100000001,0 + +
      + + Hogs Back Brewery + Tongham, Surrey + +The Street
      +Tongham
      +Surrey
      +United Kingdom
      +(01252) 783000
      +[Email]
      +www.hogsback.co.uk/
      +
      ]]>
      + #6 + + -0.7299310000000001,51.24374600000001,0 + +
      +
      + + Tyne and Wear + + Federation Brewery + Gateshead, Tyne and Wear + +Dunston
      +Gateshead
      +Tyne and Wear
      +United Kingdom
      +(0191) 4609023
      +[Email]
      ]]>
      + #6 + + -1.65757,54.954808,0 + +
      + + Jarrow Brewing + Jarrow, Tyne and Wear + +Jarrow
      +Tyne and Wear
      +United Kingdom
      +(0191) 428 5454
      +[Email]
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -1.483733,54.97861,0 + +
      + + Hadrian & Border Brewery Ltd. + Newcastle upon Tyne, Tyne and Wear + +Newcastle upon Tyne
      +Tyne and Wear
      +United Kingdom
      +(0191) 276 5302
      ]]>
      + #4 + + -1.613221,54.97781700000001,0 + +
      + + Darwin Brewery + Sunderland, Tyne and Wear + +Sunderland
      +Tyne and Wear
      +United Kingdom
      +(0191) 514 4746
      +[Email]
      +www.darwinbrewery.com/
      +
      ]]>
      + #6 + + -1.376264,54.903665,0 + +
      + + Double Maxim Beer Company + Sunderland, Tyne and Wear + +Tyne and Wear
      +United Kingdom
      +[Email]
      +www.dmbc.org.uk/
      +
      ]]>
      + #4 + + -1.381453,54.90444899999999,0 + +
      + + Mordue Brewery + Wallsend, Tyne and Wear + +West Chirton North Industrial Estate
      +Wallsend
      +Tyne and Wear
      +United Kingdom
      +(0191) 2961879
      ]]>
      + #6 + + -1.492507,55.01674,0 + +
      +
      + + Wales + + Purple Moose Brewery + Porthmadog, Wales + +Porthmadog
      +Gwynedd
      +United Kingdom
      +(01766) 515571
      +[Email]
      +www.purplemoose.co.uk/
      ]]>
      + #4 + + -4.12946,52.92828,0 + +
      + + Nag's Head + Boncath, Wales + +Boncath
      +Wales
      +United Kingdom
      +(01239) 841200
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -4.552762,52.032501,0 + +
      + + Breconshire Brewery + Brecon, Wales + +Wales
      +United Kingdom
      +[Email]
      +www.breconshirebrewery.com/
      +
      ]]>
      + #5 + + -3.390556,51.947292,0 + +
      + + Bragdy Ty Bach + Capel Bangor, Wales + +Wales
      +United Kingdom
      +01970 880248
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -3.982121,52.40441600000001,0 + +
      + + Bullmastiff Brewery + Cardiff, Wales + +Leckwith
      +Cardiff
      +Wales
      +United Kingdom
      +(02920) 665292
      ]]>
      + #8 + + -3.202867,51.46607,0 + +
      + + SA Brain & Co. Ltd. + Cardiff, Wales + +Cardiff
      +Wales
      +United Kingdom
      +(02920) 402060
      +[Email]
      +www.sabrain.com/
      +
      ]]>
      + #6 + + -3.178996000000001,51.473597,0 + +
      + + Cwmbran Spring Brewery + Cwmbran, Wales + +Upper Cwmbran
      +Cwmbran
      +Wales
      +United Kingdom
      +(0780) 3466346
      ]]>
      + #5 + + -3.025618,51.64824899999999,0 + +
      + + Rhymney Brewery + Dowlais, Wales + +Dowlais
      +Wales
      +United Kingdom
      +(01685) 722253
      +[Email]
      +www.rhymneybreweryltd.com/
      +
      ]]>
      + #4 + + -3.352512,51.760479,0 + +
      + + Bragwr Arbennig o Geredigion + Llandysul, Wales + +Llangrannog
      +Llandysul
      +Wales
      +United Kingdom
      +01239 654099
      ]]>
      + #4 + + -4.463187,52.15878099999999,0 + +
      + + Felinfoel Brewery Co Ltd + Llanelli, Wales + +Llanelli
      +Wales
      +United Kingdom
      +01554 773357
      +[Email]
      +www.felinfoel-brewery.com/
      +
      ]]>
      + #6 + + -4.145345,51.698892,0 + +
      + + Red Lion Hotel + Llanidloes, Wales + +Llanidloes
      +Wales
      +United Kingdom
      +(01686) 412270
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -3.539949,52.449341,0 + +
      + + White Hart Ales + Machen, Wales + +Nant-y-Ceisiad
      +Machen
      +Wales
      +United Kingdom
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -3.13916,51.592418,0 + +
      + + Lord Raglan Inn + Merthyr Tydfil, Wales + +Cefn-Coed-y-Cymmer
      +Merthyr Tydfil
      +Wales
      +United Kingdom
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -3.363792,51.757299,0 + +
      + + Warcop Country Ales + Newport, Wales + +Newport
      +Wales
      +United Kingdom
      +(01633) 680058
      +[Email]
      +www.warcopales.com/
      +
      ]]>
      + #4 + + -2.998343,51.58774,0 + +
      + + Pembroke Brewery Co. + Pembroke, Wales + +108 Main Street
      +Pembroke
      +Wales
      +United Kingdom
      +(01646) 682517
      ]]>
      + #5 + + -4.908433,51.67373200000001,0 + +
      + + Bragdy Ceredigion Brewery + Pentregat, Wales + +Pentregat
      +Wales
      +United Kingdom
      +(01545) 561417
      +[Email]
      ]]>
      + #4 + + -4.406529,52.14122,0 + +
      + + Bryncelyn Brewery + Swansea, Wales + +Ystalyfera
      +Swansea
      +Wales
      +United Kingdom
      +(01639) 843625
      +[Email]
      +www.bryncelynbrewery.org.uk/
      +
      +Bar/Tasting RoomMerchandiseBeer to Go / Off-LicenseTours]]>
      + #8 + + -3.941356,51.643202,0 + +
      + + Swansea Brewing Company + Swansea, Wales + +Bishopston
      +Swansea
      +Wales
      +United Kingdom
      +(01792) 290197
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -4.052148,51.58218899999999,0 + +
      + + Tomos Watkin and Sons Ltd. + Swansea, Wales + +Swansea Enterprise Park
      +Swansea
      +Wales
      +United Kingdom
      +(01792) 775333
      +[Email]
      +www.hurns.co.uk/
      +
      ]]>
      + #4 + + -3.938568,51.623158,0 + +
      + + Bragdy Ynys Mon + Talwrn, Wales + +Talwrn
      +Wales
      +United Kingdom
      +(01248) 723801
      +[Email]
      ]]>
      + #4 + + -4.266839,53.270327,0 + +
      + + Snowdonia Parc Brew Pub + Waunfawr, Wales + +Wales
      +United Kingdom
      +01286 650409
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -4.199664,53.11073,0 + +
      + + Plassey Brewery + Wrexham, Wales + +Eyton
      +Wrexham
      +Wales
      +United Kingdom
      +(01978) 781111
      +[Email]
      +www.plasseybrewery.co.uk/
      +
      ]]>
      + #6 + + -2.960821,53.057407,0 + +
      +
      + + Warwick + + Church End Brewery + Atherstone, Warwick + +Atherstone
      +Warwick
      +United Kingdom
      +(01827) 713080
      +[Email]
      +www.churchendbrewery.co.uk/
      +
      +Bar/Tasting RoomTours]]>
      + #6 + + -1.566359,52.50709000000001,0 + +
      + + Fantasy Brewery + Nuneaton, Warwick + +Nuneaton
      +Warwick
      +United Kingdom
      +(02476) 373343
      +[Email]
      +www.fantasybrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.465107,52.52468300000001,0 + +
      +
      + + West Midlands + + Aston Manor Brewery + Birmingham, West Midlands + +Aston
      +Birmingham
      +West Midlands
      +United Kingdom
      +(0121) 328 436
      +[Email]
      +www.astonmanor.co.uk/
      +
      ]]>
      + #6 + + -1.977346,52.48162899999999,0 + +
      + + Rainbow Inn and Brewery + Coventry, West Midlands + +Allesley Village
      +Coventry
      +West Midlands
      +United Kingdom
      +(01203) 402888
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.559051,52.422976,0 + +
      + + Daniel Batham & Son Ltd + Dudley, West Midlands + +Brierley Hill
      +Dudley
      +West Midlands
      +United Kingdom
      +(01384) 77229
      +[Email]
      +www.bathams.co.uk/
      +
      ]]>
      + #6 + + -2.121114,52.47118199999999,0 + +
      + + Holden's Brewery + Dudley, West Midlands + +Woodsetton
      +Dudley
      +West Midlands
      +United Kingdom
      +(01902) 880051
      +[Email]
      +www.holdensbrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurantTours]]>
      + #6 + + -2.098595,52.570911,0 + +
      + + Olde Swan + Dudley, West Midlands + +Netherton
      +Dudley
      +West Midlands
      +United Kingdom
      +(01384) 253075
      ]]>
      + #4 + + -2.087335,52.508672,0 + +
      + + Sarah Hughes Brewery + Dudley, West Midlands + +West Midlands
      +United Kingdom
      ]]>
      + #4 + + -2.087335,52.508672,0 + +
      + + Enville Brewery + Stourbridge, West Midlands + +Enville
      +Stourbridge
      +West Midlands
      +United Kingdom
      +(01384) 873728
      +[Email]
      +www.envilleales.com/
      +
      ]]>
      + #8 + + -2.287276,52.47410000000001,0 + +
      + + Highgate Brewery + Walsall, West Midlands + +Walsall
      +West Midlands
      +United Kingdom
      +(01922) 644453
      +[Email]
      +www.astonmanor.co.uk/
      +www.highgatebrewery.com/
      +
      ]]>
      + #4 + + -1.982292,52.58594,0 + +
      + + Banks's Park Brewery + Wolverhampton, West Midlands + +Wolverhampton
      +West Midlands
      +United Kingdom
      +(01902) 711811
      +[Email]
      +www.fullpint.co.uk/
      +
      ]]>
      + #6 + + -2.13693,52.586543,0 + +
      + + Goldthorn Brewery + Wolverhampton, West Midlands + +Sunbeam Street
      +Wolverhampton
      +West Midlands
      +United Kingdom
      +(01902) 756920
      +[Email]
      ]]>
      + #4 + + -2.129282,52.585725,0 + +
      + + Wolverhampton & Dudley Breweries, PLC + Wolverhampton, West Midlands + +Park Brewery
      +Wolverhampton
      +West Midlands
      +United Kingdom
      +(01902) 711811
      +[Email]
      +www.fullpint.co.uk/
      +
      ]]>
      + #8 + + -2.114798,52.58828,0 + +
      +
      + + West Sussex + + Arundel Brewery + Arundel, West Sussex + +Unit C7
      +Arundel
      +West Sussex
      +United Kingdom
      +(01903) 733111
      +[Email]
      +www.arundelbrewery.co.uk/
      +
      ]]>
      + #4 + + -0.5594980000000001,50.85550199999999,0 + +
      + + Gribble Brewery + Chichester, West Sussex + +Chichester
      +West Sussex
      +United Kingdom
      +(01243) 786893
      +[Email]
      +www.gribblebrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -0.780178,50.836639,0 + +
      + + Dark Star Brewing + Haywards Heath, West Sussex + +Ansty
      +Haywards Heath
      +West Sussex
      +United Kingdom
      +(01444) 412311
      +[Email]
      +www.darkstarbrewing.co.uk/
      +
      ]]>
      + #4 + + -0.103108,50.997318,0 + +
      + + Andy Hepworth + Horsham, West Sussex + +Horsham
      +West Sussex
      +United Kingdom
      +(01403) 269696
      ]]>
      + #4 + + -0.326967,51.063749,0 + +
      + + King and Company + Horsham, West Sussex + +Foundry Lane
      +Horsham
      +West Sussex
      +United Kingdom
      +(01403) 272102
      +[Email]
      +www.kingfamilybrewers.co.uk/
      +
      ]]>
      + #4 + + -0.326967,51.063749,0 + +
      + + W J King & Co (Brewers) + Horsham, West Sussex + +Foundry Lane
      +Horsham
      +West Sussex
      +United Kingdom
      +(01403) 272102
      +[Email]
      +www.kingfamilybrewers.co.uk/
      +
      ]]>
      + #4 + + -0.326967,51.063749,0 + +
      + + Ballard's Brewery + Petersfield, West Sussex + +Nyewood
      +Petersfield
      +West Sussex
      +United Kingdom
      +(01730) 821362
      +[Email]
      +www.ballardsbrewery.org.uk/
      +
      ]]>
      + #4 + + -0.93394,51.004629,0 + +
      + + Hammerpot Brewery + Poling, West Sussex + +Poling
      +West Sussex
      +United Kingdom
      +(01903) 883338
      +[Email]
      +www.hammerpot-brewery.co.uk/
      +
      ]]>
      + #4 + + -0.520251,50.833057,0 + +
      +
      + + West Yorkshire + + Salamander Brewing Co Ltd + Bradford, West Yorkshire + +Dudley Hill
      +Bradford
      +West Yorkshire
      +United Kingdom
      +(01274) 652 323
      +[Email]
      +www.salamanderbrewing.co.uk/
      +
      ]]>
      + #6 + + -1.725974,53.775028,0 + +
      + + Halifax Steam Brewery + Brighouse, West Yorkshire + +Brighouse
      +West Yorkshire
      +United Kingdom
      +(01484) 715074
      ]]>
      + #4 + + -1.782649,53.702853,0 + +
      + + Anglo-Dutch Brewery + Dewsbury, West Yorkshire + +Mill Street East
      +Dewsbury
      +West Yorkshire
      +United Kingdom
      +(01924) 457772
      +[Email]
      +www.anglo-dutch-brewery.co.uk/
      +
      ]]>
      + #4 + + -1.632841,53.691546,0 + +
      + + Leggers Inn + Dewsbury, West Yorkshire + +Saviltown
      +Dewsbury
      +West Yorkshire
      +United Kingdom
      +(01924) 502846
      ]]>
      + #6 + + -1.661992,53.727229,0 + +
      + + Eastwood & Sanders (Fine Ales) Ltd + Elland, West Yorkshire + +Heathfield Street
      +Elland
      +West Yorkshire
      +United Kingdom
      +(01422) 377677
      +[Email]
      ]]>
      + #4 + + -1.83378,53.68416299999999,0 + +
      + + Ryburn Brewery + Halifax, West Yorkshire + +Sowerby Bridge
      +Halifax
      +West Yorkshire
      +United Kingdom
      +(01422) 835413
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -1.861577,53.72438,0 + +
      + + Linfit Brewery + Huddersfield, West Yorkshire + +Linthwaite
      +Huddersfield
      +West Yorkshire
      +United Kingdom
      +(01484) 842370
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -1.816226,53.660261,0 + +
      + + Riverhead Brewery + Huddersfield, West Yorkshire + +Marsden
      +Huddersfield
      +West Yorkshire
      +United Kingdom
      +(01484) 841270
      +[Email]
      +www.riverheadbrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.926992,53.601038,0 + +
      + + Goose Eye Brewery + Keighley, West Yorkshire + +South Street
      +Keighley
      +West Yorkshire
      +United Kingdom
      +(01535) 605807
      +[Email]
      +www.goose-eye-brewery.co.uk/
      +
      ]]>
      + #7 + + -1.915668,53.854651,0 + +
      + + Old Bear Brewery + Keighley, West Yorkshire + +Pitt Street
      +Keighley
      +West Yorkshire
      +United Kingdom
      +(01535) 601222
      +[Email]
      +www.oldbearbrewery.co.uk/
      +
      +Bar/Tasting RoomMerchandiseBeer to Go / Off-LicenseToursPublic Internet Access]]>
      + #4 + + -1.909745,53.865692,0 + +
      + + Timothy Taylor & Co. Ltd. + Keighley, West Yorkshire + +West Yorkshire
      +United Kingdom
      +(01535) 603139
      +www.timothy-taylor.co.uk/
      +
      ]]>
      + #4 + + -1.909745,53.865692,0 + +
      + + Turkey Inn + Keighley, West Yorkshire + +Oakworth
      +Keighley
      +West Yorkshire
      +United Kingdom
      +(01535) 681339
      ]]>
      + #6 + + -1.957709,53.86159800000001,0 + +
      + + Worth Brewery + Keighley, West Yorkshire + +Keighley
      +West Yorkshire
      +United Kingdom
      +(01535) 669912
      +[Email]
      +members.aol.com/worthbrew/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.905369,53.865385,0 + +
      + + Naylor's Brewery + Keighly, West Yorkshire + +Crosshills
      +Keighly
      +West Yorkshire
      +United Kingdom
      +(01535) 637451
      +[Email]
      +www.naylorsbrewery.co.uk/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.987365,53.901526,0 + +
      + + Carlsberg UK + Leeds, West Yorkshire + +Hunslet Road
      +Leeds
      +West Yorkshire
      +United Kingdom
      +(0845) 8502850
      +www.carlsberg.co.uk/
      +
      ]]>
      + #6 + + -1.53549,53.788058,0 + +
      + + Merrimans Brewery Ltd. + Leeds, West Yorkshire + +Beeston
      +Leeds
      +West Yorkshire
      +United Kingdom
      +(0113) 2771314
      +[Email]
      +www.e-oldfart.com/
      +
      ]]>
      + #8 + + -1.559161,53.78345,0 + +
      + + Ossett Brewing + Osset, West Yorkshire + +Osset
      +West Yorkshire
      +United Kingdom
      +(01924) 261333
      +[Email]
      +www.ossett-brewery.co.uk/
      +
      ]]>
      + #8 + + -1.590374,53.667879,0 + +
      + + Briscoes Brewery + Otley, West Yorkshire + +Otley
      +West Yorkshire
      +United Kingdom
      +(01943) 466515
      +[Email]
      +freespace.virgin.net/bob.jackson/briscoe.htm
      +
      ]]>
      + #8 + + -1.700494,53.902101,0 + +
      + + Fernandes Brewery + Wakefield, West Yorkshire + +Kirkgate
      +Wakefield
      +West Yorkshire
      +United Kingdom
      +(01924) 291709
      +[Email]
      +www.fernandes-brewery.gowyld.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #8 + + -1.493069,53.680277,0 + +
      + + HB Clark and Co. (Successors) Ltd. + Wakefield, West Yorkshire + +West Yorkshire
      +United Kingdom
      +[Email]
      +www.hbclark.co.uk/
      +
      ]]>
      + #4 + + -1.499097,53.682973,0 + +
      + + Tigertops Brewery + Wakefield, West Yorkshire + +Flanshaw
      +Wakefield
      +West Yorkshire
      +United Kingdom
      +(01924) 378538
      ]]>
      + #4 + + -1.499097,53.682973,0 + +
      +
      + + Wiltshire + + Box Steam Brewery + Colerne, Wiltshire + +Rode Hill
      +Colerne
      +Wiltshire
      +United Kingdom
      +(07887) 745299
      +[Email]
      +www.boxsteambrewery.com/
      +
      ]]>
      + #4 + + -2.260135,51.439287,0 + +
      + + Wadworth and Co. Ltd. + Devizes, Wiltshire + +Devizes
      +Wiltshire
      +United Kingdom
      +(01380) 723361
      +[Email]
      +www.wadworth.co.uk/
      +
      ]]>
      + #4 + + -1.994756,51.35198199999999,0 + +
      + + Cascade Drinks Ltd. + Melksham, Wiltshire + +Bowerhill
      +Melksham
      +Wiltshire
      +United Kingdom
      +(01225) 790770
      ]]>
      + #6 + + -2.131044,51.360906,0 + +
      + + Downton Brewery Company + Salisbury, Wiltshire + +Batten Road, Downton
      +Salisbury
      +Wiltshire
      +United Kingdom
      +(01722) 322890
      ]]>
      + #4 + + -1.797626,51.067399,0 + +
      + + Hidden Brewery + Salisbury, Wiltshire + +Dinton
      +Salisbury
      +Wiltshire
      +United Kingdom
      +(01722) 716440
      +[Email]
      +www.thehiddenbrewery.com/
      +
      +Bar/Tasting RoomMerchandiseHotel RoomsBeer to Go / Off-LicenseTours]]>
      + #4 + + -1.797626,51.067399,0 + +
      + + Hop Back Brewery + Salisbury, Wiltshire + +Downton
      +Salisbury
      +Wiltshire
      +United Kingdom
      +(01725) 510986
      +[Email]
      +www.hopback.co.uk/
      +
      ]]>
      + #6 + + -1.757397,50.99572,0 + +
      + + Keystone Brewery + Salisbury, Wiltshire + +Berwick St Leonard
      +Salisbury
      +Wiltshire
      +United Kingdom
      +(01747) 820426
      +[Email]
      +www.keystonebrewery.co.uk/
      +
      ]]>
      + #4 + + -1.797626,51.067399,0 + +
      + + Stonehenge Ales Ltd + Salisbury, Wiltshire + +Netheravon
      +Salisbury
      +Wiltshire
      +United Kingdom
      +(01980) 670631
      +[Email]
      +www.stonehengeales.sagenet.co.uk/
      +
      ]]>
      + #4 + + -1.797626,51.067399,0 + +
      + + Archers The Brewers + Swindon, Wiltshire + +Churchward
      +Swindon
      +Wiltshire
      +United Kingdom
      +(01793) 879929
      +[Email]
      +www.archersbrewery.co.uk/
      +
      +Bar/Tasting RoomMerchandiseBeer to Go / Off-LicenseTours]]>
      + #4 + + -1.781985,51.558418,0 + +
      + + Arkell's Brewery Ltd. + Swindon, Wiltshire + +Wiltshire
      +United Kingdom
      +(01793) 823026
      +[Email]
      +www.arkells.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #4 + + -1.781985,51.558418,0 + +
      + + Hobden's Wessex Brewery + Warminster, Wiltshire + +Norton Ferris
      +Warminster
      +Wiltshire
      +United Kingdom
      +(01985) 844532
      +[Email]
      ]]>
      + #4 + + -2.181219,51.204922,0 + +
      + + Westbury Ales + Westbury, Wiltshire + +Westbury
      +Wiltshire
      +United Kingdom
      +(07771) 976865
      +[Email]
      +www.westburyales.com/
      +
      +Bar/Tasting RoomRestaurant]]>
      + #6 + + -2.1805,51.26242600000001,0 + +
      +
      +
      +
      +
      diff --git a/chapter_10/database_connect.php b/chapter_10/database_connect.php new file mode 100644 index 0000000..01cde0e --- /dev/null +++ b/chapter_10/database_connect.php @@ -0,0 +1,7 @@ + diff --git a/chapter_10/listing_10_01.sql b/chapter_10/listing_10_01.sql new file mode 100644 index 0000000..1acc897 --- /dev/null +++ b/chapter_10/listing_10_01.sql @@ -0,0 +1,12 @@ +create table geoname ( + name varchar(127), + state char(3), + country char(2), + population int(11), + latitude double, + longitude double, + + primary key (country, state, name), + index coordinates (latitude, longitude) +); + diff --git a/chapter_10/listing_10_02.kml b/chapter_10/listing_10_02.kml new file mode 100644 index 0000000..2f9d4aa --- /dev/null +++ b/chapter_10/listing_10_02.kml @@ -0,0 +1,213 @@ + + + + Cities in Pennsylvania + + Allentown + + + -75.4906,40.6083,0 + + + + Altoona + + + -78.395,40.5186,0 + + + + Bethel Park + + + -80.0397,40.3275,0 + + + + Bethlehem + + + -75.3708,40.6258,0 + + + + Chester + + + -75.3561,39.8494,0 + + + + Easton + + + -75.2211,40.6883,0 + + + + Erie + + + -80.0853,42.1292,0 + + + + Harrisburg + + + -76.8847,40.2736,0 + + + + Johnstown + + + -78.9222,40.3267,0 + + + + Lancaster + + + -76.3058,40.0378,0 + + + + Lebanon + + + -76.4117,40.3408,0 + + + + McKeesport + + + -79.8644,40.3478,0 + + + + Monroeville + + + -79.7883,40.4211,0 + + + + New Castle + + + -80.3472,41.0036,0 + + + + Norristown + + + -75.3403,40.1214,0 + + + + Philadelphia + + + -75.1642,39.9522,0 + + + + Pittsburgh + + + -79.9961,40.4406,0 + + + + Reading + + + -75.9272,40.3356,0 + + + + Scranton + + + -75.6628,41.4089,0 + + + + State College + + + -77.8603,40.7933,0 + + + + Wilkes-Barre + + + -75.8817,41.2458,0 + + + + Williamsport + + + -77.0014,41.2411,0 + + + + York + + + -76.7281,39.9625,0 + + + + \ No newline at end of file diff --git a/chapter_10/listing_10_03.php b/chapter_10/listing_10_03.php new file mode 100644 index 0000000..1f71a00 --- /dev/null +++ b/chapter_10/listing_10_03.php @@ -0,0 +1,54 @@ + 25000)"; + $result = mysql_query($query); + if (!$result) + die("Unable to retrieve data"); + + // Prepare the KML header + $header = ' + + + Cities in Pennsylvania + '; + + // Generate KML placemarks for the retrieved data + while ($row = mysql_fetch_array($result)) + { + $placemarks = $placemarks.' + + '.htmlentities($row['name']).' + + #city_style + + '.$row['longitude'].','.$row['latitude'].',0 + + '; + } + + // Prepare the KML footer + $footer = ' + +'; + + // Output the final KML + header('Content-type: application/vnd.google-earth.kml+xml'); + echo $header; + echo $placemarks; + echo $footer; +?> \ No newline at end of file diff --git a/chapter_10/listing_10_04.php b/chapter_10/listing_10_04.php new file mode 100644 index 0000000..515142f --- /dev/null +++ b/chapter_10/listing_10_04.php @@ -0,0 +1,56 @@ + 25000)"; + $result = mysql_query($query); + if (!$result) + die("Unable to retrieve data"); + + $now = mktime(); + + // Prepare the Atom header + $header = ' + + Cities in Pennsylvania + with population over 25,000 + '.date('c', $now).' + urn:978-1-4302-1620-9:chapter_10 + + Sterling Udell + + + '; + + // Generate GeoRSS entries for the retrieved data + while ($row = mysql_fetch_array($result)) + { + $urlname = str_replace('_', ' ', $row['name']); + $entries = $entries.' + + '.htmlentities($row['name']).' + + urn:978-1-4302-1620-9:'.$row['country'].$row['state'].'_'.$urlname.' + Population '.$row['population'].' + '.date('c', $now--).' + '.$row['latitude'].' '.$row['longitude'].' + '; + } + + // Prepare the Atom footer + $footer = ' +'; + + // Output the final Atom/GeoRSS + header('Content-type: application/atom+xml'); + echo $header; + echo $entries; + echo $footer; +?> \ No newline at end of file diff --git a/chapter_10/listing_10_05.kml b/chapter_10/listing_10_05.kml new file mode 100644 index 0000000..23b1039 --- /dev/null +++ b/chapter_10/listing_10_05.kml @@ -0,0 +1,17 @@ + + + + Largest Cities + + The 10 largest cities in the map area (North America only) + + + + 0 + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php + onStop + 0 + + + diff --git a/chapter_10/listing_10_06.php b/chapter_10/listing_10_06.php new file mode 100644 index 0000000..4362b49 --- /dev/null +++ b/chapter_10/listing_10_06.php @@ -0,0 +1,67 @@ + $viewport[2]) + $viewport[0] -= 360; + + $north = min(90, (float) $viewport[3]); + $south = max(-90, (float) $viewport[1]); + $east = min(180, (float) $viewport[2]); + $west = max(-180, (float) $viewport[0]); + + // Execute the MySQL query to retrieve the data + $query = "select * + from geoname + where (latitude between $south and $north) + and (longitude between $west and $east) + order by population desc + limit 10"; + $result = mysql_query($query); + if (!$result) + die("Unable to retrieve data"); + + // Prepare the KML header + $header = ' + + + Largest Cities + '; + + // Generate KML placemarks for the retrieved data + while ($row = mysql_fetch_array($result)) + { + $placemarks = $placemarks.' + + '.htmlentities($row['name']).' + + #city_style + + '.$row['longitude'].','.$row['latitude'].',0 + + '; + } + + // Prepare the KML footer + $footer = ' + +'; + + // Output the final KML + header('Content-type: application/vnd.google-earth.kml+xml'); + echo $header; + echo $placemarks; + echo $footer; +?> \ No newline at end of file diff --git a/chapter_10/listing_10_07.xml b/chapter_10/listing_10_07.xml new file mode 100644 index 0000000..e09324c --- /dev/null +++ b/chapter_10/listing_10_07.xml @@ -0,0 +1,16 @@ + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_03.php + + kml + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_04.php + + georss + + + diff --git a/chapter_10/listing_10_08.xml b/chapter_10/listing_10_08.xml new file mode 100644 index 0000000..166887d --- /dev/null +++ b/chapter_10/listing_10_08.xml @@ -0,0 +1,284 @@ + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-130,25,-120,30 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-120,25,-110,30 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-110,25,-100,30 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-100,25,-90,30 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-90,25,-80,30 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-80,25,-70,30 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-70,25,-60,30 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-130,30,-120,35 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-120,30,-110,35 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-110,30,-100,35 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-100,30,-90,35 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-90,30,-80,35 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-80,30,-70,35 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-70,30,-60,35 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-130,35,-120,40 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-120,35,-110,40 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-110,35,-100,40 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-100,35,-90,40 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-90,35,-80,40 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-80,35,-70,40 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-70,35,-60,40 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-130,40,-120,45 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-120,40,-110,45 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-110,40,-100,45 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-100,40,-90,45 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-90,40,-80,45 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-80,40,-70,45 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-70,40,-60,45 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-130,45,-120,50 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-120,45,-110,50 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-110,45,-100,50 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-100,45,-90,50 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-90,45,-80,50 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-80,45,-70,50 + + + kml + + + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX=-70,45,-60,50 + + + kml + + + \ No newline at end of file diff --git a/chapter_10/listing_10_09.php b/chapter_10/listing_10_09.php new file mode 100644 index 0000000..113875f --- /dev/null +++ b/chapter_10/listing_10_09.php @@ -0,0 +1,42 @@ + +'; + + // Create a sitemap url element for each grid cell + for ($lat = $south; $lat < $north; $lat += $lat_grid) + for ($lon = $west; $lon < $east; $lon += $lon_grid) + { + $urls = $urls.' + + + http://sterlingudell.com/bgmm/chapter_10/listing_10_06.php?BBOX='. + $lon.','.$lat.','.($lon + $lon_grid).','.($lat + $lat_grid).' + + + kml + + '; + } + + // Prepare the sitemap XML footer + $footer = ' +'; + + // Output the final sitemap XML + header('Content-type: application/xml'); + echo $header; + echo $urls; + echo $footer; +?> diff --git a/chapter_10/listing_10_10.sql b/chapter_10/listing_10_10.sql new file mode 100644 index 0000000..0464f95 --- /dev/null +++ b/chapter_10/listing_10_10.sql @@ -0,0 +1,9 @@ +select *, + (6371 * acos(cos(radians($lat)) * cos(radians(latitude)) * + cos(radians(longitude) - radians($lng)) + + sin(radians($lat)) * sin(radians(latitude)))) as distance + from geoname + where latitude between ($lat - 1) and ($lat + 1) + and longitude between ($lng - 1) and ($lng + 1) + order by distance asc + limit 1 diff --git a/chapter_10/listing_10_11.php b/chapter_10/listing_10_11.php new file mode 100644 index 0000000..b7d8a12 --- /dev/null +++ b/chapter_10/listing_10_11.php @@ -0,0 +1,48 @@ + \ No newline at end of file diff --git a/chapter_11/listing_11_01.php b/chapter_11/listing_11_01.php new file mode 100644 index 0000000..7cee7d4 --- /dev/null +++ b/chapter_11/listing_11_01.php @@ -0,0 +1,45 @@ + date_add(now(), interval -$days day))"; + $limit = 50; + + // Connect to the database + include 'mod_sf_db_connect.php'; + + // Execute the database query + $query = "select sParkName, + Campground.nParkID, + Avg(fLatitude) fLatitude, + Avg(fLongitude) fLongitude, + Round(Avg(nCGRating)) nCGRating, + Max(nHookups) nHookups, + Max(dtmWhen) dtmWhen, + sTownName, + sState + from Campsite + natural join Campground + where (bSuspect <> 'Y') + $filter + group by Campground.nParkID + order by dtmWhen desc + limit $limit"; + $result = mysql_query($query); + if (!$result) + die("Unable to retrieve data"); + + // Build an array holding all the retrieved data to send to the formatting routine + $campgrounds = array(); + while ($row = mysql_fetch_array($result)) + $campgrounds[] = array('lat' => round($row['fLatitude'], 6), + 'lon' => round($row['fLongitude'], 6), + 'id' => $row['nParkID'], + 'data' => $row); + + if ($_GET['type'] == 'kml') + // Return the results as KML + include 'mod_produce_kml.php'; + else + // Return the results as GeoRSS (actually Atom) + include 'mod_produce_atom.php'; +?> diff --git a/chapter_11/listing_11_02.js b/chapter_11/listing_11_02.js new file mode 100644 index 0000000..4195c71 --- /dev/null +++ b/chapter_11/listing_11_02.js @@ -0,0 +1,18 @@ +// Initialize the recent-entries map object +var options = {backgroundColor: '#D7D5E3', mapTypes: [G_PHYSICAL_MAP]}; +recentMap = new GMap2(mapDiv, options); +recentMap.setCenter(new GLatLng(39.8, -98.5), 3, G_PHYSICAL_MAP); +recentMap.enableContinuousZoom(); + +// Limit the minimum zoom for the terrain map type +G_PHYSICAL_MAP.getMinimumResolution = function () {return 3}; + +// Add a couple of standard map controls +recentMap.addControl(new GSmallMapControl()); +recentMap.addControl(new GScaleControl()); + +// Initialize the KML processor +var options = {createmarker: addDataPoint}; +geoXml = new EGeoXml(recentMap, '/services/recent_campgrounds.php?type=kml', + options); +geoXml.parse(); diff --git a/chapter_11/listing_11_03.js b/chapter_11/listing_11_03.js new file mode 100644 index 0000000..74e925e --- /dev/null +++ b/chapter_11/listing_11_03.js @@ -0,0 +1,50 @@ +function addDataPoint(coordinates, name, description, style) +{ + // addDataPoint: display a recent-entry placemark found by the KML processor + + // Create and initialize the icon from the style in the KML + var myIcon = new GIcon(); + myIcon.image = geoXml.styles[style].image; + myIcon.iconSize = new GSize(32, 32); + myIcon.shadow = geoXml.styles[style].shadow; + myIcon.shadowSize = new GSize(59, 32); + myIcon.iconAnchor = new GPoint(16, 28); + if (myIcon.image.indexOf('bus') > -1) + myIcon.infoWindowAnchor = getAnchor(myIcon.image); + + // Create a marker for this data point + var options = {icon: myIcon, title: name}; + var thisMarker = new GMarker(coordinates, options); + + // Attach infowindow to the marker with content from the KML + options = {maxWidth: 250}; + thisMarker.bindInfoWindowHtml('

      ' + name + '

      ' + + description + '
      ', options); + + // Add the marker to the recent-entries map + recentMap.addOverlay(thisMarker); + + // Also create a list entry (alongside the map) with the icon & name + var recentRow = document.createElement('li'); + recentRow.innerHTML = + '' + name; + document.getElementById('recent_list').appendChild(recentRow); + + recentRow.onclick = + function () + { + // A click on the list entry triggers a click on its associated marker + GEvent.trigger(thisMarker, 'click') + }; +}; + +function getAnchor(iconUrl) +{ + if (iconUrl.indexOf('bus') > -1) + return new GPoint(16, 0); + else if (iconUrl.indexOf('trailer') > -1) + return new GPoint(19, 10); + else + return new GPoint(16, 6); +}; + diff --git a/chapter_11/listing_11_04.js b/chapter_11/listing_11_04.js new file mode 100644 index 0000000..cc464e7 --- /dev/null +++ b/chapter_11/listing_11_04.js @@ -0,0 +1,23 @@ +function mapMoveEnd() +{ + // Get the map boundary coordinates + var mapBounds = map.getBounds(); + + // Parameterize the geodata URL based on those boundaries + geoXml.urls = [kmlUrl + 'BBOX=' + + mapBounds.getSouthWest().lng().toFixed(6) + ',' + + mapBounds.getSouthWest().lat().toFixed(6) + ',' + + mapBounds.getNorthEast().lng().toFixed(6) + ',' + + mapBounds.getNorthEast().lat().toFixed(6)]; + + // Load the KML - new markers will be added when it returns + geoXml.parse(); + + // Remove markers from display that are no longer visible + for (var m = markers.length - 1; m >= 0; m--) + if (!mapBounds.contains(markers[m].getPoint())) + removeDataPoint(m); + + // Also clear starting location out of the URL + location.hash = '#'; +}; diff --git a/chapter_11/listing_11_05.js b/chapter_11/listing_11_05.js new file mode 100644 index 0000000..8355030 --- /dev/null +++ b/chapter_11/listing_11_05.js @@ -0,0 +1,78 @@ +function addDataPoint(coordinates, name, description, style) +{ + // Check to see if this placemark is already displayed, and stop if it is + for (var m = markers.length - 1; m >= 0; m--) + { + if (markers[m].getPoint().equals(coordinates)) + return; + } + + // Create and initialize the icon from the style in the KML + var myIcon = new GIcon(); + myIcon.image = geoXml.styles[style].image; + myIcon.iconSize = new GSize(32, 32); + if (myIcon.image.indexOf('circle') > -1) + { + // It's a cluster placemark + myIcon.shadow = '/images/icons/circle_shadow.png'; + myIcon.shadowSize = new GSize(40, 40); + myIcon.iconAnchor = new GPoint(13, 13); + myIcon.infoWindowAnchor = new GPoint(13, 0); + } + else + { + // Not a cluster => an individual campground + myIcon.shadow = geoXml.styles[style].shadow; + myIcon.shadowSize = geoXml.styles[style].shadowSize; + myIcon.iconAnchor = new GPoint(16, 28); + myIcon.infoWindowAnchor = getAnchor(myIcon.image); + } + + // Create a marker for this data point + var options = {icon: myIcon, title: name}; + var thisMarker = new GMarker(coordinates, options); + markers.push(thisMarker); + + // Some different handling for clusters and campgrounds + if (myIcon.image.indexOf('circle') > -1) + { + // Cluster + thisMarker.isCluster = true; + + GEvent.addListener(thisMarker, 'click', + function () + { + // Clicking on a cluster zooms the map on its location + map.setCenter(coordinates, map.getZoom() + 2); + }); + } + else + { + // Individual campground + thisMarker.isCluster = false; + + // Attach infowindow to the marker with content from the KML + options = {maxWidth: 350}; + thisMarker.bindInfoWindowHtml('

      ' + name + '

      ' + + description + '
      ', options); + + // Also create a sidebar entry (alongside the map) with the icon, name, & descr + var sidebarRow = document.createElement('div'); + sidebarRow.id = coordinates.toUrlValue(); + sidebarRow.className = 'sidebar_row'; + sidebarRow.innerHTML = + '

      ' + name + + '

      ' + description; + sidebar.appendChild(sidebarRow); + + sidebarRow.onclick = + function () + { + // A click on the sidebar entry triggers a click on its associated marker + GEvent.trigger(thisMarker, 'click') + }; + } + + // Add the marker to the map + map.addOverlay(thisMarker); +}; diff --git a/chapter_11/listing_11_06.js b/chapter_11/listing_11_06.js new file mode 100644 index 0000000..55feef7 --- /dev/null +++ b/chapter_11/listing_11_06.js @@ -0,0 +1,14 @@ +function removeDataPoint(m) +{ + // Remove the marker from the map + map.removeOverlay(markers[m]); + + // Find and remove the sidebar entry + var id = markers[m].getPoint().toUrlValue(); + var sidebarRow = document.getElementById(id); + if (sidebarRow) + sidebar.removeChild(sidebarRow); + + // Remove the marker from our own array + markers.splice(m, 1); +}; diff --git a/chapter_11/listing_11_07.php b/chapter_11/listing_11_07.php new file mode 100644 index 0000000..0290246 --- /dev/null +++ b/chapter_11/listing_11_07.php @@ -0,0 +1,70 @@ + $viewport[2]) + $viewport[0] -= 360; + + $north = min(90, (float) $viewport[3]); + $south = max(-90, (float) $viewport[1]); + $east = min(180, (float) $viewport[2]); + $west = max(-180, (float) $viewport[0]); + + // Sort order, also from URL parameter + if ($_GET['sort'] == 'coverage') + $order_by = 'nCGRating desc, dtmWhen desc'; + else if ($_GET['sort'] == 'hookups') + $order_by = 'nHookups desc, dtmWhen desc'; + else + $order_by = 'nCount desc, dtmWhen desc'; + + // Filter, from cookies + $filter = ''; + if (is_numeric($_COOKIE['nCGRating'])) + $filter .= " and (nCGRating >= $_COOKIE[nCGRating])"; + if (is_numeric($_COOKIE['nHookups'])) + $filter .= " and (nHookups >= $_COOKIE[nHookups])"; + if (is_numeric($_COOKIE['nSatLon'])) + $filter .= " and (nSatLon = $_COOKIE[nSatLon])"; + + // Connect to the database + include 'mod_sf_db_connect.php'; + + // Execute the database query + $query = "select sParkName, + Campground.nParkID, + Avg(fLatitude) fLatitude, + Avg(fLongitude) fLongitude, + Round(Avg(nCGRating)) nCGRating, + Max(nHookups) nHookups, + Count(*) nCount, + sTownName, + sState, + date_format(dtExpire, '%Y-%m-%d') sExpire, + sResultsBlurb + from Campsite + natural join Campground + left join Sponsor using (nParkID) + where (fLatitude between $south and $north) + and (fLongitude between $west and $east) + and (bSuspect <> 'Y') + $filter + group by Campground.nParkID + order by $order_by + limit 20"; + $result = mysql_query($query); + if (!$result) + die("Unable to retrieve data"); + + // Build an array holding all the retrieved data to send to the formatting routine + $campgrounds = array(); + while ($row = mysql_fetch_array($result)) + $campgrounds[] = array('lat' => round($row['fLatitude'], 6), + 'lon' => round($row['fLongitude'], 6), + 'id' => $row['nParkID'], + 'data' => $row); + + // Return the results as KML + include 'mod_produce_kml.php'; +?> diff --git a/chapter_11/listing_11_08.js b/chapter_11/listing_11_08.js new file mode 100644 index 0000000..0ef85ea --- /dev/null +++ b/chapter_11/listing_11_08.js @@ -0,0 +1,16 @@ +function afterGeocode(response) +{ + if (response && + (response.Status.code == 200)) + { + // Address was found - extract the map coordinates from the response + var place = response.Placemark[0]; + var coordinates = new GLatLng(place.Point.coordinates[1], + place.Point.coordinates[0]); + + // Move the map there, zooming further in for more accurate results + map.setCenter(coordinates, place.AddressDetails.Accuracy + 5); + } + else + alert('Address not found. Please try again.'); +}; diff --git a/chapter_11/listing_11_09.js b/chapter_11/listing_11_09.js new file mode 100644 index 0000000..0b0750b --- /dev/null +++ b/chapter_11/listing_11_09.js @@ -0,0 +1,22 @@ +// Check for a starting location in URL +var hash = location.hash.replace('#', ''); +if (hash != '') +{ + // Found starting location - parse the coordinates & zoom from it + var viewport = startLocation.split(','); + var latitude = parseFloat(viewport[0]); + var longitude = parseFloat(viewport[1]); + var zoom = parseInt(viewport[2]); +} + +// Initialize the core map object +var options = {backgroundColor: '#D7D5E3', + mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}; +map = new GMap2(mapDiv, options); + +if (!isNaN(latitude + longitude + zoom)) + // Starting location supplied + map.setCenter(new GLatLng(latitude, longitude), zoom, G_PHYSICAL_MAP); +else + // Default starting location + map.setCenter(new GLatLng(39.8, -98.5), 4, G_PHYSICAL_MAP); diff --git a/chapter_11/listing_11_10.js b/chapter_11/listing_11_10.js new file mode 100644 index 0000000..ee36d58 --- /dev/null +++ b/chapter_11/listing_11_10.js @@ -0,0 +1,31 @@ +var startLocation; + +// Check for a starting location or search address in URL +var hash = location.hash.replace('#', ''); +if (hash != '') + startLocation = hash; + +// No starting location in URL - check for a browser cookie +if (startLocation == null) + startLocation = getCookie('lastLocation'); + +if (startLocation != null) +{ + // Found starting location - parse the coordinates & zoom from it + var viewport = startLocation.split(','); + var latitude = parseFloat(viewport[0]); + var longitude = parseFloat(viewport[1]); + var zoom = parseInt(viewport[2]); +} + +// Initialize the core map object +var options = {backgroundColor: '#D7D5E3', + mapTypes: [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP]}; +map = new GMap2(mapDiv, options); + +if (!isNaN(lat + lon + zoom)) + // Starting location supplied + map.setCenter(new GLatLng(latitude, longitude), zoom, G_PHYSICAL_MAP); +else + // Default starting location + map.setCenter(new GLatLng(39.8, -98.5), 4, G_PHYSICAL_MAP); diff --git a/chapter_11/listing_11_11.php b/chapter_11/listing_11_11.php new file mode 100644 index 0000000..1af7675 --- /dev/null +++ b/chapter_11/listing_11_11.php @@ -0,0 +1,88 @@ + + + + + ... + + var campground = {name: '$parkName', + iconUrl: '".fsCGIcon($parkRating, $maxHookups)."', color: '$color', + latitude: {$totalLatitude}, longitude: {$totalLongitude}}; + + var campsites = [".join($sites, ",")."]; + "; + ?> + + + ... + + \ No newline at end of file diff --git a/chapter_11/listing_11_12.html b/chapter_11/listing_11_12.html new file mode 100644 index 0000000..971857a --- /dev/null +++ b/chapter_11/listing_11_12.html @@ -0,0 +1,30 @@ + + + + + ... + + + + ... + + diff --git a/chapter_11/listing_11_13.js b/chapter_11/listing_11_13.js new file mode 100644 index 0000000..32e133b --- /dev/null +++ b/chapter_11/listing_11_13.js @@ -0,0 +1,35 @@ +// We'll need the campground boundaries for use in zooming +campground.bounds = new GLatLngBounds(); + +// Create a map marker for each campsite to use when zoomed in +for (var c = 0; c < campsites.length; c++) +{ + // Extract the coordinates from JSON and add it to the campground boundaries + campsites[c].coordinates = new GLatLng(campsites[c].latitude, + campsites[c].longitude); + campground.bounds.extend(campsites[c].coordinates); + + // Create campsite icon & marker + campsites[c].title = 'Site number ' + campsites[c].number; + options = {icon: createIcon(campsites[c].iconUrl), title: campsites[c].title}; + campsites[c].marker = new GMarker(campsites[c].coordinates, options); + map.addOverlay(campsites[c].marker); + + // Immediately hide the marker (our initial zoom is too far out to show it) + campsites[c].marker.hide(); + + // Attach infowindow to the marker with content from JSON + campsites[c].marker.bindInfoWindowHtml( + '
      ' + + '

      ' + campsites[c].title + '

      ' + + '' + + '

      Reported on ' + campsites[c].date + '

      ' + + '
      '); +} + +// Calculate optimal campground-wide zoom level +optimalZoom = Math.min(15, map.getBoundsZoomLevel(campground.bounds) - 1); diff --git a/chapter_11/listing_11_14.js b/chapter_11/listing_11_14.js new file mode 100644 index 0000000..c77c496 --- /dev/null +++ b/chapter_11/listing_11_14.js @@ -0,0 +1,39 @@ +function mapMoveEnd() +{ + if (map.getZoom() < optimalZoom - 1) + { + // Zoomed far enough out to only show single marker for the campground + + // Hide all the individual campsite markers + map.closeInfoWindow(); + for (var c = 0; c < campsites.length; c++) + campsites[c].marker.hide() + + // Show (and track) the campground marker + campground.marker.show(); + tracker.enable(); + } + else + { + // Zoomed far enough in to see individual campsites + + // Hide the campground marker + campground.marker.hide(); + + // Show all the individual campsite markers + siteVisible = false; + var bounds = map.getBounds(); + for (var c = 0; c < campsites.length; c++) + { + campsites[c].marker.show() + if (bounds.contains(campsites[c].coordinates)) + siteVisible = true; + } + + // Only show the marker tracker if no campsite is visible + if (siteVisible) + tracker.disable(); + else + tracker.enable(); + } +}; diff --git a/chapter_11/listing_11_15.js b/chapter_11/listing_11_15.js new file mode 100644 index 0000000..1ded83d --- /dev/null +++ b/chapter_11/listing_11_15.js @@ -0,0 +1,40 @@ +function getDirections() +{ + // getDirections: retrieve driving directions to the campground + + var startAddress = document.getElementById('saddr'); + + if (startAddress.value == '') + { + alert('Please enter a starting point for your driving directions.'); + startAddress.focus(); + } + else + { + // Starting point looks good - load driving directions + var endpoints = 'from: ' + startAddress.value + ' to:' + + campground.coordinates.toUrlValue(); + directions.load(endpoints); + } +}; + +function directionsDone() +{ + // directionsDone: show the header above the driving directions area + var status = directions.getStatus().code; + if (status == 200) + { + document.getElementById('directions_header').style.display = 'block'; + tracker.disable(); + } +}; + +function directionsError() +{ + // directionsError: a problem occurred getting driving directions + var status = directions.getStatus().code; + if (status == 500) + alert('Unable to load driving directions, sorry.'); + else + alert('Unable to locate start point for driving directions.'); +}; diff --git a/chapter_11/listing_11_16.php b/chapter_11/listing_11_16.php new file mode 100644 index 0000000..19ca34a --- /dev/null +++ b/chapter_11/listing_11_16.php @@ -0,0 +1,60 @@ + +'; + + // Create a sitemap url element for each grid cell + for ($lat = $south; $lat < $north; $lat += $lat_grid) + for ($lon = $west; $lon < $east; $lon += $lon_grid) + { + $query = "select 1 + from Campsite + where (fLatitude between $lat and ".($lat + $lat_grid).") + and (fLongitude between $lon and ".($lon + $lon_grid).")"; + $result = mysql_query($query); + if (!mysql_num_rows($result)) + continue; + + $urls = $urls.' + + + http://www.satellitefriendly.com/services/top_campgrounds.php?BBOX='. + $lon.','.$lat.','.($lon + $lon_grid).','.($lat + $lat_grid).' + + + kml + + '; + } + + // Prepare the sitemap XML footer + $footer = ' +'; + + // Output the final sitemap XML + header('Content-type: application/xml'); + echo $header; + echo $urls; + echo $footer; +?> diff --git a/chapter_11/listing_11_17.xml b/chapter_11/listing_11_17.xml new file mode 100644 index 0000000..d12b049 --- /dev/null +++ b/chapter_11/listing_11_17.xml @@ -0,0 +1,151 @@ + + + + + + + + + + p, table { + font-size: 90%; + width: 100%; + text-align: left; + } + h3 { + margin: 0; + font-size: 12pt; + } + img { + vertical-align: middle; + } + .coverage { + text-align: center; + } + + +

      + Campgrounds in North America with coverage for satellite TV and internet. + Locations from + SatelliteFriendly.com, + contributed by users on-site with GPS. +

      + +

      + View: + +

      + +

      Legend

      + + + + + + + + + + + + + + + + + + + + +
      + Multiple campgrounds in area +
      Campsite HookupsSatellite Coverage
      + Full + + +
      + Electric + + +
      + None + + +
      + + + ]]>
      +
      \ No newline at end of file diff --git a/contributing.md b/contributing.md new file mode 100644 index 0000000..f6005ad --- /dev/null +++ b/contributing.md @@ -0,0 +1,14 @@ +# Contributing to Apress Source Code + +Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. + +## How to Contribute + +1. Make sure you have a GitHub account. +2. Fork the repository for the relevant book. +3. Create a new branch on which to make your change, e.g. +`git checkout -b my_code_contribution` +4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. +5. Submit a pull request. + +Thank you for your contribution! \ No newline at end of file diff --git a/egeoxml.js b/egeoxml.js new file mode 100644 index 0000000..5720272 --- /dev/null +++ b/egeoxml.js @@ -0,0 +1,638 @@ + +/*********************************************************************\ +* * +* egeoxml.js by Mike Williams * +* * +* A Google Maps API Extension * +* * +* Renders the contents of a My Maps (or similar) KML file * +* * +* Documentation: http://econym.googlepages.com/egeoxml.htm * +* * +*********************************************************************** +* * +* Extended to work with the Mapplets API by Sterling Udell * +* * +*********************************************************************** +* * +* This Javascript is provided by Mike Williams * +* Blackpool Community Church Javascript Team * +* http://www.commchurch.freeserve.co.uk/ * +* http://econym.googlepages.com/index.htm * +* * +* This work is licenced under a Creative Commons Licence * +* http://creativecommons.org/licenses/by/2.0/uk/ * +* * +\*********************************************************************/ + + +// Version 0.0 17 Apr 2007 - Initial testing, just markers +// Version 0.1 17 Apr 2007 - Sensible shadows, and a few general improvements +// Version 0.2 18 Apr 2007 - Polylines (non-clickable, no sidebar) +// Version 0.3 18 Apr 2007 - Polygons (non-clickable, no sidebar) +// Version 0.4 18 Apr 2007 - Sidebar entries for polygons +// Version 0.5 19 Apr 2007 - Accept an array of XML filenames, and add the {sortbyname} option +// Version 0.6 19 Apr 2007 - Sidebar entries for polylines, get directions and search nearby +// Version 0.7 20 Apr 2007 - Info Window Styles +// Version 0.8 21 Apr 2007 - baseicon +// Version 0.9 21 Apr 2007 - iwoptions and markeroptions +// Version 1.0 21 Apr 2007 - Launched +// Version 1.1 25 Apr 2007 - Bugfix - would crash if no options were specified +// Version 1.2 25 Apr 2007 - If the description begins with "http://" make it into a link. +// Version 1.3 30 Apr 2007 - printgif, dropbox +// Version 1.4 14 May 2007 - Elabels +// Version 1.5 17 May 2007 - Default values for width, fill and outline +// Version 1.6 21 May 2007 - GGroundOverlay (needs API V2.79+) +// Version 1.7 22 May 2007 - Better icon positioning for MyMaps icons +// Version 1.8 31 May 2007 - polyline bugfix +// Version 1.9 23 Jun 2007 - add .parseString() method +// Version 2.0 23 Jun 2007 - .parseString() handles an array of strings +// Version 2.1 25 Jul 2007 - imagescan +// Version 2.2 10 Aug 2007 - Support new My Maps icons +// Version 2.3 25 Nov 2007 - Clear variables used by .parse() so that it can be rerun +// Version 2.4 08 Dec 2007 - polylineoptions and polygonoptions +// Version 2.5 11 Dec 2007 - EGeoXml.value() trims leading and trailing whitespace +// S.Udell 13 Dec 2007 - Fix bugs handling KML with empty points, add missing semicolons +// Version 2.6 08 Feb 2008 - Trailing whitespace wasn't removed in the previous change +// S.Udell 14 Jul 2008 - Convert for Maps / Mapplets cross-compatibility, +// removed need for first parmaeter "myvar" + +if (typeof GXml == 'undefined') +{ + // SCU: Mapplets don't have a native GXml object; this code is from the Maps API + GXml = { + parse: function (xmlText) + { + if (typeof ActiveXObject != "undefined" && + typeof GetObject != "undefined") + { + var b = new ActiveXObject("Microsoft.XMLDOM"); + b.loadXML(xmlText); + return b; + }; + + if (typeof DOMParser != "undefined") + return(new DOMParser).parseFromString(xmlText, "text/xml"); + + return x("div",null); + }, + + value: function (xmlNode) + { + if (!xmlNode) + return ""; + + var b=""; + if (xmlNode.nodeType == 3 || + xmlNode.nodeType == 4 || + xmlNode.nodeType == 2) + { + b += xmlNode.nodeValue; + } + else if (xmlNode.nodeType == 1 || + xmlNode.nodeType == 9 || + xmlNode.nodeType == 11) + { + for (var c = 0; c < xmlNode.childNodes.length; ++c) + b += arguments.callee(xmlNode.childNodes[c]) + } + return b; + } + } +} + +// Constructor + +function EGeoXml(map, url, opts) { + + // SCU: create myvar as a new element of a global array (replaces MW's first parm) + window.eGeoXml = window.eGeoXml || []; + this.myvar = 'window.eGeoXml[' + (window.eGeoXml.push(this) - 1) + ']'; + + // store the parameters + this.map = map; + this.url = url; + if (typeof url == "string") { + this.urls = [url]; + } else { + this.urls = url; + } + this.opts = opts || {}; + // infowindow styles + this.titlestyle = this.opts.titlestyle || 'style = "font-family: arial, sans-serif;font-size: medium;font-weight:bold;font-size: 100%;"'; + this.descstyle = this.opts.descstyle || 'style = "font-family: arial, sans-serif;font-size: small;padding-bottom:.7em;"'; + this.directionstyle = this.opts.directionstyle || 'style="font-family: arial, sans-serif;font-size: small;padding-left: 1px;padding-top: 1px;padding-right: 4px;"'; + // sidebar/dropbox functions + this.sidebarfn = this.opts.sidebarfn || EGeoXml.addSidebar; + this.dropboxfn = this.opts.dropboxfn || EGeoXml.addDropdown; + // elabel options + this.elabelopacity = this.opts.elabelopacity || 100; + // other useful "global" stuff + this.bounds = new GLatLngBounds(); + this.gmarkers = []; + this.gpolylines = []; + this.gpolygons = []; + this.groundoverlays = []; + this.side_bar_html = ""; + this.side_bar_list = []; + this.styles = []; // associative array + this.iwwidth = this.opts.iwwidth || 250; + this.progress = 0; + this.lastmarker = {}; + this.myimages = []; + this.imageNum =0; + this.isMapplet = !window.GBrowserIsCompatible; +}; + +// uses GXml.value, then removes leading and trailing whitespace +EGeoXml.value = function(e) { + a = GXml.value(e); + a = a.replace(/^\s*/,""); + a = a.replace(/\s*$/,""); + return a; +}; + +// Create Marker + +EGeoXml.prototype.createMarker = function(point,name,desc,style) { + var myvar=this.myvar; + var iwoptions = this.opts.iwoptions || {}; + var markeroptions = this.opts.markeroptions || {}; + var icontype = this.opts.icontype || "style"; + if ((icontype == "style") && + !!this.styles[style]) + { + var icon = G_DEFAULT_ICON; + icon = this.styles[style]; + } + if (!markeroptions.icon && !!icon) { + markeroptions.icon = icon; + } + var m = new GMarker(point, markeroptions); + + // Attempt to preload images + if (this.opts.preloadimages) { + var text = desc; + var pattern = /<\s*img/ig; + var result; + var pattern2 = /src\s*=\s*[\'\"]/; + var pattern3 = /[\'\"]/; + + while ((result = pattern.exec(text)) != null) { + var stuff = text.substr(result.index); + var result2 = pattern2.exec(stuff); + if (result2 != null) { + stuff = stuff.substr(result2.index+result2[0].length); + var result3 = pattern3.exec(stuff); + if (result3 != null) { + var imageUrl = stuff.substr(0,result3.index); + this.myimages[this.imageNum] = new Image(); + this.myimages[this.imageNum].src = imageUrl; + this.imageNum++; + } + } + } + } + + + + if (this.opts.elabelclass) { + var l = new ELabel(point, name, this.opts.elabelclass, this.opts.elabeloffset, this.elabelopacity, true); + this.map.addOverlay(l); + } + + var html = "
      " + + "

      "+name+"

      " + +"
      "+desc+"
      "; + + if (this.opts.directions) { + var html1 = html + '
      ' + + 'Get Directions: To Here - ' + + 'From Here
      ' + + 'Search nearby
      '; + var html2 = html + '
      ' + + 'Get Directions: To here - ' + + 'From Here
      ' + + 'Start address:
      ' + + '' + + '' + + '' + + '
      « Back
      '; + var html3 = html + '
      ' + + 'Get Directions: To Here - ' + + 'From Here
      ' + + 'End address:' + + '' + + '' + + '' + + '
      « Back
      '; + var html4 = html + '
      ' + + 'Search nearby: e.g. "pizza"
      ' + + '' + + '' + + '' + + '' + // + ''; + + '
      « Back
      '; + GEvent.addListener(m, "click2", function() { + m.openInfoWindowHtml(html2 + "
      ",iwoptions); + }); + GEvent.addListener(m, "click3", function() { + m.openInfoWindowHtml(html3 + "",iwoptions); + }); + GEvent.addListener(m, "click4", function() { + m.openInfoWindowHtml(html4 + "",iwoptions); + }); + } else { + var html1 = html; + } + + GEvent.addListener(m, "click", function() { + eval(myvar+".lastmarker = m"); + m.openInfoWindowHtml(html1 + "",iwoptions); + }); + if (!!this.opts.addmarker) { + this.opts.addmarker(m,name,desc,icon.image,this.gmarkers.length); + } else { + this.map.addOverlay(m); + } + this.gmarkers.push(m); + if (this.opts.sidebarid || this.opts.dropboxid) { + var n = this.gmarkers.length-1; + this.side_bar_list.push (name + "$$$marker$$$" + n +"$$$" ); + } +}; + +// Create Polyline + +EGeoXml.prototype.createPolyline = function(points,color,width,opacity,pbounds,name,desc) { + var thismap = this.map; + var iwoptions = this.opts.iwoptions || {}; + var polylineoptions = this.opts.polylineoptions || {}; + var p = new GPolyline(points,color,width,opacity,polylineoptions); + this.map.addOverlay(p); + this.gpolylines.push(p); + var html = "
      "+name+"
      " + +"
      "+desc+"
      "; + GEvent.addListener(p,"click", function() + { + if (this.isMapplet) + // Maps API (not a mapplet) + thismap.openInfoWindowHtml(p.getVertex(Math.floor(p.getVertexCount()/2)),html,iwoptions); + else + { + // Mapplet + p.getVertexCountAsync(function (count) + { + p.getVertexAsync(Math.floor(count / 2), function (vertex) + { + thismap.openInfoWindowHtml(vertex, html, iwoptions); + }); + }); + } + }); + if (this.opts.sidebarid) { + var n = this.gpolylines.length-1; + var blob = '    '; + this.side_bar_list.push (name + "$$$polyline$$$" + n +"$$$" + blob ); + } +}; + +// Create Polygon + +EGeoXml.prototype.createPolygon = function(points,color,width,opacity,fillcolor,fillopacity,pbounds, name, desc) { + var thismap = this.map; + var iwoptions = this.opts.iwoptions || {}; + var polygonoptions = this.opts.polygonoptions || {}; + var p = new GPolygon(points,color,width,opacity,fillcolor,fillopacity,polygonoptions); + this.map.addOverlay(p); + this.gpolygons.push(p); + var html = "
      "+name+"
      " + +"
      "+desc+"
      "; + GEvent.addListener(p,"click", function() { + thismap.openInfoWindowHtml(pbounds.getCenter(),html,iwoptions); + } ); + if (this.opts.sidebarid) { + var n = this.gpolygons.length-1; + var blob = '     '; + this.side_bar_list.push (name + "$$$polygon$$$" + n +"$$$" + blob ); + } +}; + + +// Sidebar factory method One - adds an entry to the sidebar +EGeoXml.addSidebar = function(myvar,name,type,i,graphic) { + if (type == "marker") { + return '' + name + '
      '; + } + if (type == "polyline") { + return '
      ' + graphic + name + '
      '; + } + if (type == "polygon") { + return '
      ' + graphic + name + '
      '; + } +}; + +// Dropdown factory method +EGeoXml.addDropdown = function(myvar,name,type,i,graphic) { + return ''; +}; + + +// Request to Parse an XML file + +EGeoXml.prototype.parse = function() { + // clear some variables + this.gmarkers = []; + this.gpolylines = []; + this.gpolygons = []; + this.groundoverlays = []; + this.side_bar_html = ""; + this.side_bar_list = []; + this.styles = []; // associative array + this.lastmarker = {}; + this.myimages = []; + this.imageNum =0; + var that = this; + this.progress = this.urls.length; + for (u=0; u 0) { + var href=EGeoXml.value(icons[0].getElementsByTagName("href")[0]); + if (!!href) { + if (!!that.opts.baseicon) { + that.styles["#"+styleID] = new GIcon(that.opts.baseicon,href); + } else { + that.styles["#"+styleID] = new GIcon(G_DEFAULT_ICON,href); + that.styles["#"+styleID].iconSize = new GSize(32,32); + that.styles["#"+styleID].shadowSize = new GSize(59,32); + that.styles["#"+styleID].dragCrossAnchor = new GPoint(2,8); + that.styles["#"+styleID].iconAnchor = new GPoint(16,32); + if (that.opts.printgif) { + var bits = href.split("/"); + var gif = bits[bits.length-1]; + gif = that.opts.printgifpath + gif.replace(/.png/i,".gif"); + that.styles["#"+styleID].printImage = gif; + that.styles["#"+styleID].mozPrintImage = gif; + } + if (!!that.opts.noshadow) { + that.styles["#"+styleID].shadow=""; + } else { + // Try to guess the shadow image + if (href.indexOf("/red.png")>-1 + || href.indexOf("/blue.png")>-1 + || href.indexOf("/green.png")>-1 + || href.indexOf("/yellow.png")>-1 + || href.indexOf("/lightblue.png")>-1 + || href.indexOf("/purple.png")>-1 + || href.indexOf("/pink.png")>-1 + || href.indexOf("/orange.png")>-1 + || href.indexOf("-dot.png")>-1 ) { + that.styles["#"+styleID].shadow="http://maps.google.com/mapfiles/ms/micons/msmarker.shadow.png"; + } + else if (href.indexOf("-pushpin.png")>-1) { + that.styles["#"+styleID].shadow="http://maps.google.com/mapfiles/ms/micons/pushpin_shadow.png"; + } + else { + var shadow = href.replace(".png",".shadow.png"); + that.styles["#"+styleID].shadow=shadow; + } + } + } + } + } + // is it a LineStyle ? + var linestyles=styles[i].getElementsByTagName("LineStyle"); + if (linestyles.length > 0) { + var width = parseInt(GXml.value(linestyles[0].getElementsByTagName("width")[0])); + if (width < 1) {width = 5;} + var color = EGeoXml.value(linestyles[0].getElementsByTagName("color")[0]); + var aa = color.substr(0,2); + var bb = color.substr(2,2); + var gg = color.substr(4,2); + var rr = color.substr(6,2); + color = "#" + rr + gg + bb; + var opacity = parseInt(aa,16)/256; + if (!that.styles["#"+styleID]) { + that.styles["#"+styleID] = {}; + } + that.styles["#"+styleID].color=color; + that.styles["#"+styleID].width=width; + that.styles["#"+styleID].opacity=opacity; + } + // is it a PolyStyle ? + var polystyles=styles[i].getElementsByTagName("PolyStyle"); + if (polystyles.length > 0) { + var fill = parseInt(GXml.value(polystyles[0].getElementsByTagName("fill")[0])); + var outline = parseInt(GXml.value(polystyles[0].getElementsByTagName("outline")[0])); + var color = EGeoXml.value(polystyles[0].getElementsByTagName("color")[0]); + + if (polystyles[0].getElementsByTagName("fill").length == 0) {fill = 1;} + if (polystyles[0].getElementsByTagName("outline").length == 0) {outline = 1;} + + var aa = color.substr(0,2); + var bb = color.substr(2,2); + var gg = color.substr(4,2); + var rr = color.substr(6,2); + color = "#" + rr + gg + bb; + + var opacity = parseInt(aa,16)/256; + if (!that.styles["#"+styleID]) { + that.styles["#"+styleID] = {}; + } + that.styles["#"+styleID].fillcolor=color; + that.styles["#"+styleID].fillopacity=opacity; + if (!fill) that.styles["#"+styleID].fillopacity = 0; + if (!outline) that.styles["#"+styleID].opacity = 0; + } + } + + // Read through the Placemarks + var placemarks = xmlDoc.documentElement.getElementsByTagName("Placemark"); + for (var i = 0; i < placemarks.length; i++) { + var name=EGeoXml.value(placemarks[i].getElementsByTagName("name")[0]); + var desc=EGeoXml.value(placemarks[i].getElementsByTagName("description")[0]); + if (desc.match(/^http:\/\//i)) { + desc = '' + desc + ''; + } + if (desc.match(/^https:\/\//i)) { + desc = '' + desc + ''; + } + var style=EGeoXml.value(placemarks[i].getElementsByTagName("styleUrl")[0]); + var coords=GXml.value(placemarks[i].getElementsByTagName("coordinates")[0]); + coords=coords.replace(/\s+/g," "); // tidy the whitespace + coords=coords.replace(/^ /,""); // remove possible leading whitespace + coords=coords.replace(/ $/,""); // remove possible trailing whitespace + coords=coords.replace(/, /,","); // tidy the commas + var path = coords.split(" "); + + // Is this a polyline/polygon? + if (path.length > 1) { + // Build the list of points + var points = []; + var pbounds = new GLatLngBounds(); + for (var p=0; p 0) { + // It's not a poly, so I guess it must be a marker + var bits = path[0].split(","); + if (bits.length >= 2) { + var point = new GLatLng(parseFloat(bits[1]),parseFloat(bits[0])); + that.bounds.extend(point); + // Does the user have their own createmarker function? + if (!!that.opts.createmarker) { + that.opts.createmarker(point, name, desc, style); + } else { + that.createMarker(point, name, desc, style); + } + } + } + } + + // Scan through the Ground Overlays + var grounds = xmlDoc.documentElement.getElementsByTagName("GroundOverlay"); + for (var i = 0; i < grounds.length; i++) { + var url=EGeoXml.value(grounds[i].getElementsByTagName("href")[0]); + var north=parseFloat(GXml.value(grounds[i].getElementsByTagName("north")[0])); + var south=parseFloat(GXml.value(grounds[i].getElementsByTagName("south")[0])); + var east=parseFloat(GXml.value(grounds[i].getElementsByTagName("east")[0])); + var west=parseFloat(GXml.value(grounds[i].getElementsByTagName("west")[0])); + var sw = new GLatLng(south,west); + var ne = new GLatLng(north,east); + var ground = new GGroundOverlay(url, new GLatLngBounds(sw,ne)); + that.bounds.extend(sw); + that.bounds.extend(ne); + that.groundoverlays.push(ground); + that.map.addOverlay(ground); + } + + // Is this the last file to be processed? + that.progress--; + if (that.progress == 0) { + // Shall we zoom to the bounds? + if (!that.opts.nozoom) { + if (that.isMapplet) + that.map.getBoundsZoomLevelAsync(that.bounds, function (zoom) + { + that.map.setCenter(that.bounds.getCenter(), zoom); + }); + else + that.map.setCenter(that.bounds.getCenter(), + that.map.getBoundsZoomLevel(that.bounds)); + } + // Shall we display the sidebar? + if (that.opts.sortbyname) { + that.side_bar_list.sort(); + } + if (that.opts.sidebarid) { + for (var i=0; i' + + '' + + that.side_bar_html + + ''; + } + + GEvent.trigger(that,"parsed"); + } +}; diff --git a/json_parse.js b/json_parse.js new file mode 100644 index 0000000..34505f4 --- /dev/null +++ b/json_parse.js @@ -0,0 +1,344 @@ +/* + http://www.JSON.org/json_parse.js + 2008-04-08 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + This file creates a json_parse function. + + json_parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = json_parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + This is a reference implementation. You are free to copy, modify, or + redistribute. + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. +*/ + +/*members "", "\"", "\/", "\\", at, b, call, charAt, f, fromCharCode, + hasOwnProperty, message, n, name, push, r, t, text +*/ + +/*global json_parse */ + +json_parse = function () { + +// This is a function that can parse a JSON text, producing a JavaScript +// data structure. It is a simple, recursive descent parser. It does not use +// eval or regular expressions, so it can be used as a model for implementing +// a JSON parser in other languages. + +// We are defining the function inside of another function to avoid creating +// global variables. + + var at, // The index of the current character + ch, // The current character + escapee = { + '"': '"', + '\\': '\\', + '/': '/', + b: '\b', + f: '\f', + n: '\n', + r: '\r', + t: '\t' + }, + text, + + error = function (m) { + +// Call error when something is wrong. + + throw { + name: 'SyntaxError', + message: m, + at: at, + text: text + }; + }, + + next = function (c) { + +// If a c parameter is provided, verify that it matches the current character. + + if (c && c !== ch) { + error("Expected '" + c + "' instead of '" + ch + "'"); + } + +// Get the next character. When there are no more characters, +// return the empty string. + + ch = text.charAt(at); + at += 1; + return ch; + }, + + number = function () { + +// Parse a number value. + + var number, + string = ''; + + if (ch === '-') { + string = '-'; + next('-'); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + if (ch === '.') { + string += '.'; + while (next() && ch >= '0' && ch <= '9') { + string += ch; + } + } + if (ch === 'e' || ch === 'E') { + string += ch; + next(); + if (ch === '-' || ch === '+') { + string += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + } + number = +string; + if (isNaN(number)) { + error("Bad number"); + } else { + return number; + } + }, + + string = function () { + +// Parse a string value. + + var hex, + i, + string = '', + uffff; + +// When parsing for string values, we must look for " and \ characters. + + if (ch === '"') { + while (next()) { + if (ch === '"') { + next(); + return string; + } else if (ch === '\\') { + next(); + if (ch === 'u') { + uffff = 0; + for (i = 0; i < 4; i += 1) { + hex = parseInt(next(), 16); + if (!isFinite(hex)) { + break; + } + uffff = uffff * 16 + hex; + } + string += String.fromCharCode(uffff); + } else if (typeof escapee[ch] === 'string') { + string += escapee[ch]; + } else { + break; + } + } else { + string += ch; + } + } + } + error("Bad string"); + }, + + white = function () { + +// Skip whitespace. + + while (ch && ch <= ' ') { + next(); + } + }, + + word = function () { + +// true, false, or null. + + switch (ch) { + case 't': + next('t'); + next('r'); + next('u'); + next('e'); + return true; + case 'f': + next('f'); + next('a'); + next('l'); + next('s'); + next('e'); + return false; + case 'n': + next('n'); + next('u'); + next('l'); + next('l'); + return null; + } + error("Unexpected '" + ch + "'"); + }, + + value, // Place holder for the value function. + + array = function () { + +// Parse an array value. + + var array = []; + + if (ch === '[') { + next('['); + white(); + if (ch === ']') { + next(']'); + return array; // empty array + } + while (ch) { + array.push(value()); + white(); + if (ch === ']') { + next(']'); + return array; + } + next(','); + white(); + } + } + error("Bad array"); + }, + + object = function () { + +// Parse an object value. + + var key, + object = {}; + + if (ch === '{') { + next('{'); + white(); + if (ch === '}') { + next('}'); + return object; // empty object + } + while (ch) { + key = string(); + white(); + next(':'); + object[key] = value(); + white(); + if (ch === '}') { + next('}'); + return object; + } + next(','); + white(); + } + } + error("Bad object"); + }; + + value = function () { + +// Parse a JSON value. It could be an object, an array, a string, a number, +// or a word. + + white(); + switch (ch) { + case '{': + return object(); + case '[': + return array(); + case '"': + return string(); + case '-': + return number(); + default: + return ch >= '0' && ch <= '9' ? number() : word(); + } + }; + +// Return the json_parse function. It will have access to all of the above +// functions and variables. + + return function (source, reviver) { + var result; + + text = source; + at = 0; + ch = ' '; + result = value(); + white(); + if (ch) { + error("Syntax error"); + } + +// If there is a reviver function, we recursively walk the new structure, +// passing each name/value pair to the reviver function for possible +// transformation, starting with a temporary root object that holds the result +// in an empty key. If there is not a reviver function, we simply return the +// result. + + return typeof reviver === 'function' ? function walk(holder, key) { + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + }({'': result}, '') : result; + }; +}(); \ No newline at end of file diff --git a/markers/black.png b/markers/black.png new file mode 100644 index 0000000..dee0818 Binary files /dev/null and b/markers/black.png differ diff --git a/markers/crosshair.png b/markers/crosshair.png new file mode 100644 index 0000000..9d394e6 Binary files /dev/null and b/markers/crosshair.png differ diff --git a/markers/green.png b/markers/green.png new file mode 100644 index 0000000..635ec06 Binary files /dev/null and b/markers/green.png differ diff --git a/markers/music.png b/markers/music.png new file mode 100644 index 0000000..7672343 Binary files /dev/null and b/markers/music.png differ diff --git a/markers/red.png b/markers/red.png new file mode 100644 index 0000000..6cc189d Binary files /dev/null and b/markers/red.png differ diff --git a/markers/shadow.png b/markers/shadow.png new file mode 100644 index 0000000..37f7731 Binary files /dev/null and b/markers/shadow.png differ diff --git a/markers/star.png b/markers/star.png new file mode 100644 index 0000000..5be7a5e Binary files /dev/null and b/markers/star.png differ diff --git a/markers/white.png b/markers/white.png new file mode 100644 index 0000000..1a6e502 Binary files /dev/null and b/markers/white.png differ diff --git a/markers/yellow.png b/markers/yellow.png new file mode 100644 index 0000000..4365777 Binary files /dev/null and b/markers/yellow.png differ