shapelib 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +36 -0
- data/LICENSE-CC-BY-SA-3.0 +375 -0
- data/LICENSE-LGPL +481 -0
- data/LICENSE-MIT +21 -0
- data/README.md +71 -4
- data/Rakefile +142 -33
- data/doc/Interface.html +53 -32
- data/doc/Interface.rd +51 -30
- data/ext/shapelib_ext/extconf.rb +5 -1
- data/ext/shapelib_ext/main.c +3 -0
- data/ext/shapelib_ext/sfcode.h +49 -17
- data/ext/shapelib_ext/sflist.h +18 -18
- data/ext/shapelib_ext/shpplus.c +245 -57
- data/ext/shapelib_ext/shpplus.h +1 -0
- data/ext/shapelib_ext/spcode.h +225 -106
- data/ext/shapelib_ext/splist.h +23 -23
- data/ext/shapelib_ext/spwkt.h +24 -19
- data/ext/shapelib_ext/valconv.h +33 -12
- data/lib/shapelib/shape.rb +4 -1
- data/lib/shapelib/version.rb +3 -1
- data/lib/shapelib.rb +2 -1
- data/shapelib.gemspec +49 -49
- data/test/test_zillow_data.rb +2217 -1
- metadata +31 -9
data/Rakefile
CHANGED
|
@@ -1,48 +1,157 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'rubygems'
|
|
2
4
|
require 'rake'
|
|
3
|
-
require '
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
5
|
+
require 'open3'
|
|
6
|
+
require 'tmpdir'
|
|
7
|
+
require 'rbconfig'
|
|
8
|
+
require 'shellwords'
|
|
9
|
+
require 'rake/clean'
|
|
10
|
+
require 'rake/testtask'
|
|
11
|
+
require 'rubygems/package_task'
|
|
12
|
+
|
|
13
|
+
desc 'Build with Clang in C23 mode and run the tests in isolation'
|
|
14
|
+
task 'c23-test' do
|
|
15
|
+
root = __dir__
|
|
16
|
+
compiler = ENV.fetch('CC', 'clang')
|
|
17
|
+
flags = "#{ENV.fetch('CFLAGS', RbConfig::CONFIG['CFLAGS'])} -std=gnu2x"
|
|
18
|
+
make = Shellwords.split(ENV['MAKE'] || RbConfig::CONFIG['MAKE'] || 'make')
|
|
19
|
+
tests = Dir.glob(File.join(root, 'test/**/test_*.rb')).sort
|
|
20
|
+
abort 'c23-test: no test files found.' if tests.empty?
|
|
21
|
+
|
|
22
|
+
build_dir = Dir.mktmpdir('shapelib-c23-')
|
|
23
|
+
puts "C23 compiler: #{compiler}"
|
|
24
|
+
puts "C23 build directory: #{build_dir}"
|
|
25
|
+
configure = <<~'RUBY'
|
|
26
|
+
require 'rbconfig'
|
|
27
|
+
RbConfig::MAKEFILE_CONFIG['CC'] = RbConfig::CONFIG['CC'] = ARGV.shift
|
|
28
|
+
$0 = ARGV.shift
|
|
29
|
+
load $0
|
|
30
|
+
RUBY
|
|
31
|
+
Dir.chdir(build_dir) do
|
|
32
|
+
sh Gem.ruby, '-e', configure, compiler,
|
|
33
|
+
File.join(root, 'ext/shapelib_ext/extconf.rb'), "--with-cflags=#{flags}"
|
|
34
|
+
sh(*make)
|
|
19
35
|
end
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
36
|
+
binary = File.join(build_dir, "shapelib_ext.#{RbConfig::CONFIG['DLEXT']}")
|
|
37
|
+
abort 'c23-test: the isolated extension was not built.' unless File.file?(binary)
|
|
38
|
+
sh Gem.ruby, "-I#{build_dir}", "-I#{File.join(root, 'lib')}", "-I#{File.join(root, 'test')}",
|
|
39
|
+
'-e', 'ARGV.each { |file| require File.expand_path(file) }', *tests
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
desc 'Build and test every installed RVM Ruby, with a results table and logs'
|
|
43
|
+
task 'rvm-test' do
|
|
44
|
+
root = __dir__
|
|
45
|
+
env = ENV.keys.grep(/\ABUNDLE_/).to_h { |key| [key, nil] }
|
|
46
|
+
env['RUBYOPT'] = nil
|
|
47
|
+
env['RUBYLIB'] = nil
|
|
48
|
+
|
|
49
|
+
begin
|
|
50
|
+
output, error, status = Open3.capture3(env, 'rvm', 'list', 'strings')
|
|
51
|
+
rescue Errno::ENOENT
|
|
52
|
+
abort 'rvm-test: RVM is not installed or its executable is not on PATH.'
|
|
53
|
+
end
|
|
54
|
+
abort "rvm-test: unable to list installed Rubies: #{error.strip}" unless status.success?
|
|
55
|
+
versions = output.lines.map(&:strip).reject(&:empty?).uniq.sort
|
|
56
|
+
abort 'rvm-test: no installed RVM Rubies found.' if versions.empty?
|
|
57
|
+
tests = Dir.glob(File.join(root, 'test/**/test_*.rb')).sort
|
|
58
|
+
abort 'rvm-test: no test files found.' if tests.empty?
|
|
59
|
+
|
|
60
|
+
logs = Dir.mktmpdir('shapelib-rvm-test-')
|
|
61
|
+
results = []
|
|
62
|
+
versions.each_with_index do |version, index|
|
|
63
|
+
puts "Testing #{version} (#{index + 1}/#{versions.length})..."
|
|
64
|
+
build_dir = File.join(logs, "build-#{index + 1}")
|
|
65
|
+
Dir.mkdir(build_dir)
|
|
66
|
+
run = lambda do |log, directory, *command|
|
|
67
|
+
system(env, 'rvm', version, 'do', *command, chdir: directory, out: log, err: %i[child out])
|
|
68
|
+
rescue SystemCallError => e
|
|
69
|
+
log.puts e.message
|
|
70
|
+
false
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
built = File.open(File.join(logs, "#{version}-build.log"), 'w') do |log|
|
|
74
|
+
run.call(log, build_dir, 'ruby', File.join(root, 'ext/shapelib_ext/extconf.rb')) && run.call(log, build_dir, 'make')
|
|
75
|
+
end
|
|
76
|
+
passed = if built
|
|
77
|
+
File.open(File.join(logs, "#{version}-test.log"), 'w') do |log|
|
|
78
|
+
run.call(log, root, 'ruby', "-I#{build_dir}", "-I#{File.join(root, 'lib')}", "-I#{File.join(root, 'test')}", '-e', 'ARGV.each { |file| require File.expand_path(file) }', *tests)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
results << [version, built ? 'PASS' : 'FAIL', if built
|
|
82
|
+
passed ? 'PASS' : 'FAIL'
|
|
83
|
+
else
|
|
84
|
+
'SKIPPED'
|
|
85
|
+
end]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
width = [4, *versions.map(&:length)].max
|
|
89
|
+
puts
|
|
90
|
+
puts format("%-#{width}s %-5s %s", 'Ruby', 'Build', 'Tests')
|
|
91
|
+
results.each { |row| puts format("%-#{width}s %-5s %s", *row) }
|
|
92
|
+
puts "Logs and isolated builds: #{logs}"
|
|
93
|
+
abort 'rvm-test: one or more versions failed; see the logs above.' if results.any? do |row|
|
|
94
|
+
row[1..2] != %w[PASS PASS]
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
spec = Gem::Specification.load(File.expand_path('shapelib.gemspec', __dir__))
|
|
99
|
+
abort 'Unable to load shapelib.gemspec' unless spec
|
|
100
|
+
Gem::PackageTask.new(spec) {}
|
|
101
|
+
|
|
102
|
+
desc 'Run tests, package the gem, and push it to RubyGems.org'
|
|
103
|
+
task release: %i[test gem] do
|
|
104
|
+
sh Gem.ruby, '-S', 'gem', 'push', File.join('pkg', spec.file_name)
|
|
23
105
|
end
|
|
24
106
|
|
|
25
|
-
require 'rake/testtask'
|
|
26
107
|
Rake::TestTask.new(:test) do |test|
|
|
27
|
-
test.libs = %w
|
|
108
|
+
test.libs = %w[lib test]
|
|
28
109
|
test.pattern = 'test/**/test_*.rb'
|
|
29
110
|
test.verbose = true
|
|
30
111
|
end
|
|
31
112
|
|
|
32
|
-
task :
|
|
33
|
-
task :
|
|
113
|
+
task test: :compile
|
|
114
|
+
task default: :test
|
|
115
|
+
|
|
116
|
+
build_dir = File.join('tmp', RUBY_PLATFORM, 'shapelib_ext', RUBY_VERSION)
|
|
117
|
+
extconf = File.expand_path('ext/shapelib_ext/extconf.rb', __dir__)
|
|
118
|
+
makefile = File.join(build_dir, 'Makefile')
|
|
119
|
+
binary = "shapelib_ext.#{RbConfig::CONFIG['DLEXT']}"
|
|
34
120
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
rdoc.rdoc_dir = 'rdoc'
|
|
39
|
-
rdoc.title = "shapelib"
|
|
40
|
-
rdoc.rdoc_files.include('README*')
|
|
41
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
121
|
+
file makefile => [extconf] do
|
|
122
|
+
mkdir_p build_dir
|
|
123
|
+
Dir.chdir(build_dir) { sh Gem.ruby, extconf, *ARGV.grep(/\A--?/) }
|
|
42
124
|
end
|
|
43
125
|
|
|
126
|
+
desc 'Compile the extension for the current Ruby'
|
|
127
|
+
task compile: makefile do
|
|
128
|
+
make = Shellwords.split(ENV['MAKE'] || RbConfig::CONFIG['MAKE'] || 'make')
|
|
129
|
+
Dir.chdir(build_dir) { sh(*make) }
|
|
130
|
+
cp File.join(build_dir, binary), File.join('lib', binary)
|
|
131
|
+
end
|
|
132
|
+
task 'compile:shapelib_ext' => :compile
|
|
133
|
+
|
|
134
|
+
CLEAN.include(build_dir)
|
|
135
|
+
CLOBBER.include('tmp', File.join('lib', binary))
|
|
136
|
+
|
|
137
|
+
rdoc_files = FileList['README*', 'lib/**/*.rb']
|
|
138
|
+
desc 'Build the HTML documentation'
|
|
139
|
+
task rdoc: 'rdoc/created.rid'
|
|
140
|
+
file 'rdoc/created.rid' => rdoc_files.to_a + ['Rakefile'] do
|
|
141
|
+
begin
|
|
142
|
+
require 'rdoc'
|
|
143
|
+
rescue LoadError => error
|
|
144
|
+
raise unless error.path == 'rdoc'
|
|
44
145
|
|
|
45
|
-
|
|
46
|
-
|
|
146
|
+
abort 'Documentation requires RDoc. Install it with: gem install rdoc'
|
|
147
|
+
end
|
|
148
|
+
RDoc::RDoc.new.document(['--op', 'rdoc', '--title', 'shapelib', *rdoc_files])
|
|
149
|
+
end
|
|
47
150
|
|
|
48
|
-
|
|
151
|
+
desc 'Rebuild the HTML documentation from scratch'
|
|
152
|
+
task rerdoc: %i[clobber_rdoc rdoc]
|
|
153
|
+
desc 'Remove generated HTML documentation'
|
|
154
|
+
task :clobber_rdoc do
|
|
155
|
+
rm_rf 'rdoc'
|
|
156
|
+
end
|
|
157
|
+
task clobber: :clobber_rdoc
|
data/doc/Interface.html
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
<link href="style.css" type="text/css" rel="stylesheet" />
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
|
-
<h1><a name="label-0" id="label-0">module
|
|
11
|
+
<h1><a name="label-0" id="label-0">module Shapelib</a></h1><!-- RDLabel: "module Shapelib" -->
|
|
12
12
|
<p>This module is a wrapper of C Shapefile Library
|
|
13
|
-
(also called <a href="http://shapelib.maptools.org/">
|
|
13
|
+
(also called <a href="http://shapelib.maptools.org/">Shapelib</a>).
|
|
14
14
|
It consists of basically two classes:
|
|
15
15
|
<a href="#label-5">ShapeFile</a> and <a href="#label-29">Shape</a>.
|
|
16
16
|
If you are unfamiliar with object-oriented programming,
|
|
@@ -20,17 +20,17 @@ please see <a href="#label-83">Appendix A: C to Ruby equivalence table</a>.</p>
|
|
|
20
20
|
<h2><a name="label-1" id="label-1">module functions</a></h2><!-- RDLabel: "module functions" -->
|
|
21
21
|
<p>Following three functions construct a point object.
|
|
22
22
|
It can be used like top level function after <code>include</code>:</p>
|
|
23
|
-
<pre>include
|
|
23
|
+
<pre>include Shapelib
|
|
24
24
|
pt = new_point(1, 2)</pre>
|
|
25
25
|
<p>Arguments <var>x</var>, <var>y</var>, <var>z</var>, and <var>m</var> <a href="#label-85">should be Float</a>.</p>
|
|
26
26
|
<dl>
|
|
27
|
-
<dt><a name="label-2" id="label-2"><code>
|
|
27
|
+
<dt><a name="label-2" id="label-2"><code>Shapelib.new_point <var>x</var>, <var>y</var></code></a></dt><!-- RDLabel: "Shapelib.new_point x, y" -->
|
|
28
28
|
<dd>
|
|
29
29
|
creates a <a href="#label-51">class Point</a> object.</dd>
|
|
30
|
-
<dt><a name="label-3" id="label-3"><code>
|
|
30
|
+
<dt><a name="label-3" id="label-3"><code>Shapelib.new_point <var>x</var>, <var>y</var>, <var>m</var></code></a></dt><!-- RDLabel: "Shapelib.new_point x, y, m" -->
|
|
31
31
|
<dd>
|
|
32
32
|
creates a <a href="#label-57">class PointM</a> object.</dd>
|
|
33
|
-
<dt><a name="label-4" id="label-4"><code>
|
|
33
|
+
<dt><a name="label-4" id="label-4"><code>Shapelib.new_point <var>x</var>, <var>y</var>, <var>m</var>, <var>z</var></code></a></dt><!-- RDLabel: "Shapelib.new_point x, y, m, z" -->
|
|
34
34
|
<dd>
|
|
35
35
|
creates a <a href="#label-59">class PointZ</a> object.</dd>
|
|
36
36
|
</dl>
|
|
@@ -52,14 +52,14 @@ or just basename (like "<code>basename</code>").
|
|
|
52
52
|
Suffix <code>.shp</code> must be lowercase if specified.
|
|
53
53
|
Both <code>.shp</code> and <code>.shx</code> files must exist at the specified path.</p>
|
|
54
54
|
<p>Argument <var>access</var> are passed to <code>fopen(3)</code> through
|
|
55
|
-
<a href="#label-92">
|
|
55
|
+
<a href="#label-92">Shapelib</a> <code>SHPOpen()</code> function.
|
|
56
56
|
Either '<code>rb</code>' or '<code>rb+</code>' should be used.</p>
|
|
57
57
|
<p>If a block is given to these constructors,
|
|
58
58
|
the opened shapefile object is yielded like File::open.
|
|
59
59
|
The shapefile is closed at the end of block,
|
|
60
60
|
and the constructor returns <code>nil</code>.</p>
|
|
61
61
|
<pre># example
|
|
62
|
-
|
|
62
|
+
Shapelib::ShapeFile.open(filename) { |fp|
|
|
63
63
|
print "#{filename} has #{fp.size} records.\n"
|
|
64
64
|
}</pre></dd>
|
|
65
65
|
<dt><a name="label-9" id="label-9"><code>ShapeFile::new <var>filename</var>, <var>shapetype</var>, <var>attrs</var></code></a></dt><!-- RDLabel: "ShapeFile::new filename, shapetype, attrs" -->
|
|
@@ -90,7 +90,14 @@ Argument <var>field_name</var> is a String for field name;
|
|
|
90
90
|
<var>field_type</var> specifies <a href="#label-87">field type</a>;
|
|
91
91
|
<var>width</var> is nonnegative Integer for field width in characters; and
|
|
92
92
|
<var>decimal</var> is nonnegative Integer for decimal points.
|
|
93
|
-
|
|
93
|
+
Field names must be at most 10 bytes and unique ignoring case.
|
|
94
|
+
Overlong or duplicate names raise ArgumentError before the field is added.
|
|
95
|
+
Only Float field requires <var>decimal</var>; otherwise it can be missing.
|
|
96
|
+
Integer and Float fields require <var>decimal</var> between 0 and 255 inclusive.
|
|
97
|
+
Date fields require width 8 and zero decimal places. They are available
|
|
98
|
+
when the native shapelib headers provide FTDate (shapelib 1.5.0 or newer).
|
|
99
|
+
Date values are eight-digit YYYYMMDD Strings, or nil for nulls.
|
|
100
|
+
Writes check the eight-digit format without calendar validation.</p>
|
|
94
101
|
<pre># example
|
|
95
102
|
fp.add_field 'name', :String, 32
|
|
96
103
|
fp.add_field 'height', "Float", 9, 1</pre></dd>
|
|
@@ -119,8 +126,9 @@ returns the name of the attribute field with <var>index</var>, or nil on failure
|
|
|
119
126
|
<dd>
|
|
120
127
|
returns the type of the <a href="#label-89">attribute field</a>.
|
|
121
128
|
The result is Symbol
|
|
122
|
-
(one of :String, :Integer, :Float, :Logical, or :Invalid)
|
|
123
|
-
or nil on failure
|
|
129
|
+
(one of :String, :Integer, :Float, :Logical, :Date, or :Invalid)
|
|
130
|
+
or nil on failure.
|
|
131
|
+
Older native libraries classify Date fields as :String.</dd>
|
|
124
132
|
<dt><a name="label-19" id="label-19"><code>shapefile.field_width <var>field</var></code></a></dt><!-- RDLabel: "shapefile.field_width field" -->
|
|
125
133
|
<dd>
|
|
126
134
|
returns the width of the <a href="#label-89">attribute field</a>.</dd>
|
|
@@ -142,7 +150,9 @@ the next record to previously read one
|
|
|
142
150
|
(or the first record #0 for the first time) is used.
|
|
143
151
|
An instance of <a href="#label-29">class Shape</a> is returned,
|
|
144
152
|
including all attributes written on the DBF.
|
|
145
|
-
|
|
153
|
+
At end of file or on a geometry-read failure, <code>nil</code> is returned.
|
|
154
|
+
If a DBF with attribute fields is present but its record cannot be read,
|
|
155
|
+
IOError is raised. Files without a DBF or with no fields remain readable.</dd>
|
|
146
156
|
<dt><a name="label-24" id="label-24"><code>shapefile.rewind</code></a></dt><!-- RDLabel: "shapefile.rewind" -->
|
|
147
157
|
<dd>
|
|
148
158
|
After that, <a href="#label-23">shapefile.read</a>
|
|
@@ -159,7 +169,8 @@ returns the number of records (or shapes) in the shapefile.
|
|
|
159
169
|
writes <var>shape</var> into shapefile at record number <var>rec</var>.
|
|
160
170
|
The <var>shape</var> must be a instance of <a href="#label-29">class Shape</a> or subclass.
|
|
161
171
|
Attributes attached to <var>shape</var> are stored into DBF file.
|
|
162
|
-
If <var>rec</var> is missing, the record is appended at the end of shapefile
|
|
172
|
+
If <var>rec</var> is missing, nil, or -1, the record is appended at the end of shapefile.
|
|
173
|
+
An existing nonnegative record index replaces that record.</dd>
|
|
163
174
|
<dt><a name="label-28" id="label-28"><code>shapefile.close</code></a></dt><!-- RDLabel: "shapefile.close" -->
|
|
164
175
|
<dd>
|
|
165
176
|
<p>The <code>close</code> method flushes all information
|
|
@@ -270,7 +281,7 @@ returns the <a href="#label-86">type of shape</a> by Symbol.</dd>
|
|
|
270
281
|
<p>returns a hash that contains all attributes and geometry information.
|
|
271
282
|
Each attribute have a key of String,
|
|
272
283
|
while geometry information has keys of Symbol.</p>
|
|
273
|
-
<pre>pt =
|
|
284
|
+
<pre>pt = Shapelib::Point::new(1, 2, 'name' => 'Madison')
|
|
274
285
|
pt.to_h => {"name"=>"Madison", :zvals=>[0.0], :n_parts=>0,
|
|
275
286
|
:n_vertices=>1, :maxbound=>[1.0, 2.0, 0.0, 0.0],
|
|
276
287
|
:part_start=>nil, :part_type=>nil, :xvals=>[1.0],
|
|
@@ -285,29 +296,29 @@ Note that this lose information.</dd>
|
|
|
285
296
|
<p>returns WKT (well known text) representation of geometry
|
|
286
297
|
as defined in <a href="#label-94">ISO 19125-1</a>.
|
|
287
298
|
<em>Caution: current implementation does not always handle Polygon[MZ] and MultiPatch correctly.</em></p>
|
|
288
|
-
<pre>
|
|
299
|
+
<pre>Shapelib::Arc.new([1, 2], [3, 4], [5, 6]).wkt
|
|
289
300
|
=> "LINESTRING(1 2, 3 4, 5 6)"
|
|
290
|
-
|
|
301
|
+
Shapelib::Arc.new([[1, 2], [3, 4]], [[5, 6], [7, 8]]).wkt
|
|
291
302
|
=> "MULTILINESTRING((1 2, 3 4), (5 6, 7 8))"</pre></dd>
|
|
292
303
|
<dt><a name="label-47" id="label-47"><code>shape.xvals</code></a></dt><!-- RDLabel: "shape.xvals" -->
|
|
293
304
|
<dd>
|
|
294
305
|
<p>returns an array of x values.</p>
|
|
295
|
-
<pre>
|
|
306
|
+
<pre>Shapelib::Arc.new([1, 2], [3, 4], [5, 6]).xvals
|
|
296
307
|
=> [1.0, 3.0, 5.0]</pre>
|
|
297
308
|
<p>Multipart shape results flattened array (all parts joined).</p>
|
|
298
|
-
<pre>
|
|
309
|
+
<pre>Shapelib::Arc.new([[1, 2], [3, 4]], [[5, 6], [7, 8]]).xvals
|
|
299
310
|
=> [1.0, 3.0, 5.0, 7.0]</pre></dd>
|
|
300
311
|
<dt><a name="label-48" id="label-48"><code>shape.yvals</code></a></dt><!-- RDLabel: "shape.yvals" -->
|
|
301
312
|
<dd>
|
|
302
313
|
<p>returns an array of y values.</p>
|
|
303
|
-
<pre>
|
|
314
|
+
<pre>Shapelib::Arc.new([1, 2], [3, 4], [5, 6]).xvals
|
|
304
315
|
=> [2.0, 4.0, 6.0]</pre></dd>
|
|
305
316
|
<dt><a name="label-49" id="label-49"><code>shape.mvals</code></a></dt><!-- RDLabel: "shape.mvals" -->
|
|
306
317
|
<dd>
|
|
307
318
|
<p>returns an array of m values. Nil is returned for missing value.</p>
|
|
308
|
-
<pre>
|
|
319
|
+
<pre>Shapelib::Arc.new([1, 2], [3, 4], [5, 6]).mvals
|
|
309
320
|
=> [nil, nil, nil]
|
|
310
|
-
|
|
321
|
+
Shapelib::ArcM.new([1, 2, 3], [4, 5, 6], [7, 8, 9]).mvals
|
|
311
322
|
=> [3, 6, 9]</pre></dd>
|
|
312
323
|
<dt><a name="label-50" id="label-50"><code>shape.zvals</code></a></dt><!-- RDLabel: "shape.zvals" -->
|
|
313
324
|
<dd>
|
|
@@ -382,7 +393,11 @@ Constructs a object with multiple polygons.</dd>
|
|
|
382
393
|
<dt><a name="label-72" id="label-72"><code>MultiPoint::new <var>point</var>, <var>point</var>, ...</code></a></dt><!-- RDLabel: "MultiPoint::new point, point, ..." -->
|
|
383
394
|
<dt><a name="label-73" id="label-73"><code>MultiPoint::new [<var>point</var>, <var>point</var>, ...]</code></a></dt><!-- RDLabel: "MultiPoint::new [point, point, ...]" -->
|
|
384
395
|
<dd>
|
|
385
|
-
Above two are the same
|
|
396
|
+
Above two are the same for a nonempty list of points. Each point may
|
|
397
|
+
be a coordinate array [x, y, m, z] or an object with x and y methods.
|
|
398
|
+
A single coordinate array is also accepted. No arguments create an
|
|
399
|
+
empty MultiPoint; for compatibility, a single empty array creates
|
|
400
|
+
one point at the origin.</dd>
|
|
386
401
|
</dl>
|
|
387
402
|
<h2><a name="label-74" id="label-74">class MultiPointM</a></h2><!-- RDLabel: "class MultiPointM" -->
|
|
388
403
|
<p>MultiPointM is similar to MultiPoint, but points also have m (measure) coordinates.</p>
|
|
@@ -398,9 +413,11 @@ Note that the first element of each array must be <a href="#label-88">part type<
|
|
|
398
413
|
<h2><a name="label-78" id="label-78">constants</a></h2><!-- RDLabel: "constants" -->
|
|
399
414
|
<h3><a name="label-79" id="label-79">Field Type Constants</a></h3><!-- RDLabel: "Field Type Constants" -->
|
|
400
415
|
<dl>
|
|
401
|
-
<dt><a name="label-80" id="label-80"><code>
|
|
402
|
-
<dt><a name="label-81" id="label-81"><code>
|
|
403
|
-
<dt><a name="label-82" id="label-82"><code>
|
|
416
|
+
<dt><a name="label-80" id="label-80"><code>Shapelib::String</code></a></dt><!-- RDLabel: "Shapelib::String" -->
|
|
417
|
+
<dt><a name="label-81" id="label-81"><code>Shapelib::Integer</code></a></dt><!-- RDLabel: "Shapelib::Integer" -->
|
|
418
|
+
<dt><a name="label-82" id="label-82"><code>Shapelib::Float</code></a></dt><!-- RDLabel: "Shapelib::Float" -->
|
|
419
|
+
<dt><code>Shapelib::Date</code></dt>
|
|
420
|
+
<dd>Available when the native shapelib headers provide FTDate.</dd>
|
|
404
421
|
</dl>
|
|
405
422
|
<h2><a name="label-83" id="label-83">Appendix A: C to Ruby equivalence table</a></h2><!-- RDLabel: "Appendix A: C to Ruby equivalence table" -->
|
|
406
423
|
<ul>
|
|
@@ -478,8 +495,12 @@ This appendix discusses the detail of acceptable value.</p>
|
|
|
478
495
|
<dd>
|
|
479
496
|
Any object that respond to <code>to_f</code> is converted to Float.
|
|
480
497
|
String is not acceptable.
|
|
481
|
-
<code>nil</code> is treated as -
|
|
498
|
+
<code>nil</code> is treated as -2e38 (NODATA) for <var>m</var> (measure) coordinate,
|
|
482
499
|
or as 0.0 otherwise.
|
|
500
|
+
Measures below -1e38 are read as nil; exactly -1e38 is valid.
|
|
501
|
+
The exact legacy null marker -2e-38 is also read as nil for compatibility
|
|
502
|
+
with files written by older versions of this gem. Other negative measures
|
|
503
|
+
are preserved.
|
|
483
504
|
</dd>
|
|
484
505
|
<dt><a name="label-86" id="label-86">type of shapes</a></dt><!-- RDLabel: "type of shapes" -->
|
|
485
506
|
<dd>
|
|
@@ -487,9 +508,9 @@ For <a href="#label-9">ShapeFile::new</a>
|
|
|
487
508
|
and <a href="#label-32">Shape::new</a>,
|
|
488
509
|
acceptable values for <var>shapetype</var> are:
|
|
489
510
|
<ul>
|
|
490
|
-
<li>Class object like
|
|
511
|
+
<li>Class object like Shapelib::Point (listed in <a href="#label-30">structure of subclasses</a>)</li>
|
|
491
512
|
<li>String such as <code>"Point"</code> or <code>"PolygonZ"</code>
|
|
492
|
-
(the same list, but do not include "
|
|
513
|
+
(the same list, but do not include "Shapelib::")</li>
|
|
493
514
|
<li>Symbol such as <code>:Point</code> or <code>:PolygonZ</code>
|
|
494
515
|
(result of <a href="#label-25">shapefile.shape_type</a> and <a href="#label-43">shape.shape_type</a>),
|
|
495
516
|
or</li>
|
|
@@ -502,8 +523,8 @@ acceptable values for <var>shapetype</var> are:
|
|
|
502
523
|
For <a href="#label-12">shapefile.add_field</a>,
|
|
503
524
|
acceptable values for <var>field_type</var> are:
|
|
504
525
|
<ul>
|
|
505
|
-
<li>String "String", "Integer", or "
|
|
506
|
-
<li>Symbol :String, :Integer, or :
|
|
526
|
+
<li>String "String", "Integer", "Float", "Logical", or "Date", or</li>
|
|
527
|
+
<li>Symbol :String, :Integer, :Float, :Logical, or :Date
|
|
507
528
|
(result of <a href="#label-18">shapefile.field_type</a>).</li>
|
|
508
529
|
<li>Integer constants listed <a href="#label-79">above</a>.</li>
|
|
509
530
|
</ul>
|
|
@@ -533,7 +554,7 @@ For <a href="#label-32">Shape::new hash</a>, the argument <var>hash</var>
|
|
|
533
554
|
</dl>
|
|
534
555
|
<h2><a name="label-91" id="label-91">References</a></h2><!-- RDLabel: "References" -->
|
|
535
556
|
<dl>
|
|
536
|
-
<dt><a name="label-92" id="label-92">
|
|
557
|
+
<dt><a name="label-92" id="label-92">Shapelib</a></dt><!-- RDLabel: "Shapelib" -->
|
|
537
558
|
<dd>
|
|
538
559
|
<a href="http://shapelib.maptools.org/shp_api.html"><URL:http://shapelib.maptools.org/shp_api.html></a>
|
|
539
560
|
<a href="http://shapelib.maptools.org/dbf_api.html"><URL:http://shapelib.maptools.org/dbf_api.html></a>
|
|
@@ -552,7 +573,7 @@ or <a href="http://shapelib.maptools.org/dl/shapefile.pdf"><URL:http://shapel
|
|
|
552
573
|
<p class="foottext">
|
|
553
574
|
<a name="foottext-1" id="foottext-1" href="#footmark-1"><sup><small>*1</small></sup></a><small>If DBF file has different number of records,
|
|
554
575
|
warning message is shown in $VERBOSE mode.</small><br />
|
|
555
|
-
<a name="foottext-2" id="foottext-2" href="#footmark-2"><sup><small>*2</small></sup></a><small>taken from <a href="#label-92">
|
|
576
|
+
<a name="foottext-2" id="foottext-2" href="#footmark-2"><sup><small>*2</small></sup></a><small>taken from <a href="#label-92">Shapelib</a> document.</small><br />
|
|
556
577
|
</p>
|
|
557
578
|
</body>
|
|
558
579
|
</html>
|
data/doc/Interface.rd
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
=begin
|
|
2
|
-
= module
|
|
2
|
+
= module Shapelib
|
|
3
3
|
|
|
4
4
|
This module is a wrapper of C Shapefile Library
|
|
5
|
-
(also called ((<
|
|
5
|
+
(also called ((<Shapelib|URL:http://shapelib.maptools.org/>))).
|
|
6
6
|
It consists of basically two classes:
|
|
7
7
|
((<ShapeFile|class ShapeFile>)) and ((<Shape|class Shape>)).
|
|
8
8
|
If you are unfamiliar with object-oriented programming,
|
|
@@ -16,16 +16,16 @@ A extension library (({shapelib})) must be required before using this module:
|
|
|
16
16
|
Following three functions construct a point object.
|
|
17
17
|
It can be used like top level function after (({include})):
|
|
18
18
|
|
|
19
|
-
include
|
|
19
|
+
include Shapelib
|
|
20
20
|
pt = new_point(1, 2)
|
|
21
21
|
|
|
22
22
|
Arguments ((|x|)), ((|y|)), ((|z|)), and ((|m|)) ((<should be Float>)).
|
|
23
23
|
|
|
24
|
-
---
|
|
24
|
+
--- Shapelib.new_point x, y
|
|
25
25
|
creates a ((<class Point>)) object.
|
|
26
|
-
---
|
|
26
|
+
--- Shapelib.new_point x, y, m
|
|
27
27
|
creates a ((<class PointM>)) object.
|
|
28
|
-
---
|
|
28
|
+
--- Shapelib.new_point x, y, m, z
|
|
29
29
|
creates a ((<class PointZ>)) object.
|
|
30
30
|
|
|
31
31
|
== class ShapeFile
|
|
@@ -47,7 +47,7 @@ when each shapefile is no longer used.
|
|
|
47
47
|
Both (({.shp})) and (({.shx})) files must exist at the specified path.
|
|
48
48
|
|
|
49
49
|
Argument ((|access|)) are passed to (({fopen(3)})) through
|
|
50
|
-
((<
|
|
50
|
+
((<Shapelib>)) (({SHPOpen()})) function.
|
|
51
51
|
Either '(({rb}))' or '(({rb+}))' should be used.
|
|
52
52
|
|
|
53
53
|
If a block is given to these constructors,
|
|
@@ -56,7 +56,7 @@ when each shapefile is no longer used.
|
|
|
56
56
|
and the constructor returns (({nil})).
|
|
57
57
|
|
|
58
58
|
# example
|
|
59
|
-
|
|
59
|
+
Shapelib::ShapeFile.open(filename) { |fp|
|
|
60
60
|
print "#{filename} has #{fp.size} records.\n"
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -87,7 +87,14 @@ when each shapefile is no longer used.
|
|
|
87
87
|
((|field_type|)) specifies ((<field type>));
|
|
88
88
|
((|width|)) is nonnegative Integer for field width in characters; and
|
|
89
89
|
((|decimal|)) is nonnegative Integer for decimal points.
|
|
90
|
+
Field names must be at most 10 bytes and unique ignoring case.
|
|
91
|
+
Overlong or duplicate names raise ArgumentError before the field is added.
|
|
90
92
|
Only Float field requires ((|decimal|)); otherwise it can be missing.
|
|
93
|
+
Integer and Float fields require ((|decimal|)) between 0 and 255 inclusive.
|
|
94
|
+
Date fields require width 8 and zero decimal places. They are available
|
|
95
|
+
when the native shapelib headers provide FTDate (shapelib 1.5.0 or newer).
|
|
96
|
+
Date values are eight-digit YYYYMMDD Strings, or nil for nulls.
|
|
97
|
+
Writes check the eight-digit format without calendar validation.
|
|
91
98
|
|
|
92
99
|
# example
|
|
93
100
|
fp.add_field 'name', :String, 32
|
|
@@ -118,8 +125,9 @@ when each shapefile is no longer used.
|
|
|
118
125
|
--- shapefile.field_type field
|
|
119
126
|
returns the type of the ((<attribute field>)).
|
|
120
127
|
The result is Symbol
|
|
121
|
-
(one of :String, :Integer, :Float, :Logical, or :Invalid)
|
|
128
|
+
(one of :String, :Integer, :Float, :Logical, :Date, or :Invalid)
|
|
122
129
|
or nil on failure.
|
|
130
|
+
Older native libraries classify Date fields as :String.
|
|
123
131
|
|
|
124
132
|
--- shapefile.field_width field
|
|
125
133
|
returns the width of the ((<attribute field>)).
|
|
@@ -141,7 +149,9 @@ when each shapefile is no longer used.
|
|
|
141
149
|
(or the first record #0 for the first time) is used.
|
|
142
150
|
An instance of ((<class Shape>)) is returned,
|
|
143
151
|
including all attributes written on the DBF.
|
|
144
|
-
|
|
152
|
+
At end of file or on a geometry-read failure, (({nil})) is returned.
|
|
153
|
+
If a DBF with attribute fields is present but its record cannot be read,
|
|
154
|
+
IOError is raised. Files without a DBF or with no fields remain readable.
|
|
145
155
|
|
|
146
156
|
--- shapefile.rewind
|
|
147
157
|
After that, ((<shapefile.read|shapefile.read rec = -1>))
|
|
@@ -159,7 +169,8 @@ when each shapefile is no longer used.
|
|
|
159
169
|
writes ((|shape|)) into shapefile at record number ((|rec|)).
|
|
160
170
|
The ((|shape|)) must be a instance of ((<class Shape>)) or subclass.
|
|
161
171
|
Attributes attached to ((|shape|)) are stored into DBF file.
|
|
162
|
-
If ((|rec|)) is missing, the record is appended at the end of shapefile.
|
|
172
|
+
If ((|rec|)) is missing, nil, or -1, the record is appended at the end of shapefile.
|
|
173
|
+
An existing nonnegative record index replaces that record.
|
|
163
174
|
|
|
164
175
|
--- shapefile.close
|
|
165
176
|
The (({close})) method flushes all information
|
|
@@ -231,7 +242,7 @@ depending on the type of shape.
|
|
|
231
242
|
It returns (({true})) if a change is made and
|
|
232
243
|
(({false})) if no change is made.
|
|
233
244
|
Only polygon objects will be affected though any object may be passed."
|
|
234
|
-
((-taken from ((<
|
|
245
|
+
((-taken from ((<Shapelib>)) document.-))
|
|
235
246
|
--- shape.shape_id
|
|
236
247
|
returns the number of record by which the shape is read from a shapefile.
|
|
237
248
|
Nil is returned if the shape is not read from file.
|
|
@@ -243,7 +254,7 @@ depending on the type of shape.
|
|
|
243
254
|
returns a hash that contains all attributes and geometry information.
|
|
244
255
|
Each attribute have a key of String,
|
|
245
256
|
while geometry information has keys of Symbol.
|
|
246
|
-
pt =
|
|
257
|
+
pt = Shapelib::Point::new(1, 2, 'name' => 'Madison')
|
|
247
258
|
pt.to_h => {"name"=>"Madison", :zvals=>[0.0], :n_parts=>0,
|
|
248
259
|
:n_vertices=>1, :maxbound=>[1.0, 2.0, 0.0, 0.0],
|
|
249
260
|
:part_start=>nil, :part_type=>nil, :xvals=>[1.0],
|
|
@@ -259,34 +270,34 @@ depending on the type of shape.
|
|
|
259
270
|
as defined in ((<ISO 19125-1>)).
|
|
260
271
|
((*Caution: current implementation does not always handle Polygon[MZ] and MultiPatch correctly.*))
|
|
261
272
|
|
|
262
|
-
|
|
273
|
+
Shapelib::Arc.new([1, 2], [3, 4], [5, 6]).wkt
|
|
263
274
|
=> "LINESTRING(1 2, 3 4, 5 6)"
|
|
264
|
-
|
|
275
|
+
Shapelib::Arc.new([[1, 2], [3, 4]], [[5, 6], [7, 8]]).wkt
|
|
265
276
|
=> "MULTILINESTRING((1 2, 3 4), (5 6, 7 8))"
|
|
266
277
|
|
|
267
278
|
--- shape.xvals
|
|
268
279
|
returns an array of x values.
|
|
269
280
|
|
|
270
|
-
|
|
281
|
+
Shapelib::Arc.new([1, 2], [3, 4], [5, 6]).xvals
|
|
271
282
|
=> [1.0, 3.0, 5.0]
|
|
272
283
|
|
|
273
284
|
Multipart shape results flattened array (all parts joined).
|
|
274
285
|
|
|
275
|
-
|
|
286
|
+
Shapelib::Arc.new([[1, 2], [3, 4]], [[5, 6], [7, 8]]).xvals
|
|
276
287
|
=> [1.0, 3.0, 5.0, 7.0]
|
|
277
288
|
|
|
278
289
|
--- shape.yvals
|
|
279
290
|
returns an array of y values.
|
|
280
291
|
|
|
281
|
-
|
|
292
|
+
Shapelib::Arc.new([1, 2], [3, 4], [5, 6]).xvals
|
|
282
293
|
=> [2.0, 4.0, 6.0]
|
|
283
294
|
|
|
284
295
|
--- shape.mvals
|
|
285
296
|
returns an array of m values. Nil is returned for missing value.
|
|
286
297
|
|
|
287
|
-
|
|
298
|
+
Shapelib::Arc.new([1, 2], [3, 4], [5, 6]).mvals
|
|
288
299
|
=> [nil, nil, nil]
|
|
289
|
-
|
|
300
|
+
Shapelib::ArcM.new([1, 2, 3], [4, 5, 6], [7, 8, 9]).mvals
|
|
290
301
|
=> [3, 6, 9]
|
|
291
302
|
|
|
292
303
|
--- shape.zvals
|
|
@@ -353,7 +364,11 @@ PolygonZ is similar to PolygonM, but points also have z coordinates.
|
|
|
353
364
|
MultiPoint is a set of points.
|
|
354
365
|
--- MultiPoint::new point, point, ...
|
|
355
366
|
--- MultiPoint::new [point, point, ...]
|
|
356
|
-
Above two are the same.
|
|
367
|
+
Above two are the same for a nonempty list of points. Each point may
|
|
368
|
+
be a coordinate array [x, y, m, z] or an object with x and y methods.
|
|
369
|
+
A single coordinate array is also accepted. No arguments create an
|
|
370
|
+
empty MultiPoint; for compatibility, a single empty array creates
|
|
371
|
+
one point at the origin.
|
|
357
372
|
|
|
358
373
|
== class MultiPointM
|
|
359
374
|
MultiPointM is similar to MultiPoint, but points also have m (measure) coordinates.
|
|
@@ -368,9 +383,11 @@ MultiPointZ is similar to MultiPointM, but points also have z coordinates.
|
|
|
368
383
|
|
|
369
384
|
== constants
|
|
370
385
|
=== Field Type Constants
|
|
371
|
-
---
|
|
372
|
-
---
|
|
373
|
-
---
|
|
386
|
+
--- Shapelib::String
|
|
387
|
+
--- Shapelib::Integer
|
|
388
|
+
--- Shapelib::Float
|
|
389
|
+
--- Shapelib::Date
|
|
390
|
+
Available when the native shapelib headers provide FTDate.
|
|
374
391
|
|
|
375
392
|
== Appendix A: C to Ruby equivalence table
|
|
376
393
|
* DBFHandle:
|
|
@@ -446,16 +463,20 @@ This appendix discusses the detail of acceptable value.
|
|
|
446
463
|
: should be Float
|
|
447
464
|
Any object that respond to (({to_f})) is converted to Float.
|
|
448
465
|
String is not acceptable.
|
|
449
|
-
(({nil})) is treated as -
|
|
466
|
+
(({nil})) is treated as -2e38 (NODATA) for ((|m|)) (measure) coordinate,
|
|
450
467
|
or as 0.0 otherwise.
|
|
468
|
+
Measures below -1e38 are read as nil; exactly -1e38 is valid.
|
|
469
|
+
The exact legacy null marker -2e-38 is also read as nil for compatibility
|
|
470
|
+
with files written by older versions of this gem. Other negative measures
|
|
471
|
+
are preserved.
|
|
451
472
|
|
|
452
473
|
: type of shapes
|
|
453
474
|
For ((<ShapeFile::new|ShapeFile::new filename, shapetype, attrs>))
|
|
454
475
|
and ((<Shape::new|Shape::new hash>)),
|
|
455
476
|
acceptable values for ((|shapetype|)) are:
|
|
456
|
-
* Class object like
|
|
477
|
+
* Class object like Shapelib::Point (listed in ((<structure of subclasses>)))
|
|
457
478
|
* String such as (({"Point"})) or (({"PolygonZ"}))
|
|
458
|
-
(the same list, but do not include "
|
|
479
|
+
(the same list, but do not include "Shapelib::")
|
|
459
480
|
* Symbol such as (({:Point})) or (({:PolygonZ}))
|
|
460
481
|
(result of ((<shapefile.shape_type>)) and ((<shape.shape_type>))),
|
|
461
482
|
or
|
|
@@ -465,8 +486,8 @@ This appendix discusses the detail of acceptable value.
|
|
|
465
486
|
: field type
|
|
466
487
|
For ((<shapefile.add_field|shapefile.add_field field_name, field_type, width, decimal = 0>)),
|
|
467
488
|
acceptable values for ((|field_type|)) are:
|
|
468
|
-
* String "String", "Integer", or "
|
|
469
|
-
* Symbol :String, :Integer, or :
|
|
489
|
+
* String "String", "Integer", "Float", "Logical", or "Date", or
|
|
490
|
+
* Symbol :String, :Integer, :Float, :Logical, or :Date
|
|
470
491
|
(result of ((<shapefile.field_type|shapefile.field_type field>))).
|
|
471
492
|
* Integer constants listed ((<above|Field Type Constants>)).
|
|
472
493
|
|
|
@@ -487,7 +508,7 @@ This appendix discusses the detail of acceptable value.
|
|
|
487
508
|
|
|
488
509
|
|
|
489
510
|
== References
|
|
490
|
-
:
|
|
511
|
+
: Shapelib
|
|
491
512
|
((<URL:http://shapelib.maptools.org/shp_api.html>))
|
|
492
513
|
((<URL:http://shapelib.maptools.org/dbf_api.html>))
|
|
493
514
|
: ESRI Whitepaper
|