rgeoserver 0.5.5 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +6 -3
- data/VERSION +1 -1
- data/lib/rgeoserver/catalog.rb +34 -8
- data/lib/rgeoserver/coverage.rb +71 -72
- data/lib/rgeoserver/coveragestore.rb +72 -82
- data/lib/rgeoserver/datastore.rb +84 -94
- data/lib/rgeoserver/featuretype.rb +71 -77
- data/lib/rgeoserver/layer.rb +128 -135
- data/lib/rgeoserver/layergroup.rb +138 -0
- data/lib/rgeoserver/resource.rb +2 -3
- data/lib/rgeoserver/rest_api_client.rb +7 -5
- data/lib/rgeoserver/style.rb +83 -88
- data/lib/rgeoserver/wmsstore.rb +6 -16
- data/lib/rgeoserver/workspace.rb +70 -77
- data/lib/rgeoserver.rb +1 -0
- data/spec/fixtures/datasets/vector/granules.qix +0 -0
- data/spec/lib/integration_test_spec.rb +63 -4
- metadata +31 -28
@@ -1,92 +1,86 @@
|
|
1
1
|
|
2
2
|
module RGeoServer
|
3
|
+
# A feature type is a vector based spatial resource or data set that originates from a data store. In some cases, like Shapefile, a feature type has a one-to-one relationship with its data store. In other cases, like PostGIS, the relationship of feature type to data store is many-to-one, with each feature type corresponding to a table in the database.
|
4
|
+
class FeatureType < ResourceInfo
|
5
|
+
OBJ_ATTRIBUTES = {:catalog => "catalog", :name => "name", :workspace => "workspace", :enabled => "enabled" }
|
6
|
+
OBJ_DEFAULT_ATTRIBUTES = {:catalog => nil, :workspace => nil, :coverage_store => nil, :name => nil, :enabled => "false" }
|
7
|
+
|
8
|
+
define_attribute_methods OBJ_ATTRIBUTES.keys
|
9
|
+
update_attribute_accessors OBJ_ATTRIBUTES
|
10
|
+
|
11
|
+
@@route = "workspaces/%s/datastores/%s/featuretypes"
|
12
|
+
@@root = "featureTypes"
|
13
|
+
@@resource_name = "featureType"
|
14
|
+
|
15
|
+
def self.root
|
16
|
+
@@root
|
17
|
+
end
|
3
18
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
define_attribute_methods OBJ_ATTRIBUTES.keys
|
9
|
-
update_attribute_accessors OBJ_ATTRIBUTES
|
10
|
-
|
11
|
-
@@r = Confstruct::Configuration.new(
|
12
|
-
:route => "workspaces/%s/datastores/%s/featuretypes",
|
13
|
-
:root => "featureTypes",
|
14
|
-
:resource_name => "featureType"
|
15
|
-
)
|
16
|
-
|
17
|
-
def self.root
|
18
|
-
@@r.root
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.create_method
|
22
|
-
:put
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.update_method
|
26
|
-
:put
|
27
|
-
end
|
28
|
-
|
19
|
+
def self.resource_name
|
20
|
+
@@resource_name
|
21
|
+
end
|
29
22
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
def self.root_xpath
|
35
|
-
"//#{root}/#{resource_name}"
|
36
|
-
end
|
23
|
+
def self.root_xpath
|
24
|
+
"//#{root}/#{resource_name}"
|
25
|
+
end
|
37
26
|
|
38
|
-
|
39
|
-
|
40
|
-
|
27
|
+
def self.member_xpath
|
28
|
+
"//#{resource_name}"
|
29
|
+
end
|
41
30
|
|
42
|
-
|
43
|
-
|
44
|
-
|
31
|
+
def route
|
32
|
+
@@route % [@workspace.name , @data_store.name ]
|
33
|
+
end
|
45
34
|
|
46
|
-
|
47
|
-
|
35
|
+
def message
|
36
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
37
|
+
xml.featureType {
|
38
|
+
xml.name @name
|
39
|
+
}
|
48
40
|
end
|
41
|
+
@message = builder.doc.to_xml
|
42
|
+
end
|
49
43
|
|
50
44
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
45
|
+
# @param [RGeoServer::Catalog] catalog
|
46
|
+
# @param [Hash] options
|
47
|
+
def initialize catalog, options
|
48
|
+
super({})
|
49
|
+
_run_initialize_callbacks do
|
50
|
+
@catalog = catalog
|
51
|
+
workspace = options[:workspace] || 'default'
|
52
|
+
if workspace.instance_of? String
|
53
|
+
@workspace = @catalog.get_workspace(workspace)
|
54
|
+
elsif workspace.instance_of? Workspace
|
55
|
+
@workspace = workspace
|
56
|
+
else
|
57
|
+
raise "Not a valid workspace"
|
58
|
+
end
|
59
|
+
data_store = options[:data_store]
|
60
|
+
if data_store.instance_of? String
|
61
|
+
@data_store = DataStore.new @catalog, :workspace => @workspace, :name => data_store
|
62
|
+
elsif data_store.instance_of? DataStore
|
63
|
+
@data_store = data_store
|
64
|
+
else
|
65
|
+
raise "Not a valid data store"
|
66
|
+
end
|
67
|
+
|
68
|
+
@name = options[:name].strip
|
69
|
+
@route = route
|
70
|
+
end
|
71
|
+
end
|
78
72
|
|
79
73
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
74
|
+
def profile_xml_to_hash profile_xml
|
75
|
+
doc = profile_xml_to_ng profile_xml
|
76
|
+
h = {
|
77
|
+
"name" => doc.at_xpath('//name').text.strip,
|
78
|
+
"workspace" => @workspace.name,
|
79
|
+
"nativeName" => doc.at_xpath('//nativeName').to_s
|
80
|
+
}.freeze
|
81
|
+
h
|
82
|
+
end
|
89
83
|
|
90
84
|
|
91
|
-
|
85
|
+
end
|
92
86
|
end
|
data/lib/rgeoserver/layer.rb
CHANGED
@@ -1,159 +1,152 @@
|
|
1
1
|
|
2
2
|
module RGeoServer
|
3
|
+
# A layer is a published resource (feature type or coverage).
|
4
|
+
class Layer < ResourceInfo
|
3
5
|
|
4
|
-
|
6
|
+
OBJ_ATTRIBUTES = {:enabled => 'enabled', :catalog => 'catalog', :name => 'name', :default_style => 'default_style', :alternate_styles => 'alternate_styles', :metadata => 'metadata', :attribution => 'attribution', :layer_type => 'type' }
|
7
|
+
OBJ_DEFAULT_ATTRIBUTES = {:enabled => 'true', :catalog => nil, :name => nil, :default_style => nil, :alternate_styles => [], :metadata => {}, :attribution => {:logo_height => '0', :logo_width => '0', 'title' => ''}, :layer_type => nil }
|
5
8
|
|
6
|
-
|
7
|
-
|
9
|
+
define_attribute_methods OBJ_ATTRIBUTES.keys
|
10
|
+
update_attribute_accessors OBJ_ATTRIBUTES
|
8
11
|
|
9
|
-
|
10
|
-
|
12
|
+
@@route = "layers"
|
13
|
+
@@resource_name = "layer"
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@@r.resource_name
|
16
|
-
end
|
15
|
+
def self.resource_name
|
16
|
+
@@resource_name
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def self.root_xpath
|
20
|
+
"//#{@@route}/#{@@resource_name}"
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
27
|
+
def route
|
28
|
+
@@route
|
29
|
+
end
|
33
30
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
# No direct layer creation
|
39
|
-
def create_route
|
40
|
-
nil
|
41
|
-
end
|
31
|
+
# No direct layer creation
|
32
|
+
def create_route
|
33
|
+
nil
|
34
|
+
end
|
42
35
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
}
|
36
|
+
def message
|
37
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
38
|
+
xml.layer {
|
39
|
+
#xml.name @name
|
40
|
+
xml.type_ layer_type
|
41
|
+
xml.enabled enabled
|
42
|
+
xml.defaultStyle {
|
43
|
+
xml.name default_style
|
44
|
+
}
|
45
|
+
xml.styles {
|
46
|
+
alternate_styles.each { |s|
|
47
|
+
xml.style {
|
48
|
+
xml.name s
|
57
49
|
}
|
58
|
-
}
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
}
|
68
|
-
|
69
|
-
return builder.doc.to_xml
|
50
|
+
}
|
51
|
+
} unless alternate_styles.empty?
|
52
|
+
xml.resource(:class => resource.class.resource_name){
|
53
|
+
xml.name resource.name
|
54
|
+
} unless resource.nil?
|
55
|
+
xml.attribution {
|
56
|
+
xml.title attribution['title'] unless attribution['title'].empty?
|
57
|
+
xml.logoWidth attribution['logo_width']
|
58
|
+
xml.logoHeight attribution['logo_height']
|
59
|
+
} if !attribution['logo_width'].nil? && !attribution['logo_height'].nil?
|
60
|
+
}
|
70
61
|
end
|
62
|
+
return builder.doc.to_xml
|
63
|
+
end
|
71
64
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
65
|
+
# @param [RGeoServer::Catalog] catalog
|
66
|
+
# @param [Hash] options
|
67
|
+
# @option options [String] :name
|
68
|
+
# @option options [String] :default_style
|
69
|
+
# @option options [Array<String>] :alternate_styles
|
70
|
+
def initialize catalog, options
|
71
|
+
super({})
|
72
|
+
_run_initialize_callbacks do
|
73
|
+
@catalog = catalog
|
74
|
+
@name = options[:name].strip
|
75
|
+
#@default_style = options[:default_style] || ''
|
76
|
+
#@alternate_styles = options[:alternate_styles] || []
|
77
|
+
end
|
78
|
+
@route = route
|
79
|
+
end
|
87
80
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
81
|
+
def resource= r
|
82
|
+
if r.is_a?(RGeoServer::Coverage) || r.is_a?(RGeoServer::FeatureType)
|
83
|
+
@resource = r
|
84
|
+
else
|
85
|
+
raise 'Unknown resource type'
|
86
|
+
end
|
87
|
+
end
|
95
88
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
else
|
110
|
-
raise 'Unknown resource type'
|
111
|
-
end
|
89
|
+
def resource
|
90
|
+
@resource ||= begin
|
91
|
+
unless profile['resource'].empty?
|
92
|
+
data_type = profile['resource']['type']
|
93
|
+
workspace = profile['resource']['workspace']
|
94
|
+
name = profile['resource']['name']
|
95
|
+
store = profile['resource']['store']
|
96
|
+
|
97
|
+
case data_type
|
98
|
+
when 'coverage'
|
99
|
+
return RGeoServer::Coverage.new @catalog, :workspace => workspace, :coverage_store => store, :name => name
|
100
|
+
when 'featureType'
|
101
|
+
return RGeoServer::FeatureType.new @catalog, :workspace => workspace, :data_store => store, :name => name
|
112
102
|
else
|
113
|
-
|
103
|
+
raise 'Unknown resource type'
|
114
104
|
end
|
115
|
-
|
105
|
+
else
|
116
106
|
nil
|
117
107
|
end
|
108
|
+
rescue Exception => e
|
109
|
+
nil
|
118
110
|
end
|
119
|
-
|
120
|
-
# TODO: Simplify if necessary with "/layers/<l>/styles[.<format>]", as speficied in the API
|
121
|
-
def get_default_style &block
|
122
|
-
self.class.list Style, @catalog, @default_style, {:layer => self}, check_remote = false, &block
|
123
|
-
end
|
124
|
-
|
125
|
-
def get_alternate_styles &block
|
126
|
-
self.class.list Style, @catalog, @alternate_styles, {:layer => self}, check_remote = false, &block
|
127
|
-
end
|
111
|
+
end
|
128
112
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
"name" => name,
|
137
|
-
"path" => doc.at_xpath('//path/text()').to_s,
|
138
|
-
"default_style" => doc.at_xpath('//defaultStyle/name/text()').to_s,
|
139
|
-
"alternate_styles" => doc.xpath('//styles/style/name/text()').collect{ |s| s.to_s},
|
140
|
-
"type" => doc.at_xpath('//type/text()').to_s,
|
141
|
-
"enabled" => doc.at_xpath('//enabled/text()').to_s,
|
142
|
-
"attribution" => {
|
143
|
-
"title" => doc.at_xpath('//attribution/title/text()').to_s,
|
144
|
-
"logo_width" => doc.at_xpath('//attribution/logoWidth/text()').to_s,
|
145
|
-
"logo_height" => doc.at_xpath('//attribution/logoHeight/text()').to_s
|
146
|
-
},
|
147
|
-
"resource" => {
|
148
|
-
"type" => doc.at_xpath('//resource/@class').to_s,
|
149
|
-
"name" => doc.at_xpath('//resource/name/text()').to_s,
|
150
|
-
"store" => store,
|
151
|
-
"workspace" => workspace
|
152
|
-
},
|
153
|
-
"metadata" => doc.xpath('//metadata/entry').inject({}){ |h, e| h.merge(e['key']=> e.text.to_s) }
|
154
|
-
}.freeze
|
155
|
-
h
|
156
|
-
end
|
157
|
-
|
113
|
+
# TODO: Simplify if necessary with "/layers/<l>/styles[.<format>]", as specified in the API
|
114
|
+
def get_default_style &block
|
115
|
+
self.class.list Style, @catalog, @default_style, {:layer => self}, check_remote = false, &block
|
116
|
+
end
|
117
|
+
|
118
|
+
def get_alternate_styles &block
|
119
|
+
self.class.list Style, @catalog, @alternate_styles, {:layer => self}, check_remote = false, &block
|
158
120
|
end
|
121
|
+
|
122
|
+
def profile_xml_to_hash profile_xml
|
123
|
+
doc = profile_xml_to_ng profile_xml
|
124
|
+
name = doc.at_xpath('//name/text()').text.strip
|
125
|
+
link = doc.at_xpath('//resource//atom:link/@href', "xmlns:atom"=>"http://www.w3.org/2005/Atom").text.strip
|
126
|
+
workspace, _, store = link.match(/workspaces\/(.*?)\/(.*?)\/(.*?)\/(.*?)\/#{name}.xml$/).to_a[1,3]
|
127
|
+
|
128
|
+
h = {
|
129
|
+
"name" => name,
|
130
|
+
"path" => doc.at_xpath('//path/text()').to_s,
|
131
|
+
"default_style" => doc.at_xpath('//defaultStyle/name/text()').to_s,
|
132
|
+
"alternate_styles" => doc.xpath('//styles/style/name/text()').collect{ |s| s.to_s},
|
133
|
+
"type" => doc.at_xpath('//type/text()').to_s,
|
134
|
+
"enabled" => doc.at_xpath('//enabled/text()').to_s,
|
135
|
+
"attribution" => {
|
136
|
+
"title" => doc.at_xpath('//attribution/title/text()').to_s,
|
137
|
+
"logo_width" => doc.at_xpath('//attribution/logoWidth/text()').to_s,
|
138
|
+
"logo_height" => doc.at_xpath('//attribution/logoHeight/text()').to_s
|
139
|
+
},
|
140
|
+
"resource" => {
|
141
|
+
"type" => doc.at_xpath('//resource/@class').to_s,
|
142
|
+
"name" => doc.at_xpath('//resource/name/text()').to_s,
|
143
|
+
"store" => store,
|
144
|
+
"workspace" => workspace
|
145
|
+
},
|
146
|
+
"metadata" => doc.xpath('//metadata/entry').inject({}){ |h, e| h.merge(e['key']=> e.text.to_s) }
|
147
|
+
}.freeze
|
148
|
+
h
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
159
152
|
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
|
2
|
+
module RGeoServer
|
3
|
+
# A layer group is a grouping of layers and styles that can be accessed as a single layer in a WMS GetMap request. A Layer group is often referred to as a "base map".
|
4
|
+
class LayerGroup < ResourceInfo
|
5
|
+
|
6
|
+
OBJ_ATTRIBUTES = {:catalog => 'catalog', :name => 'name', :layers => 'layers', :styles => 'styles', :bounds => 'bounds', :metadata => 'metadata' }
|
7
|
+
OBJ_DEFAULT_ATTRIBUTES = {:catalog => nil, :name => nil, :layers => [], :styles => [], :bounds => {'minx'=>'', 'miny' =>'', 'maxx'=>'', 'maxy'=>'', 'crs' =>''}, :metadata => {} }
|
8
|
+
|
9
|
+
define_attribute_methods OBJ_ATTRIBUTES.keys
|
10
|
+
update_attribute_accessors OBJ_ATTRIBUTES
|
11
|
+
|
12
|
+
@@route = "layergroups"
|
13
|
+
@@resource_name = "layerGroup"
|
14
|
+
|
15
|
+
def self.resource_name
|
16
|
+
@@resource_name
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.root_xpath
|
20
|
+
"//#{@@route}/#{@@resource_name}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.member_xpath
|
24
|
+
"//#{resource_name}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def route
|
28
|
+
@@route
|
29
|
+
end
|
30
|
+
|
31
|
+
def message
|
32
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
33
|
+
xml.layerGroup {
|
34
|
+
xml.name @name
|
35
|
+
xml.layers {
|
36
|
+
layers.each { |l|
|
37
|
+
xml.layer {
|
38
|
+
xml.name l.name
|
39
|
+
}
|
40
|
+
}
|
41
|
+
} unless layers.nil?
|
42
|
+
xml.styles {
|
43
|
+
styles.each { |s|
|
44
|
+
xml.style {
|
45
|
+
xml.name s.name
|
46
|
+
}
|
47
|
+
}
|
48
|
+
} unless styles.nil?
|
49
|
+
xml.bounds {
|
50
|
+
xml.minx bounds['minx']
|
51
|
+
xml.maxx bounds['maxx']
|
52
|
+
xml.miny bounds['miny']
|
53
|
+
xml.maxy bounds['maxy']
|
54
|
+
xml.crs bounds['crs']
|
55
|
+
} if @bounds
|
56
|
+
}
|
57
|
+
end
|
58
|
+
return builder.doc.to_xml
|
59
|
+
end
|
60
|
+
|
61
|
+
# @param [RGeoServer::Catalog] catalog
|
62
|
+
# @param [Hash] options
|
63
|
+
# @option options [String] :name
|
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
|
72
|
+
|
73
|
+
# @param [Array<RGeoServer::Style>] sl list of styles
|
74
|
+
def styles= sl
|
75
|
+
if sl.inject(true){|t,s| t && s.is_a?(RGeoServer::Style)}
|
76
|
+
styles_will_change! unless sl == styles
|
77
|
+
@styles = sl
|
78
|
+
else
|
79
|
+
raise 'Unknown list of styles'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def styles
|
84
|
+
@styles ||= begin
|
85
|
+
unless profile['styles'].empty?
|
86
|
+
return profile['styles'].each{ |s| RGeoServer::Style.new @catalog, :name => s.name }
|
87
|
+
else
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
rescue Exception => e
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# @param [Array<RGeoServer::Layer>] ll list of layers
|
96
|
+
def layers= ll
|
97
|
+
if ll.inject(true){ |t,l| t && l.is_a?(RGeoServer::Layer) }
|
98
|
+
layers_will_change! unless ll == layers
|
99
|
+
@layers = ll
|
100
|
+
else
|
101
|
+
raise 'Unknown list of layers'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def layers
|
106
|
+
@layers ||= begin
|
107
|
+
unless profile['layers'].empty?
|
108
|
+
return profile['layers'].each{ |s| RGeoServer::Layer.new @catalog, :name => s.name }
|
109
|
+
else
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
rescue Exception => e
|
113
|
+
nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def profile_xml_to_hash profile_xml
|
118
|
+
doc = profile_xml_to_ng profile_xml
|
119
|
+
name = doc.at_xpath('//name/text()').text.strip
|
120
|
+
|
121
|
+
h = {
|
122
|
+
"name" => name,
|
123
|
+
"layers" => doc.xpath('//layers/layer/name/text()').collect{|l| l.to_s},
|
124
|
+
"styles" => doc.xpath('//styles/style/name/text()').collect{|s| s.to_s},
|
125
|
+
"bounds" => {
|
126
|
+
"minx" => doc.at_xpath('//bounds/minx/text()').to_s,
|
127
|
+
"maxx" => doc.at_xpath('//bounds/maxx/text()').to_s,
|
128
|
+
"miny" => doc.at_xpath('//bounds/miny/text()').to_s,
|
129
|
+
"maxy" => doc.at_xpath('//bounds/maxy/text()').to_s,
|
130
|
+
"crs" => doc.at_xpath('//bounds/crs/text()')
|
131
|
+
},
|
132
|
+
"metadata" => doc.xpath('//metadata/entry').inject({}){ |h, e| h.merge(e['key']=> e.text.to_s) }
|
133
|
+
}.freeze
|
134
|
+
h
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
data/lib/rgeoserver/resource.rb
CHANGED
@@ -57,14 +57,13 @@ module RGeoServer
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def create_method
|
60
|
-
|
60
|
+
:post
|
61
61
|
end
|
62
62
|
|
63
63
|
def update_method
|
64
|
-
|
64
|
+
:put
|
65
65
|
end
|
66
66
|
|
67
|
-
|
68
67
|
# Modify or save the resource
|
69
68
|
# @param [Hash] options / query parameters
|
70
69
|
# @return [RGeoServer::ResourceInfo]
|
@@ -36,20 +36,22 @@ module RGeoServer
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
#
|
39
|
+
# Do an action on an arbitrary URL within the catalog passing no data
|
40
|
+
# Default method is GET
|
40
41
|
# @param [String] url
|
41
|
-
|
42
|
+
# @param [String] method
|
43
|
+
def do_url url, method = :get
|
42
44
|
url.slice! client.url
|
43
45
|
fetcher = client[url]
|
44
46
|
fetcher.options[:headers] ||= headers(:xml)
|
45
|
-
begin
|
46
|
-
return fetcher.get
|
47
|
+
begin
|
48
|
+
return fetcher.get if method == :get
|
49
|
+
fetcher.send method, nil
|
47
50
|
rescue RestClient::InternalServerError => e
|
48
51
|
$logger.error e.response
|
49
52
|
$logger.flush if $logger.respond_to? :flush
|
50
53
|
raise GeoServerInvalidRequest, "Error fetching URL: #{url}. See $logger for details"
|
51
54
|
end
|
52
|
-
|
53
55
|
end
|
54
56
|
|
55
57
|
# Add resource to the catalog
|