shp2geocouch 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/.gitignore +1 -0
  2. data/LICENSE +20 -0
  3. data/README.textile +44 -0
  4. data/Rakefile +17 -0
  5. data/VERSION +1 -0
  6. data/bin/shp2geocouch +124 -0
  7. metadata +73 -0
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .DS_Store
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Max Ogden
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,44 @@
1
+ h1. shp2geocouch
2
+
3
+ This is an executable rubygem that creates "GeoCouch":http://www.github.com/vmx/couchdb databases from ESRI Shapefiles in one easy step
4
+
5
+ h2. Installation
6
+
7
+ You will need access to a GeoCouch server. For instructions on setting up your own local GeoCouch, check out "my related blog post":http://maxogden.com.
8
+
9
+ Install dependencies:
10
+ @unzip@, @sed@, @ogr2ogr@
11
+
12
+ If you are on Mac OS X, you will already have @unzip@ and @sed@ installed. To get @ogr2ogr@, install "Homebrew":http://github.com/mxcl/homebrew and run @brew install gdal@.
13
+
14
+ Note: @ogr2ogr@ is usually included with the @gdal@ package (sometimes called @gdal-bin@).
15
+
16
+ Install the @shp2geocouch@ gem:
17
+
18
+ @gem install shp2geocouch@
19
+
20
+ h2. Usage
21
+
22
+ @shp2geocouch <path_to_shapefile> [your-geocouch-root-url (optional, default: http://localhost:5984)]@
23
+
24
+ example: @shp2geocouch /sweet_geo_data/Portland_Oregon_Public_Libraries.shp@
25
+ another possible example: @shp2geocouch /zipped_shapfiles/US_Railroads.zip http://myusername.couchone.com@
26
+
27
+ Once completed, you can run bounding box queries against your data! Visit the following link to receive a dump of your entire dataset as GeoJSON (a bounding box that covers the entire planet):
28
+ @http://localhost:5984/your_db_name/_design/geojson/_spatial/points?bbox=-180,180,-90,90@
29
+
30
+ If you uploaded a large dataset, you may experience a delay on the first ever spatial query as GeoCouch builds it's spatial index. You can check the status of the indexer by visiting @http://localhost:5984/_utils/status.html@
31
+
32
+ h3. Arguments:
33
+
34
+ * You can feed in either a @.shp@ file or a @.zip@ that contains a @.shp@
35
+ * @-v@ for verbose
36
+ * @--no-cleanup@ if you want @shp2geocouch@ to leave you a copy of unzipped Shapefile and converted JSON.
37
+
38
+ h2. What?
39
+
40
+ Raw geographic data is awesome, especially when it available online from entities like local governments. Unfortunately, a lot of agencies store and release their data in a proprietary format called a Shapefile, which was developed by a large for-profit corporation called ESRI, whose closed source desktop GIS software is ubiquitous in the academic and government GIS circles.
41
+
42
+ GeoCouch is a free and open source geospatial data store that is built on the the popular Apache CouchDB database. With GeoCouch, you serve your geographic data 'a la carte', or in small relevant chunks instead of having to download the entire dataset at a time. This pattern works especially well on the web, as you wouldn't want to go giving the list of all 10,000 bus stops to someone on a cellphone that's requesting just the 5 bus stops that are nearest to their location.
43
+
44
+ @shp2geocouch@ is a utility that will take a Shapefile and create a new GeoCouch database on your GeoCouch server which will contain the geographic data from the Shapefile.
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "shp2geocouch"
8
+ gem.summary = "rubygem that converts Shapefiles into GeoCouch databases"
9
+ gem.description = "rubygem that converts Shapefiles into GeoCouch databases"
10
+ gem.email = "max@maxogden.com"
11
+ gem.homepage = "http://github.com/maxogden/shp2geocouch"
12
+ gem.authors = ["Max Ogden"]
13
+ end
14
+ Jeweler::GemcutterTasks.new
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
17
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/bin/shp2geocouch ADDED
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env ruby
2
+ require 'httparty'
3
+ require 'couchrest'
4
+ require 'optparse'
5
+
6
+ class ShapefileToGeoCouch
7
+ attr_accessor :path, :extension, :name, :couch_url, :cleanup, :verbose
8
+
9
+ def initialize(options)
10
+ set_accessors(options)
11
+ @db = CouchRest.database! database_url
12
+ verify_dependencies
13
+ convert
14
+ upload
15
+ add_ddoc
16
+ cleanup if @cleanup
17
+ puts "Upload complete. Test your data at #{database_url}/_design/geojson/_spatial/points?bbox=-180,180,-90,90" if @verbose
18
+ end
19
+
20
+ def set_accessors(options)
21
+ options.each {|k,v| send("#{k.to_s}=",v)}
22
+ end
23
+
24
+ def verify_dependencies
25
+ %w(ogr2ogr sed unzip).each do |dependency|
26
+ unless %x!which #{dependency}![dependency]
27
+ raise "#{dependency} isn't installed or isn't in your current path."
28
+ end
29
+ end
30
+ begin
31
+ @db.get("")
32
+ rescue Errno::ECONNREFUSED
33
+ raise "Couldnt find a Couch instance running at #{@couch_url}"
34
+ end
35
+ end
36
+
37
+ def database_url
38
+ "#{@couch_url}/#{@name}"
39
+ end
40
+
41
+ def output_folder
42
+ File.expand_path("#{@name}_converted", Dir.pwd)
43
+ end
44
+
45
+ def find_shapefile
46
+ Dir.glob(output_folder + "/**/*.shp")[0]
47
+ end
48
+
49
+ def json
50
+ "#{output_folder}/#{@name}.json"
51
+ end
52
+
53
+ def bulk
54
+ "#{output_folder}/#{@name}_bulk.json"
55
+ end
56
+
57
+ def unzip
58
+ puts "Unzipping into #{output_folder}..." if @verbose
59
+ `unzip #{@path} -d #{output_folder}`
60
+ end
61
+
62
+ def convert
63
+ `mkdir -p #{output_folder}`
64
+ if @extension =~ /zip/i
65
+ unzip
66
+ shapefile = find_shapefile
67
+ else
68
+ shapefile = @path
69
+ end
70
+ puts "Converting Shapefile, saving as #{json}..." if @verbose
71
+ %x!ogr2ogr -t_srs EPSG:4326 -a_srs EPSG:4326 -f "GeoJSON" #{json} #{shapefile}!
72
+ puts "Reformatting json for bulk import, saving as #{bulk}..." if @verbose
73
+ %x!sed -e '/^\"type\": \"FeatureCollection\",$/d' -e '/^\"features\": \\[$/d' -e '/^{$/d' -e '/^,$/d' -e '/^}$/d' -e '/^]$/d' -e '/^$/d' -e 's/$/,/' #{json} > #{bulk}!
74
+ end
75
+
76
+ def upload
77
+ puts "Bulk loading data into GeoCouch... view progress at #{@couch_url}/_utils" if @verbose
78
+ File.open(bulk).each_line do |line|
79
+ HTTParty.post(database_url + '/_bulk_docs', :body => '{"docs": [' + line[0..-3] + "]}", :headers => {'content-type' => "application/json"})
80
+ end
81
+ end
82
+
83
+ def add_ddoc
84
+ puts "Adding spatial index design document..." if @verbose
85
+ view_exists = @db.get('_design/geojson') rescue false
86
+ unless view_exists
87
+ @db.save_doc({
88
+ "_id" => "_design/geojson",
89
+ "spatial" => {
90
+ :points => "function(doc) { emit(doc.geometry, {id: doc._id, geometry: doc.geometry}) };"
91
+ }
92
+ })
93
+ end
94
+ end
95
+
96
+ def cleanup
97
+ puts "Cleaning up..." if @verbose
98
+ %x!rm -rf #{output_folder}!
99
+ end
100
+ end
101
+
102
+ defaults = {:cleanup => true, :verbose => false}
103
+ OptionParser.new do |opts|
104
+ opts.banner = "Usage: #{__FILE__} [path-to-shapefile] [your-geocouch-root-url (optional, default: http://localhost:5984)]"
105
+ opts.on("--no-cleanup", "Don't remove converted files after upload") do |v|
106
+ defaults[:cleanup] = false
107
+ end
108
+
109
+ opts.on('-v') do |v|
110
+ defaults[:verbose] = true
111
+ end
112
+ end.parse!
113
+
114
+ raise "You must specify a Shapefile to convert." if ARGV[0].nil?
115
+
116
+ extension = ARGV[0].split('.')[1]
117
+ raise "You must specify a .shp or a .zip" unless extension =~ /zip|shp/i
118
+
119
+ name = ARGV[0].split('/')[-1].split('.')[0]
120
+
121
+ options = {:path => ARGV[0], :name => name.downcase, :extension => extension}.merge(defaults)
122
+ options[:couch_url] = ARGV[1] || "http://localhost:5984"
123
+
124
+ ShapefileToGeoCouch.new(options)
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shp2geocouch
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Max Ogden
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-09-05 00:00:00 -07:00
19
+ default_executable: shp2geocouch
20
+ dependencies: []
21
+
22
+ description: rubygem that converts Shapefiles into GeoCouch databases
23
+ email: max@maxogden.com
24
+ executables:
25
+ - shp2geocouch
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - LICENSE
30
+ - README.textile
31
+ files:
32
+ - .gitignore
33
+ - LICENSE
34
+ - README.textile
35
+ - Rakefile
36
+ - VERSION
37
+ - bin/shp2geocouch
38
+ has_rdoc: true
39
+ homepage: http://github.com/maxogden/shp2geocouch
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --charset=UTF-8
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ hash: 3
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ requirements: []
66
+
67
+ rubyforge_project:
68
+ rubygems_version: 1.3.7
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: rubygem that converts Shapefiles into GeoCouch databases
72
+ test_files: []
73
+