rgeoserver 0.5.8.2 → 0.5.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/Gemfile +4 -2
- data/README.rdoc +7 -3
- data/VERSION +1 -1
- data/lib/rgeoserver.rb +4 -1
- data/lib/rgeoserver/catalog.rb +84 -57
- data/lib/rgeoserver/datastore.rb +92 -18
- data/lib/rgeoserver/featuretype.rb +107 -35
- data/lib/rgeoserver/layer.rb +43 -43
- data/lib/rgeoserver/layergroup.rb +110 -35
- data/lib/rgeoserver/resource.rb +27 -27
- data/lib/rgeoserver/utils/boundingbox.rb +88 -0
- data/lib/rgeoserver/utils/shapefile_info.rb +89 -0
- data/rgeoserver.gemspec +5 -1
- data/spec/fixtures/datasets/vector/granules.zip +0 -0
- data/spec/integration/geoserver_spec.rb +170 -55
- data/spec/utils/boundingbox_spec.rb +77 -0
- data/spec/utils/shapefile_info_spec.rb +22 -0
- metadata +183 -29
data/lib/rgeoserver/resource.rb
CHANGED
@@ -10,7 +10,7 @@ module RGeoServer
|
|
10
10
|
define_model_callbacks :initialize, :only => :after
|
11
11
|
|
12
12
|
# mapping object parameters to profile elements
|
13
|
-
OBJ_ATTRIBUTES = {:enabled => 'enabled'}
|
13
|
+
OBJ_ATTRIBUTES = {:enabled => 'enabled'}
|
14
14
|
OBJ_DEFAULT_ATTRIBUTES = {:enabled => 'true'}
|
15
15
|
|
16
16
|
define_attribute_methods OBJ_ATTRIBUTES.keys
|
@@ -36,19 +36,19 @@ module RGeoServer
|
|
36
36
|
# @param [Array<String>] names
|
37
37
|
# @param [Hash] options
|
38
38
|
# @param [bool] check_remote if already exists in catalog and cache it
|
39
|
-
# @yield [RGeoServer::ResourceInfo]
|
39
|
+
# @yield [RGeoServer::ResourceInfo]
|
40
40
|
def self.list klass, catalog, names, options, check_remote = false, &block
|
41
41
|
if names.nil?
|
42
42
|
return []
|
43
43
|
elsif !block_given?
|
44
44
|
to_enum(:list, klass, catalog, names, options).to_a unless block_given?
|
45
|
-
else
|
45
|
+
else
|
46
46
|
(names.is_a?(Array)? names : [names]).each { |name|
|
47
47
|
obj = klass.new catalog, options.merge(:name => name)
|
48
|
-
obj.new? if check_remote
|
48
|
+
obj.new? if check_remote
|
49
49
|
block.call(obj)
|
50
|
-
}
|
51
|
-
end
|
50
|
+
}
|
51
|
+
end
|
52
52
|
end
|
53
53
|
|
54
54
|
def initialize options
|
@@ -58,7 +58,7 @@ module RGeoServer
|
|
58
58
|
def to_s
|
59
59
|
"#{self.class.name}: #{name}"
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
# Return full name of resource with namespace prefix
|
63
63
|
def prefixed_name
|
64
64
|
return "#{workspace.name}:#{name}" if self.respond_to?(:workspace)
|
@@ -66,22 +66,22 @@ module RGeoServer
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def create_method
|
69
|
-
:post
|
69
|
+
:post
|
70
70
|
end
|
71
71
|
|
72
72
|
def update_method
|
73
|
-
:put
|
73
|
+
:put
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
# We pass the old name "name_route" in case the name of the resource is being edited
|
77
77
|
# Child classes should implement this
|
78
78
|
def update_params name_route = name
|
79
|
-
{ self.class.resource_name.downcase.to_sym => name_route }
|
79
|
+
{ self.class.resource_name.downcase.to_sym => name_route }
|
80
80
|
end
|
81
81
|
|
82
82
|
# Modify or save the resource
|
83
83
|
# @param [Hash] options / query parameters
|
84
|
-
# @return [RGeoServer::ResourceInfo]
|
84
|
+
# @return [RGeoServer::ResourceInfo]
|
85
85
|
def save options = {}
|
86
86
|
@previously_changed = changes
|
87
87
|
@changed_attributes.clear
|
@@ -101,31 +101,31 @@ module RGeoServer
|
|
101
101
|
else
|
102
102
|
route = {@route => nil}
|
103
103
|
end
|
104
|
-
|
104
|
+
|
105
105
|
options = create_options.merge(options) if self.respond_to?(:create_options)
|
106
|
-
@catalog.add(route, message, create_method, options)
|
107
|
-
clear
|
106
|
+
@catalog.add(route, message, create_method, options)
|
107
|
+
clear
|
108
108
|
else
|
109
109
|
options = update_params(name_route).merge(options)
|
110
110
|
route = {@route => name_route}
|
111
|
-
@catalog.modify(route, message, update_method, options) #unless changes.empty?
|
111
|
+
@catalog.modify(route, message, update_method, options) #unless changes.empty?
|
112
112
|
end
|
113
113
|
|
114
114
|
self
|
115
115
|
end
|
116
116
|
end
|
117
|
-
|
117
|
+
|
118
118
|
# Purge resource from Geoserver Catalog
|
119
119
|
# @param [Hash] options
|
120
120
|
# @return [RGeoServer::ResourceInfo] `self`
|
121
|
-
def delete options = {}
|
121
|
+
def delete options = {}
|
122
122
|
run_callbacks :destroy do
|
123
|
-
@catalog.purge({@route => @name}, options)
|
123
|
+
@catalog.purge({@route => @name}, options) unless new?
|
124
124
|
clear
|
125
125
|
self
|
126
126
|
end
|
127
127
|
end
|
128
|
-
|
128
|
+
|
129
129
|
# Check if this resource already exists
|
130
130
|
# @return [Boolean]
|
131
131
|
def new?
|
@@ -138,13 +138,13 @@ module RGeoServer
|
|
138
138
|
@changed_attributes = {}
|
139
139
|
end
|
140
140
|
|
141
|
-
# Retrieve the resource profile as a hash and cache it
|
142
|
-
# @return [Hash]
|
141
|
+
# Retrieve the resource profile as a hash and cache it
|
142
|
+
# @return [Hash]
|
143
143
|
def profile
|
144
|
-
if @profile
|
144
|
+
if @profile
|
145
145
|
return @profile
|
146
146
|
end
|
147
|
-
|
147
|
+
|
148
148
|
@profile ||= begin
|
149
149
|
h = profile_xml_to_hash(@catalog.search @route => @name )
|
150
150
|
@new = false
|
@@ -153,7 +153,7 @@ module RGeoServer
|
|
153
153
|
# The resource is new
|
154
154
|
@new = true
|
155
155
|
{}
|
156
|
-
end.freeze
|
156
|
+
end.freeze
|
157
157
|
end
|
158
158
|
|
159
159
|
def profile= profile_xml
|
@@ -165,8 +165,8 @@ module RGeoServer
|
|
165
165
|
end
|
166
166
|
|
167
167
|
def profile_xml_to_hash profile_xml
|
168
|
-
raise NotImplementedError
|
168
|
+
raise NotImplementedError
|
169
169
|
end
|
170
170
|
|
171
171
|
end
|
172
|
-
end
|
172
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'rgeo'
|
2
|
+
|
3
|
+
module RGeoServer
|
4
|
+
class BoundingBox
|
5
|
+
attr_accessor :minx, :miny, :maxx, :maxy
|
6
|
+
|
7
|
+
@@epsilon = 0.0001
|
8
|
+
|
9
|
+
def self.epsilon
|
10
|
+
@@epsilon
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.epsilon= value
|
14
|
+
@@epsilon = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
reset
|
19
|
+
end
|
20
|
+
|
21
|
+
def reset
|
22
|
+
@minx = @miny = @maxx = @maxy = 0.0
|
23
|
+
@empty = true
|
24
|
+
end
|
25
|
+
|
26
|
+
def add x, y
|
27
|
+
if @empty
|
28
|
+
@minx = @maxx = x
|
29
|
+
@miny = @maxy = y
|
30
|
+
end
|
31
|
+
|
32
|
+
@minx = [@minx, x].min
|
33
|
+
@miny = [@miny, y].min
|
34
|
+
@maxx = [@maxx, x].max
|
35
|
+
@maxy = [@maxy, y].max
|
36
|
+
|
37
|
+
@empty = false
|
38
|
+
end
|
39
|
+
|
40
|
+
def min
|
41
|
+
[@minx, @miny]
|
42
|
+
end
|
43
|
+
|
44
|
+
def max
|
45
|
+
[@maxx, @maxy]
|
46
|
+
end
|
47
|
+
|
48
|
+
def expand rate = @@epsilon
|
49
|
+
_minx, _miny = [@minx - rate, @miny - rate]
|
50
|
+
_maxx, _maxy = [@maxx + rate, @maxy + rate]
|
51
|
+
|
52
|
+
reset
|
53
|
+
|
54
|
+
add _minx, _miny
|
55
|
+
add _maxx, _maxy
|
56
|
+
end
|
57
|
+
|
58
|
+
def constrict rate = @@epsilon
|
59
|
+
expand -rate
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_geometry
|
63
|
+
factory = RGeo::Cartesian::Factory.new
|
64
|
+
|
65
|
+
point_min, point_max = unless [@minx, @miny] == [@maxx, @maxy]
|
66
|
+
[factory.point(@minx, @miny), factory.point(@maxx, @maxy)]
|
67
|
+
else
|
68
|
+
[factory.point(@minx - @@epsilon, @miny - @@epsilon),
|
69
|
+
factory.point(@maxx + @@epsilon, @maxy + @@epsilon)]
|
70
|
+
end
|
71
|
+
|
72
|
+
line_string = factory.line_string [point_min, point_max]
|
73
|
+
line_string.envelope
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_a
|
77
|
+
[@minx, @miny, @maxx, @maxy]
|
78
|
+
end
|
79
|
+
|
80
|
+
def to_s
|
81
|
+
to_a.join(', ')
|
82
|
+
end
|
83
|
+
|
84
|
+
def inspect
|
85
|
+
"#<#{self.class} #{to_s}>"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'rgeo'
|
2
|
+
require 'rgeo/shapefile'
|
3
|
+
require 'zip/zip'
|
4
|
+
|
5
|
+
module RGeoServer
|
6
|
+
class ShapefileInfo
|
7
|
+
class ShapefileInfoGeometryNotExpected < StandardError
|
8
|
+
def initialize geometry_type
|
9
|
+
@geometry_type = geometry_type
|
10
|
+
end
|
11
|
+
|
12
|
+
def message
|
13
|
+
"The geometry type %s was not expected." % geometry_type
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :file_path
|
18
|
+
|
19
|
+
def initialize file_path
|
20
|
+
@file_path = file_path
|
21
|
+
end
|
22
|
+
|
23
|
+
def bounds
|
24
|
+
resource_init
|
25
|
+
|
26
|
+
bbox = BoundingBox.new
|
27
|
+
RGeo::Shapefile::Reader.open(@shp_path) do |shp|
|
28
|
+
shp.each do |record|
|
29
|
+
geometry = record.geometry
|
30
|
+
envelope = geometry.envelope
|
31
|
+
envelope_type = envelope.geometry_type
|
32
|
+
points = case envelope_type
|
33
|
+
when RGeo::Feature::Point
|
34
|
+
[envelope]
|
35
|
+
when RGeo::Feature::Polygon
|
36
|
+
envelope.exterior_ring.points
|
37
|
+
else
|
38
|
+
raise ShapefileInfoGeometryNotExpected, envelope_type
|
39
|
+
end
|
40
|
+
points.each { |point| bbox.add point.x, point.y }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
resource_destroy
|
45
|
+
|
46
|
+
bbox.expand if [bbox.minx, bbox.miny] == [bbox.maxx, bbox.maxy]
|
47
|
+
|
48
|
+
bbox
|
49
|
+
end
|
50
|
+
|
51
|
+
def srid
|
52
|
+
resource_init
|
53
|
+
|
54
|
+
srid = 0
|
55
|
+
RGeo::Shapefile::Reader.open(@shp_path) do |shp|
|
56
|
+
srid = shp.factory.srid
|
57
|
+
end
|
58
|
+
|
59
|
+
resource_destroy
|
60
|
+
|
61
|
+
srid
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def tmp_dir
|
66
|
+
@tmp_dir ||= Dir.mktmpdir
|
67
|
+
end
|
68
|
+
|
69
|
+
def resource_init
|
70
|
+
if @file_path =~ /\.zip$/i
|
71
|
+
Zip::ZipFile.open(@file_path) do |zipfile|
|
72
|
+
zipfile.glob('**/**').each do |entry_name|
|
73
|
+
dest_path = [tmp_dir, entry_name].join(File::SEPARATOR)
|
74
|
+
@shp_path = dest_path if entry_name.name =~ /\.shp$/i
|
75
|
+
zipfile.extract entry_name, dest_path
|
76
|
+
end
|
77
|
+
end
|
78
|
+
else
|
79
|
+
@shp_path = @file_path
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def resource_destroy
|
84
|
+
FileUtils.rm_rf [tmp_dir]
|
85
|
+
@shp_path = nil
|
86
|
+
@tmp_dir = nil
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/rgeoserver.gemspec
CHANGED
@@ -20,6 +20,9 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.add_dependency "activesupport"
|
21
21
|
s.add_dependency "activemodel"
|
22
22
|
s.add_dependency "confstruct"
|
23
|
+
s.add_dependency "rgeo"
|
24
|
+
s.add_dependency "rgeo-shapefile"
|
25
|
+
s.add_dependency "rubyzip"
|
23
26
|
|
24
27
|
s.add_development_dependency("rake")
|
25
28
|
s.add_development_dependency("shoulda")
|
@@ -28,5 +31,6 @@ Gem::Specification.new do |s|
|
|
28
31
|
s.add_development_dependency("yard")
|
29
32
|
s.add_development_dependency("equivalent-xml")
|
30
33
|
s.add_development_dependency("jettywrapper")
|
34
|
+
s.add_development_dependency("pry")
|
35
|
+
s.add_development_dependency("debugger")
|
31
36
|
end
|
32
|
-
|
Binary file
|
@@ -4,24 +4,25 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
4
4
|
CONFIG = RGeoServer::Config
|
5
5
|
|
6
6
|
before(:all) do
|
7
|
+
RestClient.log = '/tmp/restclient.log'
|
7
8
|
@catalog = RGeoServer.catalog
|
8
9
|
@fixtures_dir = File.expand_path File.join(File.dirname(__FILE__), "/../fixtures/")
|
9
10
|
@shapefile = File.expand_path File.join(@fixtures_dir, 'datasets/vector/granules.shp')
|
11
|
+
@shapefile_zip = File.expand_path File.join(@fixtures_dir, 'datasets/vector/granules.zip')
|
10
12
|
@raster = File.expand_path File.join(@fixtures_dir, 'datasets/raster/test.tif')
|
11
13
|
end
|
12
|
-
|
13
|
-
|
14
|
-
context "Namespaces" do
|
14
|
+
|
15
|
+
context "Namespaces" do
|
15
16
|
it "should instantiate a namespace resource" do
|
16
17
|
obj = RGeoServer::Namespace.new @catalog, :name => 'test_ns'
|
17
18
|
obj.new?.should == true
|
18
|
-
end
|
19
|
+
end
|
19
20
|
|
20
21
|
it "should get default namespace" do
|
21
|
-
obj = @catalog.get_default_namespace
|
22
|
+
obj = @catalog.get_default_namespace
|
22
23
|
obj.name.should_not be_empty
|
23
24
|
obj.uri.should_not be_empty
|
24
|
-
end
|
25
|
+
end
|
25
26
|
|
26
27
|
it "should create a new namespace, update and delete it right after" do
|
27
28
|
obj = RGeoServer::Namespace.new @catalog, :name => 'test_ns', :uri => 'http://localhost'
|
@@ -35,15 +36,15 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
35
36
|
ws.delete :recurse => true unless ws.new?
|
36
37
|
obj = RGeoServer::Namespace.new @catalog, :name => 'test_ns', :uri => 'http://localhost'
|
37
38
|
obj.new?.should == true
|
38
|
-
end
|
39
|
+
end
|
39
40
|
|
40
41
|
it "should be in correspondence with workspaces" do
|
41
42
|
pending "Make sure this also works on update and delete"
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
|
-
context "Workspaces" do
|
46
|
-
|
46
|
+
context "Workspaces" do
|
47
|
+
|
47
48
|
it "should get default workspace" do
|
48
49
|
w = @catalog.get_default_workspace
|
49
50
|
w.name.should_not be_empty
|
@@ -59,12 +60,12 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
59
60
|
# Switch to a default namespace that does not exist (create it too)
|
60
61
|
nws = RGeoServer::Workspace.new @catalog, :name => 'test_new_default_workspace'
|
61
62
|
dws = @catalog.set_default_workspace 'test_new_default_workspace'
|
62
|
-
aws = @catalog.get_default_workspace
|
63
|
+
aws = @catalog.get_default_workspace
|
63
64
|
aws.name.should == nws.name
|
64
65
|
aws.delete
|
65
66
|
nws.new?.should == true # nws should not exist
|
66
67
|
# Switch to a default workspace that exists
|
67
|
-
ws = @catalog.get_workspaces.first
|
68
|
+
ws = @catalog.get_workspaces.first
|
68
69
|
dws = @catalog.set_default_workspace ws.name
|
69
70
|
ws.name.should == dws.name
|
70
71
|
end
|
@@ -72,12 +73,12 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
72
73
|
it "should list workspaces" do
|
73
74
|
@catalog.get_workspaces.each{ |obj|
|
74
75
|
obj.profile.should_not be_nil
|
75
|
-
}
|
76
|
+
}
|
76
77
|
end
|
77
78
|
|
78
79
|
it "should return workspace from catalog" do
|
79
80
|
obj = @catalog.get_workspace 'topp'
|
80
|
-
obj.profile.should_not be_empty
|
81
|
+
obj.profile.should_not be_empty
|
81
82
|
end
|
82
83
|
|
83
84
|
it "should instantiate an existing worskpace object" do
|
@@ -90,7 +91,7 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
90
91
|
obj = RGeoServer::Workspace.new @catalog, :name => 'test_ws'
|
91
92
|
obj.delete(:recurse=>true) if !obj.new?
|
92
93
|
obj.new?.should == true
|
93
|
-
obj.profile.should == {}
|
94
|
+
obj.profile.should == {}
|
94
95
|
obj.save
|
95
96
|
obj.new?.should == false
|
96
97
|
obj.enabled.should == 'true'
|
@@ -104,7 +105,7 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
104
105
|
end
|
105
106
|
|
106
107
|
it "should fail trying to delete unexisting workspace names from catalog" do
|
107
|
-
lambda{ ["asdfdg", "test3", "test5", "test6"].each{ |w|
|
108
|
+
lambda{ ["asdfdg", "test3", "test5", "test6"].each{ |w|
|
108
109
|
@catalog.purge({:workspaces => w}, {:recurse => true})
|
109
110
|
}
|
110
111
|
}.should raise_error
|
@@ -113,7 +114,7 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
113
114
|
context "Datastores of a Workspace" do
|
114
115
|
before :all do
|
115
116
|
@ws = RGeoServer::Workspace.new @catalog, :name => 'test_workspace_with_stores'
|
116
|
-
@ws.save
|
117
|
+
@ws.save
|
117
118
|
end
|
118
119
|
|
119
120
|
after :all do
|
@@ -123,7 +124,7 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
123
124
|
it "should list datastore objects that belong to it" do
|
124
125
|
['s1', 's2', 's3'].each{ |s|
|
125
126
|
ds = RGeoServer::DataStore.new @catalog, :workspace => @ws, :name => s
|
126
|
-
ds.save
|
127
|
+
ds.save
|
127
128
|
}
|
128
129
|
@ws.data_stores do |ds|
|
129
130
|
ds.should be_kind_of(RGeoServer::DataStore)
|
@@ -134,14 +135,23 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
134
135
|
end
|
135
136
|
end
|
136
137
|
|
137
|
-
context "Layers" do
|
138
|
+
context "Layers" do
|
139
|
+
before :each do
|
140
|
+
@ws = RGeoServer::Workspace.new @catalog, :name => 'test_workspace_for_layers'
|
141
|
+
@ws.save
|
142
|
+
end
|
143
|
+
|
144
|
+
after :each do
|
145
|
+
@ws.delete :recurse => true
|
146
|
+
end
|
147
|
+
|
138
148
|
it "should instantiate a new layer" do
|
139
149
|
lyr = RGeoServer::Layer.new @catalog, :name => 'layer_rgeoserver_test'
|
140
150
|
lyr.new?.should == true
|
141
151
|
end
|
142
152
|
|
143
153
|
it "should not create a new layer directly" do
|
144
|
-
lyr = RGeoServer::Layer.new @catalog, :name => 'layer_rgeoserver_test'
|
154
|
+
lyr = RGeoServer::Layer.new @catalog, :name => 'layer_rgeoserver_test'
|
145
155
|
lyr.new?.should == true
|
146
156
|
lyr.default_style = 'rain'
|
147
157
|
lyr.alternate_styles = ['raster']
|
@@ -161,26 +171,29 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
161
171
|
'title' => 'New attribution title'
|
162
172
|
}
|
163
173
|
lyr.save
|
164
|
-
|
174
|
+
|
165
175
|
chklyr = RGeoServer::Layer.new @catalog, :name => original_name
|
166
176
|
lyr.eql? chklyr
|
167
|
-
|
177
|
+
|
168
178
|
# Undo changes
|
169
179
|
chklyr.attribution = original_attribution
|
170
180
|
chklyr.save
|
171
181
|
chklyr.attribution.eql? original_attribution
|
172
182
|
end
|
173
|
-
|
183
|
+
|
174
184
|
it "should be created from a store" do
|
175
185
|
# Create a Datastore and a feature type under the default workspace (set it up as nil)
|
176
|
-
ds = RGeoServer::DataStore.new @catalog, :workspace =>
|
186
|
+
ds = RGeoServer::DataStore.new @catalog, :workspace => @ws, :name => 'test_shapefile2'
|
177
187
|
ds.connection_parameters = {"url" => "file://#{@shapefile}"}
|
178
188
|
ds.enabled = true
|
179
189
|
ds.new?.should == true
|
180
190
|
ds.save
|
181
|
-
|
191
|
+
|
192
|
+
ft = RGeoServer::FeatureType.new @catalog, :workspace => @ws, :data_store => ds, :name => 'granules'
|
182
193
|
ft.save
|
183
|
-
|
194
|
+
|
195
|
+
ds.clear
|
196
|
+
|
184
197
|
lyr = RGeoServer::Layer.new @catalog, :name => 'granules'
|
185
198
|
lyr.new?.should == false
|
186
199
|
lyr.resource.eql? ft
|
@@ -190,12 +203,57 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
190
203
|
lyr.new?.should == true
|
191
204
|
end
|
192
205
|
|
206
|
+
it "should be created from a store with file upload" do
|
207
|
+
# Create a Datastore and a feature type under the default workspace (set it up as nil)
|
208
|
+
ds = RGeoServer::DataStore.new @catalog, :workspace => @ws, :name => 'test_granules'
|
209
|
+
ds.delete :recurse => true unless ds.new?
|
210
|
+
|
211
|
+
ds.enabled = true
|
212
|
+
ds.new?.should == true
|
213
|
+
ds.upload_file @shapefile_zip
|
214
|
+
|
215
|
+
ds.clear #reload DataStore
|
216
|
+
|
217
|
+
ft = RGeoServer::FeatureType.new @catalog, :workspace => @ws, :data_store => ds, :name => ds.name
|
218
|
+
ft.save
|
219
|
+
|
220
|
+
lyr = RGeoServer::Layer.new @catalog, :name => ds.name
|
221
|
+
lyr.new?.should == false
|
222
|
+
lyr.resource.eql? ft
|
223
|
+
ds.delete :recurse => true
|
224
|
+
|
225
|
+
# Check layer does not exist anymore after deleting the base store
|
226
|
+
lyr = RGeoServer::Layer.new @catalog, :name => ds.name
|
227
|
+
lyr.new?.should == true
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should be created automatically from a store with file upload" do
|
231
|
+
# Create a Datastore and a feature type under the default workspace (set it up as nil)
|
232
|
+
ds = RGeoServer::DataStore.new @catalog, :workspace => @ws, :name => 'test_granules'
|
233
|
+
ds.delete :recurse => true unless ds.new?
|
234
|
+
|
235
|
+
ds.enabled = true
|
236
|
+
ds.new?.should == true
|
237
|
+
ds.upload_file @shapefile_zip, publish: true
|
238
|
+
|
239
|
+
ds.clear #reload DataStore
|
240
|
+
|
241
|
+
lyr = RGeoServer::Layer.new @catalog, :name => ds.name
|
242
|
+
lyr.new?.should == false
|
243
|
+
ds.delete :recurse => true
|
244
|
+
|
245
|
+
# Check layer does not exist anymore after deleting the base store
|
246
|
+
lyr = RGeoServer::Layer.new @catalog, :name => ds.name
|
247
|
+
lyr.new?.should == true
|
248
|
+
end
|
249
|
+
|
193
250
|
it "should list layers" do
|
194
|
-
@catalog.get_layers.each { |l|
|
251
|
+
@catalog.get_layers.each { |l|
|
195
252
|
l.profile.should_not be_empty
|
196
253
|
}
|
197
254
|
end
|
198
|
-
|
255
|
+
|
256
|
+
it "should issue seed on an existing layer's cache" do
|
199
257
|
pending "This certainly passes. We are skipping it since it is a CPU intensive operation"
|
200
258
|
lyr = RGeoServer::Layer.new @catalog, :name => 'Arc_Sample'
|
201
259
|
options = {
|
@@ -205,10 +263,10 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
205
263
|
:format => 'image/png',
|
206
264
|
:threadCount => 1
|
207
265
|
}
|
208
|
-
lyr.seed :issue, options
|
266
|
+
lyr.seed :issue, options
|
209
267
|
end
|
210
268
|
|
211
|
-
it "should truncate an existing layer's cache" do
|
269
|
+
it "should truncate an existing layer's cache" do
|
212
270
|
lyr = RGeoServer::Layer.new @catalog, :name => 'states'
|
213
271
|
options = {
|
214
272
|
#:gridSetId => 'EPSG:2163', # this was not found in sample data
|
@@ -224,24 +282,40 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
224
282
|
3291070.6104286816,
|
225
283
|
959189.3312465074
|
226
284
|
]
|
227
|
-
},
|
285
|
+
},
|
228
286
|
:parameters => {
|
229
287
|
:STYLES => 'pophatch',
|
230
288
|
:CQL_FILTER => 'TOTPOP > 10000'
|
231
289
|
}
|
232
290
|
}
|
233
|
-
lyr.seed :truncate, options
|
291
|
+
lyr.seed :truncate, options
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'should return projection policy' do
|
295
|
+
layer = @catalog.get_layers.first.resource
|
296
|
+
layer.projection_policy.should be_kind_of(Symbol)
|
234
297
|
end
|
235
298
|
|
236
299
|
end
|
237
300
|
|
238
301
|
context "LayerGroups" do
|
302
|
+
it "should list group layers" do
|
303
|
+
@catalog.get_layergroups.each { |l|
|
304
|
+
l.profile.should_not be_empty
|
305
|
+
}
|
306
|
+
end
|
307
|
+
|
308
|
+
it "should return a group layer from catalog" do
|
309
|
+
obj = @catalog.get_layergroup 'tiger-ny'
|
310
|
+
obj.profile.should_not be_empty
|
311
|
+
end
|
312
|
+
|
239
313
|
it "should instantiate a new group layer" do
|
240
314
|
lyrs = ['a','b','c'].collect{|l| RGeoServer::Layer.new @catalog, :name => l}
|
241
315
|
stys = ['s1','s2','s3','s4'].collect{|s| RGeoServer::Style.new @catalog, :name => s}
|
242
316
|
g = RGeoServer::LayerGroup.new @catalog, :name => 'test_group_layer'
|
243
317
|
g.layers = lyrs
|
244
|
-
g.styles = stys
|
318
|
+
g.styles = stys
|
245
319
|
g.new?.should == true
|
246
320
|
end
|
247
321
|
|
@@ -257,6 +331,22 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
257
331
|
g.new?.should == true
|
258
332
|
end
|
259
333
|
|
334
|
+
it 'should return layer group bounds' do
|
335
|
+
lg = RGeoServer::LayerGroup.new @catalog, :name => 'tasmania'
|
336
|
+
bounds = lg.bounds
|
337
|
+
bounds['minx'].should > 0
|
338
|
+
bounds['miny'].should < 0
|
339
|
+
bounds['maxx'].should > 0
|
340
|
+
bounds['maxy'].should < 0
|
341
|
+
end
|
342
|
+
|
343
|
+
it 'should recalculate layer group bounds' do
|
344
|
+
lg = RGeoServer::LayerGroup.new @catalog, :name => 'tasmania'
|
345
|
+
bounds = lg.bounds
|
346
|
+
bounds_new = lg.recalculate_bounds
|
347
|
+
bounds.should == bounds_new
|
348
|
+
end
|
349
|
+
|
260
350
|
end
|
261
351
|
|
262
352
|
context "Styles" do
|
@@ -265,15 +355,15 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
265
355
|
@test_sld = Nokogiri::XML(File.new(File.join(sld_dir, 'test_style.sld')))
|
266
356
|
@pop_sld = Nokogiri::XML(File.new(File.join(sld_dir, 'poptest.sld')))
|
267
357
|
end
|
268
|
-
|
358
|
+
|
269
359
|
it "should instantiate a new style" do
|
270
360
|
style = RGeoServer::Style.new @catalog, :name => 'style_rgeoserver_test'
|
271
361
|
style.new?.should == true
|
272
362
|
end
|
273
363
|
|
274
364
|
it "should create new styles and delete them" do
|
275
|
-
{'granules_test_style'=> @test_sld, 'poptest_test_style'=> @pop_sld}.each_pair do |name,sld_ng|
|
276
|
-
style = RGeoServer::Style.new @catalog, :name => name
|
365
|
+
{'granules_test_style'=> @test_sld, 'poptest_test_style'=> @pop_sld}.each_pair do |name,sld_ng|
|
366
|
+
style = RGeoServer::Style.new @catalog, :name => name
|
277
367
|
style.sld_doc = sld_ng.to_xml
|
278
368
|
style.save
|
279
369
|
style.sld_doc.should be_equivalent_to(sld_ng)
|
@@ -282,7 +372,7 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
282
372
|
style.new?.should == true
|
283
373
|
end
|
284
374
|
end
|
285
|
-
|
375
|
+
|
286
376
|
it "should list layers that include a style" do
|
287
377
|
@catalog.get_styles[1,1].each do |s|
|
288
378
|
break
|
@@ -297,18 +387,18 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
297
387
|
end
|
298
388
|
|
299
389
|
context "Stores" do
|
300
|
-
before :
|
390
|
+
before :each do
|
301
391
|
@ws = RGeoServer::Workspace.new @catalog, :name => 'test_workspace_for_stores'
|
302
392
|
@ws.save
|
303
393
|
end
|
304
|
-
|
305
|
-
after :
|
306
|
-
@ws.delete :recurse => true
|
394
|
+
|
395
|
+
after :each do
|
396
|
+
@ws.delete :recurse => true
|
307
397
|
end
|
308
398
|
|
309
399
|
context "DataStores" do
|
310
400
|
it "should list all available data stores" do
|
311
|
-
@catalog.get_data_stores.each { |d|
|
401
|
+
@catalog.get_data_stores.each { |d|
|
312
402
|
d.profile.should_not be_empty
|
313
403
|
}
|
314
404
|
end
|
@@ -317,13 +407,38 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
317
407
|
obj = RGeoServer::DataStore.new @catalog, :workspace => @ws, :name => 'test_shapefile'
|
318
408
|
obj.new?.should == true
|
319
409
|
obj.name.should == 'test_shapefile'
|
320
|
-
obj.workspace.name.should == @ws.name
|
410
|
+
obj.workspace.name.should == @ws.name
|
411
|
+
end
|
412
|
+
|
413
|
+
it "should instantiate a datastore from file" do
|
414
|
+
obj = RGeoServer::DataStore.new @catalog, :workspace => @ws, :name => 'test_shapefile'
|
415
|
+
obj.new?.should == true
|
416
|
+
obj.name.should == 'test_shapefile'
|
417
|
+
obj.workspace.name.should == @ws.name
|
418
|
+
obj.upload_file @shapefile_zip
|
419
|
+
end
|
420
|
+
|
421
|
+
it "tries to instantiate a datastore from file with invalid data type" do
|
422
|
+
obj = RGeoServer::DataStore.new @catalog, :workspace => @ws, :name => 'test_shapefile'
|
423
|
+
obj.new?.should == true
|
424
|
+
obj.name.should == 'test_shapefile'
|
425
|
+
obj.workspace.name.should == @ws.name
|
426
|
+
expect { obj.upload_file @shapefile_zip, :data_type => :xxx }.to raise_error(RGeoServer::DataStore::DataTypeNotExpected)
|
427
|
+
end
|
428
|
+
|
429
|
+
it "tries to update an existing datastore with file" do
|
430
|
+
obj = RGeoServer::DataStore.new @catalog, :workspace => @ws, :name => 'test_shapefile'
|
431
|
+
obj.new?.should == true
|
432
|
+
obj.name.should == 'test_shapefile'
|
433
|
+
obj.workspace.name.should == @ws.name
|
434
|
+
obj.save
|
435
|
+
expect { obj.upload_file @shapefile_zip }.to raise_error(RGeoServer::DataStore::DataStoreAlreadyExists)
|
321
436
|
end
|
322
437
|
|
323
438
|
it "should not create a datastore if workspace does not exit" do
|
324
439
|
new_ws = RGeoServer::Workspace.new @catalog, :name => 'workspace_rgeoserver_test'
|
325
440
|
obj = RGeoServer::DataStore.new @catalog, :workspace => new_ws, :name => 'test_random_store'
|
326
|
-
obj.new? #.should raise_error
|
441
|
+
obj.new? #.should raise_error
|
327
442
|
end
|
328
443
|
|
329
444
|
it "should create a datastore under existing workspace, update and delete it right after" do
|
@@ -337,7 +452,7 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
337
452
|
|
338
453
|
# Add new information
|
339
454
|
new_connection_parameters = {"namespace"=>"http://localhost/test_with_stores", "url" => 'file:data/taz_shapes'}
|
340
|
-
ds.connection_parameters = new_connection_parameters
|
455
|
+
ds.connection_parameters = new_connection_parameters
|
341
456
|
ds.changed?.should == true
|
342
457
|
ds.save
|
343
458
|
ds.profile['connectionParameters'].should == new_connection_parameters
|
@@ -350,11 +465,11 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
350
465
|
ds.save
|
351
466
|
ft = RGeoServer::FeatureType.new @catalog, :workspace => @ws, :data_store => ds, :name => 'granules'
|
352
467
|
ft.save
|
353
|
-
ds.featuretypes.each do |dft|
|
468
|
+
ds.featuretypes.each do |dft|
|
354
469
|
dft.name.should == ft.name
|
355
470
|
dft.workspace.should == ft.workspace
|
356
|
-
dft.data_store.should == ft.data_store
|
357
|
-
end
|
471
|
+
dft.data_store.should == ft.data_store
|
472
|
+
end
|
358
473
|
#ft.metadata_links = [{"type"=>"text/plain", "metadataType"=>"FGDC", "content"=>"http://example.com/geonetwork/srv/en/fgdc.xml?id=2"}]
|
359
474
|
#ft.save
|
360
475
|
#ft.metadata_links.first["metadataType"].should == "FGDC"
|
@@ -363,7 +478,7 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
363
478
|
|
364
479
|
context "CoverageStores" do
|
365
480
|
it "should list all available coverage stores" do
|
366
|
-
@catalog.get_coverage_stores.each { |c|
|
481
|
+
@catalog.get_coverage_stores.each { |c|
|
367
482
|
c.profile.should_not be_empty
|
368
483
|
}
|
369
484
|
end
|
@@ -374,7 +489,7 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
374
489
|
cs.enabled = 'true'
|
375
490
|
cs.data_type = 'GeoTIFF'
|
376
491
|
cs.new?.should == true
|
377
|
-
cs.save
|
492
|
+
cs.save
|
378
493
|
cs.new?.should == false
|
379
494
|
cs.description = 'new description'
|
380
495
|
cs.description_changed?.should == true
|
@@ -394,26 +509,26 @@ describe "Integration test against a GeoServer instance", :integration => true d
|
|
394
509
|
c.title = 'Test Raster Layer'
|
395
510
|
c.abstract = 'This is the abstract of the layer'
|
396
511
|
c.save
|
397
|
-
cs.coverages.each do |ct|
|
512
|
+
cs.coverages.each do |ct|
|
398
513
|
ct.name.should == c.name
|
399
514
|
ct.workspace.should == c.workspace
|
400
|
-
ct.coverage_store.should == ct.coverage_store
|
401
|
-
end
|
515
|
+
ct.coverage_store.should == ct.coverage_store
|
516
|
+
end
|
402
517
|
#c.metadata_links = [{"type"=>"text/plain", "metadataType"=>"FGDC", "content"=>"http://example.com/geonetwork/srv/en/fgdc.xml?id=1090"}]
|
403
518
|
#c.save
|
404
519
|
#c.metadata_links.first["metadataType"].should == "FGDC"
|
405
520
|
end
|
406
521
|
end
|
407
|
-
|
522
|
+
|
408
523
|
context "Catalog operations" do
|
409
524
|
it "should reload the catalog" do
|
410
525
|
@catalog.reload
|
411
526
|
end
|
412
|
-
|
527
|
+
|
413
528
|
it "should reset the catalog" do
|
414
529
|
@catalog.reset
|
415
530
|
end
|
416
|
-
|
531
|
+
|
417
532
|
end
|
418
533
|
end
|
419
534
|
end
|