map_layers 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|