rgeoserver 0.5.5 → 0.5.6

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.
@@ -1,104 +1,99 @@
1
1
 
2
2
  module RGeoServer
3
+ # A style describes how a resource (feature type or coverage) should be symbolized or rendered by a Web Map Service. In GeoServer styles are specified with {SLD}[http://docr.geoserver.org/stable/en/user/styling/index.html#styling]
4
+ class Style < ResourceInfo
3
5
 
4
- class Style < ResourceInfo
6
+ OBJ_ATTRIBUTES = {:catalog => 'catalog', :name => 'name', :sld_version => 'sldVersion', :filename => 'filename', :sld_doc => 'sld_doc' }
7
+ OBJ_DEFAULT_ATTRIBUTES = {:catalog => nil, :name => nil, :sld_version => nil, :filename => '', :sld_doc => nil }
5
8
 
6
- OBJ_ATTRIBUTES = {:catalog => 'catalog', :name => 'name', :sld_version => 'sldVersion', :filename => 'filename', :sld_doc => 'sld_doc' }
7
- OBJ_DEFAULT_ATTRIBUTES = {:catalog => nil, :name => nil, :sld_version => nil, :filename => '', :sld_doc => nil }
9
+ define_attribute_methods OBJ_ATTRIBUTES.keys
10
+ update_attribute_accessors OBJ_ATTRIBUTES
8
11
 
9
- define_attribute_methods OBJ_ATTRIBUTES.keys
10
- update_attribute_accessors OBJ_ATTRIBUTES
12
+ @@route = "styles"
13
+ @@resource_name = "style"
14
+ @@sld_namespace = "http://www.opengis.net/sld"
11
15
 
12
- @@r = Confstruct::Configuration.new(:route => 'styles', :resource_name => 'style', :sld_namespace => 'http://www.opengis.net/sld')
13
-
14
- def self.resource_name
15
- @@r.resource_name
16
- end
16
+ def self.resource_name
17
+ @@resource_name
18
+ end
17
19
 
18
- def self.create_method
19
- :post
20
- end
20
+ def self.root_xpath
21
+ "//#{@@route}/#{@@resource_name}"
22
+ end
21
23
 
22
- def self.update_method
23
- :put
24
- end
25
-
26
- def self.root_xpath
27
- "//#{@@r.route}/#{@@r.resource_name}"
28
- end
24
+ def self.member_xpath
25
+ "//#{resource_name}"
26
+ end
29
27
 
30
- def self.member_xpath
31
- "//#{resource_name}"
32
- end
28
+ def route
29
+ @@route
30
+ end
31
+
32
+ def sld_namespace
33
+ @@sld_namespace
34
+ end
33
35
 
34
- def route
35
- @@r.route
36
- end
37
-
38
- def create_options
39
- {
40
- :headers => {
41
- :accept => :xml,
42
- :content_type=> "application/vnd.ogc.sld+xml"
43
- },
44
- :format => :xml,
45
- :name => @name
46
- }
47
- end
48
-
49
- def update_options
50
- {
51
- :headers => {
52
- :accept => :xml,
53
- :content_type=> "application/vnd.ogc.sld+xml"
54
- },
55
- :format => :sld
56
- }
57
- end
58
36
 
59
- def sld_namespace
60
- @@r.sld_namespace
61
- end
37
+ def create_options
38
+ {
39
+ :headers => {
40
+ :accept => :xml,
41
+ :content_type=> "application/vnd.ogc.sld+xml"
42
+ },
43
+ :format => :xml,
44
+ :name => @name
45
+ }
46
+ end
47
+
48
+ def update_options
49
+ {
50
+ :headers => {
51
+ :accept => :xml,
52
+ :content_type=> "application/vnd.ogc.sld+xml"
53
+ },
54
+ :format => :sld
55
+ }
56
+ end
62
57
 
63
- def message
64
- @sld_doc
65
- end
58
+ def message
59
+ @sld_doc
60
+ end
66
61
 
