simple-address-generator 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/lib/rails/generators/simple_address_generator/USAGE +6 -0
- data/lib/rails/generators/simple_address_generator/simple_address_generator_generator.rb +30 -0
- data/lib/rails/generators/simple_address_generator/templates/address.rb +43 -0
- data/lib/rails/generators/simple_address_generator/templates/addresses/_form.html.erb +53 -0
- data/lib/rails/generators/simple_address_generator/templates/addresses/edit.html.erb +6 -0
- data/lib/rails/generators/simple_address_generator/templates/addresses/index.html.erb +40 -0
- data/lib/rails/generators/simple_address_generator/templates/addresses/new.html.erb +5 -0
- data/lib/rails/generators/simple_address_generator/templates/addresses/show.html.erb +63 -0
- data/lib/rails/generators/simple_address_generator/templates/addresses_controller.rb +85 -0
- data/lib/rails/generators/simple_address_generator/templates/gmaps4rails/gmaps4rails.base.js.coffee +502 -0
- data/lib/rails/generators/simple_address_generator/templates/gmaps4rails/gmaps4rails.googlemaps.js.coffee +263 -0
- data/lib/rails/generators/simple_address_generator/templates/icon-1.png +0 -0
- data/lib/simple-address-generator.rb +10 -0
- data/lib/simple-address-generator/version.rb +7 -0
- metadata +67 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Chim Kan
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Simple::Address::Generator
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'simple-address-generator'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install simple-address-generator
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module SimpleAddressGenerator
|
2
|
+
module Generators
|
3
|
+
class SimpleAddressGeneratorGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
def create_address_model
|
7
|
+
generate("model", "address address_line_1:string address_line_2:string city:string state:string postal_code:string country:string telephone_number:string latitude:float longitude:float category_id:integer")
|
8
|
+
rake("db:migrate")
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate_everything_else
|
12
|
+
directory "gmaps4rails", "app/assets/javascripts/gmaps4rails/"
|
13
|
+
directory "addresses", "app/views/"
|
14
|
+
copy_file "addresses_controller.rb", "app/controllers/addresses_controller.rb"
|
15
|
+
copy_file "address.rb", "app/models/address.rb"
|
16
|
+
copy_file "icon-1.png", "app/assets/images/icon-1.png"
|
17
|
+
end
|
18
|
+
|
19
|
+
def insert_routes
|
20
|
+
route("resources :addresses")
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_gems
|
24
|
+
gem("geocoder")
|
25
|
+
gem("gmaps4rails")
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Address < ActiveRecord::Base
|
2
|
+
attr_accessible :address_line_1, :address_line_2, :city, :country, :full_name, :postal_code, :state, :telephone_number, :full_address, :latitude, :longitude, :gmaps, :category_id
|
3
|
+
attr_accessor :gmaps
|
4
|
+
|
5
|
+
geocoded_by :full_address
|
6
|
+
|
7
|
+
after_validation :geocode
|
8
|
+
|
9
|
+
acts_as_gmappable
|
10
|
+
|
11
|
+
|
12
|
+
def full_address
|
13
|
+
[self.address_line_1, self.address_line_2, self.city, self.state, self.country, self.postal_code].compact.join(", ")
|
14
|
+
end
|
15
|
+
|
16
|
+
def gmaps4rails_address
|
17
|
+
#describe how to retrieve the address from your model, if you use directly a db column, you can dry your code, see wiki
|
18
|
+
full_address
|
19
|
+
end
|
20
|
+
|
21
|
+
def gmaps4rails_infowindow
|
22
|
+
"#{full_address}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def gmaps4rails_title
|
26
|
+
# add here whatever text you desire
|
27
|
+
"Testing"
|
28
|
+
end
|
29
|
+
|
30
|
+
def gmaps4rails_marker_picture
|
31
|
+
{
|
32
|
+
"picture" => "/assets/icon-#{self.category_id}.png",
|
33
|
+
"width" => 30,
|
34
|
+
"height" => 30,
|
35
|
+
"marker_anchor" => [ 5, 10],
|
36
|
+
"shadow_width" => "110",
|
37
|
+
"shadow_height" => "110",
|
38
|
+
"shadow_anchor" => [5, 10]
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
<%= form_for(@address) do |f| %>
|
2
|
+
<% if @address.errors.any? %>
|
3
|
+
<div id="error_explanation">
|
4
|
+
<h2><%= pluralize(@address.errors.count, "error") %> prohibited this address from being saved:</h2>
|
5
|
+
|
6
|
+
<ul>
|
7
|
+
<% @address.errors.full_messages.each do |msg| %>
|
8
|
+
<li><%= msg %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<div class="field">
|
15
|
+
<%= f.label :full_name %><br />
|
16
|
+
<%= f.text_field :full_name %>
|
17
|
+
</div>
|
18
|
+
<div class="field">
|
19
|
+
<%= f.label :address_line_1 %><br />
|
20
|
+
<%= f.text_field :address_line_1 %>
|
21
|
+
</div>
|
22
|
+
<div class="field">
|
23
|
+
<%= f.label :address_line_2 %><br />
|
24
|
+
<%= f.text_field :address_line_2 %>
|
25
|
+
</div>
|
26
|
+
<div class="field">
|
27
|
+
<%= f.label :city %><br />
|
28
|
+
<%= f.text_field :city %>
|
29
|
+
</div>
|
30
|
+
<div class="field">
|
31
|
+
<%= f.label :state %><br />
|
32
|
+
<%= f.text_field :state %>
|
33
|
+
</div>
|
34
|
+
<div class="field">
|
35
|
+
<%= f.label :postal_code %><br />
|
36
|
+
<%= f.text_field :postal_code %>
|
37
|
+
</div>
|
38
|
+
<div class="field">
|
39
|
+
<%= f.label :country %><br />
|
40
|
+
<%= f.text_field :country %>
|
41
|
+
</div>
|
42
|
+
<div class="field">
|
43
|
+
<%= f.label :telephone_number %><br />
|
44
|
+
<%= f.text_field :telephone_number %>
|
45
|
+
</div>
|
46
|
+
<div class="field">
|
47
|
+
<%= f.label :category_id %><br />
|
48
|
+
<%= f.text_field :category_id %>
|
49
|
+
</div>
|
50
|
+
<div class="actions">
|
51
|
+
<%= f.submit %>
|
52
|
+
</div>
|
53
|
+
<% end %>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<h1>Listing addresses</h1>
|
2
|
+
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<th>Full name</th>
|
6
|
+
<th>Address line 1</th>
|
7
|
+
<th>Address line 2</th>
|
8
|
+
<th>City</th>
|
9
|
+
<th>State</th>
|
10
|
+
<th>Postal code</th>
|
11
|
+
<th>Country</th>
|
12
|
+
<th>Telephone number</th>
|
13
|
+
<th></th>
|
14
|
+
<th></th>
|
15
|
+
<th></th>
|
16
|
+
</tr>
|
17
|
+
|
18
|
+
<% @addresses.each do |address| %>
|
19
|
+
<tr>
|
20
|
+
<td><%= address.full_name %></td>
|
21
|
+
<td><%= address.address_line_1 %></td>
|
22
|
+
<td><%= address.address_line_2 %></td>
|
23
|
+
<td><%= address.city %></td>
|
24
|
+
<td><%= address.state %></td>
|
25
|
+
<td><%= address.postal_code %></td>
|
26
|
+
<td><%= address.country %></td>
|
27
|
+
<td><%= address.telephone_number %></td>
|
28
|
+
<td><%= link_to 'Show', address %></td>
|
29
|
+
<td><%= link_to 'Edit', edit_address_path(address) %></td>
|
30
|
+
<td><%= link_to 'Destroy', address, confirm: 'Are you sure?', method: :delete %></td>
|
31
|
+
</tr>
|
32
|
+
<% end %>
|
33
|
+
</table>
|
34
|
+
|
35
|
+
<br />
|
36
|
+
<p>
|
37
|
+
<%= gmaps("map_options" => { "center_longitude" => 180, "zoom" => 1, "auto_adjust" => true}, "markers" => {"data" => @json, "options" => {"rich_marker" => true } }) %>
|
38
|
+
</p>
|
39
|
+
|
40
|
+
<%= link_to 'New Address', new_address_path %>
|
@@ -0,0 +1,63 @@
|
|
1
|
+
<p id="notice"><%= notice %></p>
|
2
|
+
|
3
|
+
<p>
|
4
|
+
<b>Full name:</b>
|
5
|
+
<%= @address.full_name %>
|
6
|
+
</p>
|
7
|
+
|
8
|
+
<p>
|
9
|
+
<b>Address line 1:</b>
|
10
|
+
<%= @address.address_line_1 %>
|
11
|
+
</p>
|
12
|
+
|
13
|
+
<p>
|
14
|
+
<b>Address line 2:</b>
|
15
|
+
<%= @address.address_line_2 %>
|
16
|
+
</p>
|
17
|
+
|
18
|
+
<p>
|
19
|
+
<b>City:</b>
|
20
|
+
<%= @address.city %>
|
21
|
+
</p>
|
22
|
+
|
23
|
+
<p>
|
24
|
+
<b>State:</b>
|
25
|
+
<%= @address.state %>
|
26
|
+
</p>
|
27
|
+
|
28
|
+
<p>
|
29
|
+
<b>Postal code:</b>
|
30
|
+
<%= @address.postal_code %>
|
31
|
+
</p>
|
32
|
+
|
33
|
+
<p>
|
34
|
+
<b>Country:</b>
|
35
|
+
<%= @address.country %>
|
36
|
+
</p>
|
37
|
+
|
38
|
+
<p>
|
39
|
+
<b>Telephone number:</b>
|
40
|
+
<%= @address.telephone_number %>
|
41
|
+
</p>
|
42
|
+
|
43
|
+
<p>
|
44
|
+
<b>Latitude:</b>
|
45
|
+
<%= @address.latitude %>
|
46
|
+
</p>
|
47
|
+
|
48
|
+
<p>
|
49
|
+
<b>Longitude:</b>
|
50
|
+
<%= @address.longitude %>
|
51
|
+
</p>
|
52
|
+
|
53
|
+
<p>
|
54
|
+
<b>Full Address:</b>
|
55
|
+
<%= @address.full_address %>
|
56
|
+
</p>
|
57
|
+
|
58
|
+
<p>
|
59
|
+
<%= gmaps("map_options" => { "center_longitude" => 180, "zoom" => 1, "auto_adjust" => true}, "markers" => {"data" => @json, "options" => {"rich_marker" => true } }) %>
|
60
|
+
</p>
|
61
|
+
|
62
|
+
<%= link_to 'Edit', edit_address_path(@address) %> |
|
63
|
+
<%= link_to 'Back', addresses_path %>
|
@@ -0,0 +1,85 @@
|
|
1
|
+
class AddressesController < ApplicationController
|
2
|
+
# GET /addresses
|
3
|
+
# GET /addresses.json
|
4
|
+
def index
|
5
|
+
@addresses = Address.all
|
6
|
+
@json = @addresses.to_gmaps4rails
|
7
|
+
|
8
|
+
respond_to do |format|
|
9
|
+
format.html # index.html.erb
|
10
|
+
format.json { render json: @addresses }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /addresses/1
|
15
|
+
# GET /addresses/1.json
|
16
|
+
def show
|
17
|
+
@address = Address.find(params[:id])
|
18
|
+
@json = @address.to_gmaps4rails
|
19
|
+
|
20
|
+
respond_to do |format|
|
21
|
+
format.html # show.html.erb
|
22
|
+
format.json { render json: @address }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# GET /addresses/new
|
27
|
+
# GET /addresses/new.json
|
28
|
+
def new
|
29
|
+
@address = Address.new
|
30
|
+
|
31
|
+
respond_to do |format|
|
32
|
+
format.html # new.html.erb
|
33
|
+
format.json { render json: @address }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# GET /addresses/1/edit
|
38
|
+
def edit
|
39
|
+
@address = Address.find(params[:id])
|
40
|
+
end
|
41
|
+
|
42
|
+
# POST /addresses
|
43
|
+
# POST /addresses.json
|
44
|
+
def create
|
45
|
+
@address = Address.new(params[:address])
|
46
|
+
|
47
|
+
respond_to do |format|
|
48
|
+
if @address.save
|
49
|
+
format.html { redirect_to @address, notice: 'Address was successfully created.' }
|
50
|
+
format.json { render json: @address, status: :created, location: @address }
|
51
|
+
else
|
52
|
+
format.html { render action: "new" }
|
53
|
+
format.json { render json: @address.errors, status: :unprocessable_entity }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# PUT /addresses/1
|
59
|
+
# PUT /addresses/1.json
|
60
|
+
def update
|
61
|
+
@address = Address.find(params[:id])
|
62
|
+
|
63
|
+
respond_to do |format|
|
64
|
+
if @address.update_attributes(params[:address])
|
65
|
+
format.html { redirect_to @address, notice: 'Address was successfully updated.' }
|
66
|
+
format.json { head :no_content }
|
67
|
+
else
|
68
|
+
format.html { render action: "edit" }
|
69
|
+
format.json { render json: @address.errors, status: :unprocessable_entity }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# DELETE /addresses/1
|
75
|
+
# DELETE /addresses/1.json
|
76
|
+
def destroy
|
77
|
+
@address = Address.find(params[:id])
|
78
|
+
@address.destroy
|
79
|
+
|
80
|
+
respond_to do |format|
|
81
|
+
format.html { redirect_to addresses_url }
|
82
|
+
format.json { head :no_content }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/rails/generators/simple_address_generator/templates/gmaps4rails/gmaps4rails.base.js.coffee
ADDED
@@ -0,0 +1,502 @@
|
|
1
|
+
Gmaps = {}
|
2
|
+
|
3
|
+
Gmaps.triggerOldOnload = ->
|
4
|
+
Gmaps.oldOnload() if typeof(Gmaps.oldOnload) == 'function'
|
5
|
+
|
6
|
+
Gmaps.loadMaps = ->
|
7
|
+
#loop through all variable names.
|
8
|
+
#there should only be maps inside so it trigger their load function
|
9
|
+
for key, value of Gmaps
|
10
|
+
searchLoadIncluded = key.search(/load/)
|
11
|
+
if searchLoadIncluded == -1
|
12
|
+
load_function_name = "load_" + key
|
13
|
+
Gmaps[load_function_name]()
|
14
|
+
|
15
|
+
window.Gmaps = Gmaps
|
16
|
+
|
17
|
+
class @Gmaps4Rails
|
18
|
+
|
19
|
+
constructor: ->
|
20
|
+
#map config
|
21
|
+
@map = null #DEPRECATED: will still contain a copy of serviceObject below as transition
|
22
|
+
@serviceObject = null #contains the map we're working on
|
23
|
+
@visibleInfoWindow = null #contains the current opened infowindow
|
24
|
+
@userLocation = null #contains user's location if geolocalization was performed and successful
|
25
|
+
|
26
|
+
#empty slots
|
27
|
+
@geolocationFailure = -> false #triggered when geolocation fails. If customized, must be like= function(navigator_handles_geolocation){} where 'navigator_handles_geolocation' is a boolean
|
28
|
+
@callback = -> false #to let user set a custom callback function
|
29
|
+
@customClusterer = -> false #to let user set custom clusterer pictures
|
30
|
+
@infobox = -> false #to let user use custom infoboxes
|
31
|
+
@jsTemplate = false #to let user create infowindows client side
|
32
|
+
|
33
|
+
@default_map_options =
|
34
|
+
id: 'map'
|
35
|
+
draggable: true
|
36
|
+
detect_location: false # should the browser attempt to use geolocation detection features of HTML5?
|
37
|
+
center_on_user: false # centers map on the location detected through the browser
|
38
|
+
center_latitude: 0
|
39
|
+
center_longitude: 0
|
40
|
+
zoom: 7
|
41
|
+
maxZoom: null
|
42
|
+
minZoom: null
|
43
|
+
auto_adjust : true # adjust the map to the markers if set to true
|
44
|
+
auto_zoom: true # zoom given by auto-adjust
|
45
|
+
bounds: [] # adjust map to these limits. Should be [{"lat": , "lng": }]
|
46
|
+
raw: {} # raw json to pass additional options
|
47
|
+
|
48
|
+
@default_markers_conf =
|
49
|
+
#Marker config
|
50
|
+
title: ""
|
51
|
+
#MarkerImage config
|
52
|
+
picture : ""
|
53
|
+
width: 22
|
54
|
+
length: 32
|
55
|
+
draggable: false # how to modify: <%= gmaps( "markers" => { "data" => @object.to_gmaps4rails, "options" => { "draggable" => true }}) %>
|
56
|
+
#clustering config
|
57
|
+
do_clustering: false # do clustering if set to true
|
58
|
+
randomize: false # Google maps can't display two markers which have the same coordinates. This randomizer enables to prevent this situation from happening.
|
59
|
+
max_random_distance: 100 # in meters. Each marker coordinate could be altered by this distance in a random direction
|
60
|
+
list_container: null # id of the ul that will host links to all markers
|
61
|
+
offset: 0 # used when adding_markers to an existing map. Because new markers are concated with previous one, offset is here to prevent the existing from being re-created.
|
62
|
+
raw: {} # raw json to pass additional options
|
63
|
+
|
64
|
+
#Stored variables
|
65
|
+
@markers = [] # contains all markers. A marker contains the following: {"description": , "longitude": , "title":, "latitude":, "picture": "", "width": "", "length": "", "sidebar": "", "serviceObject": google_marker}
|
66
|
+
@boundsObject = null # contains current bounds from markers, polylines etc...
|
67
|
+
@polygons = [] # contains raw data, array of arrays (first element could be a hash containing options)
|
68
|
+
@polylines = [] # contains raw data, array of arrays (first element could be a hash containing options)
|
69
|
+
@circles = [] # contains raw data, array of hash
|
70
|
+
@markerClusterer = null # contains all marker clusterers
|
71
|
+
@markerImages = []
|
72
|
+
|
73
|
+
#tnitializes the map
|
74
|
+
initialize : ->
|
75
|
+
@serviceObject = @createMap()
|
76
|
+
@map = @serviceObject #beware, soon deprecated
|
77
|
+
if (@map_options.detect_location == true or @map_options.center_on_user == true)
|
78
|
+
@findUserLocation(this)
|
79
|
+
#resets sidebar if needed
|
80
|
+
@resetSidebarContent()
|
81
|
+
|
82
|
+
findUserLocation : (map_object) ->
|
83
|
+
if (navigator.geolocation)
|
84
|
+
#try to retrieve user's position
|
85
|
+
positionSuccessful = (position) ->
|
86
|
+
map_object.userLocation = map_object.createLatLng(position.coords.latitude, position.coords.longitude)
|
87
|
+
#change map's center to focus on user's geoloc if asked
|
88
|
+
if(map_object.map_options.center_on_user == true)
|
89
|
+
map_object.centerMapOnUser()
|
90
|
+
positionFailure = ->
|
91
|
+
map_object.geolocationFailure(true)
|
92
|
+
|
93
|
+
navigator.geolocation.getCurrentPosition( positionSuccessful, positionFailure)
|
94
|
+
else
|
95
|
+
#failure but the navigator doesn't handle geolocation
|
96
|
+
map_object.geolocationFailure(false)
|
97
|
+
|
98
|
+
|
99
|
+
#////////////////////////////////////////////////////
|
100
|
+
#//////////////////// DIRECTIONS ////////////////////
|
101
|
+
#////////////////////////////////////////////////////
|
102
|
+
|
103
|
+
create_direction : ->
|
104
|
+
directionsDisplay = new google.maps.DirectionsRenderer()
|
105
|
+
directionsService = new google.maps.DirectionsService()
|
106
|
+
|
107
|
+
directionsDisplay.setMap(@serviceObject)
|
108
|
+
#display panel only if required
|
109
|
+
if @direction_conf.display_panel
|
110
|
+
directionsDisplay.setPanel(document.getElementById(@direction_conf.panel_id))
|
111
|
+
|
112
|
+
directionsDisplay.setOptions
|
113
|
+
suppressMarkers: false
|
114
|
+
suppressInfoWindows: false
|
115
|
+
suppressPolylines: false
|
116
|
+
|
117
|
+
request =
|
118
|
+
origin: @direction_conf.origin
|
119
|
+
destination: @direction_conf.destination
|
120
|
+
waypoints: @direction_conf.waypoints
|
121
|
+
optimizeWaypoints: @direction_conf.optimizeWaypoints
|
122
|
+
unitSystem: google.maps.DirectionsUnitSystem[@direction_conf.unitSystem]
|
123
|
+
avoidHighways: @direction_conf.avoidHighways
|
124
|
+
avoidTolls: @direction_conf.avoidTolls
|
125
|
+
region: @direction_conf.region
|
126
|
+
travelMode: google.maps.DirectionsTravelMode[@direction_conf.travelMode]
|
127
|
+
language: "en"
|
128
|
+
|
129
|
+
directionsService.route request, (response, status) ->
|
130
|
+
if (status == google.maps.DirectionsStatus.OK)
|
131
|
+
directionsDisplay.setDirections(response)
|
132
|
+
|
133
|
+
#////////////////////////////////////////////////////
|
134
|
+
#///////////////////// CIRCLES //////////////////////
|
135
|
+
#////////////////////////////////////////////////////
|
136
|
+
|
137
|
+
#Loops through all circles
|
138
|
+
#Loops through all circles and draws them
|
139
|
+
create_circles : ->
|
140
|
+
for circle in @circles
|
141
|
+
@create_circle circle
|
142
|
+
|
143
|
+
create_circle : (circle) ->
|
144
|
+
#by convention, default style configuration could be integrated in the first element
|
145
|
+
if circle == @circles[0]
|
146
|
+
@circles_conf.strokeColor = circle.strokeColor if circle.strokeColor?
|
147
|
+
@circles_conf.strokeOpacity = circle.strokeOpacity if circle.strokeOpacity?
|
148
|
+
@circles_conf.strokeWeight = circle.strokeWeight if circle.strokeWeight?
|
149
|
+
@circles_conf.fillColor = circle.fillColor if circle.fillColor?
|
150
|
+
@circles_conf.fillOpacity = circle.fillOpacity if circle.fillOpacity?
|
151
|
+
|
152
|
+
if circle.lat? and circle.lng?
|
153
|
+
# always check if a config is given, if not, use defaults
|
154
|
+
# NOTE: is there a cleaner way to do this? Maybe a hash merge of some sort?
|
155
|
+
newCircle = new google.maps.Circle
|
156
|
+
center: @createLatLng(circle.lat, circle.lng)
|
157
|
+
strokeColor: circle.strokeColor || @circles_conf.strokeColor
|
158
|
+
strokeOpacity: circle.strokeOpacity || @circles_conf.strokeOpacity
|
159
|
+
strokeWeight: circle.strokeWeight || @circles_conf.strokeWeight
|
160
|
+
fillOpacity: circle.fillOpacity || @circles_conf.fillOpacity
|
161
|
+
fillColor: circle.fillColor || @circles_conf.fillColor
|
162
|
+
clickable: circle.clickable || @circles_conf.clickable
|
163
|
+
zIndex: circle.zIndex || @circles_conf.zIndex
|
164
|
+
radius: circle.radius
|
165
|
+
|
166
|
+
circle.serviceObject = newCircle
|
167
|
+
newCircle.setMap(@serviceObject)
|
168
|
+
|
169
|
+
# clear circles
|
170
|
+
clear_circles : ->
|
171
|
+
for circle in @circles
|
172
|
+
@clear_circle circle
|
173
|
+
|
174
|
+
clear_circle : (circle) ->
|
175
|
+
circle.serviceObject.setMap(null)
|
176
|
+
|
177
|
+
hide_circles : ->
|
178
|
+
for circle in @circles
|
179
|
+
@hide_circle circle
|
180
|
+
|
181
|
+
hide_circle : (circle) ->
|
182
|
+
circle.serviceObject.setMap(null)
|
183
|
+
|
184
|
+
show_circles : ->
|
185
|
+
for circle in @circles
|
186
|
+
@show_circle @circle
|
187
|
+
|
188
|
+
show_circle : (circle) ->
|
189
|
+
circle.serviceObject.setMap(@serviceObject)
|
190
|
+
|
191
|
+
#////////////////////////////////////////////////////
|
192
|
+
#///////////////////// POLYGONS /////////////////////
|
193
|
+
#////////////////////////////////////////////////////
|
194
|
+
|
195
|
+
#polygons is an array of arrays. It loops.
|
196
|
+
create_polygons : ->
|
197
|
+
for polygon in @polygons
|
198
|
+
@create_polygon(polygon)
|
199
|
+
|
200
|
+
#creates a single polygon, triggered by create_polygons
|
201
|
+
create_polygon : (polygon) ->
|
202
|
+
polygon_coordinates = []
|
203
|
+
|
204
|
+
#Polygon points are in an Array, that's why looping is necessary
|
205
|
+
for point in polygon
|
206
|
+
latlng = @createLatLng(point.lat, point.lng)
|
207
|
+
polygon_coordinates.push(latlng)
|
208
|
+
#first element of an Array could contain specific configuration for this particular polygon. If no config given, use default
|
209
|
+
if point == polygon[0]
|
210
|
+
strokeColor = point.strokeColor || @polygons_conf.strokeColor
|
211
|
+
strokeOpacity = point.strokeOpacity || @polygons_conf.strokeOpacity
|
212
|
+
strokeWeight = point.strokeWeight || @polygons_conf.strokeWeight
|
213
|
+
fillColor = point.fillColor || @polygons_conf.fillColor
|
214
|
+
fillOpacity = point.fillOpacity || @polygons_conf.fillOpacity
|
215
|
+
clickable = point.clickable || @polygons_conf.clickable
|
216
|
+
|
217
|
+
#Construct the polygon
|
218
|
+
new_poly = new google.maps.Polygon
|
219
|
+
paths: polygon_coordinates
|
220
|
+
strokeColor: strokeColor
|
221
|
+
strokeOpacity: strokeOpacity
|
222
|
+
strokeWeight: strokeWeight
|
223
|
+
fillColor: fillColor
|
224
|
+
fillOpacity: fillOpacity
|
225
|
+
clickable: clickable
|
226
|
+
map: @serviceObject
|
227
|
+
|
228
|
+
#save polygon in list
|
229
|
+
polygon.serviceObject = new_poly
|
230
|
+
|
231
|
+
#////////////////////////////////////////////////////
|
232
|
+
#/////////////////// POLYLINES //////////////////////
|
233
|
+
#////////////////////////////////////////////////////
|
234
|
+
|
235
|
+
#replace old markers with new markers on an existing map
|
236
|
+
replacePolylines : (new_polylines) ->
|
237
|
+
#reset previous polylines and kill them from map
|
238
|
+
@destroy_polylines()
|
239
|
+
#set new polylines
|
240
|
+
@polylines = new_polylines
|
241
|
+
#create
|
242
|
+
@create_polylines()
|
243
|
+
#.... and adjust map boundaries
|
244
|
+
@adjustMapToBounds()
|
245
|
+
|
246
|
+
destroy_polylines : ->
|
247
|
+
for polyline in @polylines
|
248
|
+
#delete polylines from map
|
249
|
+
polyline.serviceObject.setMap(null)
|
250
|
+
#empty array
|
251
|
+
@polylines = []
|
252
|
+
|
253
|
+
#polylines is an array of arrays. It loops.
|
254
|
+
create_polylines : ->
|
255
|
+
for polyline in @polylines
|
256
|
+
@create_polyline polyline
|
257
|
+
|
258
|
+
#creates a single polyline, triggered by create_polylines
|
259
|
+
create_polyline : (polyline) ->
|
260
|
+
polyline_coordinates = []
|
261
|
+
|
262
|
+
#2 cases here, either we have a coded array of LatLng or we have an Array of LatLng
|
263
|
+
for element in polyline
|
264
|
+
#if we have a coded array
|
265
|
+
if element.coded_array?
|
266
|
+
decoded_array = new google.maps.geometry.encoding.decodePath(element.coded_array)
|
267
|
+
#loop through every point in the array
|
268
|
+
for point in decoded_array
|
269
|
+
polyline_coordinates.push(point)
|
270
|
+
|
271
|
+
#or we have an array of latlng
|
272
|
+
else
|
273
|
+
#by convention, a single polyline could be customized in the first array or it uses default values
|
274
|
+
if element == polyline[0]
|
275
|
+
strokeColor = element.strokeColor || @polylines_conf.strokeColor
|
276
|
+
strokeOpacity = element.strokeOpacity || @polylines_conf.strokeOpacity
|
277
|
+
strokeWeight = element.strokeWeight || @polylines_conf.strokeWeight
|
278
|
+
clickable = element.clickable || @polylines_conf.clickable
|
279
|
+
zIndex = element.zIndex || @polylines_conf.zIndex
|
280
|
+
|
281
|
+
#add latlng if positions provided
|
282
|
+
if element.lat? && element.lng?
|
283
|
+
latlng = @createLatLng(element.lat, element.lng)
|
284
|
+
polyline_coordinates.push(latlng)
|
285
|
+
|
286
|
+
# Construct the polyline
|
287
|
+
new_poly = new google.maps.Polyline
|
288
|
+
path: polyline_coordinates
|
289
|
+
strokeColor: strokeColor
|
290
|
+
strokeOpacity: strokeOpacity
|
291
|
+
strokeWeight: strokeWeight
|
292
|
+
clickable: clickable
|
293
|
+
zIndex: zIndex
|
294
|
+
|
295
|
+
#save polyline
|
296
|
+
polyline.serviceObject = new_poly
|
297
|
+
new_poly.setMap(@serviceObject)
|
298
|
+
|
299
|
+
#////////////////////////////////////////////////////
|
300
|
+
#///////////////////// MARKERS //////////////////////
|
301
|
+
#////////////////////////////////////////////////////
|
302
|
+
|
303
|
+
#creates, clusterizes and adjusts map
|
304
|
+
create_markers : ->
|
305
|
+
@createServiceMarkersFromMarkers()
|
306
|
+
@clusterize()
|
307
|
+
|
308
|
+
#create google.maps Markers from data provided by user
|
309
|
+
createServiceMarkersFromMarkers : ->
|
310
|
+
for marker, index in @markers
|
311
|
+
if not @markers[index].serviceObject?
|
312
|
+
#extract options, test if value passed or use default
|
313
|
+
Lat = @markers[index].lat
|
314
|
+
Lng = @markers[index].lng
|
315
|
+
|
316
|
+
#alter coordinates if randomize is true
|
317
|
+
if @markers_conf.randomize
|
318
|
+
LatLng = @randomize(Lat, Lng)
|
319
|
+
#retrieve coordinates from the array
|
320
|
+
Lat = LatLng[0]
|
321
|
+
Lng = LatLng[1]
|
322
|
+
|
323
|
+
#save object
|
324
|
+
@markers[index].serviceObject = @createMarker
|
325
|
+
"marker_picture": if @markers[index].picture then @markers[index].picture else @markers_conf.picture
|
326
|
+
"marker_width": if @markers[index].width then @markers[index].width else @markers_conf.width
|
327
|
+
"marker_height": if @markers[index].height then @markers[index].height else @markers_conf.length
|
328
|
+
"marker_title": if @markers[index].title then @markers[index].title else null
|
329
|
+
"marker_anchor": if @markers[index].marker_anchor then @markers[index].marker_anchor else null
|
330
|
+
"shadow_anchor": if @markers[index].shadow_anchor then @markers[index].shadow_anchor else null
|
331
|
+
"shadow_picture": if @markers[index].shadow_picture then @markers[index].shadow_picture else null
|
332
|
+
"shadow_width": if @markers[index].shadow_width then @markers[index].shadow_width else null
|
333
|
+
"shadow_height": if @markers[index].shadow_height then @markers[index].shadow_height else null
|
334
|
+
"marker_draggable": if @markers[index].draggable then @markers[index].draggable else @markers_conf.draggable
|
335
|
+
"rich_marker": if @markers[index].rich_marker then @markers[index].rich_marker else null
|
336
|
+
"zindex": if @markers[index].zindex then @markers[index].zindex else null
|
337
|
+
"Lat": Lat
|
338
|
+
"Lng": Lng
|
339
|
+
"index": index
|
340
|
+
|
341
|
+
#add infowindowstuff if enabled
|
342
|
+
@createInfoWindow(@markers[index])
|
343
|
+
#create sidebar if enabled
|
344
|
+
@createSidebar(@markers[index])
|
345
|
+
|
346
|
+
@markers_conf.offset = @markers.length
|
347
|
+
|
348
|
+
#creates Image Anchor Position or return null if nothing passed
|
349
|
+
createImageAnchorPosition : (anchorLocation) ->
|
350
|
+
if (anchorLocation == null)
|
351
|
+
return null
|
352
|
+
else
|
353
|
+
return @createPoint(anchorLocation[0], anchorLocation[1])
|
354
|
+
|
355
|
+
|
356
|
+
#replace old markers with new markers on an existing map
|
357
|
+
replaceMarkers : (new_markers) ->
|
358
|
+
@clearMarkers()
|
359
|
+
#reset previous markers
|
360
|
+
@markers = new Array
|
361
|
+
#reset current bounds
|
362
|
+
@boundsObject = @createLatLngBounds()
|
363
|
+
#reset sidebar content if exists
|
364
|
+
@resetSidebarContent()
|
365
|
+
#add new markers
|
366
|
+
@markers_conf.offset = 0
|
367
|
+
@addMarkers(new_markers)
|
368
|
+
|
369
|
+
#add new markers to on an existing map
|
370
|
+
addMarkers : (new_markers) ->
|
371
|
+
#update the list of markers to take into account
|
372
|
+
@markers = @markers.concat(new_markers)
|
373
|
+
#put markers on the map
|
374
|
+
@create_markers()
|
375
|
+
@adjustMapToBounds()
|
376
|
+
|
377
|
+
#////////////////////////////////////////////////////
|
378
|
+
#///////////////////// SIDEBAR //////////////////////
|
379
|
+
#////////////////////////////////////////////////////
|
380
|
+
|
381
|
+
#//creates sidebar
|
382
|
+
createSidebar : (marker_container) ->
|
383
|
+
if (@markers_conf.list_container)
|
384
|
+
ul = document.getElementById(@markers_conf.list_container)
|
385
|
+
li = document.createElement('li')
|
386
|
+
aSel = document.createElement('a')
|
387
|
+
aSel.href = 'javascript:void(0);'
|
388
|
+
html = if marker_container.sidebar? then marker_container.sidebar else "Marker"
|
389
|
+
aSel.innerHTML = html
|
390
|
+
currentMap = this
|
391
|
+
aSel.onclick = @sidebar_element_handler(currentMap, marker_container.serviceObject, 'click')
|
392
|
+
li.appendChild(aSel)
|
393
|
+
ul.appendChild(li)
|
394
|
+
|
395
|
+
#moves map to marker clicked + open infowindow
|
396
|
+
sidebar_element_handler : (currentMap, marker, eventType) ->
|
397
|
+
return () ->
|
398
|
+
currentMap.map.panTo(marker.position)
|
399
|
+
google.maps.event.trigger(marker, eventType)
|
400
|
+
|
401
|
+
|
402
|
+
resetSidebarContent : ->
|
403
|
+
if @markers_conf.list_container isnt null
|
404
|
+
ul = document.getElementById(@markers_conf.list_container)
|
405
|
+
ul.innerHTML = ""
|
406
|
+
|
407
|
+
#////////////////////////////////////////////////////
|
408
|
+
#////////////////// MISCELLANEOUS ///////////////////
|
409
|
+
#////////////////////////////////////////////////////
|
410
|
+
|
411
|
+
#to make the map fit the different LatLng points
|
412
|
+
adjustMapToBounds : ->
|
413
|
+
#FIRST_STEP: retrieve all bounds
|
414
|
+
#create the bounds object only if necessary
|
415
|
+
if @map_options.auto_adjust or @map_options.bounds isnt null
|
416
|
+
@boundsObject = @createLatLngBounds()
|
417
|
+
|
418
|
+
#if autodjust is true, must get bounds from markers polylines etc...
|
419
|
+
if @map_options.auto_adjust
|
420
|
+
#from markers
|
421
|
+
@extendBoundsWithMarkers()
|
422
|
+
|
423
|
+
#from polylines:
|
424
|
+
for polyline in @polylines
|
425
|
+
polyline_points = polyline.serviceObject.latLngs.getArray()[0].getArray()
|
426
|
+
for point in polyline_points
|
427
|
+
@boundsObject.extend point
|
428
|
+
|
429
|
+
#from polygons:
|
430
|
+
for polygon in @polygons
|
431
|
+
polygon_points = polygon.serviceObject.latLngs.getArray()[0].getArray()
|
432
|
+
for point in polygon_points
|
433
|
+
@boundsObject.extend point
|
434
|
+
|
435
|
+
#from circles
|
436
|
+
for circle in @circles
|
437
|
+
@boundsObject.extend(circle.serviceObject.getBounds().getNorthEast())
|
438
|
+
@boundsObject.extend(circle.serviceObject.getBounds().getSouthWest())
|
439
|
+
|
440
|
+
#in every case, I've to take into account the bounds set up by the user
|
441
|
+
for bound in @map_options.bounds
|
442
|
+
#create points from bounds provided
|
443
|
+
#TODO:only works with google maps
|
444
|
+
bound = @createLatLng(bound.lat, bound.lng)
|
445
|
+
@boundsObject.extend bound
|
446
|
+
|
447
|
+
#SECOND_STEP: ajust the map to the bounds
|
448
|
+
if @map_options.auto_adjust or @map_options.bounds.length > 0
|
449
|
+
|
450
|
+
#if autozoom is false, take user info into account
|
451
|
+
if !@map_options.auto_zoom
|
452
|
+
map_center = @boundsObject.getCenter()
|
453
|
+
@map_options.center_latitude = map_center.lat()
|
454
|
+
@map_options.center_longitude = map_center.lng()
|
455
|
+
@serviceObject.setCenter(map_center)
|
456
|
+
else
|
457
|
+
@fitBounds()
|
458
|
+
|
459
|
+
#////////////////////////////////////////////////////
|
460
|
+
#///////////////// KML //////////////////
|
461
|
+
#////////////////////////////////////////////////////
|
462
|
+
|
463
|
+
create_kml : ->
|
464
|
+
for kml in @kml
|
465
|
+
kml.serviceObject = @createKmlLayer kml
|
466
|
+
|
467
|
+
#////////////////////////////////////////////////////
|
468
|
+
#///////////////// Basic functions //////////////////
|
469
|
+
#///////////////////tests coded//////////////////////
|
470
|
+
|
471
|
+
#//basic function to check existence of a variable
|
472
|
+
exists : (var_name) ->
|
473
|
+
return (var_name != "" and typeof var_name != "undefined")
|
474
|
+
|
475
|
+
|
476
|
+
#randomize
|
477
|
+
randomize : (Lat0, Lng0) ->
|
478
|
+
#distance in meters between 0 and max_random_distance (positive or negative)
|
479
|
+
dx = @markers_conf.max_random_distance * @random()
|
480
|
+
dy = @markers_conf.max_random_distance * @random()
|
481
|
+
Lat = parseFloat(Lat0) + (180/Math.PI)*(dy/6378137)
|
482
|
+
Lng = parseFloat(Lng0) + ( 90/Math.PI)*(dx/6378137)/Math.cos(Lat0)
|
483
|
+
return [Lat, Lng]
|
484
|
+
|
485
|
+
mergeObjectWithDefault : (object1, object2) ->
|
486
|
+
copy_object1 = {}
|
487
|
+
for key, value of object1
|
488
|
+
copy_object1[key] = value
|
489
|
+
|
490
|
+
for key, value of object2
|
491
|
+
unless copy_object1[key]?
|
492
|
+
copy_object1[key] = value
|
493
|
+
return copy_object1
|
494
|
+
|
495
|
+
mergeWithDefault : (objectName) ->
|
496
|
+
default_object = @["default_" + objectName]
|
497
|
+
object = @[objectName]
|
498
|
+
@[objectName] = @mergeObjectWithDefault(object, default_object)
|
499
|
+
return true
|
500
|
+
|
501
|
+
#gives a value between -1 and 1
|
502
|
+
random : -> return(Math.random() * 2 -1)
|
@@ -0,0 +1,263 @@
|
|
1
|
+
#######################################################################################################
|
2
|
+
############################################## Google maps ##########################################
|
3
|
+
#######################################################################################################
|
4
|
+
|
5
|
+
class @Gmaps4RailsGoogle extends Gmaps4Rails
|
6
|
+
|
7
|
+
constructor: ->
|
8
|
+
super
|
9
|
+
#Map settings
|
10
|
+
@map_options =
|
11
|
+
disableDefaultUI: false
|
12
|
+
disableDoubleClickZoom: false
|
13
|
+
type: "ROADMAP" # HYBRID, ROADMAP, SATELLITE, TERRAIN
|
14
|
+
|
15
|
+
#markers + info styling
|
16
|
+
@markers_conf =
|
17
|
+
clusterer_gridSize: 50
|
18
|
+
clusterer_maxZoom: 5
|
19
|
+
custom_cluster_pictures: null
|
20
|
+
custom_infowindow_class: null
|
21
|
+
|
22
|
+
@mergeWithDefault("map_options")
|
23
|
+
@mergeWithDefault("markers_conf")
|
24
|
+
|
25
|
+
@kml_options =
|
26
|
+
clickable: true
|
27
|
+
preserveViewport: false
|
28
|
+
suppressInfoWindows: false
|
29
|
+
|
30
|
+
#Polygon Styling
|
31
|
+
@polygons_conf = # default style for polygons
|
32
|
+
strokeColor: "#FFAA00"
|
33
|
+
strokeOpacity: 0.8
|
34
|
+
strokeWeight: 2
|
35
|
+
fillColor: "#000000"
|
36
|
+
fillOpacity: 0.35
|
37
|
+
clickable: false
|
38
|
+
|
39
|
+
#Polyline Styling
|
40
|
+
@polylines_conf = #default style for polylines
|
41
|
+
strokeColor: "#FF0000"
|
42
|
+
strokeOpacity: 1
|
43
|
+
strokeWeight: 2
|
44
|
+
clickable: false
|
45
|
+
zIndex: null
|
46
|
+
|
47
|
+
#Circle Styling
|
48
|
+
@circles_conf = #default style for circles
|
49
|
+
fillColor: "#00AAFF"
|
50
|
+
fillOpacity: 0.35
|
51
|
+
strokeColor: "#FFAA00"
|
52
|
+
strokeOpacity: 0.8
|
53
|
+
strokeWeight: 2
|
54
|
+
clickable: false
|
55
|
+
zIndex: null
|
56
|
+
|
57
|
+
#Direction Settings
|
58
|
+
@direction_conf =
|
59
|
+
panel_id: null
|
60
|
+
display_panel: false
|
61
|
+
origin: null
|
62
|
+
destination: null
|
63
|
+
waypoints: [] #[{location: "toulouse,fr", stopover: true}, {location: "Clermont-Ferrand, fr", stopover: true}]
|
64
|
+
optimizeWaypoints: false
|
65
|
+
unitSystem: "METRIC" #IMPERIAL
|
66
|
+
avoidHighways: false
|
67
|
+
avoidTolls: false
|
68
|
+
region: null
|
69
|
+
travelMode: "DRIVING" #WALKING, BICYCLING
|
70
|
+
|
71
|
+
#////////////////////////////////////////////////////
|
72
|
+
#/////////////// Basic Objects //////////////
|
73
|
+
#////////////////////////////////////////////////////
|
74
|
+
|
75
|
+
createPoint : (lat, lng) ->
|
76
|
+
return new google.maps.Point(lat, lng)
|
77
|
+
|
78
|
+
createLatLng : (lat, lng) ->
|
79
|
+
return new google.maps.LatLng(lat, lng)
|
80
|
+
|
81
|
+
createLatLngBounds : ->
|
82
|
+
return new google.maps.LatLngBounds()
|
83
|
+
|
84
|
+
createMap : ->
|
85
|
+
defaultOptions =
|
86
|
+
maxZoom: @map_options.maxZoom
|
87
|
+
minZoom: @map_options.minZoom
|
88
|
+
zoom: @map_options.zoom
|
89
|
+
center: @createLatLng(@map_options.center_latitude, @map_options.center_longitude)
|
90
|
+
mapTypeId: google.maps.MapTypeId[@map_options.type]
|
91
|
+
mapTypeControl: @map_options.mapTypeControl
|
92
|
+
disableDefaultUI: @map_options.disableDefaultUI
|
93
|
+
disableDoubleClickZoom: @map_options.disableDoubleClickZoom
|
94
|
+
draggable: @map_options.draggable
|
95
|
+
|
96
|
+
mergedOptions = @mergeObjectWithDefault @map_options.raw, defaultOptions
|
97
|
+
|
98
|
+
return new google.maps.Map document.getElementById(@map_options.id), mergedOptions
|
99
|
+
|
100
|
+
|
101
|
+
createMarkerImage : (markerPicture, markerSize, origin, anchor, scaledSize) ->
|
102
|
+
return new google.maps.MarkerImage(markerPicture, markerSize, origin, anchor, scaledSize)
|
103
|
+
|
104
|
+
createSize : (width, height) ->
|
105
|
+
return new google.maps.Size(width, height)
|
106
|
+
|
107
|
+
#////////////////////////////////////////////////////
|
108
|
+
#////////////////////// Markers /////////////////////
|
109
|
+
#////////////////////////////////////////////////////
|
110
|
+
|
111
|
+
createMarker : (args) ->
|
112
|
+
markerLatLng = @createLatLng(args.Lat, args.Lng)
|
113
|
+
#Marker sizes are expressed as a Size of X,Y
|
114
|
+
if args.marker_picture == "" and args.rich_marker == null
|
115
|
+
defaultOptions = {position: markerLatLng, map: @serviceObject, title: args.marker_title, draggable: args.marker_draggable, zIndex: args.zindex}
|
116
|
+
mergedOptions = @mergeObjectWithDefault @markers_conf.raw, defaultOptions
|
117
|
+
return new google.maps.Marker mergedOptions
|
118
|
+
|
119
|
+
if (args.rich_marker != null)
|
120
|
+
return new RichMarker({
|
121
|
+
position: markerLatLng
|
122
|
+
map: @serviceObject
|
123
|
+
draggable: args.marker_draggable
|
124
|
+
content: args.rich_marker
|
125
|
+
flat: if args.marker_anchor == null then false else args.marker_anchor[1]
|
126
|
+
anchor: if args.marker_anchor == null then 0 else args.marker_anchor[0]
|
127
|
+
zIndex: args.zindex
|
128
|
+
})
|
129
|
+
|
130
|
+
#default behavior
|
131
|
+
#calculate MarkerImage anchor location
|
132
|
+
imageAnchorPosition = @createImageAnchorPosition args.marker_anchor
|
133
|
+
shadowAnchorPosition = @createImageAnchorPosition args.shadow_anchor
|
134
|
+
#create or retrieve existing MarkerImages
|
135
|
+
markerImage = @createOrRetrieveImage(args.marker_picture, args.marker_width, args.marker_height, imageAnchorPosition)
|
136
|
+
shadowImage = @createOrRetrieveImage(args.shadow_picture, args.shadow_width, args.shadow_height, shadowAnchorPosition)
|
137
|
+
defaultOptions = {position: markerLatLng, map: @serviceObject, icon: markerImage, title: args.marker_title, draggable: args.marker_draggable, shadow: shadowImage, zIndex: args.zindex}
|
138
|
+
mergedOptions = @mergeObjectWithDefault @markers_conf.raw, defaultOptions
|
139
|
+
return new google.maps.Marker mergedOptions
|
140
|
+
|
141
|
+
#checks if obj is included in arr Array and returns the position or false
|
142
|
+
includeMarkerImage : (arr, obj) ->
|
143
|
+
for object, index in arr
|
144
|
+
return index if object.url == obj
|
145
|
+
return false
|
146
|
+
|
147
|
+
#checks if MarkerImage exists before creating a new one
|
148
|
+
#returns a MarkerImage or false if ever something wrong is passed as argument
|
149
|
+
createOrRetrieveImage : (currentMarkerPicture, markerWidth, markerHeight, imageAnchorPosition) ->
|
150
|
+
return null if (currentMarkerPicture == "" or currentMarkerPicture == null )
|
151
|
+
|
152
|
+
test_image_index = @includeMarkerImage(@markerImages, currentMarkerPicture)
|
153
|
+
switch test_image_index
|
154
|
+
when false
|
155
|
+
markerImage = @createMarkerImage(currentMarkerPicture, @createSize(markerWidth, markerHeight), null, imageAnchorPosition, null )
|
156
|
+
@markerImages.push(markerImage)
|
157
|
+
return markerImage
|
158
|
+
break
|
159
|
+
else
|
160
|
+
return @markerImages[test_image_index] if typeof test_image_index == 'number'
|
161
|
+
return false
|
162
|
+
|
163
|
+
#clear markers
|
164
|
+
clearMarkers : ->
|
165
|
+
for marker in @markers
|
166
|
+
@clearMarker marker
|
167
|
+
|
168
|
+
#show and hide markers
|
169
|
+
showMarkers : ->
|
170
|
+
for marker in @markers
|
171
|
+
@showMarker marker
|
172
|
+
|
173
|
+
hideMarkers : ->
|
174
|
+
for marker in @markers
|
175
|
+
@hideMarker marker
|
176
|
+
|
177
|
+
clearMarker : (marker) ->
|
178
|
+
marker.serviceObject.setMap(null)
|
179
|
+
|
180
|
+
showMarker : (marker) ->
|
181
|
+
marker.serviceObject.setVisible(true)
|
182
|
+
|
183
|
+
hideMarker : (marker) ->
|
184
|
+
marker.serviceObject.setVisible(false)
|
185
|
+
|
186
|
+
extendBoundsWithMarkers : ->
|
187
|
+
for marker in @markers
|
188
|
+
@boundsObject.extend(marker.serviceObject.position)
|
189
|
+
|
190
|
+
#////////////////////////////////////////////////////
|
191
|
+
#/////////////////// Clusterer //////////////////////
|
192
|
+
#////////////////////////////////////////////////////
|
193
|
+
|
194
|
+
createClusterer : (markers_array) ->
|
195
|
+
return new MarkerClusterer( @serviceObject, markers_array, { maxZoom: @markers_conf.clusterer_maxZoom, gridSize: @markers_conf.clusterer_gridSize, styles: @customClusterer() })
|
196
|
+
|
197
|
+
clearClusterer : ->
|
198
|
+
@markerClusterer.clearMarkers()
|
199
|
+
|
200
|
+
#creates clusters
|
201
|
+
clusterize : ->
|
202
|
+
if @markers_conf.do_clustering == true
|
203
|
+
#first clear the existing clusterer if any
|
204
|
+
@clearClusterer() if @markerClusterer != null
|
205
|
+
|
206
|
+
markers_array = new Array
|
207
|
+
for marker in @markers
|
208
|
+
markers_array.push(marker.serviceObject)
|
209
|
+
|
210
|
+
@markerClusterer = @createClusterer(markers_array)
|
211
|
+
|
212
|
+
#////////////////////////////////////////////////////
|
213
|
+
#/////////////////// INFO WINDOW ////////////////////
|
214
|
+
#////////////////////////////////////////////////////
|
215
|
+
|
216
|
+
#// creates infowindows
|
217
|
+
createInfoWindow : (marker_container) ->
|
218
|
+
if typeof(@jsTemplate) == "function" or marker_container.description?
|
219
|
+
marker_container.description = @jsTemplate(marker_container) if typeof(@jsTemplate) == "function"
|
220
|
+
if @markers_conf.custom_infowindow_class != null
|
221
|
+
#creating custom infowindow
|
222
|
+
boxText = document.createElement("div")
|
223
|
+
boxText.setAttribute("class", @markers_conf.custom_infowindow_class) #to customize
|
224
|
+
boxText.innerHTML = marker_container.description
|
225
|
+
marker_container.infowindow = new InfoBox(@infobox(boxText))
|
226
|
+
currentMap = this
|
227
|
+
google.maps.event.addListener(marker_container.serviceObject, 'click', @openInfoWindow(currentMap, marker_container.infowindow, marker_container.serviceObject))
|
228
|
+
else
|
229
|
+
#create default infowindow
|
230
|
+
marker_container.infowindow = new google.maps.InfoWindow({content: marker_container.description })
|
231
|
+
#add the listener associated
|
232
|
+
currentMap = this
|
233
|
+
google.maps.event.addListener(marker_container.serviceObject, 'click', @openInfoWindow(currentMap, marker_container.infowindow, marker_container.serviceObject))
|
234
|
+
|
235
|
+
openInfoWindow : (currentMap, infoWindow, marker) ->
|
236
|
+
return ->
|
237
|
+
# Close the latest selected marker before opening the current one.
|
238
|
+
currentMap.visibleInfoWindow.close() if currentMap.visibleInfoWindow != null
|
239
|
+
infoWindow.open(currentMap.serviceObject, marker)
|
240
|
+
currentMap.visibleInfoWindow = infoWindow
|
241
|
+
|
242
|
+
#////////////////////////////////////////////////////
|
243
|
+
#///////////////// KML //////////////////
|
244
|
+
#////////////////////////////////////////////////////
|
245
|
+
|
246
|
+
createKmlLayer : (kml) ->
|
247
|
+
kml_options = kml.options || {}
|
248
|
+
kml_options = @mergeObjectWithDefault(kml_options, @kml_options)
|
249
|
+
kml = new google.maps.KmlLayer( kml.url, kml_options)
|
250
|
+
kml.setMap(@serviceObject)
|
251
|
+
return kml
|
252
|
+
|
253
|
+
|
254
|
+
#////////////////////////////////////////////////////
|
255
|
+
#/////////////////// Other methods //////////////////
|
256
|
+
#////////////////////////////////////////////////////
|
257
|
+
|
258
|
+
fitBounds : ->
|
259
|
+
@serviceObject.fitBounds(@boundsObject) unless @boundsObject.isEmpty()
|
260
|
+
|
261
|
+
centerMapOnUser : ->
|
262
|
+
@serviceObject.setCenter(@userLocation)
|
263
|
+
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple-address-generator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Chim Kan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-07 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: ! 'simple-address-generator allows you to create a complete Address model
|
15
|
+
with fields and two main plugins that geocode address into coordinates and a Google
|
16
|
+
Maps view with custom makers. To use, just add this gem to your Gemfile and then
|
17
|
+
in your Rails 3 application, run: rails g simple-address-generator. Then run rails
|
18
|
+
s and see in your browser http://localhost:3000/addresses.'
|
19
|
+
email: designium+simple@gmail.com
|
20
|
+
executables: []
|
21
|
+
extensions: []
|
22
|
+
extra_rdoc_files: []
|
23
|
+
files:
|
24
|
+
- lib/rails/generators/simple_address_generator/simple_address_generator_generator.rb
|
25
|
+
- lib/rails/generators/simple_address_generator/templates/address.rb
|
26
|
+
- lib/rails/generators/simple_address_generator/templates/addresses/_form.html.erb
|
27
|
+
- lib/rails/generators/simple_address_generator/templates/addresses/edit.html.erb
|
28
|
+
- lib/rails/generators/simple_address_generator/templates/addresses/index.html.erb
|
29
|
+
- lib/rails/generators/simple_address_generator/templates/addresses/new.html.erb
|
30
|
+
- lib/rails/generators/simple_address_generator/templates/addresses/show.html.erb
|
31
|
+
- lib/rails/generators/simple_address_generator/templates/addresses_controller.rb
|
32
|
+
- lib/rails/generators/simple_address_generator/templates/gmaps4rails/gmaps4rails.base.js.coffee
|
33
|
+
- lib/rails/generators/simple_address_generator/templates/gmaps4rails/gmaps4rails.googlemaps.js.coffee
|
34
|
+
- lib/rails/generators/simple_address_generator/templates/icon-1.png
|
35
|
+
- lib/rails/generators/simple_address_generator/USAGE
|
36
|
+
- lib/simple-address-generator/version.rb
|
37
|
+
- lib/simple-address-generator.rb
|
38
|
+
- Gemfile
|
39
|
+
- LICENSE
|
40
|
+
- Rakefile
|
41
|
+
- README.md
|
42
|
+
homepage: ''
|
43
|
+
licenses: []
|
44
|
+
post_install_message: ! '***************************************'
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '0'
|
60
|
+
requirements: []
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.8.11
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: simple-address-generator allows you to create a complete Address model integrated
|
66
|
+
to Google Maps.
|
67
|
+
test_files: []
|