gmaps4rails 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +14 -22
- data/app/helpers/gmaps4rails/gmaps_helper.rb +1 -1
- data/app/views/gmaps4rails/_gmaps4rails.html.erb +10 -10
- data/lib/acts_as_gmappable/base.rb +65 -4
- data/lib/application_helper.rb +9 -6
- data/lib/gmaps4rails.rb +1 -0
- data/lib/hash.rb +64 -0
- data/public/javascripts/gmaps4rails.js +342 -106
- data/test/dummy/app/helpers/application_helper.rb +1 -0
- data/test/dummy/app/models/user.rb +1 -1
- data/test/dummy/app/views/users/test.rb +35 -0
- data/test/dummy/spec/base/base_spec.rb +77 -4
- data/test/dummy/spec/controllers/users_controller_spec.rb +57 -57
- data/test/dummy/spec/models/user_spec.rb +7 -6
- metadata +7 -8
- data/test/dummy/test/performance/browsing_test.rb +0 -9
- data/test/dummy/test/test_helper.rb +0 -13
data/README.rdoc
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
== Google Maps for Rails (gmaps4rails)
|
2
2
|
|
3
3
|
|
4
|
-
Gmaps4rails is developped to simply create a Google Map (Gmaps)
|
4
|
+
Gmaps4rails is developped to simply create a Google Map (Gmaps):
|
5
5
|
|
6
|
-
-
|
6
|
+
- directly from your model,
|
7
7
|
|
8
|
-
- your own json
|
8
|
+
- from your own json
|
9
9
|
|
10
|
-
It's based on Ruby on Rails 3 Engines and uses Google Maps API V3
|
10
|
+
It's based on Ruby on Rails 3 Engines and uses Google Maps API V3.
|
11
11
|
|
12
12
|
== Installation
|
13
13
|
|
@@ -16,8 +16,7 @@ It's based on Ruby on Rails 3 Engines and uses Google Maps API V3 with Marker Cl
|
|
16
16
|
== Requirements
|
17
17
|
- <%= yield :head %> (in your header)
|
18
18
|
- <%= yield :scripts %> (in your footer)
|
19
|
-
- config.serve_static_assets = true (in your production.rb)
|
20
|
-
- jQuery (used for ajax json, not mandatory if you only use the 'json' option)
|
19
|
+
- config.serve_static_assets = true (in your production.rb), or copy/paste gmaps4rails.css & gmaps4rail.js files in your app.
|
21
20
|
|
22
21
|
== Basic configuration
|
23
22
|
In your model, add:
|
@@ -36,15 +35,6 @@ Create a migration and add the following fields to your table (here users):
|
|
36
35
|
|
37
36
|
== How to?
|
38
37
|
=== QuickStart!
|
39
|
-
Say you have a User model and you want to display all the users on a map.
|
40
|
-
In your view:
|
41
|
-
|
42
|
-
<%= gmaps4rails_map("User") %>
|
43
|
-
|
44
|
-
Done!
|
45
|
-
|
46
|
-
=== Same Result, alternative solution
|
47
|
-
With this version, you won't need jQuery.
|
48
38
|
In your controller:
|
49
39
|
|
50
40
|
@json = User.all.to_gmaps4rails
|
@@ -53,22 +43,22 @@ In your view:
|
|
53
43
|
|
54
44
|
<%= gmaps4rails(@json) %>
|
55
45
|
|
56
|
-
Done
|
46
|
+
Done!
|
57
47
|
|
58
48
|
== Options
|
59
49
|
|
60
|
-
* Info window
|
50
|
+
* Markers with Info window, Custom Picture
|
61
51
|
|
62
|
-
*
|
63
|
-
|
64
|
-
* Scopes
|
65
|
-
|
66
|
-
* Create from your own json
|
52
|
+
* Circles, Polylines, Polygons
|
67
53
|
|
68
54
|
* Geocode directly your address and retrieve coordinates.
|
69
55
|
|
56
|
+
* Wrapper for 'Direction', giving instructions to go from point A to point B
|
57
|
+
|
70
58
|
* Auto-adjust the map to your markers
|
71
59
|
|
60
|
+
* Refresh your map on the fly with Javascript (and Ajax)
|
61
|
+
|
72
62
|
* {More details in the Wiki}[https://github.com/apneadiving/Google-Maps-for-Rails/wiki]
|
73
63
|
|
74
64
|
== Todo?
|
@@ -77,5 +67,7 @@ Feel free ton contact us, you have your say.
|
|
77
67
|
|
78
68
|
== Copyright
|
79
69
|
MIT license.
|
70
|
+
|
80
71
|
Authors: Benjamin Roth, David Ruyer
|
72
|
+
|
81
73
|
Contributor: Alex Vorobiev
|
@@ -1,5 +1,8 @@
|
|
1
|
-
<%
|
2
|
-
|
1
|
+
<% #enable_css enables user to avoid this css to be loaded
|
2
|
+
if enable_css == true %>
|
3
|
+
<% content_for :head do %>
|
4
|
+
<%= stylesheet_link_tag 'gmaps4rails' %>
|
5
|
+
<% end %>
|
3
6
|
<% end %>
|
4
7
|
|
5
8
|
<% content_for :scripts do %>
|
@@ -7,17 +10,14 @@
|
|
7
10
|
<script type="text/javascript" src='http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/1.0/src/markerclusterer.js'></script>
|
8
11
|
<%=javascript_include_tag 'gmaps4rails' %>
|
9
12
|
<script type="text/javascript" charset="utf-8">
|
10
|
-
<% options.each do |key, value| %>
|
11
|
-
Gmaps4Rails.<%= key %> = <%=raw value.is_a?(String) ? "'#{value}'" : value %>;
|
12
|
-
<% end %>
|
13
|
-
var builder = <%=raw options["processing"] == "json" ? builder : "'#{builder}'" %>;
|
14
13
|
|
15
14
|
window.onload = function() {
|
16
|
-
|
15
|
+
<% #true is passed here to trigger map initialization %>
|
16
|
+
<%=raw options.to_gmaps4rails(true) %>
|
17
17
|
}
|
18
18
|
</script>
|
19
19
|
<% end %>
|
20
20
|
|
21
|
-
<div id="<%= options['
|
22
|
-
<div id="<%= options['
|
23
|
-
</div>
|
21
|
+
<div id="<%= options["map_options"].nil? || options['map_options']['container_id'].nil? ? "map_container" : options['map_options']['container_id'] %>">
|
22
|
+
<div id="<%= options["map_options"].nil? || options['map_options']['id'].nil? ? "gmaps4rails_map" : options['map_options']['id'] %>"></div>
|
23
|
+
</div>
|
@@ -7,6 +7,10 @@ module Gmaps4rails
|
|
7
7
|
|
8
8
|
class GeocodeStatus < StandardError; end
|
9
9
|
class GeocodeNetStatus < StandardError; end
|
10
|
+
class GeocodeInvalidQuery < StandardError; end
|
11
|
+
class DirectionStatus < StandardError; end
|
12
|
+
class DirectionNetStatus < StandardError; end
|
13
|
+
class DirectionInvalidQuery < StandardError; end
|
10
14
|
|
11
15
|
def Gmaps4rails.create_json(object)
|
12
16
|
unless object[object.gmaps4rails_options[:lat_column]].blank? && object[object.gmaps4rails_options[:lng_column]].blank?
|
@@ -15,10 +19,11 @@ module Gmaps4rails
|
|
15
19
|
\"longitude\": \"#{object[object.gmaps4rails_options[:lng_column]]}\", \"latitude\": \"#{object[object.gmaps4rails_options[:lat_column]]}\", \"picture\": \"#{object.gmaps4rails_marker_picture['picture']}\", \"width\": \"#{object.gmaps4rails_marker_picture['width']}\", \"height\": \"#{object.gmaps4rails_marker_picture['height']}\"
|
16
20
|
} ,"
|
17
21
|
end
|
18
|
-
end
|
22
|
+
end
|
19
23
|
|
20
24
|
def Gmaps4rails.geocode(address)
|
21
25
|
if address.nil? || address.empty?
|
26
|
+
raise Gmaps4rails::GeocodeInvalidQuery, "You must provide an address"
|
22
27
|
else #coordinates are valid
|
23
28
|
geocoder = "http://maps.googleapis.com/maps/api/geocode/json?address="
|
24
29
|
output = "&sensor=false"
|
@@ -35,9 +40,11 @@ module Gmaps4rails
|
|
35
40
|
if parse["status"] == "OK"
|
36
41
|
array = []
|
37
42
|
parse["results"].each do |result|
|
38
|
-
array << {
|
43
|
+
array << {
|
44
|
+
:lat => result["geometry"]["location"]["lat"],
|
39
45
|
:lng => result["geometry"]["location"]["lng"],
|
40
|
-
:matched_address => result["formatted_address"]
|
46
|
+
:matched_address => result["formatted_address"]
|
47
|
+
}
|
41
48
|
end
|
42
49
|
return array
|
43
50
|
else #status != OK
|
@@ -49,10 +56,64 @@ module Gmaps4rails
|
|
49
56
|
raise Gmaps4rails::GeocodeNetStatus, "The request sent to google was invalid (not http success): #{request}.
|
50
57
|
Response was: #{resp}"
|
51
58
|
end #end resp test
|
52
|
-
|
53
59
|
end # end address valid
|
54
60
|
end #end geocode
|
55
61
|
|
62
|
+
#output could be raw, pretty or clean
|
63
|
+
def Gmaps4rails.destination(start_end, options={}, output="pretty")
|
64
|
+
if start_end["from"].nil? || start_end["to"].empty?
|
65
|
+
raise Gmaps4rails::DirectionInvalidQuery, "Origin and destination must be provided in a hash as first argument"
|
66
|
+
else #great, we have stuff to work with
|
67
|
+
geocoder = "http://maps.googleapis.com/maps/api/directions/json?origin=#{start_end["from"]}&destination=#{start_end["to"]}"
|
68
|
+
#if value is an Array, it means it contains the waypoints, otherwise it's chained normally
|
69
|
+
dest_options = options.empty? ? "" : "&" + options.map {|k,v| v.is_a?(Array) ? k + "=" + v * ("|") : k + "=" + v }*("&")
|
70
|
+
#send request to the google api to get the directions
|
71
|
+
request = geocoder + dest_options + "&sensor=false"
|
72
|
+
url = URI.escape(request)
|
73
|
+
resp = Net::HTTP.get_response(URI.parse(url))
|
74
|
+
#parse result if result received properly
|
75
|
+
if resp.is_a?(Net::HTTPSuccess)
|
76
|
+
#parse the json
|
77
|
+
parse = Crack::JSON.parse(resp.body)
|
78
|
+
#check if google went well
|
79
|
+
if parse["status"] == "OK"
|
80
|
+
legs = []
|
81
|
+
#Each element in the legs array specifies a single leg of the journey from the origin to the destination in the calculated route
|
82
|
+
parse["routes"].first["legs"].each do |leg|
|
83
|
+
#delete coded polyline elements from legs and store it in polylines to make output cleaner
|
84
|
+
polylines = leg["steps"].map {|step| step.delete("polyline")} if output == "pretty" || output == "clean"
|
85
|
+
legs << {
|
86
|
+
"duration" => { "text" => leg["duration"]["text"], "value" => leg["duration"]["value"].to_f },
|
87
|
+
"distance" => { "text" => leg["distance"]["text"], "value" => leg["distance"]["value"].to_f },
|
88
|
+
"steps" => leg["steps"]
|
89
|
+
}
|
90
|
+
if output == "pretty"
|
91
|
+
#polylines contain levels data, which are not that useful.
|
92
|
+
polylines.map{|poly| poly.delete("levels")}
|
93
|
+
#creat valid json from all polylines, this could be directly passed to javascript for display
|
94
|
+
json = polylines.map { |poly| {"coded_array" => poly["points"]} }.to_json
|
95
|
+
#merge results in legs
|
96
|
+
legs.last.merge!({ "polylines" => json })
|
97
|
+
end
|
98
|
+
end
|
99
|
+
return legs
|
100
|
+
else #status != OK
|
101
|
+
raise Gmaps4rails::DirectionStatus, "The query you passed seems invalid, status was: #{parse["status"]}.
|
102
|
+
Request was: #{request}"
|
103
|
+
end #end parse status
|
104
|
+
else #if not http success
|
105
|
+
raise Gmaps4rails::DirectionNetStatus, "The request sent to google was invalid (not http success): #{request}.
|
106
|
+
Response was: #{resp}"
|
107
|
+
end #end resp test
|
108
|
+
end # end origin + destination exist
|
109
|
+
end #end destination
|
110
|
+
|
111
|
+
|
112
|
+
def Gmaps4rails.filter(data)
|
113
|
+
return data if data.is_a?(Numeric)
|
114
|
+
"'#{data}'"
|
115
|
+
end
|
116
|
+
|
56
117
|
module ActsAsGmappable
|
57
118
|
|
58
119
|
module Base
|
data/lib/application_helper.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
module ApplicationHelper
|
2
2
|
|
3
|
-
def
|
4
|
-
|
3
|
+
def gmaps4rails(builder, enable_css = true )
|
4
|
+
options = {
|
5
|
+
"map_options" => { "auto_adjust" => true},
|
6
|
+
"markers" => { "data" => builder }
|
7
|
+
}
|
8
|
+
render :partial => 'gmaps4rails/gmaps4rails', :locals => { :options => options, :enable_css => enable_css }
|
5
9
|
end
|
6
10
|
|
7
|
-
def
|
8
|
-
|
9
|
-
render :partial => 'gmaps4rails/gmaps4rails', :locals => { :builder => builder, :options => options }
|
11
|
+
def gmaps(options, enable_css = true )
|
12
|
+
render :partial => 'gmaps4rails/gmaps4rails', :locals => { :options => options, :enable_css => enable_css }
|
10
13
|
end
|
11
|
-
|
14
|
+
|
12
15
|
end
|
data/lib/gmaps4rails.rb
CHANGED
data/lib/hash.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
class Hash
|
2
|
+
def to_gmaps4rails(init = false)
|
3
|
+
#the variable 'options' has the following structure
|
4
|
+
#{
|
5
|
+
# "map_options" => hash,
|
6
|
+
# "markers" => { "data" => json, "options" => hash },
|
7
|
+
# "polylines" => { "data" => json, "options" => hash },
|
8
|
+
# "polygons" => { "data" => json, "options" => hash },
|
9
|
+
# "circles" => { "data" => json, "options" => hash },
|
10
|
+
# "direction" => { "data" => hash, "options" => hash }
|
11
|
+
#}
|
12
|
+
# "map_options" and "direction" must be treated separately because there content is slightly different from the other
|
13
|
+
# - "map_options" has no data
|
14
|
+
# - "direction" has a hash as a data and waypoints options must be processed properly
|
15
|
+
#
|
16
|
+
# in the following code, I loop through the elements of the hash
|
17
|
+
#
|
18
|
+
result = Array.new
|
19
|
+
|
20
|
+
#Don't display js concerning map if no need to be initialized
|
21
|
+
if init == true
|
22
|
+
#because map should be initialized first, we must extract possible map_options
|
23
|
+
unless self["map_options"].nil?
|
24
|
+
self["map_options"].each do |option_k, option_v|
|
25
|
+
result << "Gmaps4Rails.map_options.#{option_k} = #{Gmaps4rails.filter option_v};"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
result << "Gmaps4Rails.initialize();"
|
30
|
+
end #if init
|
31
|
+
each do |category, content| #loop through options hash
|
32
|
+
case category
|
33
|
+
when "map_options"
|
34
|
+
#already taken into account above => nothing to do here
|
35
|
+
when "direction"
|
36
|
+
result << "Gmaps4Rails.direction_conf.origin = '#{content["data"]["from"]}';"
|
37
|
+
result << "Gmaps4Rails.direction_conf.destination = '#{content["data"]["to"]}';"
|
38
|
+
|
39
|
+
content["options"] ||= Array.new
|
40
|
+
content["options"].each do |option_k, option_v|
|
41
|
+
if option_k == "waypoints"
|
42
|
+
waypoints = Array.new
|
43
|
+
option_v.each do |waypoint|
|
44
|
+
waypoints << { "location" => waypoint, "stopover" => true }.to_json
|
45
|
+
end
|
46
|
+
result << "Gmaps4Rails.direction_conf.waypoints = [#{waypoints * (",")}];"
|
47
|
+
else #option_k != "waypoint" %>
|
48
|
+
result << "Gmaps4Rails.direction_conf.#{option_k} = #{Gmaps4rails.filter option_v};"
|
49
|
+
end
|
50
|
+
end #end .each %>
|
51
|
+
result << "Gmaps4Rails.create_direction();"
|
52
|
+
else #default behaviour in case condition
|
53
|
+
result << "Gmaps4Rails.#{category} = #{content["data"]};"
|
54
|
+
content["options"] ||= Array.new
|
55
|
+
content["options"].each do |option_k, option_v|
|
56
|
+
result << "Gmaps4Rails.#{category}_conf.#{option_k} = #{Gmaps4rails.filter option_v};"
|
57
|
+
end
|
58
|
+
result << "Gmaps4Rails.create_#{category}();"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
result * ('
|
62
|
+
')
|
63
|
+
end
|
64
|
+
end
|
@@ -1,136 +1,348 @@
|
|
1
|
-
google.load('maps', '3', { other_params: 'sensor=false' });
|
2
|
-
|
3
|
-
//marker_clusterer styles
|
4
|
-
var styles = [{
|
5
|
-
url: 'http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/1.0/images/people35.png',
|
6
|
-
height: 35,
|
7
|
-
width: 35,
|
8
|
-
opt_anchor: [16, 0],
|
9
|
-
opt_textColor: '#ff00ff',
|
10
|
-
opt_textSize: 10
|
11
|
-
}];
|
1
|
+
google.load('maps', '3', { other_params: 'libraries=geometry&sensor=false' });
|
12
2
|
|
13
3
|
var Gmaps4Rails = {
|
14
|
-
|
15
|
-
map: null,
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
//
|
39
|
-
//
|
40
|
-
|
41
|
-
|
42
|
-
|
4
|
+
//map config
|
5
|
+
map: null, //contains the map we're working on
|
6
|
+
|
7
|
+
//Map settings
|
8
|
+
map_options: {
|
9
|
+
id: 'gmaps4rails_map',
|
10
|
+
type: "ROADMAP", // HYBRID, ROADMAP, SATELLITE, TERRAIN
|
11
|
+
center_latitude : 0,
|
12
|
+
center_longitude : 0,
|
13
|
+
zoom : 1,
|
14
|
+
auto_adjust : false //adjust the map to the markers if set to true
|
15
|
+
},
|
16
|
+
|
17
|
+
//markers + info styling
|
18
|
+
markers_conf: {
|
19
|
+
picture : "",
|
20
|
+
width : 22,
|
21
|
+
length : 32,
|
22
|
+
//clustering config
|
23
|
+
do_clustering: true, //do clustering if set to true
|
24
|
+
clusterer_gridSize: 50, //the more the quicker but the less precise
|
25
|
+
clusterer_maxZoom: 10 //removes clusterer at this zoom level
|
26
|
+
},
|
27
|
+
|
28
|
+
//Stored variables
|
29
|
+
marker_objects: null, //contains markers LatLng
|
30
|
+
markers : [], //contains raw markers
|
31
|
+
bounds: null, //contains current bounds
|
32
|
+
polygons: null, //contains raw data, array of arrays (first element cold be a hash containing options)
|
33
|
+
polygon_objects: [], //contains processed google.maps.Polygon
|
34
|
+
polylines: null, //contains raw data, array of arrays (first element cold be a hash containing options)
|
35
|
+
polyline_objects: [], //contains processed google.maps.Polyline
|
36
|
+
circles: null, //contains raw data, array of hash
|
37
|
+
circle_objects: [], //contains processed google.maps.Circle
|
38
|
+
info_window : null,
|
39
|
+
markerClusterer: null, //contains all marker clusterers
|
40
|
+
|
41
|
+
//Polygon Styling
|
42
|
+
polygons_conf: { //default style for polygons
|
43
|
+
strokeColor: "#000",
|
44
|
+
strokeOpacity: 0.8,
|
45
|
+
strokeWeight: 2,
|
46
|
+
fillColor: "#000",
|
47
|
+
fillOpacity: 0.35
|
48
|
+
},
|
49
|
+
|
50
|
+
//Polyline Styling
|
51
|
+
polylines_conf: { //default style for polylines
|
52
|
+
strokeColor: "#FF0000",
|
53
|
+
strokeOpacity: 1,
|
54
|
+
strokeWeight: 2
|
55
|
+
},
|
56
|
+
|
57
|
+
//Circle Styling
|
58
|
+
circles_conf: { //default style for circles
|
59
|
+
fillColor: "#000",
|
60
|
+
fillOpacity: 0.35,
|
61
|
+
strokeColor: "#0000",
|
62
|
+
strokeOpacity: 0.8,
|
63
|
+
strokeWeight: 2
|
64
|
+
},
|
65
|
+
|
66
|
+
//Direction Settings
|
67
|
+
direction_conf: {
|
68
|
+
panel_id: null,
|
69
|
+
display_panel: false,
|
70
|
+
origin: null,
|
71
|
+
destination: null,
|
72
|
+
waypoints: [], //[{location: "toulouse,fr", stopover: true}, {location: "Clermont-Ferrand, fr", stopover: true}]
|
73
|
+
optimizeWaypoints: false,
|
74
|
+
unitSystem: "METRIC", //IMPERIAL
|
75
|
+
avoidHighways: false,
|
76
|
+
avoidTolls: false,
|
77
|
+
region: null,
|
78
|
+
travelMode: "DRIVING" //WALKING, BICYCLING
|
79
|
+
},
|
80
|
+
//initializes the map
|
81
|
+
initialize: function(){
|
82
|
+
this.map = new google.maps.Map(document.getElementById(this.map_options.id), {
|
83
|
+
zoom: this.map_options.zoom,
|
84
|
+
center: new google.maps.LatLng(this.map_options.center_latitude, this.map_options.center_longitude),
|
85
|
+
mapTypeId: google.maps.MapTypeId[this.map_options.type]
|
86
|
+
});
|
43
87
|
//infowindow closes when user clicks on the map
|
44
88
|
google.maps.event.addListener(this.map, 'click', function()
|
45
89
|
{ if (this.info_window != null) {this.info_window.close();}
|
46
90
|
});
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
91
|
+
//variable used for Auto-adjust
|
92
|
+
this.bounds = new google.maps.LatLngBounds();
|
93
|
+
},
|
94
|
+
|
95
|
+
create_direction: function(){
|
96
|
+
var directionsDisplay = new google.maps.DirectionsRenderer();
|
97
|
+
var directionsService = new google.maps.DirectionsService();
|
98
|
+
|
99
|
+
directionsDisplay.setMap(this.map);
|
100
|
+
//display panel only if required
|
101
|
+
if (this.direction_conf.display_panel) { directionsDisplay.setPanel(document.getElementById(this.direction_conf.panel_id)); }
|
102
|
+
directionsDisplay.setOptions({
|
103
|
+
suppressMarkers: true,
|
104
|
+
suppressInfoWindows: false,
|
105
|
+
suppressPolylines: false
|
106
|
+
});
|
107
|
+
var request = {
|
108
|
+
origin: this.direction_conf.origin,
|
109
|
+
destination: this.direction_conf.destination,
|
110
|
+
waypoints: this.direction_conf.waypoints,
|
111
|
+
optimizeWaypoints: this.direction_conf.optimizeWaypoints,
|
112
|
+
unitSystem: google.maps.DirectionsUnitSystem[this.direction_conf.unitSystem],
|
113
|
+
avoidHighways: this.direction_conf.avoidHighways,
|
114
|
+
avoidTolls: this.direction_conf.avoidTolls,
|
115
|
+
region: this.direction_conf.region,
|
116
|
+
travelMode: google.maps.DirectionsTravelMode[this.direction_conf.travelMode],
|
117
|
+
language: "fr"
|
118
|
+
};
|
119
|
+
directionsService.route(request, function(response, status) {
|
120
|
+
if (status == google.maps.DirectionsStatus.OK) {
|
121
|
+
directionsDisplay.setDirections(response);
|
122
|
+
}
|
123
|
+
});
|
124
|
+
},
|
125
|
+
|
126
|
+
//Loops through all circles
|
127
|
+
create_circles: function(){
|
128
|
+
for (var i = 0; i < this.circles.length; ++i) {
|
129
|
+
//by convention, default style configuration could be integrated in the first element
|
130
|
+
if ( i == 0 )
|
131
|
+
{
|
132
|
+
if (this.exists(this.circles[i].strokeColor )) { this.circles_conf.strokeColor = this.circles[i].strokeColor; }
|
133
|
+
if (this.exists(this.circles[i].strokeOpacity)) { this.circles_conf.strokeOpacity = this.circles[i].strokeOpacity; }
|
134
|
+
if (this.exists(this.circles[i].strokeWeight )) { this.circles_conf.strokeWeight = this.circles[i].strokeWeight; }
|
135
|
+
if (this.exists(this.circles[i].fillColor )) { this.circles_conf.fillColor = this.circles[i].fillColor; }
|
136
|
+
if (this.exists(this.circles[i].fillOpacity )) { this.circles_conf.fillOpacity = this.circles[i].fillOpacity; }
|
137
|
+
}
|
138
|
+
if (this.exists(this.circles[i].latitude) && this.exists(this.circles[i].longitude))
|
139
|
+
{
|
140
|
+
center = new google.maps.LatLng(this.circles[i].latitude, this.circles[i].longitude);
|
141
|
+
this.extend_bounds(center);
|
142
|
+
//always check if a config is given, if not, use defaults
|
143
|
+
var circle = new google.maps.Circle({
|
144
|
+
center: center,
|
145
|
+
strokeColor: this.circles[i].strokeColor || this.circles_conf.strokeColor,
|
146
|
+
strokeOpacity: this.circles[i].strokeOpacity || this.circles_conf.strokeOpacity,
|
147
|
+
strokeWeight: this.circles[i].strokeWeight || this.circles_conf.strokeWeight,
|
148
|
+
fillOpacity: this.circles[i].fillOpacity || this.circles_conf.fillOpacity,
|
149
|
+
fillColor: this.circles[i].fillColor || this.circles_conf.fillColor,
|
150
|
+
radius: this.circles[i].radius,
|
151
|
+
clickable: false
|
152
|
+
});
|
153
|
+
this.circle_objects.push(circle);
|
154
|
+
circle.setMap(this.map);
|
155
|
+
}
|
51
156
|
}
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
157
|
+
},
|
158
|
+
|
159
|
+
//polygons is an array of arrays. It loops.
|
160
|
+
create_polygons: function(){
|
161
|
+
for (var i = 0; i < this.polygons.length; ++i) {
|
162
|
+
//Polygons could be customized. By convention, customization options should be contained in the first
|
163
|
+
if (i==0)
|
164
|
+
{
|
165
|
+
//Array contain polygon elements
|
166
|
+
if (this.polygons[i] instanceof Array) {
|
167
|
+
this.create_polygon(i);
|
168
|
+
}
|
169
|
+
//hashes contain configuration which would be set as default
|
170
|
+
else{
|
171
|
+
if (this.exists(this.polygons[i].strokeColor) ) { this.polygons_conf.strokeColor = this.polygons[i].strokeColor; }
|
172
|
+
if (this.exists(this.polygons[i].strokeOpacity)) { this.polygons_conf.strokeOpacity = this.polygons[i].strokeOpacity; }
|
173
|
+
if (this.exists(this.polygons[i].strokeWeight )) { this.polygons_conf.strokeWeight = this.polygons[i].strokeWeight; }
|
174
|
+
if (this.exists(this.polygons[i].fillColor )) { this.polygons_conf.fillColor = this.polygons[i].fillColor; }
|
175
|
+
if (this.exists(this.polygons[i].fillOpacity )) { this.polygons_conf.fillOpacity = this.polygons[i].fillOpacity; }
|
176
|
+
}
|
177
|
+
}
|
178
|
+
else { this.create_polygon(i); }
|
56
179
|
}
|
57
|
-
|
180
|
+
},
|
181
|
+
|
182
|
+
//creates a single polygon, triggered by create_polygons
|
183
|
+
create_polygon: function(i){
|
184
|
+
var polygon_coordinates = [];
|
185
|
+
var strokeColor;
|
186
|
+
var strokeOpacity;
|
187
|
+
var strokeWeight;
|
188
|
+
var fillColor;
|
189
|
+
var fillOpacity;
|
190
|
+
//Polygon points are in an Array, that's why looping is necessary
|
191
|
+
for (var j = 0; j < this.polygons[i].length; ++j) {
|
192
|
+
var latlng = new google.maps.LatLng(this.polygons[i][j].latitude, this.polygons[i][j].longitude);
|
193
|
+
polygon_coordinates.push(latlng);
|
194
|
+
this.extend_bounds(latlng);
|
195
|
+
//first element of an Array could contain specific configuration for this particular polygon. If no config given, use default
|
196
|
+
if (j==0) {
|
197
|
+
strokeColor = this.polygons[i][j].strokeColor || this.polygons_conf.strokeColor;
|
198
|
+
strokeOpacity = this.polygons[i][j].strokeOpacity || this.polygons_conf.strokeOpacity;
|
199
|
+
strokeWeight = this.polygons[i][j].strokeWeight || this.polygons_conf.strokeWeight;
|
200
|
+
fillColor = this.polygons[i][j].fillColor || this.polygons_conf.fillColor;
|
201
|
+
fillOpacity = this.polygons[i][j].fillOpacity || this.polygons_conf.fillOpacity;
|
202
|
+
}
|
203
|
+
}
|
204
|
+
|
205
|
+
// Construct the polygon
|
206
|
+
var new_poly = new google.maps.Polygon({
|
207
|
+
paths: polygon_coordinates,
|
208
|
+
strokeColor: strokeColor,
|
209
|
+
strokeOpacity: strokeOpacity,
|
210
|
+
strokeWeight: strokeWeight,
|
211
|
+
fillColor: fillColor,
|
212
|
+
fillOpacity: fillOpacity,
|
213
|
+
clickable: false
|
214
|
+
});
|
215
|
+
//save polygon in list
|
216
|
+
this.polygon_objects.push(new_poly);
|
217
|
+
new_poly.setMap(this.map);
|
218
|
+
},
|
219
|
+
|
220
|
+
//polylines is an array of arrays. It loops.
|
221
|
+
create_polylines: function(){
|
222
|
+
for (var i = 0; i < this.polylines.length; ++i) {
|
223
|
+
//Polylines could be customized. By convention, customization options should be contained in the first
|
224
|
+
if (i==0)
|
225
|
+
{
|
226
|
+
//Array contain polyline elements
|
227
|
+
if (this.polylines[i] instanceof Array) {
|
228
|
+
this.create_polyline(i);
|
229
|
+
}
|
230
|
+
//hashes contain configuration which would be set as default
|
231
|
+
else{
|
232
|
+
if (this.exists(this.polylines[i].strokeColor) ) { this.polylines_conf.line_strokeColor = this.polygons[i].strokeColor; }
|
233
|
+
if (this.exists(this.polylines[i].strokeOpacity) ) { this.polylines_conf.line_strokeOpacity = this.polygons[i].strokeOpacity;}
|
234
|
+
if (this.exists(this.polylines[i].strokeWeight) ) { this.polylines_conf.line_strokeWeight = this.polygons[i].strokeWeight; }
|
235
|
+
}
|
236
|
+
}
|
237
|
+
else { this.create_polyline(i); }
|
238
|
+
}
|
239
|
+
},
|
240
|
+
|
241
|
+
//creates a single polyline, triggered by create_polylines
|
242
|
+
create_polyline: function(i){
|
243
|
+
var polyline_coordinates = [];
|
244
|
+
var strokeColor;
|
245
|
+
var strokeOpacity;
|
246
|
+
var strokeWeight;
|
247
|
+
|
248
|
+
//2 cases here, either we have a coded array of LatLng or we have an Array of LatLng
|
249
|
+
for (var j = 0; j < this.polylines[i].length; ++j) {
|
250
|
+
//if we have a coded array
|
251
|
+
if (this.exists(this.polylines[i][j].coded_array)){
|
252
|
+
var decoded_array = new google.maps.geometry.encoding.decodePath(this.polylines[i][j].coded_array);
|
253
|
+
//loop through every point in the array
|
254
|
+
for (var k = 0; k < decoded_array.length; ++k) {
|
255
|
+
polyline_coordinates.push(decoded_array[k]);
|
256
|
+
this.extend_bounds(decoded_array[k]);
|
257
|
+
polyline_coordinates.push(decoded_array[k]);
|
258
|
+
}
|
259
|
+
}
|
260
|
+
//or we have an array of latlng
|
261
|
+
else{
|
262
|
+
//by convention, a single polyline could be customized in the first array or it uses default values
|
263
|
+
if (j==0){
|
264
|
+
strokeColor = this.polylines[i][0].strokeColor || this.polylines_conf.strokeColor;
|
265
|
+
strokeOpacity = this.polylines[i][0].strokeOpacity || this.polylines_conf.strokeOpacity;
|
266
|
+
strokeWeight = this.polylines[i][0].strokeWeight || this.polylines_conf.strokeWeight;
|
267
|
+
}
|
268
|
+
//add latlng if positions provided
|
269
|
+
if (this.exists(this.polylines[i][j].latitude) && this.exists(this.polylines[i][j].longitude))
|
270
|
+
{
|
271
|
+
var latlng = new google.maps.LatLng(this.polylines[i][j].latitude, this.polylines[i][j].longitude);
|
272
|
+
polyline_coordinates.push(latlng);
|
273
|
+
this.extend_bounds(latlng);
|
274
|
+
}
|
275
|
+
}
|
276
|
+
}
|
277
|
+
// Construct the polyline
|
278
|
+
var new_poly = new google.maps.Polyline({
|
279
|
+
path: polyline_coordinates,
|
280
|
+
strokeColor: strokeColor,
|
281
|
+
strokeOpacity: strokeOpacity,
|
282
|
+
strokeWeight: strokeWeight,
|
283
|
+
clickable: false
|
284
|
+
});
|
285
|
+
//save polyline
|
286
|
+
this.polyline_objects.push(new_poly);
|
287
|
+
new_poly.setMap(this.map);
|
288
|
+
},
|
289
|
+
|
290
|
+
//Two options:
|
291
|
+
// 1- processing == "rails_model" && builder = model_name
|
292
|
+
// 2- processing == "json" && builder = json in format: [{"description": , "longitude": , "title":, "latitude":, "picture": "", "width": "", "length": ""}]
|
293
|
+
create_markers: function() {
|
294
|
+
this.setup_Markers();
|
295
|
+
|
296
|
+
if (this.map_options.auto_adjust) {
|
58
297
|
this.map.fitBounds(this.bounds);
|
59
298
|
}
|
60
299
|
},
|
61
300
|
|
62
301
|
// clear markers
|
63
302
|
clear_markers: function(){
|
64
|
-
if (this.
|
65
|
-
for (i in this.
|
66
|
-
this.
|
303
|
+
if (this.marker_objects) {
|
304
|
+
for (i in this.marker_objects) {
|
305
|
+
this.marker_objects[i].setMap(null);
|
67
306
|
}
|
68
|
-
this.
|
307
|
+
this.marker_objects = null;
|
69
308
|
}
|
70
309
|
},
|
71
310
|
|
72
311
|
// replace old markers with new markers on an existing map
|
73
312
|
replace_markers: function(new_markers){
|
74
313
|
this.clear_markers();
|
75
|
-
this.
|
314
|
+
this.markers = [];
|
76
315
|
this.add_markers(new_markers);
|
77
316
|
},
|
78
317
|
|
79
318
|
//add new markers to on an existing map (beware, it doesn't check duplicates)
|
80
319
|
add_markers: function(new_markers){
|
81
|
-
this.
|
320
|
+
this.markers = this.markers.concat(new_markers);
|
82
321
|
this.setup_Markers();
|
83
|
-
if (this.auto_adjust) {
|
322
|
+
if (this.map_options.auto_adjust) {
|
84
323
|
this.map.fitBounds(this.bounds);
|
85
324
|
}
|
86
325
|
},
|
87
326
|
|
88
|
-
|
89
|
-
reset_map: function(){
|
90
|
-
this.map = new google.maps.Map(document.getElementById(this.map_id), {
|
91
|
-
zoom: this.map_zoom,
|
92
|
-
center: new google.maps.LatLng(this.map_center_latitude, this.map_center_longitude),
|
93
|
-
mapTypeId: google.maps.MapTypeId.ROADMAP
|
94
|
-
});
|
95
|
-
},
|
96
|
-
|
97
|
-
//creates the necessary query to get the model + scope, and sends json to setup_Markers
|
98
|
-
create_from_model: function (filter_value) {
|
99
|
-
request = this.base_url + '?model=' + this.rails_model;
|
100
|
-
|
101
|
-
if(this.model_scope != null)
|
102
|
-
{ request += '&scope=' + this.model_scope; }
|
103
|
-
jQuery.getJSON(request,function(data){
|
104
|
-
Gmaps4Rails.locations = data;
|
105
|
-
Gmaps4Rails.setup_Markers();
|
106
|
-
}
|
107
|
-
);
|
108
|
-
},
|
109
|
-
|
110
|
-
//Creates Marker from the locations passed + markerClusterer
|
327
|
+
//Creates Marker from the markers passed + markerClusterer
|
111
328
|
setup_Markers: function () {
|
112
329
|
//variable used for Marker Clusterer
|
113
|
-
var
|
114
|
-
//variable used for Auto-adjust
|
115
|
-
this.bounds = new google.maps.LatLngBounds();
|
330
|
+
var marker_objects = [];
|
116
331
|
|
117
332
|
//resets Clusterer if needed
|
118
333
|
if (this.markerClusterer) {
|
119
334
|
this.markerClusterer.clearMarkers();
|
120
335
|
}
|
121
336
|
// Add markers to the map
|
122
|
-
for (var i = 0; i < this.
|
337
|
+
for (var i = 0; i < this.markers.length; ++i) {
|
123
338
|
//test if value passed or use default
|
124
|
-
var marker_picture = this.
|
125
|
-
var marker_width = this.
|
126
|
-
var marker_height = this.
|
127
|
-
var marker_title = this.
|
339
|
+
var marker_picture = this.exists(this.markers[i].picture) ? this.markers[i].picture : this.markers_conf.picture;
|
340
|
+
var marker_width = this.exists(this.markers[i].width) ? this.markers[i].width : this.markers_conf.width;
|
341
|
+
var marker_height = this.exists(this.markers[i].height) ? this.markers[i].height : this.markers_conf.length;
|
342
|
+
var marker_title = this.exists(this.markers[i].title) ? this.markers[i].title : null;
|
128
343
|
|
129
|
-
var myLatLng = new google.maps.LatLng(this.
|
130
|
-
|
131
|
-
if (this.auto_adjust) {
|
132
|
-
this.bounds.extend(myLatLng);
|
133
|
-
}
|
344
|
+
var myLatLng = new google.maps.LatLng(this.markers[i].latitude, this.markers[i].longitude);
|
345
|
+
this.extend_bounds(myLatLng);
|
134
346
|
|
135
347
|
// Marker sizes are expressed as a Size of X,Y
|
136
348
|
if (marker_picture == "")
|
@@ -141,37 +353,61 @@ var Gmaps4Rails = {
|
|
141
353
|
var ThisMarker = new google.maps.Marker({position: myLatLng, map: this.map, icon: image, title: marker_title});
|
142
354
|
}
|
143
355
|
//save object for later use, basically, to get back the text to display when clicking it
|
144
|
-
this.
|
356
|
+
this.markers[i].marker_object = ThisMarker;
|
145
357
|
//save the marker again in a list for the clusterer
|
146
|
-
|
358
|
+
marker_objects.push(ThisMarker);
|
147
359
|
//add click listener
|
148
|
-
google.maps.event.addListener(Gmaps4Rails.
|
360
|
+
google.maps.event.addListener(Gmaps4Rails.markers[i].marker_object, 'click', function() { if (Gmaps4Rails.info_window!=null) {Gmaps4Rails.info_window.close();}; Gmaps4Rails.getInfoWindow(this);});
|
149
361
|
}
|
150
|
-
this.setup_Clusterer(
|
362
|
+
this.setup_Clusterer(marker_objects);
|
151
363
|
},
|
152
364
|
|
153
365
|
//get info_window content when listener calls it
|
154
366
|
getInfoWindow: function(which)
|
155
367
|
{
|
156
|
-
for ( var m = 0; m < this.
|
368
|
+
for ( var m = 0; m < this.markers.length; ++m )
|
157
369
|
{
|
158
|
-
var markerInfo = this.
|
159
|
-
if ( markerInfo == which && this.
|
370
|
+
var markerInfo = this.markers[m].marker_object;
|
371
|
+
if ( markerInfo == which && this.markers[m].description != "")
|
160
372
|
{
|
161
|
-
this.info_window = new google.maps.InfoWindow({content: this.
|
373
|
+
this.info_window = new google.maps.InfoWindow({content: this.markers[m].description });
|
162
374
|
this.info_window.open( this.map, which );
|
163
375
|
return;
|
164
376
|
}
|
165
377
|
}
|
166
378
|
},
|
167
|
-
|
379
|
+
|
380
|
+
setup_Clusterer: function(marker_objects)
|
168
381
|
{
|
169
|
-
if (this.do_clustering == true)
|
382
|
+
if (this.markers_conf.do_clustering == true)
|
170
383
|
{
|
171
|
-
this.markerClusterer = new MarkerClusterer(this.map,
|
172
|
-
|
173
|
-
|
174
|
-
|
384
|
+
this.markerClusterer = new MarkerClusterer(this.map, marker_objects, { maxZoom: this.markers_conf.clusterer_maxZoom,
|
385
|
+
gridSize: this.markers_conf.clusterer_gridSize,
|
386
|
+
//styles: styles TODO: offer clusterer customization
|
387
|
+
});
|
175
388
|
}
|
389
|
+
},
|
390
|
+
|
391
|
+
//to make the map fit the different LatLng points
|
392
|
+
extend_bounds: function(latlng) {
|
393
|
+
//extending bounds, ref: http://unicornless.com/code/google-maps-v3-auto-zoom-and-auto-center
|
394
|
+
if (this.map_options.auto_adjust) {
|
395
|
+
this.bounds.extend(latlng);
|
396
|
+
}
|
397
|
+
},
|
398
|
+
|
399
|
+
//basic function to check existence of a variable
|
400
|
+
exists: function(var_name) {
|
401
|
+
return var_name != "" && typeof var_name !== "undefined"
|
176
402
|
}
|
177
403
|
};
|
404
|
+
|
405
|
+
//marker_clusterer styles
|
406
|
+
// var styles = [{
|
407
|
+
// url: 'http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerclusterer/1.0/images/people35.png',
|
408
|
+
// height: 35,
|
409
|
+
// width: 35,
|
410
|
+
// opt_anchor: [16, 0],
|
411
|
+
// opt_textColor: '#ff00ff',
|
412
|
+
// opt_textSize: 10
|
413
|
+
// }];
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Gmaps4Rails.map_options.center_longitude = 180;
|
2
|
+
Gmaps4Rails.map_options.type = 'SATELLITE';
|
3
|
+
Gmaps4Rails.map_options.zoom = 3;
|
4
|
+
Gmaps4Rails.initialize();
|
5
|
+
Gmaps4Rails.polylines = [[
|
6
|
+
{\"longitude\": -122.214897, \"latitude\": 37.772323},
|
7
|
+
{\"longitude\": -157.821856, \"latitude\": 21.291982},
|
8
|
+
{\"longitude\": 178.431, \"latitude\": -18.142599},
|
9
|
+
{\"longitude\": 153.027892, \"latitude\": -27.46758}
|
10
|
+
],
|
11
|
+
[
|
12
|
+
{\"longitude\": -120.214897, \"latitude\": 30.772323, \"strokeColor\": \"#000\", \"strokeWeight\" : 2 },
|
13
|
+
{\"longitude\": -10.821856, \"latitude\": 50.291982}
|
14
|
+
]];
|
15
|
+
Gmaps4Rails.create_polylines();
|
16
|
+
Gmaps4Rails.circles = [
|
17
|
+
{\"longitude\": -122.214897, \"latitude\": 37.772323, \"radius\": 1000000},
|
18
|
+
{\"longitude\": 122.214897, \"latitude\": 37.772323, \"radius\": 1000000, \"strokeColor\": \"#FF0000\"}
|
19
|
+
];
|
20
|
+
Gmaps4Rails.create_circles();
|
21
|
+
Gmaps4Rails.polygons = [[
|
22
|
+
{\"longitude\": -80.190262, \"latitude\": 25.774252},
|
23
|
+
{\"longitude\": -66.118292, \"latitude\": 18.466465},
|
24
|
+
{\"longitude\": -64.75737, \"latitude\": 32.321384}
|
25
|
+
]];
|
26
|
+
Gmaps4Rails.create_polygons();
|
27
|
+
Gmaps4Rails.markers = [{ \"description\": \"\", \"title\": \"\", \"longitude\": \"5.9311119\", \"latitude\": \"43.1251606\", \"picture\": \"\", \"width\": \"\", \"height\": \"\" } ,{ \"description\": \"\", \"title\": \"\", \"longitude\": \"2.3509871\", \"latitude\": \"48.8566667\", \"picture\": \"\", \"width\": \"\", \"height\": \"\" } ];
|
28
|
+
Gmaps4Rails.create_markers();
|
29
|
+
Gmaps4Rails.direction_conf.origin = 'toulon, france';
|
30
|
+
Gmaps4Rails.direction_conf.destination = 'paris, france';
|
31
|
+
Gmaps4Rails.direction_conf.display_panel = 'true';
|
32
|
+
Gmaps4Rails.direction_conf.panel_id = 'instructions';
|
33
|
+
Gmaps4Rails.direction_conf.travelMode = 'DRIVING';
|
34
|
+
Gmaps4Rails.direction_conf.waypoints = [{\"stopover\":true,\"location\":\"toulouse, france\"},{\"stopover\":true,\"location\":\"brest, france\"}];
|
35
|
+
Gmaps4Rails.create_direction();
|
@@ -1,15 +1,88 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe "
|
4
|
-
|
3
|
+
describe "Geocode" do
|
4
|
+
|
5
5
|
it "should geocode properly an address" do
|
6
6
|
Gmaps4rails.geocode("alaska").should == [{:lat=>63.588753, :lng=>-154.4930619, :matched_address=>"Alaska, USA"}]
|
7
7
|
end
|
8
8
|
|
9
|
-
it "should raise an error when
|
9
|
+
it "should raise an error when address invalid" do
|
10
10
|
lambda { Gmaps4rails.geocode("home")}.should raise_error Gmaps4rails::GeocodeStatus
|
11
11
|
end
|
12
12
|
|
13
13
|
it "should raise an error when net connection failed" #TODO: Damn, I don't know how to test that!
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "JS creation from hash" do
|
18
|
+
|
19
|
+
it "should format entries properly" do
|
20
|
+
options_hash = {
|
21
|
+
"map_options" => { "type" => "SATELLITE", "center_longitude" => 180, "zoom" => 3},
|
22
|
+
"markers" => { "data" => '[{ "description": "", "title": "", "longitude": "5.9311119", "latitude": "43.1251606", "picture": "", "width": "", "height": "" } ,{ "description": "", "title": "", "longitude": "2.3509871", "latitude": "48.8566667", "picture": "", "width": "", "height": "" } ]' },
|
23
|
+
"polylines" => { "data" => '[[
|
24
|
+
{"longitude": -122.214897, "latitude": 37.772323},
|
25
|
+
{"longitude": -157.821856, "latitude": 21.291982},
|
26
|
+
{"longitude": 178.431, "latitude": -18.142599},
|
27
|
+
{"longitude": 153.027892, "latitude": -27.46758}
|
28
|
+
],
|
29
|
+
[
|
30
|
+
{"longitude": -120.214897, "latitude": 30.772323, "strokeColor": "#000", "strokeWeight" : 2 },
|
31
|
+
{"longitude": -10.821856, "latitude": 50.291982}
|
32
|
+
]]' },
|
33
|
+
"polygons" => { "data" => '[[
|
34
|
+
{"longitude": -80.190262, "latitude": 25.774252},
|
35
|
+
{"longitude": -66.118292, "latitude": 18.466465},
|
36
|
+
{"longitude": -64.75737, "latitude": 32.321384}
|
37
|
+
]]' },
|
38
|
+
"circles" => { "data" => '[
|
39
|
+
{"longitude": -122.214897, "latitude": 37.772323, "radius": 1000000},
|
40
|
+
{"longitude": 122.214897, "latitude": 37.772323, "radius": 1000000, "strokeColor": "#FF0000"}
|
41
|
+
]',
|
42
|
+
},
|
43
|
+
"direction" => {
|
44
|
+
"data" => { "from" => "toulon, france", "to" => "paris, france"} ,
|
45
|
+
"options" => {"waypoints" => ["toulouse, france", "brest, france"], "travelMode" => "DRIVING", "display_panel" => true, "panel_id" => "instructions"}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
options_hash.to_gmaps4rails.should == "Gmaps4Rails.polylines = [[\n{\"longitude\": -122.214897, \"latitude\": 37.772323},\n{\"longitude\": -157.821856, \"latitude\": 21.291982},\n{\"longitude\": 178.431, \"latitude\": -18.142599},\n{\"longitude\": 153.027892, \"latitude\": -27.46758}\n],\n[\n{\"longitude\": -120.214897, \"latitude\": 30.772323, \"strokeColor\": \"#000\", \"strokeWeight\" : 2 },\n{\"longitude\": -10.821856, \"latitude\": 50.291982}\n]];\nGmaps4Rails.create_polylines();\nGmaps4Rails.circles = [\n{\"longitude\": -122.214897, \"latitude\": 37.772323, \"radius\": 1000000},\n{\"longitude\": 122.214897, \"latitude\": 37.772323, \"radius\": 1000000, \"strokeColor\": \"#FF0000\"}\n];\nGmaps4Rails.create_circles();\nGmaps4Rails.polygons = [[\n{\"longitude\": -80.190262, \"latitude\": 25.774252},\n{\"longitude\": -66.118292, \"latitude\": 18.466465},\n{\"longitude\": -64.75737, \"latitude\": 32.321384}\n]];\nGmaps4Rails.create_polygons();\nGmaps4Rails.markers = [{ \"description\": \"\", \"title\": \"\", \"longitude\": \"5.9311119\", \"latitude\": \"43.1251606\", \"picture\": \"\", \"width\": \"\", \"height\": \"\" } ,{ \"description\": \"\", \"title\": \"\", \"longitude\": \"2.3509871\", \"latitude\": \"48.8566667\", \"picture\": \"\", \"width\": \"\", \"height\": \"\" } ];\nGmaps4Rails.create_markers();\nGmaps4Rails.direction_conf.origin = 'toulon, france';\nGmaps4Rails.direction_conf.destination = 'paris, france';\nGmaps4Rails.direction_conf.display_panel = 'true';\nGmaps4Rails.direction_conf.panel_id = 'instructions';\nGmaps4Rails.direction_conf.travelMode = 'DRIVING';\nGmaps4Rails.direction_conf.waypoints = [{\"stopover\":true,\"location\":\"toulouse, france\"},{\"stopover\":true,\"location\":\"brest, france\"}];\nGmaps4Rails.create_direction();"
|
49
|
+
end
|
14
50
|
|
15
|
-
|
51
|
+
it "should add map settings when 'true' passed" do
|
52
|
+
options_hash = {
|
53
|
+
"map_options" => { "type" => "SATELLITE", "center_longitude" => 180, "zoom" => 3},
|
54
|
+
"markers" => { "data" => '[{ "description": "", "title": "", "longitude": "5.9311119", "latitude": "43.1251606", "picture": "", "width": "", "height": "" } ,{ "description": "", "title": "", "longitude": "2.3509871", "latitude": "48.8566667", "picture": "", "width": "", "height": "" } ]' },
|
55
|
+
"polylines" => { "data" => '[[
|
56
|
+
{"longitude": -122.214897, "latitude": 37.772323},
|
57
|
+
{"longitude": -157.821856, "latitude": 21.291982},
|
58
|
+
{"longitude": 178.431, "latitude": -18.142599},
|
59
|
+
{"longitude": 153.027892, "latitude": -27.46758}
|
60
|
+
],
|
61
|
+
[
|
62
|
+
{"longitude": -120.214897, "latitude": 30.772323, "strokeColor": "#000", "strokeWeight" : 2 },
|
63
|
+
{"longitude": -10.821856, "latitude": 50.291982}
|
64
|
+
]]' },
|
65
|
+
"polygons" => { "data" => '[[
|
66
|
+
{"longitude": -80.190262, "latitude": 25.774252},
|
67
|
+
{"longitude": -66.118292, "latitude": 18.466465},
|
68
|
+
{"longitude": -64.75737, "latitude": 32.321384}
|
69
|
+
]]' },
|
70
|
+
"circles" => { "data" => '[
|
71
|
+
{"longitude": -122.214897, "latitude": 37.772323, "radius": 1000000},
|
72
|
+
{"longitude": 122.214897, "latitude": 37.772323, "radius": 1000000, "strokeColor": "#FF0000"}
|
73
|
+
]',
|
74
|
+
},
|
75
|
+
"direction" => {
|
76
|
+
"data" => { "from" => "toulon, france", "to" => "paris, france"} ,
|
77
|
+
"options" => {"waypoints" => ["toulouse, france", "brest, france"], "travelMode" => "DRIVING", "display_panel" => true, "panel_id" => "instructions"}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
options_hash.to_gmaps4rails(true).should == "Gmaps4Rails.map_options.center_longitude = 180;\nGmaps4Rails.map_options.type = 'SATELLITE';\nGmaps4Rails.map_options.zoom = 3;\nGmaps4Rails.initialize();\nGmaps4Rails.polylines = [[\n{\"longitude\": -122.214897, \"latitude\": 37.772323},\n{\"longitude\": -157.821856, \"latitude\": 21.291982},\n{\"longitude\": 178.431, \"latitude\": -18.142599},\n{\"longitude\": 153.027892, \"latitude\": -27.46758}\n],\n[\n{\"longitude\": -120.214897, \"latitude\": 30.772323, \"strokeColor\": \"#000\", \"strokeWeight\" : 2 },\n{\"longitude\": -10.821856, \"latitude\": 50.291982}\n]];\nGmaps4Rails.create_polylines();\nGmaps4Rails.circles = [\n{\"longitude\": -122.214897, \"latitude\": 37.772323, \"radius\": 1000000},\n{\"longitude\": 122.214897, \"latitude\": 37.772323, \"radius\": 1000000, \"strokeColor\": \"#FF0000\"}\n];\nGmaps4Rails.create_circles();\nGmaps4Rails.polygons = [[\n{\"longitude\": -80.190262, \"latitude\": 25.774252},\n{\"longitude\": -66.118292, \"latitude\": 18.466465},\n{\"longitude\": -64.75737, \"latitude\": 32.321384}\n]];\nGmaps4Rails.create_polygons();\nGmaps4Rails.markers = [{ \"description\": \"\", \"title\": \"\", \"longitude\": \"5.9311119\", \"latitude\": \"43.1251606\", \"picture\": \"\", \"width\": \"\", \"height\": \"\" } ,{ \"description\": \"\", \"title\": \"\", \"longitude\": \"2.3509871\", \"latitude\": \"48.8566667\", \"picture\": \"\", \"width\": \"\", \"height\": \"\" } ];\nGmaps4Rails.create_markers();\nGmaps4Rails.direction_conf.origin = 'toulon, france';\nGmaps4Rails.direction_conf.destination = 'paris, france';\nGmaps4Rails.direction_conf.display_panel = 'true';\nGmaps4Rails.direction_conf.panel_id = 'instructions';\nGmaps4Rails.direction_conf.travelMode = 'DRIVING';\nGmaps4Rails.direction_conf.waypoints = [{\"stopover\":true,\"location\":\"toulouse, france\"},{\"stopover\":true,\"location\":\"brest, france\"}];\nGmaps4Rails.create_direction();"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "Destination" do
|
85
|
+
it "should render info from only start_end args"
|
86
|
+
it "should accept all options properly"
|
87
|
+
it "should format output in accordance with 'output' variable"
|
88
|
+
end
|
@@ -1,57 +1,57 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
-
|
3
|
-
describe UsersController do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
1
|
+
# require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
#
|
3
|
+
# describe UsersController do
|
4
|
+
# fixtures :all
|
5
|
+
# render_views
|
6
|
+
#
|
7
|
+
# it "index action should render index template" do
|
8
|
+
# get :index
|
9
|
+
# response.should render_template(:index)
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# it "show action should render show template" do
|
13
|
+
# get :show, :id => User.first
|
14
|
+
# response.should render_template(:show)
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# it "new action should render new template" do
|
18
|
+
# get :new
|
19
|
+
# response.should render_template(:new)
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# it "create action should render new template when model is invalid" do
|
23
|
+
# User.any_instance.stubs(:valid?).returns(false)
|
24
|
+
# post :create
|
25
|
+
# response.should render_template(:new)
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# it "create action should redirect when model is valid" do
|
29
|
+
# User.any_instance.stubs(:valid?).returns(true)
|
30
|
+
# post :create
|
31
|
+
# response.should redirect_to(user_url(assigns[:user]))
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# it "edit action should render edit template" do
|
35
|
+
# get :edit, :id => User.first
|
36
|
+
# response.should render_template(:edit)
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# it "update action should render edit template when model is invalid" do
|
40
|
+
# User.any_instance.stubs(:valid?).returns(false)
|
41
|
+
# put :update, :id => User.first
|
42
|
+
# response.should render_template(:edit)
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# it "update action should redirect when model is valid" do
|
46
|
+
# User.any_instance.stubs(:valid?).returns(true)
|
47
|
+
# put :update, :id => User.first
|
48
|
+
# response.should redirect_to(user_url(assigns[:user]))
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# it "destroy action should destroy model and redirect to index action" do
|
52
|
+
# user = User.first
|
53
|
+
# delete :destroy, :id => user
|
54
|
+
# response.should redirect_to(users_url)
|
55
|
+
# User.exists?(user.id).should be_false
|
56
|
+
# end
|
57
|
+
# end
|
@@ -11,16 +11,16 @@ describe "Acts as gmappable" do
|
|
11
11
|
@user.latitude.should == 43.1251606
|
12
12
|
@user.longitude.should == 5.9311119
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
it "should set boolean to true once user is created" do
|
16
16
|
@user.gmaps.should == true
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
it "should render a valid json from an array of ojects" do
|
20
20
|
@user2 = User.create!(:name => "me", :address => "Paris, France" )
|
21
21
|
User.all.to_gmaps4rails.should == "[{\n\"description\": \"\", \"title\": \"\",\n\"longitude\": \"5.9311119\", \"latitude\": \"43.1251606\", \"picture\": \"\", \"width\": \"\", \"height\": \"\"\n} ,{\n\"description\": \"\", \"title\": \"\",\n\"longitude\": \"2.3509871\", \"latitude\": \"48.8566667\", \"picture\": \"\", \"width\": \"\", \"height\": \"\"\n} ]"
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
it "should render a valid json from a single object" do
|
25
25
|
@user.to_gmaps4rails.should == "[{\n\"description\": \"\", \"title\": \"\",\n\"longitude\": \"5.9311119\", \"latitude\": \"43.1251606\", \"picture\": \"\", \"width\": \"\", \"height\": \"\"\n} ]"
|
26
26
|
end
|
@@ -41,7 +41,7 @@ describe "Acts as gmappable" do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
|
44
|
+
|
45
45
|
describe "standard configuration, invalid address" do
|
46
46
|
before(:each) do
|
47
47
|
@user = User.new(:name => "me", :address => "home" )
|
@@ -55,8 +55,8 @@ describe "Acts as gmappable" do
|
|
55
55
|
@user.gmaps.should_not == true
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
59
|
-
|
58
|
+
|
59
|
+
|
60
60
|
describe "model customization" do
|
61
61
|
it "should render a valid json even if there is no instance in the db" do
|
62
62
|
User.all.to_gmaps4rails.should == "[]"
|
@@ -189,4 +189,5 @@ describe "Acts as gmappable" do
|
|
189
189
|
@user.to_gmaps4rails.should == "[{\n\"description\": \"\", \"title\": \"Sweet Title\",\n\"longitude\": \"5.9311119\", \"latitude\": \"43.1251606\", \"picture\": \"http://www.blankdots.com/img/github-32x32.png\", \"width\": \"32\", \"height\": \"32\"\n} ]"
|
190
190
|
end
|
191
191
|
end
|
192
|
+
|
192
193
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gmaps4rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 6
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Benjamin Roth
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-03-
|
19
|
+
date: 2011-03-17 00:00:00 +01:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -50,6 +50,7 @@ files:
|
|
50
50
|
- lib/application_helper.rb
|
51
51
|
- lib/array.rb
|
52
52
|
- lib/gmaps4rails.rb
|
53
|
+
- lib/hash.rb
|
53
54
|
- lib/rails/generators/gmaps4rails/gmaps4rails_generator.rb
|
54
55
|
- lib/rails/generators/gmaps4rails/templates/initializer.rb
|
55
56
|
- lib/rails/generators/gmaps4rails/templates/migration.rb
|
@@ -65,6 +66,7 @@ files:
|
|
65
66
|
- test/dummy/app/helpers/application_helper.rb
|
66
67
|
- test/dummy/app/helpers/users_helper.rb
|
67
68
|
- test/dummy/app/models/user.rb
|
69
|
+
- test/dummy/app/views/users/test.rb
|
68
70
|
- test/dummy/config/application.rb
|
69
71
|
- test/dummy/config/boot.rb
|
70
72
|
- test/dummy/config/environment.rb
|
@@ -84,8 +86,6 @@ files:
|
|
84
86
|
- test/dummy/spec/controllers/users_controller_spec.rb
|
85
87
|
- test/dummy/spec/models/user_spec.rb
|
86
88
|
- test/dummy/spec/spec_helper.rb
|
87
|
-
- test/dummy/test/performance/browsing_test.rb
|
88
|
-
- test/dummy/test/test_helper.rb
|
89
89
|
has_rdoc: true
|
90
90
|
homepage: http://github.com/apneadiving/Google-Maps-for-Rails
|
91
91
|
licenses: []
|
@@ -126,6 +126,7 @@ test_files:
|
|
126
126
|
- test/dummy/app/helpers/application_helper.rb
|
127
127
|
- test/dummy/app/helpers/users_helper.rb
|
128
128
|
- test/dummy/app/models/user.rb
|
129
|
+
- test/dummy/app/views/users/test.rb
|
129
130
|
- test/dummy/config/application.rb
|
130
131
|
- test/dummy/config/boot.rb
|
131
132
|
- test/dummy/config/environment.rb
|
@@ -145,5 +146,3 @@ test_files:
|
|
145
146
|
- test/dummy/spec/controllers/users_controller_spec.rb
|
146
147
|
- test/dummy/spec/models/user_spec.rb
|
147
148
|
- test/dummy/spec/spec_helper.rb
|
148
|
-
- test/dummy/test/performance/browsing_test.rb
|
149
|
-
- test/dummy/test/test_helper.rb
|
@@ -1,13 +0,0 @@
|
|
1
|
-
ENV["RAILS_ENV"] = "test"
|
2
|
-
require File.expand_path('../../config/environment', __FILE__)
|
3
|
-
require 'rails/test_help'
|
4
|
-
|
5
|
-
class ActiveSupport::TestCase
|
6
|
-
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
|
7
|
-
#
|
8
|
-
# Note: You'll currently still have to declare fixtures explicitly in integration tests
|
9
|
-
# -- they do not yet inherit this setting
|
10
|
-
fixtures :all
|
11
|
-
|
12
|
-
# Add more helper methods to be used by all tests here...
|
13
|
-
end
|