67
- # @param [RGeoServer::Catalog] catalog
68
- # @param [Hash] options
69
- def initialize catalog, options
70
- super({})
71
- _run_initialize_callbacks do
72
- @catalog = catalog
73
- @name = options[:name].strip
74
- end
75
- @route = route
76
- end
77
-
78
- # Obtain all layers that use this style.
79
- # WARNING: This will be slow and inneficient when the list of all layers is too long.
80
- def layers &block
81
- return to_enum(:layers).to_a unless block_given?
82
- @catalog.get_layers do |l|
83
- lyrs = [l.profile['default_style']]+l.profile['alternate_styles']
84
- yield l if lyrs.include? @name
85
- end
86
- end
62
+ # @param [RGeoServer::Catalog] catalog
63
+ # @param [Hash] options
64
+ def initialize catalog, options
65
+ super({})
66
+ _run_initialize_callbacks do
67
+ @catalog = catalog
68
+ @name = options[:name].strip
69
+ end
70
+ @route = route
71
+ end
87
72
 
88
- def profile_xml_to_hash profile_xml
89
- doc = profile_xml_to_ng profile_xml
90
- h = {
91
- 'name' => doc.at_xpath('//name').text.strip,
92
- 'sld_version' => doc.at_xpath('//sldVersion/version/text()').to_s,
93
- 'filename' => doc.at_xpath('//filename/text()').to_s,
94
- 'sld_doc' => begin
95
- Nokogiri::XML(@catalog.search({:styles => @name}, options={:format => 'sld'})).to_xml
96
- rescue RestClient::ResourceNotFound
97
- nil
98
- end
99
- }.freeze
100
- h
101
- end
102
-
73
+ # Obtain all layers that use this style.
74
+ # WARNING: This will be slow and inneficient when the list of all layers is too long.
75
+ def layers &block
76
+ return to_enum(:layers).to_a unless block_given?
77
+ @catalog.get_layers do |l|
78
+ lyrs = [l.profile['default_style']]+l.profile['alternate_styles']
79
+ yield l if lyrs.include? @name
80
+ end
103
81
  end
82
+
83
+ def profile_xml_to_hash profile_xml
84
+ doc = profile_xml_to_ng profile_xml
85
+ h = {
86
+ 'name' => doc.at_xpath('//name').text.strip,
87
+ 'sld_version' => doc.at_xpath('//sldVersion/version/text()').to_s,
88
+ 'filename' => doc.at_xpath('//filename/text()').to_s,
89
+ 'sld_doc' => begin
90
+ Nokogiri::XML(@catalog.search({:styles => @name}, options={:format => 'sld'})).to_xml
91
+ rescue RestClient::ResourceNotFound
92
+ nil
93
+ end
94
+ }.freeze
95
+ h
96
+ end
97
+
98
+ end
104
99
  end
@@ -5,26 +5,16 @@ module RGeoServer
5
5
 
6
6
  define_attribute_methods [:catalog, :workspace, :name]
7
7
 
8
- @@r = Confstruct::Configuration.new(
9
- :route => "workspaces/%s/wmsstores",
10
- :root => "wmsStores",
11
- :resource_name => "wmsStore"
12
- )
8
+ @@route = "workspaces/%s/wmsstores"
9
+ @@root = "wmsStores"
10
+ @@resource_name = "wmsStore"
13
11
 
14
12
  def self.root
15
- @@r.root
16
- end
17
-
18
- def self.create_method
19
- :put
20
- end
21
-
22
- def self.update_method
23
- :put
13
+ @@root
24
14
  end
25
15
 
26
16
  def self.resource_name
27
- @@r.resource_name
17
+ @@resource_name
28
18
  end
29
19
 
30
20
  def self.root_xpath
@@ -36,7 +26,7 @@ module RGeoServer
36
26
  end
37
27
 
38
28
  def route
39
- @@r.route % @workspace.name
29
+ @@route % @workspace.name
40
30
  end
41
31
 
42
32
  def xml options = nil
@@ -1,95 +1,88 @@
1
1
 
2
2
  module RGeoServer
3
+ # A workspace is a grouping of data stores. More commonly known as a namespace, it is commonly used to group data that is related in some way.
4
+ class Workspace < ResourceInfo
3
5
 
4
- class Workspace < ResourceInfo
6
+ OBJ_ATTRIBUTES = {:enabled => 'enabled', :catalog => 'catalog', :name => 'name' }
7
+ OBJ_DEFAULT_ATTRIBUTES = {:enabled => 'true', :catalog => nil, :name => nil }
5
8
 
