Permalink
Browse files

chapter four

  • Loading branch information...
1 parent 07c1930 commit b6b175b31a09c60363f1122f832c44ce52b3b49c @ashchan committed Jun 27, 2008
View
10 README
@@ -1,7 +1,11 @@
-Sample codes from the book [Beginning Google Maps Applications with Rails and Ajax: From Novice to Professional](http://www.amazon.com/Beginning-Google-Maps-Applications-Rails/dp/1590597877)
+Sample codes from the book [Beginning Google Maps Applications with Rails and Ajax: From Novice to Professional](http://www.amazon.com/Beginning-Google-Maps-Applications-Rails/dp/1590597877).
-This sample is of Rails 2.1, using Sqlite3.
+The book's site is http://googlemapsbook.com/ .
-The source code from the book has some typos, and some of them don't work. I've tried my best to make the it work.
+This sample uses Rails 2.1 and Sqlite3.
+
+The source code from the book has some typos, and some of them don't work. I've tried my best to make it work.
+
+Thanks to the authors of the book, for bringing us this book, and for allowing me to use the source code and make it public on github.
The Chinese translation of the book sucks, see http://blog.ashchan.com/archive/2008/06/25/professional-book/ .
@@ -0,0 +1,6 @@
+class ChapFourController < ApplicationController
+ def map
+ @stores = Store.all
+ end
+
+end
@@ -0,0 +1,2 @@
+module ChapFourHelper
+end
View
@@ -1,2 +1,15 @@
+# == Schema Information
+# Schema version: 20080627051703
+#
+# Table name: markers
+#
+# id :integer not null, primary key
+# lat :decimal(, )
+# lng :decimal(, )
+# found :string(100)
+# left :string(100)
+# icon :string(100) default("")
+#
+
class Marker < ActiveRecord::Base
end
View
@@ -0,0 +1,22 @@
+# == Schema Information
+# Schema version: 20080627051703
+#
+# Table name: stores
+#
+# id :integer not null, primary key
+# name :string(50)
+# address :string(100)
+# address2 :string(100)
+# city :string(50)
+# state :string(2)
+# zip :string(9)
+# phone :string(15)
+# lat :string(20)
+# lng :string(20)
+#
+
+class Store < ActiveRecord::Base
+ def full_address
+ "#{address}, #{city}, #{state}, #{zip}"
+ end
+end
@@ -0,0 +1,18 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+ <title>Google Maps JavaScript API Example</title>
+ <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAApuqJ-ievoI8n0KBpKtZuyxTJQa0g3IQ9GZqIMmInSLzwtGDKaBSt40PUewe_UUsm_5pWXNbz5adklA"
+ type="text/javascript"></script>
+
+ <%= javascript_include_tag 'prototype', 'application' %>
+ <script type="text/javascript" charset="utf-8">
+ var stores = <%= (@stores.collect { |s| s.attributes }).to_json %>;
+ </script>
+ </head>
+ <body>
+ <div id="map" style="width: 800px; height: 500px"></div>
+ </body>
+</html>
@@ -7,7 +7,7 @@
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAApuqJ-ievoI8n0KBpKtZuyxTJQa0g3IQ9GZqIMmInSLzwtGDKaBSt40PUewe_UUsm_5pWXNbz5adklA"
type="text/javascript"></script>
- <%= javascript_include_tag 'prototype', 'application' %>
+ <%= javascript_include_tag 'prototype', 'application_chap_three' %>
</head>
<body>
<div id="map" style="width: 800px; height: 500px"></div>
View
Binary file not shown.
@@ -0,0 +1,19 @@
+class CreateStores < ActiveRecord::Migration
+ def self.up
+ create_table :stores do |t|
+ t.string :name, :limit => 50
+ t.string :address, :limit => 100
+ t.string :address2, :limit => 100
+ t.string :city, :limit => 50
+ t.string :state, :limit => 2
+ t.string :zip, :limit => 9
+ t.string :phone, :limit => 15
+ t.string :lat, :limit => 20
+ t.string :lng, :limit => 20
+ end
+ end
+
+ def self.down
+ drop_table :stores
+ end
+end
View
@@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20080626030014) do
+ActiveRecord::Schema.define(:version => 20080627051703) do
create_table "markers", :force => true do |t|
t.decimal "lat"
@@ -19,4 +19,16 @@
t.string "icon", :limit => 100, :default => ""
end
+ create_table "stores", :force => true do |t|
+ t.string "name", :limit => 50
+ t.string "address", :limit => 100
+ t.string "address2", :limit => 100
+ t.string "city", :limit => 50
+ t.string "state", :limit => 2
+ t.string "zip", :limit => 9
+ t.string "phone", :limit => 15
+ t.string "lat", :limit => 20
+ t.string "lng", :limit => 20
+ end
+
end
@@ -0,0 +1,54 @@
+require 'open-uri'
+require 'rexml/document'
+
+api_key = "ABQIAAAApuqJ-ievoI8n0KBpKtZuyxTJQa0g3IQ9GZqIMmInSLzwtGDKaBSt40PUewe_UUsm_5pWXNbz5adklA"
+
+task :google_geocode => :environment do
+
+ Store.all.each do |store|
+ puts "\nStore: #{store.name}"
+ puts "Source Address: #{store.full_address}"
+
+ xml = open("http://maps.google.com/maps/geo?q=#{CGI.escape(store.full_address)}&output=xml&key=#{api_key}").read
+ doc = REXML::Document.new(xml)
+
+ puts "Status: " + doc.elements['//kml/Response/Status/code'].text
+
+ if doc.elements['//kml/Response/Status/code'].text != '200'
+ puts "Unable to parse Google response for #{store.name}"
+ else
+ doc.root.each_element('//Response') do |response|
+ response.each_element("//Placemark") do |place|
+ lng, lat = place.elements['//coordinates'].text.split(',')
+
+ puts "Result Address: " << place.elements['//address'].text
+ puts " Latitude: #{lat}"
+ puts " Longitude: #{lng}"
+ end
+ end
+ end
+ end
+
+end
+
+task :google_persist => :environment do
+ Store.all.each do |store|
+ puts "\nStore: #{store.name}"
+ puts "Source Address: #{store.full_address}"
+
+ xml = open("http://maps.google.com/maps/geo?q=#{CGI.escape(store.full_address)}&output=xml&key=#{api_key}").read
+ doc = REXML::Document.new(xml)
+
+ puts "Status: " + doc.elements['//kml/Response/Status/code'].text
+
+ if doc.elements['//kml/Response/Status/code'].text != '200'
+ puts "Unable to parse Google response for #{store.name}"
+ else
+ lng, lat = doc.root.elements['//coordinates'].text.split(',')
+
+ store.lat = lat
+ store.lng = lng
+ store.save
+ end
+ end
+end
@@ -1,121 +1,34 @@
var map;
-var centerLatitude = 37.4419;
-var centerLongitude = -122.1419;
-var startZoom = 12;
-
-function createMarker() {
- var lng = $('longitude').value;
- var lat = $('latitude').value;
- var formValues = Form.serialize('geocache-input');
- new Ajax.Request('create',
- {
- parameters: formValues,
- onComplete: function(request) {
- res = eval("(" + request.responseText + ")");
-
- if (!res.success) {
- alert(res.content);
- }
- else {
- var latlng = new GLatLng(parseFloat(lat), parseFloat(lng));
- var marker = addMarkerToMap(latlng, res.content, res.icon);
- map.addOverlay(marker);
- map.closeInfoWindow();
- }
- }
- });
-
- return false;
-}
-
-function listMarkers() {
- var request = GXmlHttp.create();
- request.open('GET', 'list', true);
- request.onreadystatechange = function() {
- if (request.readyState == 4) {
- markers = eval("(" + request.responseText + ")");
- for (var i = 0; i < markers.length; ++i) {
- var marker = markers[i].marker;
- var lat = marker.lat;
- var lng = marker.lng;
-
- if (lat && lng) {
- var latlng = new GLatLng(parseFloat(lat), parseFloat(lng));
-
- var html = '<div><strong>Found</strong> '
- + marker.found
- + '</div><div><strong>Left</strong> '
- + marker.left
- + '</div>';
-
- map.addOverlay(addMarkerToMap(latlng, html, marker.icon));
- }
- }
- }
- }
-
- request.send(null);
-}
-
-function addMarkerToMap(latlng, html, iconImage) {
- if (iconImage != "") {
- var icon = new GIcon();
- icon.image = iconImage;
- icon.iconSize = new GSize(25, 25);
- icon.iconAnchor = new GPoint(14, 25);
- icon.infoWindowAnchor = new GPoint(14, 14);
- var marker = new GMarker(latlng, icon);
- }
- else {
- var marker = new GMarker(latlng);
- }
+var centerLatitude = 40.6897;
+var centerLongitude = -95.0446;
+var startZoom = 3;
+
+var RonJonLogo = new GIcon();
+RonJonLogo.image = "http://book.earthcode.com/chapter4/StoreLocationMap/ronjonsurfshoplogo.png"
+RonJonLogo.iconSize = new GSize(48, 24);
+RonJonLogo.iconAnchor = new GPoint(24, 14);
+RonJonLogo.infoWindowAnchor = new GPoint(24, 24);
+
+function addMarker(latitude, longitude, description) {
+ var marker = new GMarker(new GLatLng(latitude, longitude), RonJonLogo);
+ GEvent.addListener(marker, 'click',
+ function() { marker.openInfoWindowHtml(description); }
+ );
- GEvent.addListener(marker, 'click', function() {
- var markerHTML = html;
- marker.openInfoWindowHtml(markerHTML);
- });
- return marker;
-}
-
-function onMapClick(overlay, latlng) {
- /* click on a marker also tiggers this event, but without a latlng value*/
- if (!latlng)
- return;
-
- var inputForm = document.createElement("form");
- inputForm.setAttribute("action", "");
- inputForm.onsubmit = function() { createMarker(); return false; }
- inputForm.id = 'geocache-input';
-
- var lng = latlng.lng();
- var lat = latlng.lat();
-
- inputForm.innerHTML = '<fieldset style="width:150px;">'
- + '<legend>New Marker</legend>'
- + '<label for="found">Found</label>'
- + '<input type="text" id="found" name="m[found]" style="width: 100%;" />'
- + '<label for="left">Left</label>'
- + '<input type="text" id="left" name="m[left]" style="width: 100%;" />'
- + '<label for="icon">Icon URL</label>'
- + '<input type="text" id="icon" name="m[icon]" style="width: 100%" />'
- + '<input type="submit" value="Save" />'
- + '<input type="hidden" id="longitude" name="m[lng]" value="' + lng + '" />'
- + '<input type="hidden" id="latitude" name="m[lat]" value ="' + lat + '" />'
- + '</fieldset>';
- map.openInfoWindow(latlng, inputForm);
+ map.addOverlay(marker);
}
function init() {
if (!GBrowserIsCompatible())
return;
map = new GMap2(document.getElementById("map"));
- listMarkers();
map.addControl(new GSmallMapControl());
- map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(centerLatitude, centerLongitude), startZoom);
- GEvent.addListener(map, 'click', onMapClick);
+ for (i = 0; i < stores.length; ++i) {
+ addMarker(stores[i].lat, stores[i].lng, stores[i].name)
+ }
}
window.onload = init;
Oops, something went wrong.

0 comments on commit b6b175b

Please sign in to comment.