esri_shapefile 0.0.1
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 +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +51 -0
- data/Rakefile +2 -0
- data/lib/esri_shapefile/byte_model/field.rb +48 -0
- data/lib/esri_shapefile/byte_model.rb +43 -0
- data/lib/esri_shapefile/models/main_file_header.rb +47 -0
- data/lib/esri_shapefile/models/record_header.rb +28 -0
- data/lib/esri_shapefile/models/shapes/multi_patch.rb +33 -0
- data/lib/esri_shapefile/models/shapes/multi_point.rb +21 -0
- data/lib/esri_shapefile/models/shapes/multi_point_m.rb +25 -0
- data/lib/esri_shapefile/models/shapes/multi_point_z.rb +29 -0
- data/lib/esri_shapefile/models/shapes/null.rb +19 -0
- data/lib/esri_shapefile/models/shapes/point.rb +19 -0
- data/lib/esri_shapefile/models/shapes/point_m.rb +20 -0
- data/lib/esri_shapefile/models/shapes/point_z.rb +21 -0
- data/lib/esri_shapefile/models/shapes/poly_line.rb +43 -0
- data/lib/esri_shapefile/models/shapes/poly_line_m.rb +50 -0
- data/lib/esri_shapefile/models/shapes/poly_line_z.rb +63 -0
- data/lib/esri_shapefile/models/shapes/polygon.rb +38 -0
- data/lib/esri_shapefile/models/shapes/polygon_m.rb +52 -0
- data/lib/esri_shapefile/models/shapes/polygon_z.rb +65 -0
- data/lib/esri_shapefile/models/shapes.rb +33 -0
- data/lib/esri_shapefile/reader.rb +44 -0
- data/lib/esri_shapefile/version.rb +3 -0
- data/lib/esri_shapefile.rb +29 -0
- data/spec/esri_shapefile/field_spec.rb +95 -0
- data/spec/esri_shapefile/model_spec.rb +26 -0
- data/spec/esri_shapefile/models/main_file_header_spec.rb +72 -0
- data/spec/esri_shapefile/models/record_header_spec.rb +26 -0
- data/spec/esri_shapefile/models/shapes/point_spec.rb +24 -0
- data/spec/spec_helper.rb +105 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1eea7f296a0ef93cc09b8fe87fa30a3c01c67e61
|
4
|
+
data.tar.gz: 5f2f82a3facd9330fde2125598c443c529103551
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a5e5a80ef2d2665e3f608229da92f49ae671d29dc74f2e9b222fb9eacb48f93eddcfd5b4edda8c4e9ff3328d013590fee16bc2bd2a09cf6b4dc0b5e8db308108
|
7
|
+
data.tar.gz: 53354693c75d1f5f68c040462b343456d598eae0bbcd603373a1a0f20c3c6b2c29b89a9a8a8f1cfb29a4bbd1bbdb4823730cbd25c4cb413e393cc39a5d3a3848
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 Joe Karayusuf
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# EsriShapefile
|
2
|
+
|
3
|
+
Ruby library to read an [ESRI Shapefile](https://www.esri.com/library/whitepapers/pdfs/shapefile.pdf)
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'esri_shapefile'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install esri_shapefile
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### Read the header of a shapefile
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require 'esri_shapefile'
|
27
|
+
reader = EsriShapefile::Reader.new("/path/to/shapefile")
|
28
|
+
reader.main_file_header # => Instance of EsriShapefile::MainFileHeader
|
29
|
+
```
|
30
|
+
|
31
|
+
### Read all of the records in a shapefile
|
32
|
+
|
33
|
+
Supported shapes can be found [here](lib/esri_shapefile/models/shapes)
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
require 'esri_shapefile'
|
37
|
+
reader = EsriShapefile::Reader.new("path/to/shapefile")
|
38
|
+
reader.each_record do |header, shape|
|
39
|
+
# Iterate over each record with access to the header and shape.
|
40
|
+
# The header will be an instance of the EsriShapefile::RecordHeader class.
|
41
|
+
# The shape will be one of the shape models found in the models/shapes directory. Example: EsriShapefile::Shapes::Polygon
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
## Contributing
|
46
|
+
|
47
|
+
1. Fork it ( https://github.com/karayusuf/esri_shapefile/fork )
|
48
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
49
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
50
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
51
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module EsriShapefile
|
2
|
+
module ByteModel
|
3
|
+
class Field
|
4
|
+
attr_reader :name, :position, :type, :byte_order, :number
|
5
|
+
|
6
|
+
TYPES = {
|
7
|
+
integer: { bytesize: 4, unpack: { big: 'l>', little: 'l<' } },
|
8
|
+
double: { bytesize: 8, unpack: { big: 'G', little: 'E' } },
|
9
|
+
point: { bytesize: 16, unpack: { big: 'G', little: 'E', multiplier: 2 } },
|
10
|
+
}
|
11
|
+
|
12
|
+
def initialize(name, position:, type:, byte_order:, number: nil)
|
13
|
+
@name = name
|
14
|
+
@position = position
|
15
|
+
@type = type
|
16
|
+
@number = number
|
17
|
+
@byte_order = byte_order
|
18
|
+
end
|
19
|
+
|
20
|
+
def list?
|
21
|
+
!@number.nil?
|
22
|
+
end
|
23
|
+
|
24
|
+
def number
|
25
|
+
@number.nil? ? 1 : @number
|
26
|
+
end
|
27
|
+
|
28
|
+
def number_depends_on_field?
|
29
|
+
@number.is_a?(Symbol)
|
30
|
+
end
|
31
|
+
|
32
|
+
def unused?
|
33
|
+
name == :unused
|
34
|
+
end
|
35
|
+
|
36
|
+
def bytesize
|
37
|
+
TYPES[@type][:bytesize]
|
38
|
+
end
|
39
|
+
|
40
|
+
def unpack_format(values = {})
|
41
|
+
number_of_consecutive_values = number_depends_on_field? ? values[number] : number
|
42
|
+
multiplier = TYPES[@type][:unpack][:multiplier] || 1
|
43
|
+
unpack_format = TYPES[@type][:unpack][@byte_order]
|
44
|
+
"#{unpack_format}#{number_of_consecutive_values * multiplier}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module EsriShapefile
|
2
|
+
module ByteModel
|
3
|
+
|
4
|
+
def field(name, number: nil, position:, type:, byte_order:)
|
5
|
+
attr_accessor name unless name == :unused
|
6
|
+
fields << Field.new(name, position: position, type: type, byte_order: byte_order, number: number)
|
7
|
+
end
|
8
|
+
|
9
|
+
def fields
|
10
|
+
@fields ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def from_bytes(bytes)
|
14
|
+
field_values = {}
|
15
|
+
fields.reduce(0) do |offset, field|
|
16
|
+
if !field.unused?
|
17
|
+
unpack_format = field.unpack_format(field_values)
|
18
|
+
field_value = bytes.unpack("@#{offset}#{unpack_format}")
|
19
|
+
|
20
|
+
if field.type == :point
|
21
|
+
field_value = field_value.each_slice(2).map do |x, y|
|
22
|
+
point = Shapes::Point.new
|
23
|
+
point.x = x
|
24
|
+
point.y = y
|
25
|
+
point
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
field_values[field.name] = field.list? ? field_value : field_value.first
|
30
|
+
end
|
31
|
+
|
32
|
+
offset += field.bytesize
|
33
|
+
(offset < bytes.size) ? offset : break
|
34
|
+
end
|
35
|
+
|
36
|
+
field_values.reduce(self.new) do |model, (field, value)|
|
37
|
+
model.send("#{field}=", value)
|
38
|
+
model
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
#
|
5
|
+
# The main file header is 100 bytes long. The fields in the file header are
|
6
|
+
# listed below with their byte position, type, and byte order. Position is
|
7
|
+
# with respect to the start of the file.
|
8
|
+
#
|
9
|
+
class MainFileHeader
|
10
|
+
extend EsriShapefile::ByteModel
|
11
|
+
|
12
|
+
field :file_code, position: 0, type: :integer, byte_order: :big
|
13
|
+
field :unused, position: 4, type: :integer, byte_order: :big
|
14
|
+
field :unused, position: 8, type: :integer, byte_order: :big
|
15
|
+
field :unused, position: 12, type: :integer, byte_order: :big
|
16
|
+
field :unused, position: 16, type: :integer, byte_order: :big
|
17
|
+
field :unused, position: 20, type: :integer, byte_order: :big
|
18
|
+
|
19
|
+
field :file_length, position: 24, type: :integer, byte_order: :big
|
20
|
+
field :version, position: 28, type: :integer, byte_order: :little
|
21
|
+
field :shape_type, position: 32, type: :integer, byte_order: :little
|
22
|
+
|
23
|
+
field :x_min, position: 36, type: :double, byte_order: :little
|
24
|
+
field :y_min, position: 44, type: :double, byte_order: :little
|
25
|
+
field :x_max, position: 52, type: :double, byte_order: :little
|
26
|
+
field :y_max, position: 60, type: :double, byte_order: :little
|
27
|
+
|
28
|
+
field :z_min, position: 68, type: :double, byte_order: :little
|
29
|
+
field :z_max, position: 76, type: :double, byte_order: :little
|
30
|
+
field :m_min, position: 84, type: :double, byte_order: :little
|
31
|
+
field :m_max, position: 92, type: :double, byte_order: :little
|
32
|
+
|
33
|
+
# The value for file length is the total length of the file in 16-bit words
|
34
|
+
# (including the fifty 16-bit words that make up the header). This means
|
35
|
+
# that we need to multiply the value by 2 in order to know the size of the
|
36
|
+
# file in bytes
|
37
|
+
def file_length_bytes
|
38
|
+
file_length * 2
|
39
|
+
end
|
40
|
+
|
41
|
+
def shape
|
42
|
+
Shapes.from_type(shape_type)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
#
|
5
|
+
# The header for each record stores the record number and content length for
|
6
|
+
# the record. Record headers have a fixed length of 8 bytes. The list of
|
7
|
+
# fields shows the fields in the record header with their byte position, type,
|
8
|
+
# and byte order. The field position is with respect to the start of the
|
9
|
+
# record.
|
10
|
+
#
|
11
|
+
class RecordHeader
|
12
|
+
extend EsriShapefile::ByteModel
|
13
|
+
|
14
|
+
# Record numbers begin at 1.
|
15
|
+
field :record_number, position: 0, type: :integer, byte_order: :big
|
16
|
+
|
17
|
+
# The content length for a record is the length of the record contents
|
18
|
+
# section measured in 16-bit words. Each record, therefore, contributes (4 +
|
19
|
+
# content_length) 16-bit words toward the total length of the file, as
|
20
|
+
# stored as Byte 24 in the file header.
|
21
|
+
field :content_length, position: 4, type: :integer, byte_order: :big
|
22
|
+
|
23
|
+
def content_length_bytes
|
24
|
+
content_length * 2
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
#
|
7
|
+
#
|
8
|
+
class MultiPatch
|
9
|
+
extend EsriShapefile::ByteModel
|
10
|
+
|
11
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
12
|
+
field :x_min, position: 4, type: :double, byte_order: :little
|
13
|
+
field :y_min, position: 12, type: :double, byte_order: :little
|
14
|
+
field :x_max, position: 20, type: :double, byte_order: :little
|
15
|
+
field :y_max, position: 28, type: :double, byte_order: :little
|
16
|
+
|
17
|
+
field :num_parts, position: 36, type: :integer, byte_order: :little
|
18
|
+
field :num_points, position: 40, type: :integer, byte_order: :little
|
19
|
+
field :parts, position: 44, type: :integer, byte_order: :little, number: :num_parts
|
20
|
+
field :part_types, position: :w, type: :integer, byte_order: :little, number: :num_parts
|
21
|
+
field :points, position: :x, type: :point, byte_order: :little, number: :num_points
|
22
|
+
|
23
|
+
field :z_min, position: :x, type: :double, byte_order: :little
|
24
|
+
field :z_max, position: :x_plus_8, type: :double, byte_order: :little
|
25
|
+
field :z_array, position: :x_plus_16, type: :double, byte_order: :little, number: :num_points
|
26
|
+
|
27
|
+
field :m_min, position: :y, type: :double, byte_order: :little
|
28
|
+
field :m_max, position: :y_plus_8, type: :double, byte_order: :little
|
29
|
+
field :m_array, position: :y_plus_16, type: :double, byte_order: :little, number: :num_points
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
# A MultiPoint represents a set of points.
|
7
|
+
#
|
8
|
+
class MultiPoint
|
9
|
+
extend EsriShapefile::ByteModel
|
10
|
+
|
11
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
12
|
+
field :x_min, position: 4, type: :double, byte_order: :little
|
13
|
+
field :y_min, position: 12, type: :double, byte_order: :little
|
14
|
+
field :x_max, position: 20, type: :double, byte_order: :little
|
15
|
+
field :y_max, position: 28, type: :double, byte_order: :little
|
16
|
+
field :num_points, position: 36, type: :integer, byte_order: :little
|
17
|
+
field :points, position: 40, type: :point, byte_order: :little, number: :num_points
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
# A MultiPoint represents a set of points.
|
7
|
+
#
|
8
|
+
class MultiPointM
|
9
|
+
extend EsriShapefile::ByteModel
|
10
|
+
|
11
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
12
|
+
field :x_min, position: 4, type: :double, byte_order: :little
|
13
|
+
field :y_min, position: 12, type: :double, byte_order: :little
|
14
|
+
field :x_max, position: 20, type: :double, byte_order: :little
|
15
|
+
field :y_max, position: 28, type: :double, byte_order: :little
|
16
|
+
field :num_points, position: 36, type: :integer, byte_order: :little
|
17
|
+
field :points, position: 40, type: :point, byte_order: :little, number: :num_points
|
18
|
+
|
19
|
+
field :m_min, position: :x, type: :double, byte_order: :little
|
20
|
+
field :m_max, position: :x_plus_8, type: :double, byte_order: :little
|
21
|
+
field :m_array, position: :x_plus_16, type: :double, byte_order: :little, number: :num_points
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
# A MultiPoint represents a set of points.
|
7
|
+
#
|
8
|
+
class MultiPointZ
|
9
|
+
extend EsriShapefile::ByteModel
|
10
|
+
|
11
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
12
|
+
field :x_min, position: 4, type: :double, byte_order: :little
|
13
|
+
field :y_min, position: 12, type: :double, byte_order: :little
|
14
|
+
field :x_max, position: 20, type: :double, byte_order: :little
|
15
|
+
field :y_max, position: 28, type: :double, byte_order: :little
|
16
|
+
field :num_points, position: 36, type: :integer, byte_order: :little
|
17
|
+
field :points, position: 40, type: :point, byte_order: :little, number: :num_points
|
18
|
+
|
19
|
+
field :z_min, position: :x, type: :double, byte_order: :little
|
20
|
+
field :z_max, position: :x_plus_8, type: :double, byte_order: :little
|
21
|
+
field :z_array, position: :x_plus_16, type: :double, byte_order: :little, number: :num_points
|
22
|
+
|
23
|
+
field :m_min, position: :y, type: :double, byte_order: :little
|
24
|
+
field :m_max, position: :y_plus_8, type: :double, byte_order: :little
|
25
|
+
field :m_array, position: :y_plus_16, type: :double, byte_order: :little, number: :num_points
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
# A shape type of 0 indicates a null shape, with no geometric data for the
|
7
|
+
# shape. Each feature type (point, lie, polygon, etc.) supports nulls - it
|
8
|
+
# is valid to have points and null points in the same shapefile. Often null
|
9
|
+
# shapes are place holders; they are used during shapefile creation and are
|
10
|
+
# populated with geometric data soon after they are created.
|
11
|
+
#
|
12
|
+
class Null
|
13
|
+
extend EsriShapefile::ByteModel
|
14
|
+
|
15
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
# A point consists of a pair of double-precision coordinates
|
7
|
+
# in the order X,Y.
|
8
|
+
#
|
9
|
+
class Point
|
10
|
+
extend EsriShapefile::ByteModel
|
11
|
+
|
12
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
13
|
+
field :x, position: 4, type: :double, byte_order: :little
|
14
|
+
field :y, position: 12, type: :double, byte_order: :little
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
# A point consists of a pair of double-precision coordinates
|
7
|
+
# in the order X,Y,Z plus a measure.
|
8
|
+
#
|
9
|
+
class PointM
|
10
|
+
extend EsriShapefile::ByteModel
|
11
|
+
|
12
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
13
|
+
field :x, position: 4, type: :double, byte_order: :little
|
14
|
+
field :y, position: 12, type: :double, byte_order: :little
|
15
|
+
field :measure, position: 28, type: :double, byte_order: :little
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
# A point consists of a pair of double-precision coordinates
|
7
|
+
# in the order X,Y,Z plus a measure.
|
8
|
+
#
|
9
|
+
class PointZ
|
10
|
+
extend EsriShapefile::ByteModel
|
11
|
+
|
12
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
13
|
+
field :x, position: 4, type: :double, byte_order: :little
|
14
|
+
field :y, position: 12, type: :double, byte_order: :little
|
15
|
+
field :z, position: 20, type: :double, byte_order: :little
|
16
|
+
field :measure, position: 28, type: :double, byte_order: :little
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
# A PolyLine is an ordered set of vertices that consists of one or more
|
7
|
+
# parts. A part is a connected sequence of two or more points. Parts may or
|
8
|
+
# may not be connected to one another. Parts may or may not intersect one
|
9
|
+
# another.
|
10
|
+
#
|
11
|
+
# Because this specification does not forbid consecutive points with
|
12
|
+
# identical coordinates, shapefile readers must handle such cases. On the
|
13
|
+
# other hand, the degenerate, zero length parts that might result are not
|
14
|
+
# allowed.
|
15
|
+
#
|
16
|
+
class PolyLine
|
17
|
+
extend EsriShapefile::ByteModel
|
18
|
+
|
19
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
20
|
+
field :x_min, position: 4, type: :double, byte_order: :little
|
21
|
+
field :y_min, position: 12, type: :double, byte_order: :little
|
22
|
+
field :x_max, position: 20, type: :double, byte_order: :little
|
23
|
+
field :y_max, position: 28, type: :double, byte_order: :little
|
24
|
+
|
25
|
+
# The number of parts in the PolyLine
|
26
|
+
field :num_parts, position: 36, type: :integer, byte_order: :little
|
27
|
+
|
28
|
+
# The total number of points for all parts.
|
29
|
+
field :num_points, position: 40, type: :integer, byte_order: :little
|
30
|
+
|
31
|
+
# An array of length num_parts. Stores, for each PolyLine, the index of
|
32
|
+
# its first point in the points array. Array indexes are with respect to 0.
|
33
|
+
field :parts, position: 44, type: :integer, byte_order: :little, number: :num_parts
|
34
|
+
|
35
|
+
# An array of length NumPoints. The points for each part in the PolyLine
|
36
|
+
# are stored end to end. The points for Part 2 follow the points for
|
37
|
+
# Part 1, and so on. The parts array holds the array index of the starting
|
38
|
+
# point for each part. There is no delimiter in the points array between parts.
|
39
|
+
field :points, position: :x, type: :point, byte_order: :little, number: :num_points
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
# A PolyLineM consists of one or more parts. A part is a connected sequence
|
7
|
+
# of two or more points. Parts may or may not be connected to one another.
|
8
|
+
# Parts may or may not intersect one another.
|
9
|
+
#
|
10
|
+
class PolyLineM
|
11
|
+
extend EsriShapefile::ByteModel
|
12
|
+
|
13
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
14
|
+
field :x_min, position: 4, type: :double, byte_order: :little
|
15
|
+
field :y_min, position: 12, type: :double, byte_order: :little
|
16
|
+
field :x_max, position: 20, type: :double, byte_order: :little
|
17
|
+
field :y_max, position: 28, type: :double, byte_order: :little
|
18
|
+
|
19
|
+
# The number of parts in the PolyLine
|
20
|
+
field :num_parts, position: 36, type: :integer, byte_order: :little
|
21
|
+
|
22
|
+
# The total number of points for all parts.
|
23
|
+
field :num_points, position: 40, type: :integer, byte_order: :little
|
24
|
+
|
25
|
+
# An array of length num_parts. Stores, for each PolyLine, the index of
|
26
|
+
# its first point in the points array. Array indexes are with respect to 0.
|
27
|
+
field :parts, position: 44, type: :integer, byte_order: :little, number: :num_parts
|
28
|
+
|
29
|
+
# An array of length NumPoints. The points for each part in the PolyLine
|
30
|
+
# are stored end to end. The points for Part 2 follow the points for
|
31
|
+
# Part 1, and so on. The parts array holds the array index of the starting
|
32
|
+
# point for each part. There is no delimiter in the points array between parts.
|
33
|
+
field :points, position: :x, type: :point, byte_order: :little, number: :num_points
|
34
|
+
|
35
|
+
# The minimum measure for the PolyLineZ
|
36
|
+
field :m_min, position: :z, type: :double, byte_order: :little
|
37
|
+
|
38
|
+
# The maximum measure for the PolyLineZ
|
39
|
+
field :m_max, position: :z_plus_8, type: :double, byte_order: :little
|
40
|
+
|
41
|
+
# An array of length num_points. The measures for each part in the
|
42
|
+
# PolyLineZ are stored end to end. The measures for Part 2 follow the
|
43
|
+
# measures for Part 1, and so on. The parts array holds the array index of
|
44
|
+
# the starting measure for each part. There is no delimited in the measure
|
45
|
+
# array between parts.
|
46
|
+
field :m_array, position: :z_plus_16, type: :double, byte_order: :little, number: :num_points
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
# A PolyLineZ consists of one or more parts. A part is a connected sequence
|
7
|
+
# of two or more points. Parts may or may not be connected to one another.
|
8
|
+
# Parts may or may not intersect one another.
|
9
|
+
#
|
10
|
+
class PolyLineZ
|
11
|
+
extend EsriShapefile::ByteModel
|
12
|
+
|
13
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
14
|
+
field :x_min, position: 4, type: :double, byte_order: :little
|
15
|
+
field :y_min, position: 12, type: :double, byte_order: :little
|
16
|
+
field :x_max, position: 20, type: :double, byte_order: :little
|
17
|
+
field :y_max, position: 28, type: :double, byte_order: :little
|
18
|
+
|
19
|
+
# The number of parts in the PolyLine
|
20
|
+
field :num_parts, position: 36, type: :integer, byte_order: :little
|
21
|
+
|
22
|
+
# The total number of points for all parts.
|
23
|
+
field :num_points, position: 40, type: :integer, byte_order: :little
|
24
|
+
|
25
|
+
# An array of length num_parts. Stores, for each PolyLine, the index of
|
26
|
+
# its first point in the points array. Array indexes are with respect to 0.
|
27
|
+
field :parts, position: 44, type: :integer, byte_order: :little, number: :num_parts
|
28
|
+
|
29
|
+
# An array of length NumPoints. The points for each part in the PolyLine
|
30
|
+
# are stored end to end. The points for Part 2 follow the points for
|
31
|
+
# Part 1, and so on. The parts array holds the array index of the starting
|
32
|
+
# point for each part. There is no delimiter in the points array between parts.
|
33
|
+
field :points, position: :x, type: :point, byte_order: :little, number: :num_points
|
34
|
+
|
35
|
+
# The minimum Z value for the PolyLineZ
|
36
|
+
field :z_min, position: :y, type: :double, byte_order: :little
|
37
|
+
|
38
|
+
# The maximum Z value for the PoliyLineZ
|
39
|
+
field :z_max, position: :y_plus_8, type: :double, byte_order: :little
|
40
|
+
|
41
|
+
# An array of length num_points. the Z values for each part in the
|
42
|
+
# PolyLineZ are stored end to end. The Z values for Part 2 follow the Z
|
43
|
+
# values for Part 1, and so on. The parts array holds the array index of
|
44
|
+
# the starting point for each part. There is no delimited in the Z array
|
45
|
+
# between parts.
|
46
|
+
field :z_array, position: :y_plus_16, type: :double, byte_order: :little, number: :num_points
|
47
|
+
|
48
|
+
# The minimum measure for the PolyLineZ
|
49
|
+
field :m_min, position: :z, type: :double, byte_order: :little
|
50
|
+
|
51
|
+
# The maximum measure for the PolyLineZ
|
52
|
+
field :m_max, position: :z_plus_8, type: :double, byte_order: :little
|
53
|
+
|
54
|
+
# An array of length num_points. The measures for each part in the
|
55
|
+
# PolyLineZ are stored end to end. The measures for Part 2 follow the
|
56
|
+
# measures for Part 1, and so on. The parts array holds the array index of
|
57
|
+
# the starting measure for each part. There is no delimited in the measure
|
58
|
+
# array between parts.
|
59
|
+
field :m_array, position: :z_plus_16, type: :double, byte_order: :little, number: :num_points
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'esri_shapefile/byte_model'
|
2
|
+
|
3
|
+
module EsriShapefile
|
4
|
+
module Shapes
|
5
|
+
#
|
6
|
+
# A polygon consists of one or more rings. A ring is a connected sequence of
|
7
|
+
# four or more points that form a closed, non-self-intersecting loop. A
|
8
|
+
# polygon may contain multiple outer rings. The order of vertices or
|
9
|
+
# orientation for a ring indicates which side of the ring is the interior of
|
10
|
+
# the polygon. The neighborhood to the right of an observer walking along
|
11
|
+
# the ring in vertex order is the neighborhood inside the polygon. Vertices
|
12
|
+
# of rings defining holes in polygons are in counterclockwise direction.
|
13
|
+
# Vertices for a single, ringed polygon are, therefore, always in clockwise
|
14
|
+
# order. The rings of a polygon are referred to as its parts.
|
15
|
+
#
|
16
|
+
# Because this specification does not forbid consecutive points with
|
17
|
+
# identical coordinates, shapefile readers must handle such cases. On the
|
18
|
+
# other hand, the degenerate, zero length or zero area parts that might
|
19
|
+
# result are not allowed.
|
20
|
+
#
|
21
|
+
# The Polygon structure is identical to the PolyLine structure.
|
22
|
+
#
|
23
|
+
class Polygon
|
24
|
+
extend EsriShapefile::ByteModel
|
25
|
+
|
26
|
+
field :shape_type, position: 0, type: :integer, byte_order: :little
|
27
|
+
field :x_min, position: 4, type: :double, byte_order: :little
|
28
|
+
field :y_min, position: 12, type: :double, byte_order: :little
|
29
|
+
field :x_max, position: 20, type: :double, byte_order: :little
|
30
|
+
field :y_max, position: 28, type: :double, byte_order: :little
|
31
|
+
field :num_parts, position: 36, type: :integer, byte_order: :little
|
32
|
+
field :num_points, position: 40, type: :integer, byte_order: :little
|
33
|
+
field :parts, position: 44, type: :integer, byte_order: :little, number: :num_parts
|
34
|
+
field :points, position: :x, type: :point, byte_order: :little, number: :num_points
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|