6
- OBJ_ATTRIBUTES = {:enabled => 'enabled', :catalog => 'catalog', :name => 'name' }
7
- OBJ_DEFAULT_ATTRIBUTES = {:enabled => 'true', :catalog => nil, :name => nil }
9
+ define_attribute_methods OBJ_ATTRIBUTES.keys
10
+ update_attribute_accessors OBJ_ATTRIBUTES
8
11
 
9
- define_attribute_methods OBJ_ATTRIBUTES.keys
10
- update_attribute_accessors OBJ_ATTRIBUTES
12
+ @@route = "workspaces"
13
+ @@resource_name = "workspace"
11
14
 
12
- @@r = Confstruct::Configuration.new(:route => 'workspaces', :resource_name => 'workspace')
13
-
14
- def self.resource_name
15
- @@r.resource_name
16
- end
15
+ def self.resource_name
16
+ @@resource_name
17
+ end
17
18
 
18
- def self.create_method
19
- :post
20
- end
19
+ def self.root_xpath
20
+ "//#{@@route}/#{@@resource_name}"
21
+ end
21
22
 
22
- def self.update_method
23
- :put
24
- end
25
-
26
- def self.root_xpath
27
- "//#{@@r.route}/#{@@r.resource_name}"
28
- end
23
+ def self.member_xpath
24
+ "//#{resource_name}"
25
+ end
29
26
 
30
- def self.member_xpath
31
- "//#{resource_name}"
32
- end
27
+ def route
28
+ @@route
29
+ end
33
30
 
34
- def route
35
- @@r.route
31
+ def message
32
+ builder = Nokogiri::XML::Builder.new do |xml|
33
+ xml.workspace {
34
+ xml.enabled @enabled if enabled_changed?
35
+ xml.name @name
36
+ }
36
37
  end
38
+ return builder.doc.to_xml
39
+ end
37
40
 
38
- def message
39
- builder = Nokogiri::XML::Builder.new do |xml|
40
- xml.workspace {
41
- xml.enabled @enabled if enabled_changed?
42
- xml.name @name
43
- }
44
- end
45
- return builder.doc.to_xml
46
- end
41
+ # @param [RGeoServer::Catalog] catalog
42
+ # @param [Hash] options
43
+ def initialize catalog, options
44
+ super({})
45
+ _run_initialize_callbacks do
46
+ @catalog = catalog
47
+ @name = options[:name].strip
48
+ end
49
+ @route = route
50
+ end
47
51
 
48
- # @param [RGeoServer::Catalog] catalog
49
- # @param [Hash] options
50
- def initialize catalog, options
51
- super({})
52
- _run_initialize_callbacks do
53
- @catalog = catalog
54
- @name = options[:name].strip
55
- end
56
- @route = route
57
- end
52
+ def data_stores &block
53
+ self.class.list DataStore, @catalog, profile['dataStores'], {:workspace => self}, check_remote = true, &block
54
+ end
55
+
56
+ def coverage_stores &block
57
+ self.class.list CoverageStore, @catalog, profile['coverageStores'], {:workspace => self}, check_remote = true, &block
58
+ end
58
59
 
59
- def data_stores &block
60
- self.class.list DataStore, @catalog, profile['dataStores'], {:workspace => self}, check_remote = true, &block
61
- end
62
-
63
- def coverage_stores &block
64
- self.class.list CoverageStore, @catalog, profile['coverageStores'], {:workspace => self}, check_remote = true, &block
65
- end
60
+ def wms_stores &block
61
+ self.class.list WmsStore, @catalog, profile['wmsStores'], {:workspace => self}, check_remote = true, &block
62
+ end
66
63
 
