sinatra_wms 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -2
- data/Rakefile +5 -0
- data/lib/sinatra_wms/rmagick_extension.rb +21 -29
- data/lib/sinatra_wms/version.rb +2 -1
- data/lib/sinatra_wms.rb +22 -4
- data/sinatra_wms.gemspec +3 -1
- data/spec/sinatra_wms_spec.rb +37 -0
- data/spec/spec_helper.rb +6 -0
- metadata +21 -3
data/README.rdoc
CHANGED
@@ -11,7 +11,7 @@ Another way would be to use a Google Map or something and use a JavaScript to ad
|
|
11
11
|
You could zoom in and out an such - but you'd have to care about getting your data to JavaScript to add the markers. And it won't be that fast once you reach some kind of limit.
|
12
12
|
|
13
13
|
The solution for this problem: WMS (Web Map Service).
|
14
|
-
This gem helps you to provide a WMS to be used with OpenLayers. OpenLayers will display
|
14
|
+
This gem helps you to provide a WMS to be used with OpenLayers. OpenLayers will display a baselayer (OpenStreetMap or Google Maps) at a configurable Opacity and add your data on top of it. Whenever you scroll or zoom around the map, OpenLayers will request images of a part of the visible screen. Your code has to generate them on-the-fly and deliver them back.
|
15
15
|
|
16
16
|
|
17
17
|
== How do I use SinatraWMS?
|
@@ -50,8 +50,11 @@ In my example, I will use SinatraWMS to display the locations of my geolocated t
|
|
50
50
|
# This is the main entry point for this app.
|
51
51
|
# This code just outputs generic HTML code to load OpenLayers, show the OSM
|
52
52
|
# as transparent background and our WMS stuff on top of that.
|
53
|
+
# +:baselayer+ defined which source is used as a map underneath your data.
|
54
|
+
# You could replace +:osm+ by e.g. +:google_streets+ to show Google's street
|
55
|
+
# maps.
|
53
56
|
get '/' do
|
54
|
-
SinatraWMS::get_html_for_map_at url("/wms"), :opacity=>0.3, :title=>"My Tweets"
|
57
|
+
SinatraWMS::get_html_for_map_at url("/wms"), :opacity=>0.3, :title=>"My Tweets", :baselayer=>:osm
|
55
58
|
end
|
56
59
|
|
57
60
|
# This code gets run for every image requested by OpenLayers. It is given a
|
data/Rakefile
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
require 'rdoc/task'
|
2
2
|
require 'bundler/gem_tasks'
|
3
|
+
require 'rspec/core/rake_task'
|
3
4
|
|
4
5
|
RDoc::Task.new do |r|
|
5
6
|
r.main = "README.rdoc"
|
6
7
|
r.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
7
8
|
end
|
9
|
+
|
10
|
+
RSpec::Core::RakeTask.new('spec')
|
11
|
+
|
12
|
+
task :default=>:spec
|
@@ -4,29 +4,28 @@ require 'RMagick'
|
|
4
4
|
# Monkeypatching RMagick to add some methods to +Magick::Draw+.
|
5
5
|
module Magick
|
6
6
|
class Draw
|
7
|
-
##
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
## Wrapper for +color+, but with coordinates given in WGS84.
|
8
|
+
def color_wgs84(x, y, *args); args.unshift(* latlon_to_pixels(x, y)); color(*args); end
|
9
|
+
## Wrapper for +point+, but with coordinates given in WGS84.
|
10
|
+
def point_wgs84(x, y, *args); args.unshift(* latlon_to_pixels(x, y)); point(*args); end
|
11
|
+
## Wrapper for +matte+, but with coordinates given in WGS84.
|
12
|
+
def matte_wgs84(x, y, *args); args.unshift(* latlon_to_pixels(x, y)); matte(*args); end
|
13
|
+
## Wrapper for +text+, but with coordinates given in WGS84.
|
14
|
+
def text_wgs84(x, y, *args); args.unshift(* latlon_to_pixels(x, y)); text(*args); end
|
15
|
+
## Wrapper for +bigpoint+, but with coordinates given in WGS84.
|
16
|
+
def bigpoint_wgs84(x, y, *args); args.unshift(* latlon_to_pixels(x, y)); bigpoint(*args); end
|
17
|
+
## Wrapper for +ellipse+, but with coordinates given in WGS84.
|
18
|
+
def ellipse_wgs84(x, y, *args); args.unshift(* latlon_to_pixels(x, y)); ellipse(*args); end
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
def
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
args[2], args[3] = latlon_to_pixels(args[2], args[3])
|
24
|
-
end
|
25
|
-
send(result[1], *args, &block)
|
26
|
-
else
|
27
|
-
super(sym, *args, &block)
|
28
|
-
end
|
29
|
-
end
|
20
|
+
|
21
|
+
## Wrapper for +circle+, but with coordinates given in WGS84.
|
22
|
+
def circle_wgs84 (x1, y1, x2, y2, *args); args.unshift(* latlon_to_pixels(x2, y2)).unshift(* latlon_to_pixels(x1, y1)); cirle(*args); end
|
23
|
+
## Wrapper for +line+, but with coordinates given in WGS84.
|
24
|
+
def line_wgs84 (x1, y1, x2, y2, *args); args.unshift(* latlon_to_pixels(x2, y2)).unshift(* latlon_to_pixels(x1, y1)); line(*args); end
|
25
|
+
## Wrapper for +rectangle+, but with coordinates given in WGS84.
|
26
|
+
def rectangle_wgs84 (x1, y1, x2, y2, *args); args.unshift(* latlon_to_pixels(x2, y2)).unshift(* latlon_to_pixels(x1, y1)); rectangle(*args); end
|
27
|
+
## Wrapper for +roundrectangle+, but with coordinates given in WGS84.
|
28
|
+
def roundrectangle_wgs84 (x1, y1, x2, y2, *args); args.unshift(* latlon_to_pixels(x2, y2)).unshift(* latlon_to_pixels(x1, y1)); roundrectangle(*args); end
|
30
29
|
|
31
30
|
##
|
32
31
|
# This method gets the data from +SinatraExtension+ and does some calculations
|
@@ -45,13 +44,6 @@ module Magick
|
|
45
44
|
rectangle(x-1, y-1, x+1, y+1)
|
46
45
|
end
|
47
46
|
|
48
|
-
##
|
49
|
-
# See +method_missing+
|
50
|
-
def respond_to?(sym)
|
51
|
-
result = sym.to_s.match /^([a-z0-9_]+)_(?:wgs84)$/
|
52
|
-
(result && super(result[1]) && @wms_settings) || super(sym)
|
53
|
-
end
|
54
|
-
|
55
47
|
private
|
56
48
|
##
|
57
49
|
# Converts WGS84 coordinates to pixel values.
|
data/lib/sinatra_wms/version.rb
CHANGED
data/lib/sinatra_wms.rb
CHANGED
@@ -13,7 +13,7 @@ module SinatraWMS
|
|
13
13
|
end
|
14
14
|
|
15
15
|
##
|
16
|
-
# Returns generic HTML code to display a transparent OSM
|
16
|
+
# Returns generic HTML code to display a transparent basemap (OSM or Google Maps) and images from the WMS.
|
17
17
|
#
|
18
18
|
# * +url+ has to be the full URL to the WMS. Since this module can't use Sinatra's helper,
|
19
19
|
# please call it using this helper, e.g. +url("/wms")+.
|
@@ -21,15 +21,32 @@ module SinatraWMS
|
|
21
21
|
# * +:title+ - Sets the HTML title attribute.
|
22
22
|
# * +:opacity:+ - Sets the opacity of the OSM map in the background.
|
23
23
|
# * +:datasource_name+ - Sets the name of the WMS source in the layer selector menu.
|
24
|
+
# * +:baselayer+ - Which baselayer to use. Supported values are:
|
25
|
+
# * +:osm+ (default)
|
26
|
+
# * +:google_streets+
|
27
|
+
# * +:google_satellite+
|
28
|
+
# * +:google_hybrid+
|
29
|
+
# * +:google_terrain+
|
24
30
|
def self.get_html_for_map_at(url, options={})
|
25
31
|
options[:title] ||= "Sinatra-WMS"
|
26
32
|
options[:opacity] ||= 1
|
27
33
|
options[:datasource_name] ||= "WMS-Data"
|
34
|
+
options[:baselayer] ||= :osm
|
35
|
+
|
36
|
+
baselayer_definition = case options[:baselayer]
|
37
|
+
when :osm then "new OpenLayers.Layer.OSM()"
|
38
|
+
when :google_streets then 'new OpenLayers.Layer.Google("Google Streets")'
|
39
|
+
when :google_satellite then 'new OpenLayers.Layer.Google("Google Satellite", {type: google.maps.MapTypeId.SATELLITE})'
|
40
|
+
when :google_hybrid then 'new OpenLayers.Layer.Google("Google Hybrid", {type: google.maps.MapTypeId.HYBRID})'
|
41
|
+
when :google_terrain then 'new OpenLayers.Layer.Google("Google Terrain", {type: google.maps.MapTypeId.TERRAIN})'
|
42
|
+
else raise "Unknown value for baselayer: #{options[:baselayer]}"
|
43
|
+
end
|
28
44
|
|
29
45
|
%Q{
|
30
46
|
<html>
|
31
47
|
<head>
|
32
48
|
<title>#{options[:title]}</title>
|
49
|
+
#{options[:baselayer].to_s[0..6]=='google_' ? '<script src="http://maps.google.com/maps/api/js?v=3.2&sensor=false"></script>' : '' }
|
33
50
|
<script src="http://openlayers.org/api/OpenLayers.js"></script>
|
34
51
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
|
35
52
|
</head>
|
@@ -41,9 +58,10 @@ module SinatraWMS
|
|
41
58
|
var map = new OpenLayers.Map('map');
|
42
59
|
map.addControl(new OpenLayers.Control.LayerSwitcher());
|
43
60
|
|
44
|
-
var
|
45
|
-
|
46
|
-
|
61
|
+
var base_layer = #{baselayer_definition};
|
62
|
+
map.addLayer(base_layer);
|
63
|
+
base_layer.setOpacity(#{options[:opacity]});
|
64
|
+
|
47
65
|
|
48
66
|
var layer = new OpenLayers.Layer.WMS("#{options[:datasource_name]}", "#{url}", {transparent: true}, {maxExtent: imagebounds});
|
49
67
|
|
data/sinatra_wms.gemspec
CHANGED
@@ -10,12 +10,14 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.homepage = "http://github.com/fabianonline/sinatra_wms"
|
11
11
|
s.summary = "Extends Sinatra to allow the developer to easily build a WMS server"
|
12
12
|
s.description = %q(A WMS (Web Map Service) is a great way to show lots of geolocated data on a map. Instead of generating static images (which will either be huge or don't have enough resolution), a WMS allows you to dynamically zoom in and out of your dataset.
|
13
|
-
This gem allows you to very easily represent your data via a WMS. On one hand it extends Sinatra to give it a method called "wms" to process WMS-requests; on the other hand it extends RMagick to allow the developer to use coordinates in the methods used for drawing.
|
13
|
+
This gem allows you to very easily represent your data via a WMS. On one hand it extends Sinatra to give it a method called "wms" to process WMS-requests; on the other hand it extends RMagick to allow the developer to use coordinates in the methods used for drawing.
|
14
|
+
Convenient methods to easily generate HTML code to show your WMS data on top of OpenStreetMaps or Google Maps are also included.)
|
14
15
|
|
15
16
|
s.rubyforge_project = "sinatra_wms"
|
16
17
|
|
17
18
|
s.add_dependency('sinatra', '>=1.0.0')
|
18
19
|
s.add_dependency('rmagick')
|
20
|
+
s.add_development_dependency('rspec', '~> 2.9')
|
19
21
|
|
20
22
|
s.files = `git ls-files`.split("\n")
|
21
23
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'sinatra_wms'
|
3
|
+
|
4
|
+
describe SinatraWMS do
|
5
|
+
describe 'merc_to_latlon' do
|
6
|
+
it 'should work at the center of the coordinate system' do
|
7
|
+
SinatraWMS::merc_to_latlon(0, 0).should == [0.0, 0.0]
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should work for other coordinates' do
|
11
|
+
coords = SinatraWMS::merc_to_latlon(-626172.13571216376, 6887893.4928337997)
|
12
|
+
(coords[0]*100000000).round.should == 5248278022
|
13
|
+
(coords[1]*1000).round.should == -5625
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'get_html_for_map_at' do
|
18
|
+
it 'should include the correct URL' do
|
19
|
+
SinatraWMS::get_html_for_map_at('/test').should =~ /new OpenLayers.Layer.WMS\("[^"]+", "\/test"/
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'shouldn\'t load Google Maps unless necessary' do
|
23
|
+
SinatraWMS::get_html_for_map_at('/test').should_not =~ /maps.google.com\/maps\/api\/js/
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should load Google Maps when necessary' do
|
27
|
+
SinatraWMS::get_html_for_map_at('/test', :baselayer=>:google_streets).should =~ /maps.google.com\/maps\/api\/js/
|
28
|
+
SinatraWMS::get_html_for_map_at('/test', :baselayer=>:google_satellite).should =~ /maps.google.com\/maps\/api\/js/
|
29
|
+
SinatraWMS::get_html_for_map_at('/test', :baselayer=>:google_hybrid).should =~ /maps.google.com\/maps\/api\/js/
|
30
|
+
SinatraWMS::get_html_for_map_at('/test', :baselayer=>:google_terrain).should =~ /maps.google.com\/maps\/api\/js/
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should raise an error when an unknown baselayer is to be set' do
|
34
|
+
expect {SinatraWMS::get_html_for_map_at('/test', :baselayer=>:foo)}.to raise_error
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.2
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Fabian Schlenz (@fabianonline)
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-04-
|
18
|
+
date: 2012-04-24 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -48,9 +48,25 @@ dependencies:
|
|
48
48
|
version: "0"
|
49
49
|
type: :runtime
|
50
50
|
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: rspec
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 17
|
60
|
+
segments:
|
61
|
+
- 2
|
62
|
+
- 9
|
63
|
+
version: "2.9"
|
64
|
+
type: :development
|
65
|
+
version_requirements: *id003
|
51
66
|
description: |-
|
52
67
|
A WMS (Web Map Service) is a great way to show lots of geolocated data on a map. Instead of generating static images (which will either be huge or don't have enough resolution), a WMS allows you to dynamically zoom in and out of your dataset.
|
53
68
|
This gem allows you to very easily represent your data via a WMS. On one hand it extends Sinatra to give it a method called "wms" to process WMS-requests; on the other hand it extends RMagick to allow the developer to use coordinates in the methods used for drawing.
|
69
|
+
Convenient methods to easily generate HTML code to show your WMS data on top of OpenStreetMaps or Google Maps are also included.
|
54
70
|
email:
|
55
71
|
- mail@fabianonline.de
|
56
72
|
executables: []
|
@@ -69,6 +85,8 @@ files:
|
|
69
85
|
- lib/sinatra_wms/sinatra_extension.rb
|
70
86
|
- lib/sinatra_wms/version.rb
|
71
87
|
- sinatra_wms.gemspec
|
88
|
+
- spec/sinatra_wms_spec.rb
|
89
|
+
- spec/spec_helper.rb
|
72
90
|
has_rdoc: true
|
73
91
|
homepage: http://github.com/fabianonline/sinatra_wms
|
74
92
|
licenses: []
|