sinatra_wms 0.0.2 → 0.1.0
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/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: []
|