67
- def wms_stores &block
68
- self.class.list WmsStore, @catalog, profile['wmsStores'], {:workspace => self}, check_remote = true, &block
69
- end
70
-
71
- def profile_xml_to_hash profile_xml
72
- doc = profile_xml_to_ng profile_xml
73
- h = {'name' => doc.at_xpath('//name').text.strip, 'enabled' => @enabled }
74
- doc.xpath('//atom:link/@href', "xmlns:atom"=>"http://www.w3.org/2005/Atom").each{ |l|
75
- target = l.text.match(/([a-zA-Z]+)\.xml$/)[1]
76
- if !target.nil? && target != l.parent.parent.name.to_s.downcase
77
- begin
78
- h[l.parent.parent.name.to_s] << target
79
- rescue
80
- h[l.parent.parent.name.to_s] = []
81
- end
82
- else
83
- h[l.parent.parent.name.to_s] = begin
84
- response = @catalog.fetch_url l.text
85
- Nokogiri::XML(response).xpath('//name').collect{ |a| a.text.strip }
86
- rescue RestClient::ResourceNotFound
87
- []
88
- end.freeze
64
+ def profile_xml_to_hash profile_xml
65
+ doc = profile_xml_to_ng profile_xml
66
+ h = {'name' => doc.at_xpath('//name').text.strip, 'enabled' => @enabled }
67
+ doc.xpath('//atom:link/@href', "xmlns:atom"=>"http://www.w3.org/2005/Atom").each{ |l|
68
+ target = l.text.match(/([a-zA-Z]+)\.xml$/)[1]
69
+ if !target.nil? && target != l.parent.parent.name.to_s.downcase
70
+ begin
71
+ h[l.parent.parent.name.to_s] << target
72
+ rescue
73
+ h[l.parent.parent.name.to_s] = []
89
74
  end
90
- }
91
- h
92
- end
93
-
75
+ else
76
+ h[l.parent.parent.name.to_s] = begin
77
+ response = @catalog.do_url l.text
78
+ Nokogiri::XML(response).xpath('//name').collect{ |a| a.text.strip }
79
+ rescue RestClient::ResourceNotFound
80
+ []
81
+ end.freeze
82
+ end
83
+ }
84
+ h
94
85
  end
86
+
87
+ end
95
88
  end
data/lib/rgeoserver.rb CHANGED
@@ -16,6 +16,7 @@ module RGeoServer
16
16
  autoload :WmsStore, "rgeoserver/wmsstore"
17
17
  autoload :Style, "rgeoserver/style"
18
18
  autoload :Layer, "rgeoserver/layer"
19
+ autoload :LayerGroup, "rgeoserver/layergroup"
19
20
 
20
21
  require 'restclient'
21
22
  require 'nokogiri'
@@ -5,6 +5,7 @@ describe "Integration test against a GeoServer instance", :integration => true d
5
5
 
6
6
  before(:all) do
7
7
  @catalog = RGeoServer.catalog
8
+ @fixtures_dir = File.join(File.dirname(__FILE__), "/../fixtures/")
8
9
  end
9
10
 
10
11
 
@@ -86,7 +87,8 @@ describe "Integration test against a GeoServer instance", :integration => true d
86
87
  lyr.default_style = 'rain'
87
88
  lyr.alternate_styles = ['raster']
88
89
  lyr.enabled = 'true'
89
- expect{ lyr.save }.to raise_error
90
+ lyr.resource = @catalog.get_coverage 'sf','sfdem', 'sfdem'
91
+ expect{ lyr.save }.to raise_error
90
92
  end
91
93
 
92
94
  it "should list layers" do
@@ -96,9 +98,33 @@ describe "Integration test against a GeoServer instance", :integration => true d
96
98
  end
97
99
  end
98
100
 
101
+ context "LayerGroups" do
102
+ it "should instantiate a new group layer" do
103
+ lyrs = ['a','b','c'].collect{|l| RGeoServer::Layer.new @catalog, :name => l}
104
+ stys = ['s1','s2','s3','s4'].collect{|s| RGeoServer::Style.new @catalog, :name => s}
105
+ g = RGeoServer::LayerGroup.new @catalog, :name => 'test_group_layer'
106
+ g.layers = lyrs
107
+ g.styles = stys
108
+ g.new?.should == true
109
+ end
110
+
111
+ it "should create a new group layer from existing layers and styles and delete it right after" do
112
+ g = RGeoServer::LayerGroup.new @catalog, :name => 'test_group_layer'
113
+ g.layers = @catalog.get_layers[1,2]
114
+ g.styles = @catalog.get_styles[1,2]
115
+ g.new?.should == true
116
+ g.save
117
+ # Bounds metadata should come back aggregated from the server
118
+ g.bounds['maxx'].should_not == ''
119
+ g.delete
120
+ g.new?.should == true
121
+ end
122
+
123
+ end
124
+
99
125
  context "Styles" do
100
126
  before :all do
