map_layers 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +1 -1
- data/{README → README.md} +89 -18
- data/init.rb +3 -7
- data/lib/map_layers.rb +13 -323
- data/lib/map_layers/config.rb +20 -0
- data/lib/map_layers/feature.rb +12 -0
- data/lib/map_layers/georss.rb +120 -0
- data/lib/map_layers/js_wrapper.rb +3 -0
- data/lib/map_layers/kml.rb +53 -0
- data/lib/map_layers/railtie.rb +27 -0
- data/lib/map_layers/version.rb +1 -1
- data/lib/map_layers/wfs.rb +104 -0
- data/map_layers.gemspec +5 -5
- metadata +43 -36
- data/lib/map_layers/#geonames.rb# +0 -66
data/Gemfile.lock
CHANGED
data/{README → README.md}
RENAMED
@@ -1,27 +1,41 @@
|
|
1
|
-
|
1
|
+
# MapLayers
|
2
2
|
|
3
3
|
MapLayers makes it easy to integrate a dynamic map in a Rails application. It can display map tiles and markers loaded from many different data sources.
|
4
|
-
The included map viewer is OpenLayers
|
5
|
-
With MapLayers you can
|
4
|
+
The included map viewer is [OpenLayers](http://www.openlayers.org/).
|
5
|
+
With MapLayers you can :
|
6
|
+
- display and publish ActiveRecord models with geographic data.
|
7
|
+
- make your own map model
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
+
Getting Started
|
10
|
+
---------------
|
9
11
|
|
10
12
|
Install the latest version of the plugin:
|
11
|
-
|
13
|
+
sudo gem install map_layers
|
14
|
+
Or with bundler add to your Gemfile :
|
15
|
+
gem "map_layers"
|
12
16
|
|
13
17
|
Create a controller and a view
|
18
|
+
|
19
|
+
``` bash
|
14
20
|
./script/generate controller Map index
|
21
|
+
```
|
22
|
+
|
23
|
+
Initialization of the map
|
24
|
+
-------------------------
|
15
25
|
|
16
|
-
===Initialization of the map
|
17
26
|
Add the map viewer initialization to the index action in the controller:
|
27
|
+
|
28
|
+
``` ruby
|
18
29
|
@map = MapLayers::Map.new("map") do |map, page|
|
19
30
|
page << map.add_layer(MapLayers::GOOGLE)
|
20
31
|
page << map.zoom_to_max_extent()
|
21
32
|
end
|
33
|
+
```
|
22
34
|
|
35
|
+
``` ruby
|
23
36
|
Add this to the head of your view:
|
24
37
|
<%= map_layers_includes :google => "ABQIAAAA3HdfrnxFAPWyY-aiJUxmqRTJQa0g3IQ9GZqIMmInSLzwtGDKaBQ0KYLwBEKSM7F9gCevcsIf6WPuIQ" %>
|
38
|
+
```
|
25
39
|
|
26
40
|
Put a map in the body your view:
|
27
41
|
<div id="map" style="width: 512px; height: 256px;"></div>
|
@@ -30,8 +44,12 @@ Put a map in the body your view:
|
|
30
44
|
|
31
45
|
Test your basic map with <tt>http://localhost:3000/map</tt>
|
32
46
|
|
33
|
-
|
47
|
+
Multiple layers
|
48
|
+
---------------
|
49
|
+
|
34
50
|
Add a second layer and some more controls in the controller action:
|
51
|
+
|
52
|
+
``` ruby
|
35
53
|
@map = MapLayers::Map.new("map") do |map, page|
|
36
54
|
page << map.add_layer(MapLayers::GOOGLE)
|
37
55
|
page << map.add_layer(MapLayers::YAHOO_HYBRID)
|
@@ -42,119 +60,172 @@ Add a second layer and some more controls in the controller action:
|
|
42
60
|
|
43
61
|
page << map.zoom_to_max_extent()
|
44
62
|
end
|
63
|
+
```
|
45
64
|
|
46
65
|
Add the Yahoo Javascript library to the includes:
|
66
|
+
|
67
|
+
``` ruby
|
47
68
|
<%= map_layers_includes :google => "ABQIAAAA3HdfrnxFAPWyY-aiJUxmqRTJQa0g3IQ9GZqIMmInSLzwtGDKaBQ0KYLwBEKSM7F9gCevcsIf6WPuIQ", :yahoo => "euzuro-openlayers" %>
|
69
|
+
```
|
48
70
|
|
49
71
|
There are many more predefined layer types available:
|
50
72
|
GOOGLE_SATELLITE, GOOGLE_HYBRID, GOOGLE_PHYSICAL, VE_ROAD, VE_AERIAL, VE_HYBRID, YAHOO, YAHOO_SATELLITE, YAHOO_HYBRID, MULTIMAP, OSM_MAPNIK, OSM_TELASCIENCE, GEOPOLE_OSM, NASA_GLOBAL_MOSAIC, BLUE_MARBLE_NG, WORLDWIND, WORLDWIND_URBAN, WORLDWIND_BATHY
|
51
73
|
|
52
74
|
To include all Javascript APIs, insert your API keys in the following statement:
|
75
|
+
|
76
|
+
``` ruby
|
53
77
|
<%= map_layers_includes :google => "ABQIAAAA3HdfrnxFAPWyY-aiJUxmqRTJQa0g3IQ9GZqIMmInSLzwtGDKaBQ0KYLwBEKSM7F9gCevcsIf6WPuIQ", :multimap => "metacarta_04", :virtualearth => true, :yahoo => "euzuro-openlayers" %>
|
78
|
+
```
|
54
79
|
|
80
|
+
Updating the map
|
81
|
+
----------------
|
55
82
|
|
56
|
-
===Updating the map
|
57
83
|
Now we want to add some simple markers in an Ajax action.
|
58
84
|
First we add a link in the view:
|
59
85
|
|
86
|
+
``` ruby
|
60
87
|
<%= link_to_remote "Add marker", :url => { :action => "add_marker" } %>
|
88
|
+
```
|
61
89
|
|
62
90
|
This requires including the prototype library:
|
63
91
|
|
92
|
+
``` ruby
|
64
93
|
<%= javascript_include_tag 'prototype' %>
|
94
|
+
```
|
65
95
|
|
66
96
|
Then we include a marker layer in the map. Put this after the add_layer statements in the controller:
|
67
97
|
|
98
|
+
``` ruby
|
68
99
|
page.assign("markers", Layer::Markers.new('Markers'))
|
69
100
|
page << map.addLayer(:markers)
|
101
|
+
```
|
70
102
|
|
71
103
|
and then we implement the Ajax action:
|
72
104
|
|
105
|
+
``` ruby
|
73
106
|
def add_marker
|
74
107
|
render :update do |page|
|
75
108
|
@markers = JsVar.new('markers')
|
76
109
|
page << @markers.add_marker(OpenLayers::Marker.new(OpenLayers::LonLat.new(rand*50,rand*50)))
|
77
110
|
end
|
78
111
|
end
|
112
|
+
```
|
79
113
|
|
80
114
|
For accessing the marker layer in the Ajax action, we declare a Javascript variable with <tt>page.assign</tt> and access the variable later with the +JsVar+ wrapper.
|
81
115
|
|
82
116
|
|
83
|
-
|
117
|
+
OpenStreetMap in WGS84
|
118
|
+
----------------------
|
84
119
|
|
85
120
|
To overlay data in WGS84 projection you can use a customized Open Street Map:
|
86
121
|
|
122
|
+
``` ruby
|
87
123
|
@map = MapLayers::Map.new("map") do |map, page|
|
88
124
|
page << map.add_layer(MapLayers::GEOPOLE_OSM)
|
89
125
|
page << map.zoom_to_max_extent()
|
90
126
|
end
|
127
|
+
```
|
91
128
|
|
92
|
-
|
93
|
-
|
129
|
+
Publish your own data
|
130
|
+
---------------------
|
94
131
|
|
95
132
|
Create a model:
|
133
|
+
|
134
|
+
``` bash
|
96
135
|
./script/generate model --skip-timestamps --skip-fixture Place placeName:string countryCode:string postalCode:string lat:float lng:float
|
97
136
|
rake db:migrate
|
137
|
+
```
|
98
138
|
|
99
139
|
Import some places:
|
140
|
+
|
141
|
+
``` bash
|
100
142
|
./script/runner "Geonames::Postalcode.search('Sidney').each { |pc| Place.create(pc.attributes.slice('placeName', 'postalCode', 'countryCode', 'lat', 'lng')) }"
|
143
|
+
```
|
101
144
|
|
102
145
|
Add a new controller with a map_layer:
|
103
146
|
|
147
|
+
``` ruby
|
104
148
|
class PlacesController < ApplicationController
|
105
149
|
|
106
150
|
map_layer :place, :text => :placeName
|
107
151
|
|
108
152
|
end
|
153
|
+
```
|
109
154
|
|
110
155
|
And add a layer to the map:
|
111
156
|
|
157
|
+
``` ruby
|
112
158
|
page << map.addLayer(Layer::GeoRSS.new("GeoRSS", "/places/georss"))
|
113
|
-
|
159
|
+
```
|
114
160
|
|
115
161
|
Other types of served layers:
|
116
162
|
|
163
|
+
``` ruby
|
117
164
|
page << map.add_layer(Layer::GML.new("Places KML", "/places/kml", {:format=> JsExpr.new("OpenLayers.Format.KML")}))
|
118
165
|
|
119
166
|
page << map.add_layer(Layer::WFS.new("Places WFS", "/places/wfs", {:typename => "places"}, {:featureClass => JsExpr.new("OpenLayers.Feature.WFS")}))
|
167
|
+
```
|
120
168
|
|
121
169
|
|
122
|
-
|
170
|
+
Spatial database support
|
171
|
+
------------------------
|
123
172
|
|
124
173
|
Using a spatial database requires GeoRuby[http://georuby.rubyforge.org/] and the Spatial Adapter for Rails:
|
125
174
|
|
175
|
+
``` bash
|
126
176
|
sudo gem install georuby
|
127
177
|
ruby script/plugin install svn://rubyforge.org/var/svn/georuby/SpatialAdapter/trunk/spatial_adapter
|
178
|
+
```
|
128
179
|
|
129
180
|
Install spatial functions in your DB (e.g. Postgis 8.1):
|
181
|
+
|
182
|
+
``` bash
|
130
183
|
DB=map_layers_dev
|
131
184
|
createlang plpgsql $DB
|
132
185
|
psql -d $DB -q -f /usr/share/postgresql-8.1-postgis/lwpostgis.sql
|
186
|
+
```
|
133
187
|
|
134
188
|
Create a model:
|
189
|
+
|
190
|
+
``` bash
|
135
191
|
./script/generate model --skip-timestamps --skip-fixture WeatherStation name:string geom:point
|
136
192
|
rake db:migrate
|
193
|
+
```
|
137
194
|
|
138
195
|
Import some weather stations:
|
196
|
+
|
197
|
+
``` bash
|
139
198
|
./script/runner "Geonames::Weather.weather(:north => 44.1, :south => -9.9, :east => -22.4, :west => 55.2).each { |st| WeatherStation.create(:name => st.stationName, :geom => Point.from_x_y(st.lng, st.lat)) }"
|
199
|
+
```
|
140
200
|
|
141
201
|
Add a new controller with a map_layer:
|
142
202
|
|
203
|
+
``` ruby
|
143
204
|
class WeatherStationsController < ApplicationController
|
144
205
|
|
145
206
|
map_layer :weather_stations, :geometry => :geom
|
146
207
|
|
147
208
|
end
|
209
|
+
```
|
148
210
|
|
149
211
|
And add a WFS layer to the map:
|
150
212
|
|
213
|
+
``` ruby
|
151
214
|
page << map.add_layer(Layer::WFS.new("Weather Stations", "/weather_stations/wfs", {:typename => "weather_stations"}, {:featureClass => JsExpr.new("OpenLayers.Feature.WFS")}))
|
215
|
+
```
|
216
|
+
|
217
|
+
License
|
218
|
+
-------
|
152
219
|
|
153
|
-
==License
|
154
220
|
The MapLayers plugin for Rails is released under the MIT license.
|
155
221
|
|
156
|
-
|
157
|
-
|
222
|
+
Development
|
223
|
+
-----------
|
224
|
+
|
225
|
+
* Source hosted at [GitHub](https://github.com/ldonnet/map_layers).
|
226
|
+
* Report issues and feature requests to [GitHub Issues](https://github.com/ldonnet/map_layers/issues).
|
227
|
+
|
228
|
+
Pull requests are very welcome! Make sure your patches are well tested. Please create a topic branch for every separate change you make. Please **do not change** the version in your pull-request.
|
158
229
|
|
159
230
|
|
160
|
-
<em>Copyright (c)
|
231
|
+
<em>Copyright (c) 2011 Luc Donnet, Dryade</em>
|
data/init.rb
CHANGED
@@ -1,8 +1,4 @@
|
|
1
|
-
require
|
2
|
-
require 'map_layers/
|
1
|
+
require File.join(File.dirname(__FILE__), "lib", "map_layers")
|
2
|
+
require 'map_layers/railtie'
|
3
3
|
|
4
|
-
|
5
|
-
ActionView::Base.send(:include, MapLayers)
|
6
|
-
ActionView::Base.send(:include, MapLayers::ViewHelpers)
|
7
|
-
|
8
|
-
Mime::Type.register "application/vnd.google-earth.kml+xml", :kml
|
4
|
+
MapLayers::Railtie.insert
|
data/lib/map_layers.rb
CHANGED
@@ -1,18 +1,11 @@
|
|
1
|
-
require '
|
1
|
+
require 'map_layers/version'
|
2
|
+
require 'map_layers/config'
|
3
|
+
require 'map_layers/js_wrapper'
|
4
|
+
require 'map_layers/open_layers'
|
5
|
+
require 'map_layers/map'
|
6
|
+
require 'map_layers/railtie'
|
2
7
|
|
3
8
|
module MapLayers # :nodoc:
|
4
|
-
|
5
|
-
#Include helpers in the given scope to AC and AV.
|
6
|
-
# def self.include_helpers(scope)
|
7
|
-
# ActiveSupport.on_load(:action_controller) do
|
8
|
-
# include scope::MapLayers
|
9
|
-
# end
|
10
|
-
|
11
|
-
# ActiveSupport.on_load(:action_view) do
|
12
|
-
# include scope::MapLayers
|
13
|
-
# include scope::MapLayers::ViewHelpers
|
14
|
-
# end
|
15
|
-
# end
|
16
9
|
|
17
10
|
# extend the class that include this with the methods in ClassMethods
|
18
11
|
def self.included(base)
|
@@ -34,13 +27,13 @@ module MapLayers # :nodoc:
|
|
34
27
|
# create the configuration
|
35
28
|
@map_layers_config = MapLayers::Config::new(model_id, options)
|
36
29
|
|
37
|
-
module_eval do
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
30
|
+
# module_eval do
|
31
|
+
# include MapLayers::KML
|
32
|
+
# include MapLayers::WFS
|
33
|
+
# include MapLayers::GeoRSS
|
34
|
+
# include MapLayers::Proxy
|
35
|
+
# include MapLayers::Rest
|
36
|
+
# end
|
44
37
|
|
45
38
|
#session :off, :only => [:kml, :wfs, :georss]
|
46
39
|
|
@@ -51,308 +44,5 @@ module MapLayers # :nodoc:
|
|
51
44
|
end
|
52
45
|
|
53
46
|
end
|
54
|
-
|
55
|
-
|
56
|
-
class Config
|
57
|
-
attr_reader :model_id, :id, :lat, :lon, :geometry, :text
|
58
|
-
|
59
|
-
def initialize(model_id, options)
|
60
|
-
@model_id = model_id.to_s.pluralize.singularize
|
61
|
-
@id = options[:id] || :id
|
62
|
-
@lat = options[:lat] || :lat
|
63
|
-
@lon = options[:lon] || :lng
|
64
|
-
@geometry = options[:geometry]
|
65
|
-
@text = options[:text] || :name
|
66
|
-
end
|
67
|
-
|
68
|
-
def model
|
69
|
-
@model ||= @model_id.to_s.camelize.constantize
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
|
74
|
-
class Feature < Struct.new(:text, :x, :y, :id)
|
75
|
-
attr_accessor :geometry
|
76
|
-
def self.from_geom(text, geom, id = nil)
|
77
|
-
f = new(text, geom.x, geom.y, id)
|
78
|
-
f.geometry = geom
|
79
|
-
f
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# KML Server methods
|
84
|
-
module KML
|
85
|
-
|
86
|
-
# Publish layer in KML format
|
87
|
-
def kml
|
88
|
-
rows = map_layers_config.model.find(:all, :limit => KML_FEATURE_LIMIT)
|
89
|
-
@features = rows.collect do |row|
|
90
|
-
if map_layers_config.geometry
|
91
|
-
Feature.from_geom(row.send(map_layers_config.text), row.send(map_layers_config.geometry))
|
92
|
-
else
|
93
|
-
Feature.new(row.send(map_layers_config.text), row.send(map_layers_config.lon), row.send(map_layers_config.lat))
|
94
|
-
end
|
95
|
-
end
|
96
|
-
@folder_name = map_layers_config.model_id.to_s.pluralize.humanize
|
97
|
-
logger.info "MapLayers::KML: returning #{@features.size} features"
|
98
|
-
render :inline => KML_XML_ERB, :content_type => "text/xml"
|
99
|
-
rescue Exception => e
|
100
|
-
logger.error "MapLayers::KML: returning no features - Caught exception '#{e}'"
|
101
|
-
render :text => KML_EMPTY_RESPONSE, :content_type => "text/xml"
|
102
|
-
end
|
103
|
-
|
104
|
-
protected
|
105
|
-
|
106
|
-
KML_FEATURE_LIMIT = 1000
|
107
|
-
|
108
|
-
KML_XML_ERB = <<EOS # :nodoc:
|
109
|
-
<?xml version="1.0" encoding="UTF-8" ?>
|
110
|
-
<kml xmlns="http://earth.google.com/kml/2.0">
|
111
|
-
<Document>
|
112
|
-
<Folder><name><%= @folder_name %></name>
|
113
|
-
<% for feature in @features -%>
|
114
|
-
<Placemark>
|
115
|
-
<description><%= feature.text %></description>
|
116
|
-
<Point><coordinates><%= feature.x %>,<%= feature.y %></coordinates></Point>
|
117
|
-
</Placemark>
|
118
|
-
<% end -%>
|
119
|
-
</Folder>
|
120
|
-
</Document>
|
121
|
-
</kml>
|
122
|
-
EOS
|
123
|
-
|
124
|
-
KML_EMPTY_RESPONSE = <<EOS # :nodoc:
|
125
|
-
<?xml version="1.0" encoding="UTF-8" ?>
|
126
|
-
<kml xmlns="http://earth.google.com/kml/2.0">
|
127
|
-
<Document>
|
128
|
-
</Document>
|
129
|
-
</kml>
|
130
|
-
EOS
|
131
|
-
|
132
|
-
end
|
133
|
-
|
134
|
-
# WFS Server methods
|
135
|
-
module WFS
|
136
|
-
|
137
|
-
WGS84 = 4326
|
138
|
-
|
139
|
-
# Publish layer in WFS format
|
140
|
-
def wfs
|
141
|
-
minx, miny, maxx, maxy = extract_params
|
142
|
-
model = map_layers_config.model
|
143
|
-
if map_layers_config.geometry
|
144
|
-
db_srid = model.columns_hash[map_layers_config.geometry.to_s].srid
|
145
|
-
if db_srid != @srid && !db_srid.nil? && db_srid != -1
|
146
|
-
#Transform geometry from db_srid to requested srid (not possible for undefined db_srid)
|
147
|
-
geom = "Transform(#{geom},#{@srid}) AS #{geom}"
|
148
|
-
end
|
149
|
-
|
150
|
-
spatial_cond = if model.respond_to?(:sanitize_sql_hash_for_conditions)
|
151
|
-
model.sanitize_sql_hash_for_conditions(map_layers_config.geometry => [[minx, miny],[maxx, maxy], db_srid])
|
152
|
-
else # Rails < 2
|
153
|
-
model.sanitize_sql_hash(map_layers_config.geometry => [[minx, miny],[maxx, maxy], db_srid])
|
154
|
-
end
|
155
|
-
#spatial_cond = "Transform(#{spatial_cond}, #{db_srid}) )" Not necessary: bbox is always WGS84 !?
|
156
|
-
|
157
|
-
rows = model.find(:all, :conditions => spatial_cond, :limit => @maxfeatures)
|
158
|
-
@features = rows.collect do |row|
|
159
|
-
Feature.from_geom(row.send(map_layers_config.text), row.send(map_layers_config.geometry.to_s))
|
160
|
-
end
|
161
|
-
else
|
162
|
-
rows = model.find(:all, :limit => @maxfeatures)
|
163
|
-
@features = rows.collect do |row|
|
164
|
-
Feature.new(row.send(map_layers_config.text), row.send(map_layers_config.lon), row.send(map_layers_config.lat))
|
165
|
-
end
|
166
|
-
end
|
167
|
-
logger.info "MapLayers::WFS: returning #{@features.size} features"
|
168
|
-
render :inline => WFS_XML_ERB, :content_type => "text/xml"
|
169
|
-
rescue Exception => e
|
170
|
-
logger.error "MapLayers::WFS: returning no features - Caught exception '#{e}'"
|
171
|
-
render :text => WFS_EMPTY_RESPONSE, :content_type => "text/xml"
|
172
|
-
end
|
173
|
-
|
174
|
-
protected
|
175
|
-
|
176
|
-
WFS_FEATURE_LIMIT = 1000
|
177
|
-
|
178
|
-
def extract_params # :nodoc:
|
179
|
-
@maxfeatures = (params[:maxfeatures] || WFS_FEATURE_LIMIT).to_i
|
180
|
-
@srid = params['SRS'].split(/:/)[1].to_i rescue WGS84
|
181
|
-
req_bbox = params['BBOX'].split(/,/).collect {|n| n.to_f } rescue nil
|
182
|
-
@bbox = req_bbox || [-180.0, -90.0, 180.0, 90.0]
|
183
|
-
end
|
184
|
-
|
185
|
-
WFS_XML_ERB = <<EOS # :nodoc:
|
186
|
-
<?xml version='1.0' encoding="UTF-8" ?>
|
187
|
-
<wfs:FeatureCollection
|
188
|
-
xmlns:ms="http://mapserver.gis.umn.edu/mapserver"
|
189
|
-
xmlns:wfs="http://www.opengis.net/wfs"
|
190
|
-
xmlns:gml="http://www.opengis.net/gml"
|
191
|
-
xmlns:ogc="http://www.opengis.net/ogc"
|
192
|
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
193
|
-
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengeospatial.net/wfs/1.0.0/WFS-basic.xsd
|
194
|
-
http://mapserver.gis.umn.edu/mapserver http://www.geopole.org/map/wfs?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAME=geopole&OUTPUTFORMAT=XMLSCHEMA">
|
195
|
-
<gml:boundedBy>
|
196
|
-
<gml:Box srsName="EPSG:<%= @srid %>">
|
197
|
-
<gml:coordinates><%= @bbox[0] %>,<%= @bbox[1] %> <%= @bbox[2] %>,<%= @bbox[3] %></gml:coordinates>
|
198
|
-
</gml:Box>
|
199
|
-
</gml:boundedBy>
|
200
|
-
<% for feature in @features -%>
|
201
|
-
<gml:featureMember>
|
202
|
-
<ms:geopole>
|
203
|
-
<gml:boundedBy>
|
204
|
-
<gml:Box srsName="EPSG:<%= @srid %>">
|
205
|
-
<gml:coordinates><%= feature.x %>,<%= feature.y %> <%= feature.x %>,<%= feature.y %></gml:coordinates>
|
206
|
-
</gml:Box>
|
207
|
-
</gml:boundedBy>
|
208
|
-
<ms:msGeometry>
|
209
|
-
<gml:Point srsName="EPSG:<%= @srid %>">
|
210
|
-
<gml:coordinates><%= feature.x %>,<%= feature.y %></gml:coordinates>
|
211
|
-
</gml:Point>
|
212
|
-
</ms:msGeometry>
|
213
|
-
<ms:text><%= feature.text %></ms:text>
|
214
|
-
</ms:geopole>
|
215
|
-
</gml:featureMember>
|
216
|
-
<% end -%>
|
217
|
-
</wfs:FeatureCollection>
|
218
|
-
EOS
|
219
|
-
|
220
|
-
WFS_EMPTY_RESPONSE = <<EOS # :nodoc:
|
221
|
-
<?xml version='1.0' encoding="UTF-8" ?>
|
222
|
-
<wfs:FeatureCollection
|
223
|
-
xmlns:wfs="http://www.opengis.net/wfs"
|
224
|
-
xmlns:gml="http://www.opengis.net/gml"
|
225
|
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
226
|
-
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengeospatial.net/wfs/1.0.0/WFS-basic.xsd">
|
227
|
-
<gml:boundedBy>
|
228
|
-
<gml:null>missing</gml:null>
|
229
|
-
</gml:boundedBy>
|
230
|
-
</wfs:FeatureCollection>
|
231
|
-
EOS
|
232
|
-
|
233
|
-
end
|
234
|
-
|
235
|
-
# GeoRSS Server methods
|
236
|
-
# http://www.georss.org/1
|
237
|
-
|
238
|
-
module GeoRSS
|
239
|
-
|
240
|
-
# Publish layer in GeoRSS format
|
241
|
-
def georss
|
242
|
-
rows = map_layers_config.model.find(:all, :limit => GEORSS_FEATURE_LIMIT)
|
243
|
-
@features = rows.collect do |row|
|
244
|
-
if map_layers_config.geometry
|
245
|
-
Feature.from_geom(row.send(map_layers_config.text), row.send(map_layers_config.geometry), row.send(map_layers_config.id))
|
246
|
-
else
|
247
|
-
Feature.new(row.send(map_layers_config.text), row.send(map_layers_config.lon), row.send(map_layers_config.lat))
|
248
|
-
end
|
249
|
-
end
|
250
|
-
@base_url = "http://#{request.env["HTTP_HOST"]}/"
|
251
|
-
@item_url = "#{@base_url}#{map_layers_config.model_id.to_s.pluralize}"
|
252
|
-
@title = map_layers_config.model_id.to_s.pluralize.humanize
|
253
|
-
logger.info "MapLayers::GEORSS: returning #{@features.size} features"
|
254
|
-
render :inline => GEORSS_XML_ERB, :content_type => "text/xml"
|
255
|
-
rescue Exception => e
|
256
|
-
logger.error "MapLayers::GEORSS: returning no features - Caught exception '#{e}'"
|
257
|
-
render :text => GEORSS_EMPTY_RESPONSE, :content_type => "text/xml"
|
258
|
-
end
|
259
|
-
|
260
|
-
protected
|
261
|
-
|
262
|
-
GEORSS_FEATURE_LIMIT = 1000
|
263
|
-
|
264
|
-
GEORSS_XML_ERB = <<EOS # :nodoc:
|
265
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
266
|
-
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
267
|
-
xmlns="http://purl.org/rss/1.0/"
|
268
|
-
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
269
|
-
xmlns:georss="http://www.georss.org/georss">
|
270
|
-
<docs>This is an RSS file. Copy the URL into your aggregator of choice. If you don't know what this means and want to learn more, please see: <span>http://platial.typepad.com/news/2006/04/really_simple_t.html</span> for more info.</docs>
|
271
|
-
<channel rdf:about="<%= @base_url %>">
|
272
|
-
<link><%= @base_url %></link>
|
273
|
-
<title><%= @title %></title>
|
274
|
-
<description></description>
|
275
|
-
<items>
|
276
|
-
<rdf:Seq>
|
277
|
-
<% for feature in @features -%>
|
278
|
-
<rdf:li resource="<%= @item_url %>/<%= feature.id %>"/>
|
279
|
-
<% end -%>
|
280
|
-
</rdf:Seq>
|
281
|
-
</items>
|
282
|
-
</channel>
|
283
|
-
<% ts=Time.now.rfc2822 -%>
|
284
|
-
<% for feature in @features -%>
|
285
|
-
<item rdf:about="<%= @item_url %>/<%= feature.id %>">
|
286
|
-
<!--<link><%= @item_url %>/<%= feature.id %></link>-->
|
287
|
-
<title><%= @title %></title>
|
288
|
-
<description><![CDATA[<%= feature.text %>]]></description>
|
289
|
-
<georss:point><%= feature.y %> <%= feature.x %></georss:point>
|
290
|
-
<dc:creator>map-layers</dc:creator>
|
291
|
-
<dc:date><%= ts %></dc:date>
|
292
|
-
</item>
|
293
|
-
<% end -%>
|
294
|
-
</rdf:RDF>
|
295
|
-
EOS
|
296
|
-
|
297
|
-
GEORSS_EMPTY_RESPONSE = <<EOS # :nodoc:
|
298
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
299
|
-
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
300
|
-
xmlns="http://purl.org/rss/1.0/">
|
301
|
-
<docs></docs>
|
302
|
-
<channel rdf:about="http://purl.org/rss/1.0/">
|
303
|
-
<link>http://purl.org/rss/1.0/</link>
|
304
|
-
<title>Empty GeoRSS</title>
|
305
|
-
<description></description>
|
306
|
-
<items>
|
307
|
-
<rdf:Seq>
|
308
|
-
</rdf:Seq>
|
309
|
-
</items>
|
310
|
-
</channel>
|
311
|
-
</rdf:RDF>
|
312
|
-
EOS
|
313
|
-
|
314
|
-
end
|
315
|
-
|
316
|
-
# Remote http Proxy
|
317
|
-
module Proxy
|
318
|
-
|
319
|
-
# Register an url, before the proxy is called
|
320
|
-
def register_remote_url(url)
|
321
|
-
session[:proxy_url] ||= []
|
322
|
-
session[:proxy_url] << url
|
323
|
-
end
|
324
|
-
|
325
|
-
# Proxy for accessing remote files like GeoRSS, which is not allowed directly from the browser
|
326
|
-
def proxy
|
327
|
-
if session[:proxy_url].nil? || !session[:proxy_url].include?(params["url"])
|
328
|
-
logger.warn "Proxy request not in session: #{params["url"]}"
|
329
|
-
render :nothing => true
|
330
|
-
return
|
331
|
-
end
|
332
|
-
|
333
|
-
url = URI.parse(URI.encode(params[:url]))
|
334
|
-
logger.debug "Proxy request for #{url.scheme}://#{url.host}#{url.path}"
|
335
|
-
|
336
|
-
result = Net::HTTP.get_response(url)
|
337
|
-
render :text => result.body, :status => result.code, :content_type => "text/xml"
|
338
|
-
end
|
339
|
-
end
|
340
|
-
|
341
|
-
# Restful feture Server methods (http://featureserver.org/)
|
342
|
-
module Rest
|
343
|
-
|
344
|
-
def index
|
345
|
-
respond_to do |format|
|
346
|
-
format.xml { wfs }
|
347
|
-
format.kml { kml }
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
end
|
352
47
|
|
353
48
|
end
|
354
|
-
|
355
|
-
require 'map_layers/version'
|
356
|
-
require 'map_layers/js_wrapper'
|
357
|
-
require 'map_layers/open_layers'
|
358
|
-
require 'map_layers/map'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module MapLayers
|
2
|
+
|
3
|
+
class Config
|
4
|
+
attr_reader :model_id, :id, :lat, :lon, :geometry, :text
|
5
|
+
|
6
|
+
def initialize(model_id, options)
|
7
|
+
@model_id = model_id.to_s.pluralize.singularize
|
8
|
+
@id = options[:id] || :id
|
9
|
+
@lat = options[:lat] || :lat
|
10
|
+
@lon = options[:lon] || :lng
|
11
|
+
@geometry = options[:geometry]
|
12
|
+
@text = options[:text] || :name
|
13
|
+
end
|
14
|
+
|
15
|
+
def model
|
16
|
+
@model ||= @model_id.to_s.camelize.constantize
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module MapLayers
|
2
|
+
|
3
|
+
# GeoRSS Server methods
|
4
|
+
# http://www.georss.org/1
|
5
|
+
module GeoRSS
|
6
|
+
|
7
|
+
# Publish layer in GeoRSS format
|
8
|
+
def georss
|
9
|
+
rows = map_layers_config.model.find(:all, :limit => GEORSS_FEATURE_LIMIT)
|
10
|
+
@features = rows.collect do |row|
|
11
|
+
if map_layers_config.geometry
|
12
|
+
Feature.from_geom(row.send(map_layers_config.text), row.send(map_layers_config.geometry), row.send(map_layers_config.id))
|
13
|
+
else
|
14
|
+
Feature.new(row.send(map_layers_config.text), row.send(map_layers_config.lon), row.send(map_layers_config.lat))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@base_url = "http://#{request.env["HTTP_HOST"]}/"
|
18
|
+
@item_url = "#{@base_url}#{map_layers_config.model_id.to_s.pluralize}"
|
19
|
+
@title = map_layers_config.model_id.to_s.pluralize.humanize
|
20
|
+
logger.info "MapLayers::GEORSS: returning #{@features.size} features"
|
21
|
+
render :inline => GEORSS_XML_ERB, :content_type => "text/xml"
|
22
|
+
rescue Exception => e
|
23
|
+
logger.error "MapLayers::GEORSS: returning no features - Caught exception '#{e}'"
|
24
|
+
render :text => GEORSS_EMPTY_RESPONSE, :content_type => "text/xml"
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
GEORSS_FEATURE_LIMIT = 1000
|
30
|
+
|
31
|
+
GEORSS_XML_ERB = <<EOS # :nodoc:
|
32
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
33
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
34
|
+
xmlns="http://purl.org/rss/1.0/"
|
35
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
36
|
+
xmlns:georss="http://www.georss.org/georss">
|
37
|
+
<docs>This is an RSS file. Copy the URL into your aggregator of choice. If you don't know what this means and want to learn more, please see: <span>http://platial.typepad.com/news/2006/04/really_simple_t.html</span> for more info.</docs>
|
38
|
+
<channel rdf:about="<%= @base_url %>">
|
39
|
+
<link><%= @base_url %></link>
|
40
|
+
<title><%= @title %></title>
|
41
|
+
<description></description>
|
42
|
+
<items>
|
43
|
+
<rdf:Seq>
|
44
|
+
<% for feature in @features -%>
|
45
|
+
<rdf:li resource="<%= @item_url %>/<%= feature.id %>"/>
|
46
|
+
<% end -%>
|
47
|
+
</rdf:Seq>
|
48
|
+
</items>
|
49
|
+
</channel>
|
50
|
+
<% ts=Time.now.rfc2822 -%>
|
51
|
+
<% for feature in @features -%>
|
52
|
+
<item rdf:about="<%= @item_url %>/<%= feature.id %>">
|
53
|
+
<!--<link><%= @item_url %>/<%= feature.id %></link>-->
|
54
|
+
<title><%= @title %></title>
|
55
|
+
<description><![CDATA[<%= feature.text %>]]></description>
|
56
|
+
<georss:point><%= feature.y %> <%= feature.x %></georss:point>
|
57
|
+
<dc:creator>map-layers</dc:creator>
|
58
|
+
<dc:date><%= ts %></dc:date>
|
59
|
+
</item>
|
60
|
+
<% end -%>
|
61
|
+
</rdf:RDF>
|
62
|
+
EOS
|
63
|
+
|
64
|
+
|
65
|
+
GEORSS_EMPTY_RESPONSE = <<EOS # :nodoc:
|
66
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
67
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
68
|
+
xmlns="http://purl.org/rss/1.0/">
|
69
|
+
<docs></docs>
|
70
|
+
<channel rdf:about="http://purl.org/rss/1.0/">
|
71
|
+
<link>http://purl.org/rss/1.0/</link>
|
72
|
+
<title>Empty GeoRSS</title>
|
73
|
+
<description></description>
|
74
|
+
<items>
|
75
|
+
<rdf:Seq>
|
76
|
+
</rdf:Seq>
|
77
|
+
</items>
|
78
|
+
</channel>
|
79
|
+
</rdf:RDF>
|
80
|
+
EOS
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
# Remote http Proxy
|
85
|
+
module Proxy
|
86
|
+
|
87
|
+
# Register an url, before the proxy is called
|
88
|
+
def register_remote_url(url)
|
89
|
+
session[:proxy_url] ||= []
|
90
|
+
session[:proxy_url] << url
|
91
|
+
end
|
92
|
+
|
93
|
+
# Proxy for accessing remote files like GeoRSS, which is not allowed directly from the browser
|
94
|
+
def proxy
|
95
|
+
if session[:proxy_url].nil? || !session[:proxy_url].include?(params["url"])
|
96
|
+
logger.warn "Proxy request not in session: #{params["url"]}"
|
97
|
+
render :nothing => true
|
98
|
+
return
|
99
|
+
end
|
100
|
+
|
101
|
+
url = URI.parse(URI.encode(params[:url]))
|
102
|
+
logger.debug "Proxy request for #{url.scheme}://#{url.host}#{url.path}"
|
103
|
+
|
104
|
+
result = Net::HTTP.get_response(url)
|
105
|
+
render :text => result.body, :status => result.code, :content_type => "text/xml"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Restful feture Server methods (http://featureserver.org/)
|
110
|
+
module Rest
|
111
|
+
|
112
|
+
def index
|
113
|
+
respond_to do |format|
|
114
|
+
format.xml { wfs }
|
115
|
+
format.kml { kml }
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module MapLayers
|
2
|
+
|
3
|
+
# KML Server methods
|
4
|
+
module KML
|
5
|
+
|
6
|
+
# Publish layer in KML format
|
7
|
+
def kml
|
8
|
+
rows = map_layers_config.model.find(:all, :limit => KML_FEATURE_LIMIT)
|
9
|
+
@features = rows.collect do |row|
|
10
|
+
if map_layers_config.geometry
|
11
|
+
Feature.from_geom(row.send(map_layers_config.text), row.send(map_layers_config.geometry))
|
12
|
+
else
|
13
|
+
Feature.new(row.send(map_layers_config.text), row.send(map_layers_config.lon), row.send(map_layers_config.lat))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
@folder_name = map_layers_config.model_id.to_s.pluralize.humanize
|
17
|
+
logger.info "MapLayers::KML: returning #{@features.size} features"
|
18
|
+
render :inline => KML_XML_ERB, :content_type => "text/xml"
|
19
|
+
rescue Exception => e
|
20
|
+
logger.error "MapLayers::KML: returning no features - Caught exception '#{e}'"
|
21
|
+
render :text => KML_EMPTY_RESPONSE, :content_type => "text/xml"
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
KML_FEATURE_LIMIT = 1000
|
27
|
+
|
28
|
+
KML_XML_ERB = <<EOS # :nodoc:
|
29
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
30
|
+
<kml xmlns="http://earth.google.com/kml/2.0">
|
31
|
+
<Document>
|
32
|
+
<Folder><name><%= @folder_name %></name>
|
33
|
+
<% for feature in @features -%>
|
34
|
+
<Placemark>
|
35
|
+
<description><%= feature.text %></description>
|
36
|
+
<Point><coordinates><%= feature.x %>,<%= feature.y %></coordinates></Point>
|
37
|
+
</Placemark>
|
38
|
+
<% end -%>
|
39
|
+
</Folder>
|
40
|
+
</Document>
|
41
|
+
</kml>
|
42
|
+
EOS
|
43
|
+
|
44
|
+
KML_EMPTY_RESPONSE = <<EOS # :nodoc:
|
45
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
46
|
+
<kml xmlns="http://earth.google.com/kml/2.0">
|
47
|
+
<Document>
|
48
|
+
</Document>
|
49
|
+
</kml>
|
50
|
+
EOS
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'map_layers'
|
4
|
+
require 'map_layers/view_helpers'
|
5
|
+
|
6
|
+
module MapLayers
|
7
|
+
# Rails 3 initialization
|
8
|
+
if defined? Rails::Railtie
|
9
|
+
require 'rails'
|
10
|
+
class Railtie < Rails::Railtie
|
11
|
+
initializer 'map_layers.initialize' do
|
12
|
+
MapLayers::Railtie.insert
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
class Railtie
|
19
|
+
def self.insert
|
20
|
+
ActionController::Base.send(:include, MapLayers)
|
21
|
+
ActionView::Base.send(:include, MapLayers)
|
22
|
+
ActionView::Base.send(:include, MapLayers::ViewHelpers)
|
23
|
+
Mime::Type.register "application/vnd.google-earth.kml+xml", :kml
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/lib/map_layers/version.rb
CHANGED
@@ -0,0 +1,104 @@
|
|
1
|
+
module MapLayers
|
2
|
+
|
3
|
+
# WFS Server methods
|
4
|
+
module WFS
|
5
|
+
|
6
|
+
WGS84 = 4326
|
7
|
+
|
8
|
+
# Publish layer in WFS format
|
9
|
+
def wfs
|
10
|
+
minx, miny, maxx, maxy = extract_params
|
11
|
+
model = map_layers_config.model
|
12
|
+
if map_layers_config.geometry
|
13
|
+
db_srid = model.columns_hash[map_layers_config.geometry.to_s].srid
|
14
|
+
if db_srid != @srid && !db_srid.nil? && db_srid != -1
|
15
|
+
#Transform geometry from db_srid to requested srid (not possible for undefined db_srid)
|
16
|
+
geom = "Transform(#{geom},#{@srid}) AS #{geom}"
|
17
|
+
end
|
18
|
+
|
19
|
+
spatial_cond = if model.respond_to?(:sanitize_sql_hash_for_conditions)
|
20
|
+
model.sanitize_sql_hash_for_conditions(map_layers_config.geometry => [[minx, miny],[maxx, maxy], db_srid])
|
21
|
+
else # Rails < 2
|
22
|
+
model.sanitize_sql_hash(map_layers_config.geometry => [[minx, miny],[maxx, maxy], db_srid])
|
23
|
+
end
|
24
|
+
#spatial_cond = "Transform(#{spatial_cond}, #{db_srid}) )" Not necessary: bbox is always WGS84 !?
|
25
|
+
|
26
|
+
rows = model.find(:all, :conditions => spatial_cond, :limit => @maxfeatures)
|
27
|
+
@features = rows.collect do |row|
|
28
|
+
Feature.from_geom(row.send(map_layers_config.text), row.send(map_layers_config.geometry.to_s))
|
29
|
+
end
|
30
|
+
else
|
31
|
+
rows = model.find(:all, :limit => @maxfeatures)
|
32
|
+
@features = rows.collect do |row|
|
33
|
+
Feature.new(row.send(map_layers_config.text), row.send(map_layers_config.lon), row.send(map_layers_config.lat))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
logger.info "MapLayers::WFS: returning #{@features.size} features"
|
37
|
+
render :inline => WFS_XML_ERB, :content_type => "text/xml"
|
38
|
+
rescue Exception => e
|
39
|
+
logger.error "MapLayers::WFS: returning no features - Caught exception '#{e}'"
|
40
|
+
render :text => WFS_EMPTY_RESPONSE, :content_type => "text/xml"
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
WFS_FEATURE_LIMIT = 1000
|
46
|
+
|
47
|
+
def extract_params # :nodoc:
|
48
|
+
@maxfeatures = (params[:maxfeatures] || WFS_FEATURE_LIMIT).to_i
|
49
|
+
@srid = params['SRS'].split(/:/)[1].to_i rescue WGS84
|
50
|
+
req_bbox = params['BBOX'].split(/,/).collect {|n| n.to_f } rescue nil
|
51
|
+
@bbox = req_bbox || [-180.0, -90.0, 180.0, 90.0]
|
52
|
+
end
|
53
|
+
|
54
|
+
WFS_XML_ERB = <<EOS # :nodoc:
|
55
|
+
<?xml version='1.0' encoding="UTF-8" ?>
|
56
|
+
<wfs:FeatureCollection
|
57
|
+
xmlns:ms="http://mapserver.gis.umn.edu/mapserver"
|
58
|
+
xmlns:wfs="http://www.opengis.net/wfs"
|
59
|
+
xmlns:gml="http://www.opengis.net/gml"
|
60
|
+
xmlns:ogc="http://www.opengis.net/ogc"
|
61
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
62
|
+
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengeospatial.net/wfs/1.0.0/WFS-basic.xsd
|
63
|
+
http://mapserver.gis.umn.edu/mapserver http://www.geopole.org/map/wfs?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAME=geopole&OUTPUTFORMAT=XMLSCHEMA">
|
64
|
+
<gml:boundedBy>
|
65
|
+
<gml:Box srsName="EPSG:<%= @srid %>">
|
66
|
+
<gml:coordinates><%= @bbox[0] %>,<%= @bbox[1] %> <%= @bbox[2] %>,<%= @bbox[3] %></gml:coordinates>
|
67
|
+
</gml:Box>
|
68
|
+
</gml:boundedBy>
|
69
|
+
<% for feature in @features -%>
|
70
|
+
<gml:featureMember>
|
71
|
+
<ms:geopole>
|
72
|
+
<gml:boundedBy>
|
73
|
+
<gml:Box srsName="EPSG:<%= @srid %>">
|
74
|
+
<gml:coordinates><%= feature.x %>,<%= feature.y %> <%= feature.x %>,<%= feature.y %></gml:coordinates>
|
75
|
+
</gml:Box>
|
76
|
+
</gml:boundedBy>
|
77
|
+
<ms:msGeometry>
|
78
|
+
<gml:Point srsName="EPSG:<%= @srid %>">
|
79
|
+
<gml:coordinates><%= feature.x %>,<%= feature.y %></gml:coordinates>
|
80
|
+
</gml:Point>
|
81
|
+
</ms:msGeometry>
|
82
|
+
<ms:text><%= feature.text %></ms:text>
|
83
|
+
</ms:geopole>
|
84
|
+
</gml:featureMember>
|
85
|
+
<% end -%>
|
86
|
+
</wfs:FeatureCollection>
|
87
|
+
EOS
|
88
|
+
|
89
|
+
WFS_EMPTY_RESPONSE = <<EOS # :nodoc:
|
90
|
+
<?xml version='1.0' encoding="UTF-8" ?>
|
91
|
+
<wfs:FeatureCollection
|
92
|
+
xmlns:wfs="http://www.opengis.net/wfs"
|
93
|
+
xmlns:gml="http://www.opengis.net/gml"
|
94
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
95
|
+
xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengeospatial.net/wfs/1.0.0/WFS-basic.xsd">
|
96
|
+
<gml:boundedBy>
|
97
|
+
<gml:null>missing</gml:null>
|
98
|
+
</gml:boundedBy>
|
99
|
+
</wfs:FeatureCollection>
|
100
|
+
EOS
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
data/map_layers.gemspec
CHANGED
@@ -6,8 +6,8 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "map_layers"
|
7
7
|
s.version = MapLayers::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = ["Luc Donnet", "Alban Peignier"]
|
10
|
-
s.email = ["luc.donnet@
|
9
|
+
s.authors = ["Luc Donnet", "Alban Peignier", "Pirmin Kalberer"]
|
10
|
+
s.email = ["luc.donnet@free.fr", "alban.peignier@free.fr", "pka@sourcepole.ch"]
|
11
11
|
s.homepage = "http://github.com/ldonnet/map_layers"
|
12
12
|
s.summary = %q{library dedicated to generate OSM javascript}
|
13
13
|
s.description = %q{library dedicated to generate OSM javascript}
|
@@ -19,10 +19,10 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
if ENV['
|
23
|
-
s.add_development_dependency(%q<rails>, ["~>
|
22
|
+
if ENV['RAILS_3']
|
23
|
+
s.add_development_dependency(%q<rails>, ["~> 3.0.0"])
|
24
24
|
else
|
25
|
-
s.add_development_dependency(%q<rails>, [">= 3.
|
25
|
+
s.add_development_dependency(%q<rails>, [">= 2.3.8"])
|
26
26
|
end
|
27
27
|
s.add_development_dependency(%q<rspec>, ["~> 2.0.0"])
|
28
28
|
s.add_development_dependency(%q<rspec-rails>, ["~> 2.0.0"])
|
metadata
CHANGED
@@ -1,42 +1,45 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: map_layers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 4
|
10
|
+
version: 0.0.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Luc Donnet
|
14
14
|
- Alban Peignier
|
15
|
+
- Pirmin Kalberer
|
15
16
|
autorequire:
|
16
17
|
bindir: bin
|
17
18
|
cert_chain: []
|
18
19
|
|
19
|
-
date: 2011-
|
20
|
+
date: 2011-09-30 00:00:00 +02:00
|
20
21
|
default_executable:
|
21
22
|
dependencies:
|
22
23
|
- !ruby/object:Gem::Dependency
|
23
|
-
|
24
|
+
name: rails
|
25
|
+
prerelease: false
|
26
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
27
|
none: false
|
25
28
|
requirements:
|
26
29
|
- - ">="
|
27
30
|
- !ruby/object:Gem::Version
|
28
|
-
hash:
|
31
|
+
hash: 19
|
29
32
|
segments:
|
33
|
+
- 2
|
30
34
|
- 3
|
31
|
-
-
|
32
|
-
|
33
|
-
version: 3.0.0
|
34
|
-
requirement: *id001
|
35
|
+
- 8
|
36
|
+
version: 2.3.8
|
35
37
|
type: :development
|
36
|
-
|
37
|
-
prerelease: false
|
38
|
+
version_requirements: *id001
|
38
39
|
- !ruby/object:Gem::Dependency
|
39
|
-
|
40
|
+
name: rspec
|
41
|
+
prerelease: false
|
42
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
43
|
none: false
|
41
44
|
requirements:
|
42
45
|
- - ~>
|
@@ -47,12 +50,12 @@ dependencies:
|
|
47
50
|
- 0
|
48
51
|
- 0
|
49
52
|
version: 2.0.0
|
50
|
-
requirement: *id002
|
51
53
|
type: :development
|
52
|
-
|
53
|
-
prerelease: false
|
54
|
+
version_requirements: *id002
|
54
55
|
- !ruby/object:Gem::Dependency
|
55
|
-
|
56
|
+
name: rspec-rails
|
57
|
+
prerelease: false
|
58
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
59
|
none: false
|
57
60
|
requirements:
|
58
61
|
- - ~>
|
@@ -63,12 +66,12 @@ dependencies:
|
|
63
66
|
- 0
|
64
67
|
- 0
|
65
68
|
version: 2.0.0
|
66
|
-
requirement: *id003
|
67
69
|
type: :development
|
68
|
-
|
69
|
-
prerelease: false
|
70
|
+
version_requirements: *id003
|
70
71
|
- !ruby/object:Gem::Dependency
|
71
|
-
|
72
|
+
name: rake
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
72
75
|
none: false
|
73
76
|
requirements:
|
74
77
|
- - ">="
|
@@ -77,12 +80,12 @@ dependencies:
|
|
77
80
|
segments:
|
78
81
|
- 0
|
79
82
|
version: "0"
|
80
|
-
requirement: *id004
|
81
83
|
type: :development
|
82
|
-
|
83
|
-
prerelease: false
|
84
|
+
version_requirements: *id004
|
84
85
|
- !ruby/object:Gem::Dependency
|
85
|
-
|
86
|
+
name: autotest-rails
|
87
|
+
prerelease: false
|
88
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
86
89
|
none: false
|
87
90
|
requirements:
|
88
91
|
- - ">="
|
@@ -91,12 +94,12 @@ dependencies:
|
|
91
94
|
segments:
|
92
95
|
- 0
|
93
96
|
version: "0"
|
94
|
-
requirement: *id005
|
95
97
|
type: :development
|
96
|
-
|
97
|
-
prerelease: false
|
98
|
+
version_requirements: *id005
|
98
99
|
- !ruby/object:Gem::Dependency
|
99
|
-
|
100
|
+
name: autotest-notification
|
101
|
+
prerelease: false
|
102
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
100
103
|
none: false
|
101
104
|
requirements:
|
102
105
|
- - ">="
|
@@ -105,14 +108,13 @@ dependencies:
|
|
105
108
|
segments:
|
106
109
|
- 0
|
107
110
|
version: "0"
|
108
|
-
requirement: *id006
|
109
111
|
type: :development
|
110
|
-
|
111
|
-
prerelease: false
|
112
|
+
version_requirements: *id006
|
112
113
|
description: library dedicated to generate OSM javascript
|
113
114
|
email:
|
114
|
-
- luc.donnet@
|
115
|
-
- alban.peignier@
|
115
|
+
- luc.donnet@free.fr
|
116
|
+
- alban.peignier@free.fr
|
117
|
+
- pka@sourcepole.ch
|
116
118
|
executables: []
|
117
119
|
|
118
120
|
extensions: []
|
@@ -126,19 +128,24 @@ files:
|
|
126
128
|
- Gemfile
|
127
129
|
- Gemfile.lock
|
128
130
|
- MIT-LICENSE
|
129
|
-
- README
|
131
|
+
- README.md
|
130
132
|
- Rakefile
|
131
133
|
- autotest/discover.rb
|
132
134
|
- init.rb
|
133
135
|
- install.rb
|
134
136
|
- lib/map_layers.rb
|
135
|
-
- lib/map_layers
|
137
|
+
- lib/map_layers/config.rb
|
138
|
+
- lib/map_layers/feature.rb
|
136
139
|
- lib/map_layers/geonames.rb
|
140
|
+
- lib/map_layers/georss.rb
|
137
141
|
- lib/map_layers/js_wrapper.rb
|
142
|
+
- lib/map_layers/kml.rb
|
138
143
|
- lib/map_layers/map.rb
|
139
144
|
- lib/map_layers/open_layers.rb
|
145
|
+
- lib/map_layers/railtie.rb
|
140
146
|
- lib/map_layers/version.rb
|
141
147
|
- lib/map_layers/view_helpers.rb
|
148
|
+
- lib/map_layers/wfs.rb
|
142
149
|
- map_layers.gemspec
|
143
150
|
- rails/init.rb
|
144
151
|
- spec/lib/map_layers/js_wrapper_spec.rb
|
@@ -1,66 +0,0 @@
|
|
1
|
-
rere# GeoNames REST services
|
2
|
-
#
|
3
|
-
# http://www.geonames.org/export/web-services.html
|
4
|
-
#
|
5
|
-
module Geonames
|
6
|
-
|
7
|
-
module JsonFormat # :nodoc:
|
8
|
-
extend self
|
9
|
-
|
10
|
-
def extension
|
11
|
-
"json"
|
12
|
-
end
|
13
|
-
|
14
|
-
def mime_type
|
15
|
-
"application/json"
|
16
|
-
end
|
17
|
-
|
18
|
-
def encode(hash)
|
19
|
-
hash.to_json
|
20
|
-
end
|
21
|
-
|
22
|
-
def decode(json)
|
23
|
-
h = ActiveSupport::JSON.decode(json)
|
24
|
-
h.values.flatten # Return type must be an array of hashes
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# GeoNames REST services base class
|
29
|
-
class GeonamesResource < ActiveResource::Base
|
30
|
-
self.site = "http://ws.geonames.org/"
|
31
|
-
self.format = JsonFormat
|
32
|
-
end
|
33
|
-
|
34
|
-
# GeoNames Postalode REST services
|
35
|
-
class Postalcode < GeonamesResource
|
36
|
-
# Postal code search
|
37
|
-
#
|
38
|
-
# http://www.geonames.org/export/web-services.html#postalCodeSearch
|
39
|
-
#
|
40
|
-
def self.search(placename, options = {:maxRows => 50})
|
41
|
-
self.find(:all, :from => "/postalCodeSearchJSON", :params => { :placename => placename }.merge(options))
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# GeoNames Weather REST services
|
46
|
-
class Weather < GeonamesResource
|
47
|
-
# Weather stations with the most recent weather observation
|
48
|
-
#
|
49
|
-
# Example: Geonames::Weather.weather(:north => 44.1, :south => -9.9, :east => -22.4, :west => 55.2)
|
50
|
-
#
|
51
|
-
# http://www.geonames.org/export/JSON-webservices.html#weatherJSON
|
52
|
-
#
|
53
|
-
def self.weather(options)
|
54
|
-
self.find(:all, :from => "/weatherJSON", :params => options)
|
55
|
-
end
|
56
|
-
|
57
|
-
# Weather station and the most recent weather observation for the ICAO code
|
58
|
-
#
|
59
|
-
# http://www.geonames.org/export/JSON-webservices.html#weatherIcaoJSON
|
60
|
-
#
|
61
|
-
def self.weatherIcao(icao, options = {})
|
62
|
-
self.find(:all, :from => "/weatherIcaoJSON", :params => { :ICAO => icao }.merge(options))
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|