ffi-ogr 0.1.0.pre → 0.1.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b9dde86c53cf560c92a01c1d443f9beac5ec1b5
4
- data.tar.gz: ad9969a5ca379d9595dd13ae5428ca747718f2f3
3
+ metadata.gz: 05e06c17b1e9e0694b0ff9a7deb4308048ad9f6f
4
+ data.tar.gz: 89a97fbea029d509c949fc1d8ebd62c22b6a1f46
5
5
  SHA512:
6
- metadata.gz: c83069cc2d02ec53ce2b9d6864aa79388044a68e65cd007fedfdbf3ef8a513be7b566fdec58357501681adf5eec5df3b5181dbfd02fc27e7ba26511f7a3bbcc1
7
- data.tar.gz: efaa386893615bffed98d19ed34a31fd4ab1d5071c6137823e709652968d09b35d9540eb0144b2eb71db2211596ee048e187e420c22ca4ed267d0af9c08323b4
6
+ metadata.gz: fda92892f274226cce09ee1994aaa774a17dac70e1edcd720d879d872e9f86a70a0c2eae6723fe57cb5a93a0dae888b54aa8ebf96a3f370cdc342372890ac98f
7
+ data.tar.gz: 55759dbc143c2439baa0dda8e70ba5ac67bb5de3ddf86841c9ed6afecc77bbb9997b1c4524e42cee7220b3758ffce10813d28e3a6b681d53a5a6f296e3012200
data/README.md CHANGED
@@ -1,23 +1,46 @@
1
+ [![Build Status](https://travis-ci.org/scooterw/ffi-ogr.png?branch=master)](https://travis-ci.org/scooterw/ffi-ogr)
2
+ [![Code Climate](https://codeclimate.com/github/scooterw/ffi-ogr.png)](https://codeclimate.com/github/scooterw/ffi-ogr)
3
+
4
+ GDAL must be installed:
5
+
6
+ Mac:
7
+ ```
8
+ brew install gdal
9
+ ```
10
+
11
+ Ubuntu:
12
+ ```
13
+ sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 16126D3A3E5C1192
14
+ sudo apt-get install python-software-properties -y
15
+ sudo add-apt-repository ppa:ubuntugis/ppa -y
16
+ sudo apt-get update -qq
17
+ sudo apt-get install libgdal-dev
18
+ ```
19
+
1
20
  ffi-ogr
2
21
  ... for convenient access to OGR functionality from Ruby
3
22
 
4
23
  To run: `bin/ogr_console`
5
24
 
6
- To read from a known file type (currently SHP, JSON/GeoJSON, raw Github GeoJSON URL, Esri Feature Service URL):
25
+ To read from a known file type (currently SHP, JSON/GeoJSON, CSV, raw Github GeoJSON URL, raw (spatial) CSV URL, Esri Feature Service URL):
7
26
 
8
27
  ```ruby
9
28
  data = OGR.read('https://raw.github.com/colemanm/hurricanes/master/fl_2004_hurricanes.geojson')
10
29
  => #<OGR::DataSource:0x007fb830aa3af8 @ptr=#<FFI::AutoPointer address=0x007fb8311ab990>>
11
30
 
12
31
  # output to SHP file
13
- data.to_shp '/~Desktop/github_to_shp.shp'
32
+ data.to_shp '~/Desktop/github_to_shp.shp'
33
+ => nil
34
+
35
+ # output to CSV file
36
+ data.to_csv '~/Desktop/github_to_csv.csv'
14
37
  => nil
15
38
  ```
16
39
 
17
40
  To read a shapefile:
18
41
 
19
42
  ```ruby
20
- shp = OGR::ShpReader.new.read './spec/data/ne_110m_coastline/ne_110m_coastline.shp'
43
+ shp = OGR.read './spec/data/ne_110m_coastline/ne_110m_coastline.shp'
21
44
  # => #<OGR::DataSource:0x007fba4d19c328 @ptr=#<FFI::AutoPointer address=0x007fba4c4cdc50>>
22
45
 
23
46
  shp.to_geojson '~/Desktop/output.geojson'
@@ -27,7 +50,7 @@ shp.to_geojson '~/Desktop/output.geojson'
27
50
  To reproject a shapefile:
28
51
 
29
52
  ```ruby
30
- shp = OGR::ShpReader.new.read './spec/data/ne_110m_coastline/ne_110m_coastline.shp'
53
+ shp = OGR.read './spec/data/ne_110m_coastline/ne_110m_coastline.shp'
31
54
  # => #<OGR::DataSource:0x007fba4d19c328 @ptr=#<FFI::AutoPointer address=0x007fba4c4cdc50>>
32
55
 
33
56
  shp.to_json
@@ -44,17 +67,10 @@ shp.to_shp '~/Desktop/reprojected_shp.shp', {spatial_ref: new_sr}
44
67
  # => Output reprojected SHP to specified file
45
68
  ```
46
69
 
47
- A reader may also be inferred by file extension (currently works for shp and json/geojson):
48
-
49
- ```ruby
50
- shp = OGR::Reader.from_file_type './spec/data/ne_110m_coastline/ne_110m_coastline.shp'
51
- ```
52
-
53
70
  To create a shapefile:
54
71
 
55
72
  ```ruby
56
- writer = OGR::ShpWriter.new
57
- writer.set_output '~/Documents/shapefiles/my_new.shp'
73
+ writer = OGR.create_writer '~/Documents/shapefiles/my_new.shp'
58
74
 
59
75
  shp = writer.ptr
60
76
 
@@ -84,10 +100,11 @@ layer.add_feature feature
84
100
  layer.sync
85
101
  ```
86
102
 
87
- A writer may also be inferred by file extension (currently works for shp and json/geojson):
103
+ A writer may be fetched by driver type:
88
104
 
89
105
  ```ruby
90
- writer = OGR::Writer.from_file_type '~/Documents/shapefiles/my_new.shp'
106
+ writer = OGR.get_writer 'shp'
107
+ writer.set_output '~/Documents/shapefiles/my_new.shp'
91
108
  ```
92
109
 
93
- Tested on: MRI 1.9.3 / 2.0.0 and JRuby 1.7.3+
110
+ Tested on: MRI (1.9/2.0), JRuby (1.9/2.0), and Rubinius (1.9/2.0)
data/lib/ffi-ogr.rb CHANGED
@@ -6,23 +6,21 @@ module OGR
6
6
 
7
7
  DRIVER_TYPES = {
8
8
  'shapefile' => 'ESRI Shapefile',
9
- 'geojson' => 'GeoJSON'
9
+ 'shp' => 'ESRI Shapefile',
10
+ 'geojson' => 'GeoJSON',
11
+ 'json' => 'GeoJSON',
12
+ 'csv' => 'CSV',
13
+ 'kml' => 'KML'
10
14
  }
11
15
 
12
16
  autoload :Reader, File.join(OGR_BASE, 'reader')
13
- autoload :GenericReader, File.join(OGR_BASE, 'generic_reader')
14
- autoload :ShpReader, File.join(OGR_BASE, 'shp_reader')
15
- autoload :GeoJSONReader, File.join(OGR_BASE, 'geo_json_reader')
16
- autoload :UrlGeoJSONReader, File.join(OGR_BASE, 'url_geo_json_reader')
17
- autoload :FeatureServiceReader, File.join(OGR_BASE, 'feature_service_reader')
18
- autoload :GithubReader, File.join(OGR_BASE, 'github_reader')
17
+ autoload :HttpReader, File.join(OGR_BASE, 'http_reader')
19
18
  autoload :Writer, File.join(OGR_BASE, 'writer')
20
- autoload :GenericWriter, File.join(OGR_BASE, 'generic_writer')
21
- autoload :ShpWriter, File.join(OGR_BASE, 'shp_writer')
22
- autoload :GeoJSONWriter, File.join(OGR_BASE, 'geo_json_writer')
23
19
  autoload :DataSource, File.join(OGR_BASE, 'data_source')
24
20
  autoload :Shapefile, File.join(OGR_BASE, 'shapefile')
25
21
  autoload :GeoJSON, File.join(OGR_BASE, 'geo_json')
22
+ autoload :CSV, File.join(OGR_BASE, 'csv')
23
+ autoload :KML, File.join(OGR_BASE, 'kml')
26
24
  autoload :Tools, File.join(OGR_BASE, 'tools')
27
25
  autoload :Layer, File.join(OGR_BASE, 'layer')
28
26
  autoload :Feature, File.join(OGR_BASE, 'feature')
@@ -341,17 +339,36 @@ module OGR
341
339
  FFI::MemoryPointer.from_string(str)
342
340
  end
343
341
 
342
+ def get_writer(source)
343
+ extension = source.split('.').last
344
+ driver = DRIVER_TYPES[extension]
345
+
346
+ raise RuntimeError.new "Could not find appropriate driver" if driver.nil?
347
+
348
+ Writer.new(driver)
349
+ end
350
+
351
+ def create_writer(path)
352
+ raise RuntimeError.new "Path already exists: #{path}" if File.exists?(path)
353
+
354
+ writer = get_writer path
355
+ writer.set_output path
356
+ writer
357
+ end
358
+
344
359
  def read(source)
345
360
  case source
346
361
  when /http:|https:/
347
- UrlGeoJSONReader.new.read source
348
- when /.shp/
349
- ShpReader.new.read source
350
- when /.json|.geojson/
351
- GeoJSONReader.new.read source
362
+ HttpReader.new.read source
352
363
  else
353
- raise RuntimeError.new("Could not determine file type based on input")
364
+ extension = source.split('.').last
365
+ driver = DRIVER_TYPES[extension]
366
+
367
+ raise RuntimeError.new "Could not determine file type" if driver.nil?
368
+
369
+ Reader.new(driver).read source
354
370
  end
355
371
  end
356
372
  end
357
373
  end
374
+
@@ -0,0 +1,3 @@
1
+ module OGR
2
+ class CSV < DataSource;end
3
+ end
@@ -129,18 +129,35 @@ module OGR
129
129
  end
130
130
  alias_method :fields, :get_fields
131
131
 
132
- def to_shp(output_path, spatial_ref=nil)
132
+ def to_format(format, output_path, spatial_ref=nil)
133
133
  raise RuntimeError.new("Output path not specified.") if output_path.nil?
134
134
 
135
135
  # TODO: handle parsing of spatial_ref -> copy options
136
136
 
137
- if spatial_ref.instance_of? OGR::SpatialReference
138
- copy_with_transform('shapefile', output_path, spatial_ref)
139
- elsif spatial_ref.nil?
140
- copy('shapefile', output_path, spatial_ref)
137
+ unless spatial_ref
138
+ copy format, output_path, spatial_ref
139
+ else
140
+ if spatial_ref[:spatial_ref].instance_of? OGR::SpatialReference
141
+ copy_with_transform format, output_path, spatial_ref[:spatial_ref]
142
+ else
143
+ raise RuntimeError.new("Invalid spatial reference specified.")
144
+ end
141
145
  end
142
146
  end
143
147
 
148
+ def to_shp(output_path, spatial_ref=nil)
149
+ to_format('shapefile', output_path, spatial_ref)
150
+ end
151
+
152
+ def to_csv(output_path, spatial_ref=nil)
153
+ to_format('csv', output_path, spatial_ref)
154
+ end
155
+
156
+ def to_kml(output_path, spatial_ref=nil)
157
+ warn "KML output will always be in EPSG:4326" unless spatial_ref.nil?
158
+ to_format('kml', output_path, spatial_ref)
159
+ end
160
+
144
161
  def to_geojson(output_path, options=nil)
145
162
  raise RuntimeError.new("Output path not specified.") if output_path.nil?
146
163
 
@@ -0,0 +1,37 @@
1
+ require 'fileutils'
2
+ require 'securerandom'
3
+ require 'faraday'
4
+
5
+ module OGR
6
+ class HttpReader
7
+ def read(url, writeable=false)
8
+ file_extension = url.split('.').last
9
+ driver = OGR::DRIVER_TYPES[file_extension]
10
+
11
+ if driver.nil?
12
+ unless url =~ /FeatureServer/
13
+ raise RuntimeError.new "File type not supported."
14
+ else
15
+ # ? assume Esri Feature Service ?
16
+ file_extension = 'json'
17
+ driver = OGR::DRIVER_TYPES[file_extension]
18
+ end
19
+ end
20
+
21
+ file_name = "#{SecureRandom.urlsafe_base64}.#{file_extension}"
22
+
23
+ http_resource = Faraday.get(url).body
24
+
25
+ File.open(file_name, 'wb') do |f|
26
+ f.write http_resource
27
+ end
28
+
29
+ ds = Reader.new(driver).read(file_name, writeable)
30
+
31
+ FileUtils.rm file_name
32
+
33
+ ds
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,4 @@
1
+ module OGR
2
+ class KML < DataSource;end
3
+ end
4
+
@@ -2,6 +2,8 @@ module OGR
2
2
  class Reader
3
3
  include OGR::FFIOGR
4
4
 
5
+ attr_accessor :type
6
+
5
7
  TF_MAP = {
6
8
  true => 1,
7
9
  false => 0,
@@ -9,20 +11,11 @@ module OGR
9
11
  0 => false
10
12
  }
11
13
 
12
- # Reader Class NOT to be used directly
13
- # Use subclasses e.g. ShpReader
14
- def initialize;end
15
-
16
- def self.from_file_type(path)
17
- path = File.expand_path(path)
18
-
19
- if path =~ /.shp/
20
- ShpReader.new
21
- elsif path =~ /.geojson|.json/
22
- GeoJSONReader.new
23
- else
24
- raise RuntimeError.new("Could not determine appropriate reader for this file type")
25
- end
14
+ def initialize(driver_name)
15
+ OGRRegisterAll()
16
+ @driver = OGRGetDriverByName(driver_name)
17
+ raise RuntimeError.new "Invalid driver name" if @driver.null?
18
+ @type = driver_name
26
19
  end
27
20
 
28
21
  def read(file_path, writeable=false)
@@ -31,3 +24,4 @@ module OGR
31
24
  end
32
25
  end
33
26
  end
27
+
@@ -1,3 +1,3 @@
1
1
  module OGR
2
- VERSION = '0.1.0.pre'
2
+ VERSION = '0.1.0.pre2'
3
3
  end
@@ -2,9 +2,14 @@ module OGR
2
2
  class Writer
3
3
  include OGR::FFIOGR
4
4
 
5
- attr_accessor :ptr
5
+ attr_accessor :ptr, :type
6
6
 
7
- def initialize;end
7
+ def initialize(driver_name)
8
+ OGRRegisterAll()
9
+ @driver = OGRGetDriverByName(driver_name)
10
+ raise RuntimeError.new "Invalid driver name" if @driver.null?
11
+ @type = driver_name
12
+ end
8
13
 
9
14
  def set_output(path, options={})
10
15
  path = File.expand_path(path)
@@ -12,31 +17,6 @@ module OGR
12
17
  @ptr = OGR::Tools.cast_data_source(ds)
13
18
  @ptr
14
19
  end
15
-
16
- def self.from_file_type(path)
17
- path = File.expand_path(path)
18
-
19
- unless File.exists? path
20
- if path =~ /.shp/
21
- writer = ShpWriter.new
22
- elsif path =~ /.geojson|.json/
23
- writer = GeoJSONWriter.new
24
- else
25
- raise RuntimeError.new("Could not determine appropriate writer for this file type")
26
- end
27
-
28
- writer.set_output(path)
29
- writer
30
- else
31
- raise RuntimeError.new("Path already exists: #{path}")
32
- end
33
- end
34
-
35
- def export(output_path)
36
- writer = Writer.from_file_type output_path
37
- data_source = writer.ds
38
-
39
- # @ptr -> data_source
40
- end
41
20
  end
42
21
  end
22
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-ogr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.pre
4
+ version: 0.1.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scooter Wadsworth
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-01 00:00:00.000000000 Z
11
+ date: 2013-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description: FFI wrapper for OGR
84
98
  email:
85
99
  - scooterwadsworth@gmail.com
@@ -91,19 +105,16 @@ files:
91
105
  - README.md
92
106
  - bin/ogr_console
93
107
  - lib/ffi-ogr/coordinate_transformation.rb
108
+ - lib/ffi-ogr/csv.rb
94
109
  - lib/ffi-ogr/data_source.rb
95
110
  - lib/ffi-ogr/envelope.rb
96
111
  - lib/ffi-ogr/feature.rb
97
- - lib/ffi-ogr/feature_service_reader.rb
98
- - lib/ffi-ogr/generic_reader.rb
99
- - lib/ffi-ogr/generic_writer.rb
100
112
  - lib/ffi-ogr/geo_json.rb
101
- - lib/ffi-ogr/geo_json_reader.rb
102
- - lib/ffi-ogr/geo_json_writer.rb
103
113
  - lib/ffi-ogr/geometry.rb
104
114
  - lib/ffi-ogr/geometry_collection.rb
105
115
  - lib/ffi-ogr/geometry_collection_25d.rb
106
- - lib/ffi-ogr/github_reader.rb
116
+ - lib/ffi-ogr/http_reader.rb
117
+ - lib/ffi-ogr/kml.rb
107
118
  - lib/ffi-ogr/layer.rb
108
119
  - lib/ffi-ogr/line_string.rb
109
120
  - lib/ffi-ogr/line_string_25d.rb
@@ -121,11 +132,8 @@ files:
121
132
  - lib/ffi-ogr/polygon_25d.rb
122
133
  - lib/ffi-ogr/reader.rb
123
134
  - lib/ffi-ogr/shapefile.rb
124
- - lib/ffi-ogr/shp_reader.rb
125
- - lib/ffi-ogr/shp_writer.rb
126
135
  - lib/ffi-ogr/spatial_reference.rb
127
136
  - lib/ffi-ogr/tools.rb
128
- - lib/ffi-ogr/url_geo_json_reader.rb
129
137
  - lib/ffi-ogr/version.rb
130
138
  - lib/ffi-ogr/writer.rb
131
139
  - lib/ffi-ogr.rb
@@ -1,3 +0,0 @@
1
- module OGR
2
- class FeatureServiceReader < UrlGeoJSONReader;end
3
- end
@@ -1,9 +0,0 @@
1
- module OGR
2
- class GenericReader < Reader
3
- def initialize(driver_name)
4
- OGRRegisterAll()
5
- @driver = OGRGetDriverByName(driver_name)
6
- raise RuntimeError.new("Invalid driver name") if @driver.null?
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module OGR
2
- class GenericWriter < Writer
3
- def initialize(driver_name)
4
- OGRRegisterAll()
5
- @driver = OGRGetDriverByName(driver_name)
6
- raise RuntimeError.new("Invalid driver name") if @driver.null?
7
- end
8
- end
9
- end
@@ -1,8 +0,0 @@
1
- module OGR
2
- class GeoJSONReader < Reader
3
- def initialize
4
- OGRRegisterAll()
5
- @driver = OGRGetDriverByName("GeoJSON")
6
- end
7
- end
8
- end
@@ -1,8 +0,0 @@
1
- module OGR
2
- class GeoJSONWriter < Writer
3
- def initialize
4
- OGRRegisterAll()
5
- @driver = OGRGetDriverByName("GeoJSON")
6
- end
7
- end
8
- end
@@ -1,3 +0,0 @@
1
- module OGR
2
- class GithubReader < UrlGeoJSONReader;end
3
- end
@@ -1,8 +0,0 @@
1
- module OGR
2
- class ShpReader < Reader
3
- def initialize
4
- OGRRegisterAll()
5
- @driver = OGRGetDriverByName("ESRI Shapefile")
6
- end
7
- end
8
- end
@@ -1,8 +0,0 @@
1
- module OGR
2
- class ShpWriter < Writer
3
- def initialize
4
- OGRRegisterAll()
5
- @driver = OGRGetDriverByName("ESRI Shapefile")
6
- end
7
- end
8
- end
@@ -1,22 +0,0 @@
1
- require 'fileutils'
2
- require 'securerandom'
3
- require 'faraday'
4
-
5
- module OGR
6
- class UrlGeoJSONReader < GeoJSONReader
7
- def read(url, writeable=false)
8
- file_name = "#{SecureRandom.urlsafe_base64}.json"
9
- remote_json = Faraday.get(url).body
10
-
11
- File.open(file_name, 'wb') do |f|
12
- f.write(remote_json)
13
- end
14
-
15
- data_source = super(file_name, writeable)
16
-
17
- FileUtils.rm(file_name)
18
-
19
- data_source
20
- end
21
- end
22
- end