shp2geocouch 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/LICENSE +20 -0
- data/README.textile +44 -0
- data/Rakefile +17 -0
- data/VERSION +1 -0
- data/bin/shp2geocouch +124 -0
- 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
|
+
|