ym4r 0.2.2 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +26 -2
- data/lib/ym4r/google_maps/geocoding/geocoding.rb +4 -2
- data/lib/ym4r/google_maps/javascript/markerGroup.js +104 -0
- data/lib/ym4r/google_maps/map.rb +17 -5
- data/lib/ym4r/google_maps/mapping.rb +13 -4
- data/lib/ym4r/google_maps/overlay.rb +20 -1
- data/rakefile.rb +1 -1
- metadata +3 -2
data/README
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
=YM4R
|
2
|
-
This is YM4R 0.
|
2
|
+
This is YM4R 0.3.1. The goal of YM4R (which naturally means Yellow Maps For Ruby...) is to ease the use of the Google Maps (including the Geocoding API) and Yahoo! Maps API's (including the Geocoding, Map Image, Traffic and Local Search API's) from Ruby and Rails.
|
3
3
|
|
4
4
|
==Operations
|
5
5
|
===Google Maps
|
@@ -54,6 +54,30 @@ For example, if you want to add a marker to the map, you need to do a few things
|
|
54
54
|
What is sent to the browser will be the fllowing JavaScript code:
|
55
55
|
map.addOverlay(new GMarker(new GLatLng(123123.1,12313.76),{title:\"Hello again!\"}))
|
56
56
|
|
57
|
+
====GMarkerGroup
|
58
|
+
A new type of GOverlay is available, called GMarkerGroup. To use it you would have to include in your HTML template the JavaScript file markerGroup.js found in the <tt>lib/ym4r/google_maps/javascript</tt> directory of the distribution.
|
59
|
+
|
60
|
+
It is useful in 2 situations:
|
61
|
+
- Display and undisplay a group of markers without referencing all of them. You just declare your marker group globally and call +activate+ and +deactivate+ on this group in response, for example, to clicks on links on your page..
|
62
|
+
- Keeping an index of markers, for example, in order to show one of these markers in reponse to a click on a link (the way Google Local does with the results of the search).
|
63
|
+
|
64
|
+
Here is how you would use it from your Ruby code:
|
65
|
+
@map = GMap.new("map_div")
|
66
|
+
marker1 = GMarker.new([123.55,123.988],:info_window => "Hello from 1!")
|
67
|
+
marker2 = GMarker.new([87.123,18.9],:info_window =>"Hello from 2!")
|
68
|
+
@map.overlay_global_init(GMarkerGroup.new(true,
|
69
|
+
1 => marker1,
|
70
|
+
2 => marker2),"myGroup")
|
71
|
+
Here I have created an active (ie which is going to be displayed when the map is created) marker group called +myGroup+ with 2 markers, which I want to reference later. If I did not want to reference them later (I just want to be able to display and undisplay the marker group), I could have passed an array instead of the hash.
|
72
|
+
|
73
|
+
Then in your template, you could have that:
|
74
|
+
<a href="#" onclick="myGroup.showMarker(1);return false;">Click here to display marker1</a>
|
75
|
+
<a href="#" onclick="myGroup.showMarker(2);return false;">Click here to display marker2</a>
|
76
|
+
<%= @map.to_div %>
|
77
|
+
When you click on one of the links, the corresponding marker has its info window displayed.
|
78
|
+
|
79
|
+
You can call +activate+ and +deactivate+ to display or undisplay a group of markers. You can add new markers with +addMarker(marker,id)+. Again if you don't care about referencing the marker, you don't need to pass an id. If the marker group is active, the newly added marker will be displayed immediately. Otherwise it will be displayed the next time the group is activated. Finally, since it is an overlay, the group will be removed when calling clearOverlays on the GMap object.
|
80
|
+
|
57
81
|
====Adding new map types
|
58
82
|
It is now possible to easily add new map types, on top of the already existing ones, like G_SATELLITE_MAP or G_NORMAL_MAP. The imagery for these new map types can come from layers of the standard map types or can be taken either from a WMS server or from pretiled images on a server (that can be generated with a tool that comes with the library).
|
59
83
|
|
@@ -91,7 +115,7 @@ If you want to wipe out the existing map types (for example the 3 default ones),
|
|
91
115
|
The YM4R library provides 2 tools to generate tiles. They are in the +tools+ directory of the YM4R distribution. These tools can naturally be used to generate tiles even if you don't use the YM4R library to manipulate your Google Maps. You will just have to write the code to fetch the tiles by yourself.
|
92
116
|
|
93
117
|
=====tile_wms.rb
|
94
|
-
This is to generate tiles from an already existing WMS server. It can be useful if you don't want to setup a permanent WMS server but still want to display your geographic data files (any format compatible with your WMS server can then be used). It can also be used to cache data from public servers, which can sometimes be very slow to answer requests. Run "ruby tile_wms.rb" to know what the options are. These are very similar to the ones passed to the WMSTiler constructor, although the <tt>-g</tt> (<tt>--gmap-setting</tt>) needs to be explained in more details. It uses the data that comes from this tool: http://www.onnyturf.com/google/latlontotile.html. Basically you need to center the map at the zoom you need to get your desired extent. When you are satisfied, the tool will give you the following data: the X and Y values of the upper left corner tile, 17 minus the zoom level (this is because the V2 of the Google Maps API reversed the zoom order), the number of horizontal and vertical tiles that you want. You will then pass to the <tt>-g</tt>
|
118
|
+
This is to generate tiles from an already existing WMS server. It can be useful if you don't want to setup a permanent WMS server but still want to display your geographic data files (any format compatible with your WMS server can then be used). It can also be used to cache data from public servers, which can sometimes be very slow to answer requests. Run "ruby tile_wms.rb" to know what the options are. These are very similar to the ones passed to the WMSTiler constructor, although the <tt>-g</tt> (<tt>--gmap-setting</tt>) needs to be explained in more details. It uses the data that comes from this tool: http://www.onnyturf.com/google/latlontotile.html. Basically you need to center the map at the zoom you need to get your desired extent. When you are satisfied, the tool will give you the following data: the X and Y values of the upper left corner tile, 17 minus the zoom level (this is because the V2 of the Google Maps API reversed the zoom order), the number of horizontal and vertical tiles that you want. You will then pass to the <tt>-g</tt> option 5 integers in the order previously described, for example:
|
95
119
|
-g 300,383,7,3,2
|
96
120
|
About the zoom level, if the tools tells you 7, you should pass 10 (17 - 7) to the <tt>-g</tt> option.
|
97
121
|
|
@@ -25,7 +25,7 @@ module Ym4r
|
|
25
25
|
end
|
26
26
|
|
27
27
|
doc = REXML::Document.new(xml)
|
28
|
-
|
28
|
+
|
29
29
|
response = doc.elements['//Response']
|
30
30
|
placemarks = Placemarks.new(response.elements['name'].text,response.elements['Status/code'].text.to_i)
|
31
31
|
response.elements.each("Placemark") do |placemark|
|
@@ -34,6 +34,7 @@ module Ym4r
|
|
34
34
|
data_administrative = data['//AdministrativeAreaName']
|
35
35
|
data_sub_administrative = data['//SubAdministrativeAreaName']
|
36
36
|
data_locality = data['//LocalityName']
|
37
|
+
data_dependent_locality = data['//DependentLocalityName']
|
37
38
|
data_thoroughfare = data['//ThoroughfareName']
|
38
39
|
data_postal_code = data['//PostalCodeNumber']
|
39
40
|
placemarks << Geocoding::Placemark.new(data['address'].text,
|
@@ -41,6 +42,7 @@ module Ym4r
|
|
41
42
|
data_administrative.nil? ? "" : data_administrative.text,
|
42
43
|
data_sub_administrative.nil? ? "" : data_sub_administrative.text,
|
43
44
|
data_locality.nil? ? "" : data_locality.text,
|
45
|
+
data_dependent_locality.nil? ? "" : data_dependent_locality.text,
|
44
46
|
data_thoroughfare.nil? ? "" : data_thoroughfare.text,
|
45
47
|
data_postal_code.nil? ? "" : data_postal_code.text,
|
46
48
|
*(data['//coordinates'].text.split(",")[0..1].collect {|l| l.to_f }))
|
@@ -60,7 +62,7 @@ module Ym4r
|
|
60
62
|
end
|
61
63
|
|
62
64
|
#A result from the Geocoding service.
|
63
|
-
class Placemark < Struct.new(:address,:country_code,:administrative_area,:sub_administrative_area,:locality,:thoroughfare,:postal_code,:longitude,:latitude)
|
65
|
+
class Placemark < Struct.new(:address,:country_code,:administrative_area,:sub_administrative_area,:locality,:dependent_locality,:thoroughfare,:postal_code,:longitude,:latitude)
|
64
66
|
def lonlat
|
65
67
|
[longitude,latitude]
|
66
68
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
function GMarkerGroup(active, markers, markersById) {
|
2
|
+
this.active = active;
|
3
|
+
this.markers = markers || new Array();
|
4
|
+
this.markersById = markersById || new Object();
|
5
|
+
}
|
6
|
+
|
7
|
+
GMarkerGroup.prototype = new GOverlay();
|
8
|
+
|
9
|
+
GMarkerGroup.prototype.initialize = function(map) {
|
10
|
+
this.map = map;
|
11
|
+
|
12
|
+
if(this.active){
|
13
|
+
for(var i = 0 , len = this.markers.length; i < len; i++) {
|
14
|
+
this.map.addOverlay(this.markers[i]);
|
15
|
+
}
|
16
|
+
for(var id in this.markersById){
|
17
|
+
this.map.addOverlay(this.markersById[id]);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
//If not already done (ie if not inactive) remove all the markers from the map
|
23
|
+
GMarkerGroup.prototype.remove = function() {
|
24
|
+
this.deactivate();
|
25
|
+
}
|
26
|
+
|
27
|
+
GMarkerGroup.prototype.redraw = function(force){
|
28
|
+
//Nothing to do : markers are already taken care of
|
29
|
+
}
|
30
|
+
|
31
|
+
//Copy the data to a new Marker Group
|
32
|
+
GMarkerGroup.prototype.copy = function() {
|
33
|
+
var overlay = new GMarkerGroup(this.active);
|
34
|
+
overlay.markers = this.markers; //Need to do deep copy
|
35
|
+
overlay.markersById = this.markersById; //Need to do deep copy
|
36
|
+
return overlay;
|
37
|
+
}
|
38
|
+
|
39
|
+
//Inactivate the Marker group and clear the internal content
|
40
|
+
GMarkerGroup.prototype.clear = function(){
|
41
|
+
//deactivate the map first (which removes the markers from the map)
|
42
|
+
this.deactivate;
|
43
|
+
//Clear the internal content
|
44
|
+
this.markers = new Array();
|
45
|
+
this.markersById = new Object();
|
46
|
+
}
|
47
|
+
|
48
|
+
//Add a marker to the GMarkerGroup ; Adds it now to the map if the GMarkerGroup is active ; Should only be used AFTER the group overlay has been added to the map
|
49
|
+
GMarkerGroup.prototype.addMarker = function(marker,id){
|
50
|
+
if(id == undefined){
|
51
|
+
this.markers.push(marker);
|
52
|
+
}else{
|
53
|
+
this.markersById[id] = marker;
|
54
|
+
}
|
55
|
+
if(this.active && this.map != undefined ){
|
56
|
+
this.map.addOverlay(marker);
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
//Open the info window (or info window tabs) of a marker
|
61
|
+
GMarkerGroup.prototype.showMarker = function(id){
|
62
|
+
var marker = this.markersById[id];
|
63
|
+
if(marker != undefined){
|
64
|
+
//Check if I can just send the click event to the marker
|
65
|
+
GEvent.trigger(marker,"click");
|
66
|
+
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
//Activate (or deactivate depending on the argument) the GMarkerGroup
|
71
|
+
GMarkerGroup.prototype.activate = function(active){
|
72
|
+
active = (active == undefined) ? true : active;
|
73
|
+
if(!active){
|
74
|
+
if(this.active){
|
75
|
+
if(this.map != undefined){
|
76
|
+
for(var i = 0 , len = this.markers.length; i < len; i++){
|
77
|
+
this.map.removeOverlay(this.markers[i])
|
78
|
+
}
|
79
|
+
for(var id in this.markersById){
|
80
|
+
this.map.removeOverlay(this.markersById[id]);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
this.active = false;
|
84
|
+
}
|
85
|
+
}else{
|
86
|
+
if(!this.active){
|
87
|
+
if(this.map != undefined){
|
88
|
+
for(var i = 0 , len = this.markers.length; i < len; i++){
|
89
|
+
this.map.addOverlay(this.markers[i]);
|
90
|
+
}
|
91
|
+
for(var id in this.markersById){
|
92
|
+
this.map.addOverlay(this.markersById[id]);
|
93
|
+
}
|
94
|
+
}
|
95
|
+
this.active = true;
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
//Deactivate the Group Overlay (convenience method)
|
101
|
+
GMarkerGroup.prototype.deactivate = function(){
|
102
|
+
this.activate(false);
|
103
|
+
}
|
104
|
+
|
data/lib/ym4r/google_maps/map.rb
CHANGED
@@ -16,6 +16,7 @@ module Ym4r
|
|
16
16
|
@variable = variable
|
17
17
|
@init = []
|
18
18
|
@init_end = [] #for stuff that must be initialized at the end (controls)
|
19
|
+
@init_begin = [] #for stuff that must be initialized at the beginning (center + zoom)
|
19
20
|
@global_init = []
|
20
21
|
end
|
21
22
|
|
@@ -54,9 +55,9 @@ module Ym4r
|
|
54
55
|
#Initializes the initial center and zoom of the map. +center+ can be both a GLatLng object or a 2-float array.
|
55
56
|
def center_zoom_init(center, zoom)
|
56
57
|
if center.is_a?(GLatLng)
|
57
|
-
@
|
58
|
+
@init_begin << set_center(center,zoom)
|
58
59
|
else
|
59
|
-
@
|
60
|
+
@init_begin << set_center(GLatLng.new(center),zoom)
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
@@ -83,17 +84,28 @@ module Ym4r
|
|
83
84
|
@global_init << code
|
84
85
|
end
|
85
86
|
|
86
|
-
#
|
87
|
+
#Deprecated. Use icon_global_init instead.
|
87
88
|
def icon_init(icon , name)
|
89
|
+
icon_global_init(icon , name)
|
90
|
+
end
|
91
|
+
|
92
|
+
#Initializes an icon and makes it globally accessible through the JavaScript variable of name +variable+.
|
93
|
+
def icon_global_init(icon , name)
|
88
94
|
declare_global_init(icon,name)
|
89
95
|
end
|
96
|
+
|
97
|
+
#Declares the overlay globally with name +name+
|
98
|
+
def overlay_global_init(overlay,name)
|
99
|
+
declare_global_init(overlay,name)
|
100
|
+
@init << add_overlay(overlay)
|
101
|
+
end
|
90
102
|
|
91
103
|
#Globally declare a MappingObject with variable name "name"
|
92
104
|
def declare_global_init(variable,name)
|
93
105
|
@global_init << variable.declare(name)
|
94
106
|
end
|
95
107
|
|
96
|
-
#Outputs the initialization code for the map. By default, it outputs the script tags, performs the initialization
|
108
|
+
#Outputs the initialization code for the map. By default, it outputs the script tags, performs the initialization in reponse to the onload event of the window and makes the map globally available.
|
97
109
|
def to_html(options = {})
|
98
110
|
no_load = options[:no_load]
|
99
111
|
no_script_tag = options[:no_script_tag]
|
@@ -114,6 +126,7 @@ module Ym4r
|
|
114
126
|
else
|
115
127
|
html << "#{assign_to(@variable)}\n"
|
116
128
|
end
|
129
|
+
html << @init_begin * "\n"
|
117
130
|
html << @init * "\n"
|
118
131
|
html << @init_end * "\n"
|
119
132
|
html << "\n}\n}\n" if !no_load
|
@@ -128,7 +141,6 @@ module Ym4r
|
|
128
141
|
end
|
129
142
|
end
|
130
143
|
|
131
|
-
|
132
144
|
end
|
133
145
|
end
|
134
146
|
|
@@ -5,12 +5,21 @@ module Ym4r
|
|
5
5
|
#The name of the variable in JavaScript space.
|
6
6
|
attr_reader :variable
|
7
7
|
|
8
|
-
#Creates javascript code for missing methods
|
8
|
+
#Creates javascript code for missing methods + takes care of listeners
|
9
9
|
def method_missing(name,*args)
|
10
|
-
|
11
|
-
|
10
|
+
str_name = name.to_s
|
11
|
+
if str_name =~ /^on_(.*)/
|
12
|
+
if args.length != 1
|
13
|
+
raise ArgumentError("Only 1 argument is allowed on on_ methods");
|
14
|
+
else
|
15
|
+
Variable.new("GEvent.addListener(#{to_javascript},\"#{javascriptify_method($1)}\",#{args[0]})")
|
16
|
+
end
|
17
|
+
else
|
18
|
+
args.collect! do |arg|
|
19
|
+
MappingObject.javascriptify_variable(arg)
|
20
|
+
end
|
21
|
+
Variable.new("#{to_javascript}.#{MappingObject.javascriptify_method(str_name)}(#{args.join(",")})")
|
12
22
|
end
|
13
|
-
Variable.new("#{to_javascript}.#{MappingObject.javascriptify_method(name.to_s)}(#{args.join(",")})")
|
14
23
|
end
|
15
24
|
|
16
25
|
#Creates javascript code for array or hash indexing
|
@@ -94,9 +94,28 @@ module Ym4r
|
|
94
94
|
a << ",#{MappingObject.javascriptify_variable(@opacity)}" if @opacity
|
95
95
|
a << ")"
|
96
96
|
end
|
97
|
-
|
98
97
|
end
|
99
98
|
|
99
|
+
class GMarkerGroup
|
100
|
+
include MappingObject
|
101
|
+
attr_accessor :active, :markers, :markers_by_id
|
102
|
+
|
103
|
+
def initialize(active = true , markers = nil)
|
104
|
+
@active = active
|
105
|
+
@markers = []
|
106
|
+
@markers_by_id = {}
|
107
|
+
if markers.is_a?(Array)
|
108
|
+
@markers = markers
|
109
|
+
elsif markers.is_a?(Hash)
|
110
|
+
@markers_by_id = markers
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def create
|
115
|
+
"new GMarkerGroup(#{MappingObject.javascriptify_variable(@active)},#{MappingObject.javascriptify_variable(@markers)},#{MappingObject.javascriptify_variable(@markers_by_id)})"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
100
119
|
#A basic Latitude/longitude point.
|
101
120
|
class GLatLng
|
102
121
|
include MappingObject
|
data/rakefile.rb
CHANGED
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ym4r
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2006-06-
|
6
|
+
version: 0.3.1
|
7
|
+
date: 2006-06-18 00:00:00 +05:00
|
8
8
|
summary: Using Google Maps and Yahoo! Maps from Ruby and Rails
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -59,6 +59,7 @@ files:
|
|
59
59
|
- lib/ym4r/yahoo_maps/flash/tool.rb
|
60
60
|
- lib/ym4r/yahoo_maps/flash/widget.rb
|
61
61
|
- lib/ym4r/google_maps/config/config.yml
|
62
|
+
- lib/ym4r/google_maps/javascript/markerGroup.js
|
62
63
|
- lib/ym4r/google_maps/javascript/wms-gs.js
|
63
64
|
- tools/tile_image.rb
|
64
65
|
- tools/tile_wms.rb
|