citysdk 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,230 @@
1
+ module CitySDK
2
+
3
+ class Importer
4
+ attr_reader :filereader, :api
5
+
6
+ def initialize(pars)
7
+ @params = pars
8
+
9
+ raise Exception.new("Missing :host in Importer parameters.") if @params[:host].nil?
10
+ raise Exception.new("Missing :layername in Importer parameters.") if @params[:layername].nil?
11
+ raise Exception.new("Missing :file_path in Importer parameters.") if @params[:file_path].nil?
12
+
13
+ @api = CitySDK::API.new(@params[:host])
14
+ if @params[:email]
15
+ raise Exception.new("Missing :passw in Importer parameters.") if @params[:passw].nil?
16
+ raise Exception.new("Failure to authenticate '#{@params[:email]}' with api.") if not @api.authenticate(@params[:email],@params[:passw])
17
+ @api.release
18
+ end
19
+
20
+ @params[:addresslayer] = 'bag.vbo' if @params[:addressleyer].nil?
21
+ @params[:addressfield] = 'postcode_huisnummer' if @params[:addressfield].nil?
22
+
23
+ @params[:create_type] = 'create' if @params[:create_type].nil?
24
+ # CREATE_TYPE_UPDATE = 'update'
25
+ # CREATE_TYPE_ROUTES = 'routes'
26
+ # CREATE_TYPE_CREATE = 'create'
27
+
28
+
29
+ @filereader = FileReader.new(@params)
30
+ end
31
+
32
+ def setLayerStatus(m)
33
+ begin
34
+ sign_in
35
+ @api.set_layer_status(m.gsub("\n","<br/>"))
36
+ sign_out
37
+ rescue Exception => e
38
+ puts "File Importer setLayerStatus Exception #{e.message}"
39
+ end
40
+ end
41
+
42
+ def setParameter(k,v)
43
+ begin
44
+ @params[(k.to_sym rescue k) || k] = v
45
+ return true
46
+ rescue
47
+ end
48
+ nil
49
+ end
50
+
51
+ def setMatchParameter(l,f,v)
52
+ begin
53
+ @params[:match] = [] if @params[:match].nil?
54
+ @params[:match] << [l,f,v]
55
+ return true
56
+ rescue
57
+ end
58
+ nil
59
+ end
60
+
61
+ def sign_in
62
+ if @params[:email].nil?
63
+ raise Exception.new("No credentials provided..")
64
+ end
65
+
66
+ begin
67
+ sign_out if @signed_in
68
+ @api.set_host(@params[:host])
69
+ @api.set_layer(@params[:layername])
70
+ @api.set_matchTemplate(@params[:match_tpl]) if @params[:match_tpl]
71
+ @api.set_createTemplate(@params[:create_tpl]) if @params[:create_tpl]
72
+ @api.authenticate(@params[:email],@params[:passw])
73
+ @signed_in = true
74
+ rescue => e
75
+ @api.release
76
+ raise e
77
+ ensure
78
+ end
79
+ end
80
+
81
+ def sign_out
82
+ @signed_in = false
83
+ return @api.release
84
+ end
85
+
86
+ def filterFields(h)
87
+ data = {}
88
+ h.each_key do |k|
89
+ data[k] = h[k] if @params[:fields].include?(k)
90
+ end
91
+ data
92
+ end
93
+
94
+ def doImport(dryrun=false)
95
+ result = {
96
+ :updated => 0,
97
+ :created => 0,
98
+ :not_added => 0
99
+ }
100
+
101
+ failed = nil
102
+
103
+ if @params[:hasaddress] == 'certain'
104
+ failed = addToAddress(dryrun)
105
+ # elsif @params[:hasaddress] == 'maybe'
106
+ # failed = addToAddress(dryrun)
107
+ end
108
+
109
+ if failed == []
110
+ result[:updated] += @filereader.content.length
111
+ return result
112
+ end
113
+
114
+ if failed
115
+ result[:updated] += (@filereader.content.length - failed.length)
116
+ end
117
+
118
+ nodes = failed || @filereader.content
119
+
120
+ count = nodes.length
121
+
122
+ @api.set_createTemplate(
123
+ {
124
+ :create => {
125
+ :params => { #TODO other create types!!
126
+ :create_type => @params[:create_type],
127
+ :srid => @params[:srid] || 4326
128
+ }
129
+ }
130
+ }
131
+ )
132
+
133
+ match_tpl = {
134
+ :match => {
135
+ :params => {
136
+ :debug => true,
137
+ :layers => {}
138
+ }
139
+ }
140
+ }
141
+
142
+ begin
143
+ sign_in
144
+ if @params[:unique_id] and @params[:match] and (@params[:hasgeometry] != 'unknown')
145
+
146
+ match_tpl[:match][:params][:radius] = @params[:radius] || 200
147
+ match_tpl[:match][:params][:geometry_type] = @params[:geometry_type] || :point
148
+ @params[:match].each do |a|
149
+ match_tpl[:match][:params][:layers][a[0]] = {} if match_tpl[:match][:params][:layers][a[0]].nil?
150
+ match_tpl[:match][:params][:layers][a[0]][a[1]] = a[2]
151
+ end
152
+ @api.set_matchTemplate(match_tpl)
153
+ nodes.each do |rec|
154
+ node = {
155
+ :geom => rec[:geometry],
156
+ :id => rec[:properties][@params[:unique_id]]
157
+ }
158
+ node[:name] = rec[:properties][@params[:name]] if @params[:name]
159
+ node[:data] = rec[:properties]
160
+ @api.match_create_node(node) if not dryrun
161
+ count -= 1
162
+ end
163
+ @api.match_create_flush
164
+
165
+ elsif @params[:unique_id] and (@params[:hasgeometry] != 'unknown')
166
+
167
+ begin
168
+ nodes.each do |rec|
169
+ node = {
170
+ :geom => rec[:geometry],
171
+ :id => rec[:properties][@params[:unique_id]]
172
+ }
173
+ node[:name] = rec[:properties][@params[:name]] if @params[:name]
174
+ node[:data] = rec[:properties]
175
+ @api.create_node(node) if not dryrun
176
+ count -= 1
177
+ end
178
+ @api.create_flush
179
+ rescue => e
180
+ raise e
181
+ end
182
+ else
183
+ raise Exception.new("Cannot import. Geometry or uniuque id is not known for records.") if failed.nil?
184
+ end
185
+ ensure
186
+ a = sign_out
187
+ result[:updated] += a[0]
188
+ result[:created] += a[1]
189
+ result[:not_added] = count
190
+ end
191
+ return result
192
+ end
193
+
194
+ def addToAddress(dryrun=false)
195
+ failed = []
196
+ if @params[:postcode] and @params[:housenumber]
197
+ begin
198
+ sign_in
199
+ @filereader.content.each do |rec|
200
+ row = rec[:properties]
201
+ pc = row[@params[:postcode]].downcase.gsub(/[^a-z0-9]/,'')
202
+ hn = row[@params[:housenumber]]
203
+ qres = {}
204
+ if not (pc.empty? or hn.empty?)
205
+ hn.scan(/\d+/).reverse.each { |n|
206
+ qres = @api.get("/nodes?#{@params[:addresslayer]}::#{@params[:addressfield]}=#{pc + n}")
207
+ break if qres[:status]=='success' and qres[:record_count].to_i >= 1
208
+ }
209
+ else
210
+ qres[:status]='nix'
211
+ end
212
+ if qres[:status]=='success' and qres[:results] and qres[:results][0]
213
+ url = '/' + qres[:results][0][:cdk_id] + '/' + @params[:layername]
214
+ n = @api.put(url,{'data'=>filterFields(row)}) if not dryrun
215
+ else
216
+ failed << rec
217
+ end
218
+ end
219
+ rescue => e
220
+ raise e
221
+ ensure
222
+ sign_out
223
+ end
224
+ return failed
225
+ end
226
+ raise Exception.new("Addresses not well defined in dataset.")
227
+ end
228
+
229
+ end
230
+ end
@@ -0,0 +1,33 @@
1
+ require 'json'
2
+
3
+ class NilClass
4
+ def empty?; true; end
5
+ end
6
+
7
+ module CitySDK
8
+
9
+ class Exception < ::Exception
10
+ def initialize(message,parms=nil,srcfile=nil,srcline=nil)
11
+ if parms and srcfile and srcline
12
+ file = File.basename( parms[:originalfile] ? parms[:originalfile] : ( parms[:filepath] || '-' ) )
13
+ m = "#{Time.now.strftime("%b %M %Y, %H:%M")}; CitySDK, processing file: #{file}\n Exception in #{File.basename(srcfile)}, #{srcline}\n #{message}"
14
+ else
15
+ m = "#{Time.now.strftime("%b %M %Y, %H:%M")}; CitySDK Exception: #{message}"
16
+ end
17
+ super(m)
18
+ $stderr.puts(m) if parms and parms[:verbose]
19
+ end
20
+ end
21
+
22
+ def self.parseJson(jsonstring)
23
+ begin
24
+ return JSON.parse(jsonstring,{:symbolize_names => true})
25
+ rescue Exception => e
26
+ raise CitySDK::Exception.new(e.message)
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+
33
+
data/spec/api_spec.rb ADDED
@@ -0,0 +1,64 @@
1
+
2
+
3
+ module CitySDK
4
+ TEST_HOST = 'test-api.citysdk.waag.org'
5
+ TEST_USER = 'test@waag.org'
6
+ TEST_PASS = '123Test321'
7
+
8
+ TEST_LAYER = {
9
+ :data => {
10
+ :name => 'test.rspec',
11
+ :description => 'for testing',
12
+ :organization => 'waag',
13
+ :category => 'security.test'
14
+ }
15
+ }
16
+
17
+ describe API do
18
+
19
+ before(:each) do
20
+ @api = API.new(TEST_HOST)
21
+ TEST_USER.should_not == 'citysdk@waag.org'
22
+ end
23
+
24
+ after(:each) do
25
+ @api.release
26
+ end
27
+
28
+ it "can be connected to" do
29
+ @api.should_not == nil
30
+ end
31
+
32
+ it "can be queried" do
33
+ @api.get('/layers')[:status].should == 'success'
34
+ end
35
+
36
+ it "can be authorized against" do
37
+ @api.authenticate(TEST_USER,TEST_PASS).should == true
38
+ end
39
+
40
+ # it "can create and delete a test layer" do
41
+ # @api.authenticate(TEST_USER,TEST_PASS).should == true
42
+ # @api.put('/layers',TEST_LAYER)[:status].should == 'success'
43
+ # @api.delete('/layer/test.rspec?delete_layer=true')[:status].should == 'success'
44
+ # end
45
+
46
+ it "can not create a layer in an unauthorized domain" do
47
+ h = TEST_LAYER.dup
48
+ h[:data][:name] = 'unauthorized.rspec'
49
+ @api.authenticate(TEST_USER,TEST_PASS).should == true
50
+ expect { @api.put('/layers',h) }.to raise_error(HostException,"Not authorized for domain 'unauthorized'.")
51
+ TEST_LAYER[:data][:name] = 'test.rspec'
52
+ end
53
+
54
+ it "can not add data to a layer not owned" do
55
+ res = @api.get('/nodes?per_page=1')
56
+ res[:status].should == 'success'
57
+ cdk = res[:results][0][:cdk_id]
58
+ @api.authenticate(TEST_USER,TEST_PASS).should == true
59
+ expect { @api.put("/#{cdk}/osm",{:data=>{:plop => 'pipo'}}) }.to raise_error(HostException,"Not authorized for layer 'osm'.")
60
+ end
61
+
62
+ end
63
+
64
+ end
Binary file
@@ -0,0 +1,25 @@
1
+ {
2
+ "type": "FeatureCollection",
3
+ "features": [
4
+ { "type": "Feature",
5
+ "id": "TrajectSensor_Route059",
6
+ "properties": {
7
+ "DSSObjectType": "TRAJECT_SENSOR",
8
+ "LOCATION": "TrajectSensor_Route059",
9
+ "TIMESTAMP": "13-07-2013 15:45:30",
10
+ "COLOR": "#00FF00",
11
+ "VELOCITY": 33,
12
+ "LENGTH": 961,
13
+ "TRAVELTIME": 104,
14
+ "TRAVELTIME_FF": 961
15
+ },
16
+ "geometry": {
17
+ "type": "LineString",
18
+ "coordinates": [ [123289, 487663], [123606, 487587], [123691, 487565], [123792, 487540], [123830, 487520], [123866, 487500], [123888, 487488], [123901, 487479], [123978, 487426], [123982, 487422], [124019, 487394], [124024, 487385], [124037, 487373], [124051, 487358], [124059, 487346], [124067, 487336], [124072, 487316]]
19
+ }
20
+ },
21
+ { "type": "Feature", "id": "TrajectSensor_Route058", "properties": { "DSSObjectType": "TRAJECT_SENSOR", "LOCATION": "TrajectSensor_Route058", "TIMESTAMP": "13-07-2013 15:45:27", "COLOR": "#00FF00", "VELOCITY": 45, "LENGTH": 961, "TRAVELTIME": 76, "TRAVELTIME_FF": 69}, "geometry": { "type": "LineString", "coordinates": [ [124153, 487283], [124138, 487340], [124119, 487371], [124110, 487384], [124095, 487401], [124091, 487404], [124053, 487430], [124009, 487466], [123929, 487521], [123914, 487531], [123890, 487544], [123853, 487564], [123809, 487586], [123703, 487613], [123618, 487635], [123349, 487699]]}},
22
+ { "type": "Feature", "id": "TrajectSensor_Route057", "properties": { "DSSObjectType": "TRAJECT_SENSOR", "LOCATION": "TrajectSensor_Route057", "TIMESTAMP": "13-07-2013 15:44:51", "COLOR": "#FF9900", "VELOCITY": 18, "LENGTH": 3960, "TRAVELTIME": 775, "TRAVELTIME_FF": 285}, "geometry": { "type": "LineString", "coordinates": [ [118925, 483606], [118912, 483647], [118913, 483654], [118918, 483697], [118921, 483731], [118928, 483773], [118933, 483814], [118936, 483834], [118937, 483875], [118937, 483900], [118935, 483921], [118928, 483952], [118921, 483987], [118918, 483997], [118908, 484046], [118889, 484130], [118879, 484176], [118876, 484193], [118874, 484204], [118873, 484206], [118875, 484206], [118873, 484205], [118877, 484207], [118898, 484217], [118916, 484226], [118921, 484228], [118955, 484252], [118958, 484314], [118955, 484460], [118954, 484490], [118953, 484548], [118953, 484647], [118945, 484678], [118931, 484727], [118936, 484719], [118953, 484731], [118965, 484750], [118967, 484762], [118970, 484773], [118964, 484799], [118951, 484817], [118933, 484828], [118910, 484834], [118907, 484824], [118902, 484876], [118891, 484914], [118888, 484928], [118886, 484934], [118879, 484958], [118872, 484986], [118866, 485006], [118861, 485026], [118851, 485072], [118846, 485098], [118843, 485111], [118836, 485145], [118831, 485169], [118819, 485224], [118812, 485254], [118807, 485282], [118803, 485301], [118801, 485318], [118796, 485352], [118793, 485366], [118788, 485390], [118758, 485505], [118753, 485526], [118750, 485535], [118744, 485545], [118750, 485551], [118755, 485575], [118761, 485592], [118776, 485610], [118777, 485612], [118789, 485628], [118800, 485651], [118791, 485659], [118810, 485655], [118909, 485692], [118933, 485702], [119016, 485737], [119056, 485754], [119097, 485771], [119108, 485776], [119141, 485791], [119190, 485809], [119218, 485820], [119319, 485859], [119414, 485897], [119477, 485921], [119588, 485961], [119636, 485980], [119681, 485998], [119738, 486021], [119769, 486034], [119870, 486077], [120009, 486134], [120030, 486142], [120135, 486184], [120143, 486187], [120151, 486191], [120208, 486216], [120330, 486273]]}}
23
+ ]
24
+ }
25
+
@@ -0,0 +1,5 @@
1
+ nummer;name;stars;rooms;beds;camping;municipality;town;postcode;street;number;buurt2005;wijk;buurt2010;quarter
2
+ 1;Eden Amsterdam American Hotel;4;175;354; ;Amsterdam;Amsterdam;1017PN;Leidsekade;97;A07b;A;A07b;A
3
+ 2;Amstel Intercontinental Amsterdam;5;79;165; ;Amsterdam;Amsterdam;1018GX;Professor Tulpplein;1;A08b;A;A08b;A
4
+ 3;Amsterdam Centre,nh;4;232;424; ;Amsterdam;Amsterdam;1054ES;Stadhouderskade;7;D22a;D;E22a;E
5
+ 4;Barbizon Palace,nh;5;274;548; ;Amsterdam;Amsterdam;1012AD;Prins Hendrikkade;59-72;A00a;A;A00a;A
data/spec/files/rk.csv ADDED
@@ -0,0 +1,6 @@
1
+ gml_id;bevoegd_gezag;rrgs_id;naam_inrichting;straat;huisnummer;postcode;plaats;gemeente;wm_vergunning;date_changed;longitude;latitude
2
+ ID_23;Gemeente ALBRANDSWAARD;12438;RIJNPOORT BV;Ambachtsstraat;5;X176PR;POORTUGAAL;ALBRANDSWAARD;315599;15-05-2009;4.406100015089653;51.85913344374868
3
+ ID_24;Gemeente HARDENBERG;3870;Autobedrijf Wessels Dedemsvaart BV.;Langewijk;198; ;DEDEMSVAART;HARDENBERG;90740;07-04-2011;6.464028693395486;52.60686467883884
4
+ ID_63;Gemeente PUTTEN;7445;Tankstation Pieper;Broekermolenweg;3;X882MG;PUTTEN;PUTTEN;M07/09;31-01-2011;5.55024558211801;52.2490702463568
5
+ ID_9676;Gemeente BOXTEL;1818;Tankstation Texaco Ooiendonk;Rijksweg ;2; ; ;BOXTEL;481;02-02-2011;5.36197249261972;51.55510273583312
6
+ ID_9533;Gemeente BEEMSTER;9961;Tankstation B.P. Kruisoord;Rijksweg A7;; ;NOORDBEEMSTER;BEEMSTER;2003-6032;16-01-2012;4.977775378849885;52.58074726262354
Binary file
@@ -0,0 +1,42 @@
1
+ [
2
+ {
3
+ "alias": "true",
4
+ "code": "GVC",
5
+ "country": "NL",
6
+ "lat": "52.080276",
7
+ "long": "4.325",
8
+ "name": "'s-Gravenhage"
9
+ },
10
+ {
11
+ "alias": "true",
12
+ "code": "ALM",
13
+ "country": "NL",
14
+ "lat": "52.37503",
15
+ "long": "5.21764",
16
+ "name": "Almere"
17
+ },
18
+ {
19
+ "alias": "true",
20
+ "code": "APN",
21
+ "country": "NL",
22
+ "lat": "52.124443",
23
+ "long": "4.657778",
24
+ "name": "Alphen aan den Rijn"
25
+ },
26
+ {
27
+ "alias": "true",
28
+ "code": "ASD",
29
+ "country": "NL",
30
+ "lat": "52.378887",
31
+ "long": "4.9002776",
32
+ "name": "Amsterdam"
33
+ },
34
+ {
35
+ "alias": "true",
36
+ "code": "SHL",
37
+ "country": "NL",
38
+ "lat": "52.309444",
39
+ "long": "4.7619443",
40
+ "name": "Amsterdam Airport"
41
+ }
42
+ ]
@@ -0,0 +1,3 @@
1
+ "gid";"verkoop_pu";"b_dat_verk";"e_dat_verk";"oms";"domein_cod";"gmrotation";"geom"
2
+ 18;19184;"2007-02-12";"";"Hofwijckstraat 42 BORD";363;0.259811880644949;"0104000020E61000000100000001010000001960CC67A2661340142840BDAD304A40"
3
+ 19;19191;"2007-02-12";"";"Spaanse Brabanderstraat 31 BORD";363;0.260326709794243;"0104000020E6100000010000000101000000B7EDEED58C65134069AFCF2E90304A40"
@@ -0,0 +1,137 @@
1
+
2
+
3
+ module CitySDK
4
+
5
+ describe "Importer" do
6
+
7
+
8
+ def newImporter(f)
9
+ @importer = Importer.new({
10
+ :host=>TEST_HOST,
11
+ :layername=>'test.rspec',
12
+ :file_path => f
13
+ })
14
+ end
15
+
16
+ after(:each) do
17
+ if @layerCreated
18
+ @importer.api.authenticate(TEST_USER,TEST_PASS) do
19
+ @importer.api.delete("/layer/test.rspec?delete_layer=true")
20
+ end.should_not == nil
21
+ end
22
+ end
23
+
24
+
25
+ it "checks parameters" do
26
+ expect { Importer.new({:a=>1}) }.to raise_error(CitySDK::Exception)
27
+ end
28
+
29
+ it "succesfully creates a FileReader" do
30
+ newImporter('./spec/files/wkb.csv')
31
+ @importer.should_not == nil
32
+ @importer.filereader.params[:unique_id].should == :gid
33
+ end
34
+
35
+ it "can add a (match) parameter" do
36
+ newImporter('./spec/files/wkb.csv')
37
+ @importer.setParameter('freut',:nix).should be_true
38
+ @importer.setMatchParameter('freut','pipo',nil).should be_true
39
+ end
40
+
41
+ it "needs authorization to import" do
42
+ newImporter('./spec/files/hotels.csv')
43
+ expect { @importer.doImport }.to raise_error(CitySDK::Exception)
44
+ end
45
+
46
+ it "can make a match and add data to osm obj" do
47
+ newImporter('./spec/files/rk.csv')
48
+
49
+ @importer.api.authenticate(TEST_USER,TEST_PASS) do
50
+ @importer.api.put('/layers',TEST_LAYER)[:status].should == 'success'
51
+ end.should_not == nil
52
+ @layerCreated = true
53
+ @importer.setParameter(:email,TEST_USER).should be_true
54
+ @importer.setParameter(:passw,TEST_PASS).should be_true
55
+
56
+ @importer.setMatchParameter('osm','amenity','fuel').should be_true
57
+
58
+ res = @importer.doImport[:not_added].should == 0
59
+ res = @importer.api.get("/nodes?count&layer=test.rspec")
60
+ res[:record_count].should == 5
61
+ puts JSON.pretty_generate(res)
62
+ end
63
+
64
+
65
+ it "can make a layer and add data to and address" do
66
+
67
+ newImporter('./spec/files/hotels.csv')
68
+
69
+ @importer.api.authenticate(TEST_USER,TEST_PASS) do
70
+ @importer.api.put('/layers',TEST_LAYER)[:status].should == 'success'
71
+ end.should_not == nil
72
+ @layerCreated = true
73
+
74
+ @importer.setParameter(:email,TEST_USER).should be_true
75
+ @importer.setParameter(:passw,TEST_PASS).should be_true
76
+ if TEST_HOST == 'api.citysdk.waag.org'
77
+ @importer.doImport[:not_added].should == 0
78
+ res = @importer.api.get("/nodes?count&layer=test.rspec")
79
+ res[:record_count].should == 4
80
+ else
81
+ @importer.doImport[:not_added].should == 4
82
+ end
83
+
84
+ end
85
+
86
+ end
87
+
88
+ describe "FileReader" do
89
+
90
+ it "can parse json" do
91
+ j = CitySDK::parseJson('{ "arr" : [0,1,1,1], "hash": {"aap": "noot"}, "num": 0 }')
92
+ j[:arr].length.should == 4
93
+ j[:num].class.should == Fixnum
94
+ j[:hash][:aap].should == "noot"
95
+ end
96
+
97
+ it "can read json files" do
98
+ fr = FileReader.new({:file_path => './spec/files/stations.json'})
99
+ File.basename(fr.file).should == 'stations.json'
100
+ fr.params[:geomtry_type].should == 'Point'
101
+ fr.params[:srid].should == 4326
102
+ fr.params[:unique_id].should == :code
103
+ end
104
+
105
+ it "can read geojson files" do
106
+ fr = FileReader.new({:file_path => './spec/files/geojsonTest.GeoJSON'})
107
+ File.basename(fr.file).should == 'geojsonTest.GeoJSON'
108
+ fr.params[:unique_id].should == nil
109
+ end
110
+
111
+ it "can read csv files" do
112
+ fr = FileReader.new({:file_path => './spec/files/csvtest.zip'})
113
+ File.basename(fr.file).should == 'akw.csv'
114
+ fr.params[:srid].should == 4326
115
+ fr.params[:colsep].should == ';'
116
+ fr.params[:unique_id].should == :ID
117
+ end
118
+
119
+ it "can read csv files with wkb geometry" do
120
+ fr = FileReader.new({:file_path => './spec/files/wkb.csv'})
121
+ File.basename(fr.file).should == 'wkb.csv'
122
+ fr.params[:srid].should == 4326
123
+ fr.params[:colsep].should == ';'
124
+ fr.params[:unique_id].should == :gid
125
+ end
126
+
127
+ it "can read zipped shape files" do
128
+ fr = FileReader.new({:file_path => './spec/files/shapeTest.zip'})
129
+ fr.params[:srid].should == 2100
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+
136
+
137
+ # puts JSON.pretty_generate(fr.content[0])