101
- sld_dir = File.join(File.dirname(__FILE__), '/../fixtures/styles/')
127
+ sld_dir = File.join(@fixtures_dir, 'styles')
102
128
  @test_sld = Nokogiri::XML(File.new(File.join(sld_dir, 'test_style.sld')))
103
129
  @pop_sld = Nokogiri::XML(File.new(File.join(sld_dir, 'poptest.sld')))
104
130
  end
@@ -137,6 +163,8 @@ describe "Integration test against a GeoServer instance", :integration => true d
137
163
  before :all do
138
164
  @ws = RGeoServer::Workspace.new @catalog, :name => 'test_workspace_for_stores'
139
165
  @ws.save
166
+ @shapefile = File.join(@fixtures_dir, 'datasets/vector/granules.shp')
167
+ @raster = File.join(@fixtures_dir, 'datasets/raster/test.tif')
140
168
  end
141
169
 
142
170
  after :all do
@@ -164,7 +192,7 @@ describe "Integration test against a GeoServer instance", :integration => true d
164
192
  end
165
193
 
166
194
  it "should create a datastore under existing workspace, update and delete it right after" do
167
- ds = RGeoServer::DataStore.new @catalog, :workspace => @ws, :name => 'test', :connection_parameters => {"namespace"=>"http://test_workspace_for_stores", "url" => "file://tmp/geo.tif"}
195
+ ds = RGeoServer::DataStore.new @catalog, :workspace => @ws, :name => 'test', :connection_parameters => {"namespace"=>"http://test_workspace_for_stores", "url" => "file:#{@shapefile}"}
168
196
  ds.new?.should == true
169
197
  ds.save
170
198
  ds.new?.should == false
@@ -179,6 +207,15 @@ describe "Integration test against a GeoServer instance", :integration => true d
179
207
  ds.profile['connectionParameters'].should == new_connection_parameters
180
208
  ds.delete
181
209
  end
210
+
211
+ it "should create a datastore under existing workspace and add a feature type that will also create a layer" do
212
+ ds = RGeoServer::DataStore.new @catalog, :workspace => @ws, :name => 'test', :connection_parameters => {"namespace"=>"http://test_workspace_for_stores", "url" => "file:#{@shapefile}"}
213
+ ds.new?.should == true
214
+ ds.save
215
+ ft = RGeoServer::FeatureType.new @catalog, :workspace => @ws, :data_store => ds, :name => 'granules'
216
+ ft.save
217
+
218
+ end
182
219
  end
183
220
 
184
221
  context "CoverageStores" do
@@ -189,7 +226,7 @@ describe "Integration test against a GeoServer instance", :integration => true d
189
226
  end
190
227
  it "should create a coverage store under existing workspace, update and delete it right after" do
191
228
  cs = RGeoServer::CoverageStore.new @catalog, :workspace => @ws, :name => 'test_coverage_store'
192
- cs.url = "file:data_dir/sf/raster.tif"
229
+ cs.url = "file://#{@raster}"
193
230
  cs.description = 'description'
194
231
  cs.enabled = 'true'
195
232
  cs.data_type = 'GeoTIFF'
@@ -202,6 +239,28 @@ describe "Integration test against a GeoServer instance", :integration => true d
202
239
  cs.description.should == 'new description'
203
240
  cs.new?.should == false
204
241
  end
242
+ it "should create a coverage store under existing workspace and add a coverage to it. A layer must be created as a result of this operation" do
243
+ cs = RGeoServer::CoverageStore.new @catalog, :workspace => @ws, :name => 'raster'
244
+ cs.url = "file://#{@raster}"
245
+ cs.description = 'description'
246
+ cs.enabled = 'true'
247
+ cs.data_type = 'GeoTIFF'
248
+ cs.save
249
+ c = RGeoServer::Coverage.new @catalog, :workspace => @ws, :coverage_store => cs, :name => 'raster'
250
+ c.title = 'Test Raster Layer'
251
+ #c.save
252
+ end
253
+ end
254
+
255
+ context "Catalog operations" do
256
+ it "should reload the catalog" do
257
+ @catalog.reload
258
+ end
259
+
260
+ it "should reset the catalog" do
261
+ @catalog.reset
262
+ end
263
+
205
264
  end
206
265
  end
207
266
  end