esri_shapefile 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/esri_shapefile.rb +4 -1
- data/lib/esri_shapefile/byte_model.rb +39 -25
- data/lib/esri_shapefile/byte_model/field.rb +10 -2
- data/lib/esri_shapefile/converter/svg.rb +56 -0
- data/lib/esri_shapefile/converter/svg/polygon.rb +25 -0
- data/lib/esri_shapefile/models/main_file_header.rb +1 -1
- data/lib/esri_shapefile/models/record_header.rb +1 -1
- data/lib/esri_shapefile/models/shapes/multi_patch.rb +1 -1
- data/lib/esri_shapefile/models/shapes/multi_point.rb +1 -1
- data/lib/esri_shapefile/models/shapes/multi_point_m.rb +1 -1
- data/lib/esri_shapefile/models/shapes/multi_point_z.rb +1 -1
- data/lib/esri_shapefile/models/shapes/null.rb +1 -1
- data/lib/esri_shapefile/models/shapes/point.rb +13 -1
- data/lib/esri_shapefile/models/shapes/point_m.rb +1 -1
- data/lib/esri_shapefile/models/shapes/point_z.rb +1 -1
- data/lib/esri_shapefile/models/shapes/poly_line.rb +1 -1
- data/lib/esri_shapefile/models/shapes/poly_line_m.rb +1 -1
- data/lib/esri_shapefile/models/shapes/poly_line_z.rb +1 -1
- data/lib/esri_shapefile/models/shapes/polygon.rb +10 -1
- data/lib/esri_shapefile/models/shapes/polygon_m.rb +1 -1
- data/lib/esri_shapefile/models/shapes/polygon_z.rb +1 -1
- data/lib/esri_shapefile/models/utils/ring.rb +38 -0
- data/lib/esri_shapefile/reader.rb +18 -2
- data/lib/esri_shapefile/version.rb +1 -1
- data/spec/esri_shapefile/model_spec.rb +1 -1
- data/spec/esri_shapefile/models/shapes/polygon_spec.rb +51 -0
- data/spec/spec_helper.rb +1 -1
- metadata +36 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb1817abc87ffd5412b71bd0bb63bf45b2b139d2
|
4
|
+
data.tar.gz: 56eb64d557473ecb32f2f1b95597795ad8dd46b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0258bfab1a89bcde50fface153b299bb623a12e9494bcc093c3bda6ee70cbdbb6c66a357260cfce9c5abda4d3306551908d5e1efdf90c4d0fdb2f9c5f7e40a6b
|
7
|
+
data.tar.gz: 8348c2c65807999818dcfca9879f5baed08ef5f3e565970ee9690b987ba01c2f6649254a42a7d62945ff024d6b9b5f292da488fd4f7ff45708e137069a4f5ca1
|
data/lib/esri_shapefile.rb
CHANGED
@@ -2,6 +2,8 @@ require "esri_shapefile/version"
|
|
2
2
|
require "esri_shapefile/byte_model"
|
3
3
|
require "esri_shapefile/byte_model/field"
|
4
4
|
|
5
|
+
require "esri_shapefile/models/utils/ring"
|
6
|
+
|
5
7
|
require "esri_shapefile/models/shapes/null"
|
6
8
|
require "esri_shapefile/models/shapes/point"
|
7
9
|
require "esri_shapefile/models/shapes/point_m"
|
@@ -22,8 +24,9 @@ require "esri_shapefile/models/main_file_header"
|
|
22
24
|
require "esri_shapefile/models/record_header"
|
23
25
|
|
24
26
|
require "esri_shapefile/reader"
|
27
|
+
require "esri_shapefile/converter/svg"
|
28
|
+
require "esri_shapefile/converter/svg/polygon"
|
25
29
|
|
26
30
|
module EsriShapefile
|
27
|
-
# Your code goes here...
|
28
31
|
end
|
29
32
|
|
@@ -1,41 +1,55 @@
|
|
1
1
|
module EsriShapefile
|
2
2
|
module ByteModel
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
attr_accessor :metadata
|
5
|
+
|
6
|
+
def self.included(model)
|
7
|
+
model.extend(ClassMethods)
|
7
8
|
end
|
8
9
|
|
9
|
-
def
|
10
|
-
|
10
|
+
def self.extended(model)
|
11
|
+
error_message = "\nInvalid ByteModel usage: `extend EsriShapefile::ByteModel`\n"
|
12
|
+
error_message << "Please change the syntax to `include EsriShapefile::ByteModel'"
|
13
|
+
raise error_message
|
11
14
|
end
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
module ClassMethods
|
17
|
+
def field(name, number: nil, position:, type:, byte_order:)
|
18
|
+
attr_accessor name unless name == :unused
|
19
|
+
fields << Field.new(name, position: position, type: type, byte_order: byte_order, number: number)
|
20
|
+
end
|
21
|
+
|
22
|
+
def fields
|
23
|
+
@fields ||= []
|
24
|
+
end
|
25
|
+
|
26
|
+
def from_bytes(bytes)
|
27
|
+
field_values = {}
|
28
|
+
fields.reduce(0) do |offset, field|
|
29
|
+
if !field.unused?
|
30
|
+
unpack_format = field.unpack_format(field_values)
|
31
|
+
field_value = bytes.unpack("@#{offset}#{unpack_format}")
|
32
|
+
|
33
|
+
if field.type == :point
|
34
|
+
field_value = field_value.each_slice(2).map do |x, y|
|
35
|
+
point = Shapes::Point.new
|
36
|
+
point.x = x
|
37
|
+
point.y = y
|
38
|
+
point
|
39
|
+
end
|
26
40
|
end
|
41
|
+
|
42
|
+
field_values[field.name] = field.list? ? field_value : field_value.first
|
27
43
|
end
|
28
44
|
|
29
|
-
|
45
|
+
offset += field.bytesize(field_values)
|
46
|
+
(offset < bytes.size) ? offset : break
|
30
47
|
end
|
31
48
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
field_values.reduce(self.new) do |model, (field, value)|
|
37
|
-
model.send("#{field}=", value)
|
49
|
+
field_values.reduce(self.new) do |model, (field, value)|
|
50
|
+
model.send("#{field}=", value)
|
38
51
|
model
|
52
|
+
end
|
39
53
|
end
|
40
54
|
end
|
41
55
|
|
@@ -33,8 +33,16 @@ module EsriShapefile
|
|
33
33
|
name == :unused
|
34
34
|
end
|
35
35
|
|
36
|
-
def bytesize
|
37
|
-
TYPES[@type][:bytesize]
|
36
|
+
def bytesize(values = {})
|
37
|
+
size = TYPES[@type][:bytesize]
|
38
|
+
|
39
|
+
if number_depends_on_field?
|
40
|
+
multiplier = TYPES[@type][:unpack][:multiplier] || 1
|
41
|
+
number_of_consecutive_values = number_depends_on_field? ? values[number] : number
|
42
|
+
number_of_consecutive_values * multiplier * size
|
43
|
+
else
|
44
|
+
size
|
45
|
+
end
|
38
46
|
end
|
39
47
|
|
40
48
|
def unpack_format(values = {})
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module EsriShapefile
|
2
|
+
module Converter
|
3
|
+
class Svg
|
4
|
+
|
5
|
+
attr_reader :shapefile_path
|
6
|
+
|
7
|
+
def initialize(shapefile_path)
|
8
|
+
@shapefile_path = shapefile_path
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(output_filepath)
|
12
|
+
File.open(output_filepath, "w") do |output_file|
|
13
|
+
reader = EsriShapefile::Reader.new(shapefile_path)
|
14
|
+
output_file.write(open_svg_header(reader.main_file_header))
|
15
|
+
|
16
|
+
reader.each_record do |record_header, shape|
|
17
|
+
shape_converter = get_shape_converter(shape)
|
18
|
+
output_file.write(shape_converter.to_svg(shape))
|
19
|
+
end
|
20
|
+
|
21
|
+
output_file.write(close_svg_header)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def get_shape_converter(shape)
|
28
|
+
case
|
29
|
+
when Shapes::Polygon then Svg::Polygon
|
30
|
+
else raise "Shape not supported"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def open_svg_header(main_file_header)
|
35
|
+
header = '<!DOCTYPE html>'
|
36
|
+
header << '<html>'
|
37
|
+
header << '<body>'
|
38
|
+
|
39
|
+
height = main_file_header.y_max - main_file_header.y_min
|
40
|
+
width = main_file_header.x_max - main_file_header.x_min
|
41
|
+
|
42
|
+
header << "<svg "
|
43
|
+
header << " height=\"100%\""
|
44
|
+
header << " width=\"100%\""
|
45
|
+
header << " viewbox=\"#{main_file_header.x_min} #{-main_file_header.y_max} #{width} #{height}\" >"
|
46
|
+
header
|
47
|
+
end
|
48
|
+
|
49
|
+
def close_svg_header
|
50
|
+
'</svg></body></html>'
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module EsriShapefile
|
2
|
+
module Converter
|
3
|
+
class Svg::Polygon
|
4
|
+
|
5
|
+
def self.to_svg(polygon)
|
6
|
+
svg = '<g'
|
7
|
+
polygon.metadata.each do |key, value|
|
8
|
+
svg << " #{key}=\"#{value}\""
|
9
|
+
end
|
10
|
+
svg << '>'
|
11
|
+
|
12
|
+
polygon.rings.each do |ring|
|
13
|
+
svg << '<polygon points="'
|
14
|
+
ring.points.each do |ring|
|
15
|
+
svg << "#{ring.x},#{-ring.y} "
|
16
|
+
end
|
17
|
+
svg << '" />'
|
18
|
+
end
|
19
|
+
|
20
|
+
svg << "</g>"
|
21
|
+
svg
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -7,7 +7,7 @@ module EsriShapefile
|
|
7
7
|
# with respect to the start of the file.
|
8
8
|
#
|
9
9
|
class MainFileHeader
|
10
|
-
|
10
|
+
include EsriShapefile::ByteModel
|
11
11
|
|
12
12
|
field :file_code, position: 0, type: :integer, byte_order: :big
|
13
13
|
field :unused, position: 4, type: :integer, byte_order: :big
|
@@ -6,7 +6,7 @@ module EsriShapefile
|
|
6
6
|
# A MultiPoint represents a set of points.
|
7
7
|
#
|
8
8
|
class MultiPoint
|
9
|
-
|
9
|
+
include EsriShapefile::ByteModel
|
10
10
|
|
11
11
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
12
12
|
field :x_min, position: 4, type: :double, byte_order: :little
|
@@ -6,7 +6,7 @@ module EsriShapefile
|
|
6
6
|
# A MultiPoint represents a set of points.
|
7
7
|
#
|
8
8
|
class MultiPointM
|
9
|
-
|
9
|
+
include EsriShapefile::ByteModel
|
10
10
|
|
11
11
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
12
12
|
field :x_min, position: 4, type: :double, byte_order: :little
|
@@ -6,7 +6,7 @@ module EsriShapefile
|
|
6
6
|
# A MultiPoint represents a set of points.
|
7
7
|
#
|
8
8
|
class MultiPointZ
|
9
|
-
|
9
|
+
include EsriShapefile::ByteModel
|
10
10
|
|
11
11
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
12
12
|
field :x_min, position: 4, type: :double, byte_order: :little
|
@@ -7,12 +7,24 @@ module EsriShapefile
|
|
7
7
|
# in the order X,Y.
|
8
8
|
#
|
9
9
|
class Point
|
10
|
-
|
10
|
+
include EsriShapefile::ByteModel
|
11
11
|
|
12
12
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
13
13
|
field :x, position: 4, type: :double, byte_order: :little
|
14
14
|
field :y, position: 12, type: :double, byte_order: :little
|
15
15
|
|
16
|
+
def self.at(x:, y:)
|
17
|
+
point = Point.new
|
18
|
+
point.x = x
|
19
|
+
point.y = y
|
20
|
+
point
|
21
|
+
end
|
22
|
+
|
23
|
+
def eql?(point)
|
24
|
+
point.is_a?(Point) && point.x == x && point.y == y
|
25
|
+
end
|
26
|
+
alias_method :==, :eql?
|
27
|
+
|
16
28
|
end
|
17
29
|
end
|
18
30
|
end
|
@@ -7,7 +7,7 @@ module EsriShapefile
|
|
7
7
|
# in the order X,Y,Z plus a measure.
|
8
8
|
#
|
9
9
|
class PointM
|
10
|
-
|
10
|
+
include EsriShapefile::ByteModel
|
11
11
|
|
12
12
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
13
13
|
field :x, position: 4, type: :double, byte_order: :little
|
@@ -7,7 +7,7 @@ module EsriShapefile
|
|
7
7
|
# in the order X,Y,Z plus a measure.
|
8
8
|
#
|
9
9
|
class PointZ
|
10
|
-
|
10
|
+
include EsriShapefile::ByteModel
|
11
11
|
|
12
12
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
13
13
|
field :x, position: 4, type: :double, byte_order: :little
|
@@ -14,7 +14,7 @@ module EsriShapefile
|
|
14
14
|
# allowed.
|
15
15
|
#
|
16
16
|
class PolyLine
|
17
|
-
|
17
|
+
include EsriShapefile::ByteModel
|
18
18
|
|
19
19
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
20
20
|
field :x_min, position: 4, type: :double, byte_order: :little
|
@@ -8,7 +8,7 @@ module EsriShapefile
|
|
8
8
|
# Parts may or may not intersect one another.
|
9
9
|
#
|
10
10
|
class PolyLineM
|
11
|
-
|
11
|
+
include EsriShapefile::ByteModel
|
12
12
|
|
13
13
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
14
14
|
field :x_min, position: 4, type: :double, byte_order: :little
|
@@ -8,7 +8,7 @@ module EsriShapefile
|
|
8
8
|
# Parts may or may not intersect one another.
|
9
9
|
#
|
10
10
|
class PolyLineZ
|
11
|
-
|
11
|
+
include EsriShapefile::ByteModel
|
12
12
|
|
13
13
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
14
14
|
field :x_min, position: 4, type: :double, byte_order: :little
|
@@ -21,7 +21,7 @@ module EsriShapefile
|
|
21
21
|
# The Polygon structure is identical to the PolyLine structure.
|
22
22
|
#
|
23
23
|
class Polygon
|
24
|
-
|
24
|
+
include EsriShapefile::ByteModel
|
25
25
|
|
26
26
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
27
27
|
field :x_min, position: 4, type: :double, byte_order: :little
|
@@ -32,6 +32,15 @@ module EsriShapefile
|
|
32
32
|
field :num_points, position: 40, type: :integer, byte_order: :little
|
33
33
|
field :parts, position: 44, type: :integer, byte_order: :little, number: :num_parts
|
34
34
|
field :points, position: :x, type: :point, byte_order: :little, number: :num_points
|
35
|
+
|
36
|
+
def rings
|
37
|
+
@rings ||= begin
|
38
|
+
ring_parts = (parts + [points.size])
|
39
|
+
ring_parts.each_cons(2).map do |ring_start_index, next_ring_index|
|
40
|
+
Ring.new(points[ring_start_index...next_ring_index])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
35
44
|
end
|
36
45
|
end
|
37
46
|
end
|
@@ -10,7 +10,7 @@ module EsriShapefile
|
|
10
10
|
# The PolygonM structure is identical to the PolyLineM structure
|
11
11
|
#
|
12
12
|
class PolygonM
|
13
|
-
|
13
|
+
include EsriShapefile::ByteModel
|
14
14
|
|
15
15
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
16
16
|
field :x_min, position: 4, type: :double, byte_order: :little
|
@@ -10,7 +10,7 @@ module EsriShapefile
|
|
10
10
|
# The PolygonZ structure is identical to the PolyLineZ structure
|
11
11
|
#
|
12
12
|
class PolygonZ
|
13
|
-
|
13
|
+
include EsriShapefile::ByteModel
|
14
14
|
|
15
15
|
field :shape_type, position: 0, type: :integer, byte_order: :little
|
16
16
|
field :x_min, position: 4, type: :double, byte_order: :little
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module EsriShapefile
|
2
|
+
class Ring
|
3
|
+
attr_reader :points, :direction
|
4
|
+
|
5
|
+
def initialize(points)
|
6
|
+
@points = points
|
7
|
+
@direction = determine_direction(points)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Sum over the edges, (x2 − x1)(y2 + y1). If the result is positive the
|
13
|
+
# curve is clockwise, if it's negative the curve is counter-clockwise. (The
|
14
|
+
# result is twice the enclosed area, with a +/- convention.)
|
15
|
+
#
|
16
|
+
# point[0] = (5,0) edge[0]: (6-5)(4+0) = 4
|
17
|
+
# point[1] = (6,4) edge[1]: (4-6)(5+4) = -18
|
18
|
+
# point[2] = (4,5) edge[2]: (1-4)(5+5) = -30
|
19
|
+
# point[3] = (1,5) edge[3]: (1-1)(0+5) = 0
|
20
|
+
# point[4] = (1,0) edge[4]: (5-1)(0+0) = 0
|
21
|
+
# ---
|
22
|
+
# -44 counter-clockwise
|
23
|
+
def determine_direction(points)
|
24
|
+
sum_over_edges = points.
|
25
|
+
each_cons(2).
|
26
|
+
reduce(0) { |sum, (p1, p2)| sum += ((p2.x - p1.x) * (p2.y + p1.y)) }
|
27
|
+
|
28
|
+
sum_over_edges < 0 ? :count_clockwise : :clockwise
|
29
|
+
end
|
30
|
+
|
31
|
+
def eql?(ring)
|
32
|
+
ring.is_a?(Ring) && ring.points == @points && ring.direction == @direction
|
33
|
+
end
|
34
|
+
alias_method :==, :eql?
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'dbf'
|
3
|
+
|
1
4
|
module EsriShapefile
|
2
5
|
class Reader
|
3
6
|
|
@@ -7,15 +10,19 @@ module EsriShapefile
|
|
7
10
|
attr_reader :main_file_header
|
8
11
|
|
9
12
|
def initialize(path_to_shapefile)
|
10
|
-
@path_to_shapefile = path_to_shapefile
|
13
|
+
@path_to_shapefile = Pathname.new(path_to_shapefile)
|
14
|
+
@path_to_dbf = @path_to_shapefile.sub_ext(".dbf")
|
15
|
+
|
11
16
|
@main_file_header = parse_main_file_header
|
12
17
|
end
|
13
18
|
|
14
19
|
def each_record
|
20
|
+
dbf = @path_to_dbf.file? ? DBF::Table.new(@path_to_dbf.to_s) : nil
|
21
|
+
|
15
22
|
File.open(@path_to_shapefile) do |file|
|
16
23
|
file.pos = MAIN_FILE_HEADER_BYTESIZE
|
17
24
|
|
18
|
-
(0..Float::INFINITY).lazy.reduce(file.pos) do |current_offset,
|
25
|
+
(0..Float::INFINITY).lazy.reduce(file.pos) do |current_offset, _|
|
19
26
|
break if current_offset >= main_file_header.file_length_bytes
|
20
27
|
|
21
28
|
record_header_bytes = file.read(RECORD_HEADER_BYTESIZE)
|
@@ -23,7 +30,9 @@ module EsriShapefile
|
|
23
30
|
|
24
31
|
shape_bytes = file.read(record_header.content_length_bytes)
|
25
32
|
shape_class = Shapes.find_by_bytes(shape_bytes)
|
33
|
+
|
26
34
|
shape = shape_class.from_bytes(shape_bytes)
|
35
|
+
shape.metadata = get_record_metadata(dbf, record_header.record_number)
|
27
36
|
|
28
37
|
yield record_header, shape
|
29
38
|
|
@@ -34,6 +43,13 @@ module EsriShapefile
|
|
34
43
|
|
35
44
|
private
|
36
45
|
|
46
|
+
# Retrieve the metadata for the shape from the associated .dbf file.
|
47
|
+
# Record numbers are one based, while the dbf file reader is 0 based.
|
48
|
+
# So we subtract one from the record number when performing the lookup.
|
49
|
+
def get_record_metadata(dbf, record_number)
|
50
|
+
dbf.nil? ? {} : dbf.find(record_number - 1).attributes
|
51
|
+
end
|
52
|
+
|
37
53
|
def parse_main_file_header
|
38
54
|
main_file_header_bytes = File.binread(@path_to_shapefile, 100, 0)
|
39
55
|
MainFileHeader.from_bytes(main_file_header_bytes)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pry'
|
3
|
+
|
4
|
+
module EsriShapefile
|
5
|
+
module Shapes
|
6
|
+
describe Polygon do
|
7
|
+
|
8
|
+
let(:polygon) do
|
9
|
+
polygon = Shapes::Polygon.new
|
10
|
+
polygon.parts = [0,5]
|
11
|
+
polygon.points = [
|
12
|
+
Point.at(x: 200, y: 200),
|
13
|
+
Point.at(x: 250, y: 250),
|
14
|
+
Point.at(x: 300, y: 200),
|
15
|
+
Point.at(x: 250, y: 150),
|
16
|
+
Point.at(x: 200, y: 200),
|
17
|
+
|
18
|
+
Point.at(x: 100, y: 200),
|
19
|
+
Point.at(x: 250, y: 350),
|
20
|
+
Point.at(x: 400, y: 200),
|
21
|
+
Point.at(x: 250, y: 50),
|
22
|
+
Point.at(x: 100, y: 200),
|
23
|
+
]
|
24
|
+
polygon
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#rings" do
|
28
|
+
it "foo" do
|
29
|
+
expect(polygon.rings).to eql([
|
30
|
+
Ring.new([
|
31
|
+
Point.at(x: 200, y: 200),
|
32
|
+
Point.at(x: 250, y: 250),
|
33
|
+
Point.at(x: 300, y: 200),
|
34
|
+
Point.at(x: 250, y: 150),
|
35
|
+
Point.at(x: 200, y: 200),
|
36
|
+
]),
|
37
|
+
Ring.new([
|
38
|
+
Point.at(x: 100, y: 200),
|
39
|
+
Point.at(x: 250, y: 350),
|
40
|
+
Point.at(x: 400, y: 200),
|
41
|
+
Point.at(x: 250, y: 50),
|
42
|
+
Point.at(x: 100, y: 200),
|
43
|
+
])
|
44
|
+
])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
data/spec/spec_helper.rb
CHANGED
@@ -47,7 +47,7 @@ RSpec.configure do |config|
|
|
47
47
|
# compatibility in RSpec 3). It causes shared context metadata to be
|
48
48
|
# inherited by the metadata hash of host groups and examples, rather than
|
49
49
|
# triggering implicit auto-inclusion in groups with matching metadata.
|
50
|
-
config.shared_context_metadata_behavior = :apply_to_host_groups
|
50
|
+
# config.shared_context_metadata_behavior = :apply_to_host_groups
|
51
51
|
|
52
52
|
# The settings below are suggested to provide a good initial experience
|
53
53
|
# with RSpec, but feel free to customize to your heart's content.
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: esri_shapefile
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Karayusuf
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dbf
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,20 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '3.4'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description: Library to read and write ESRI Shapefiles
|
56
84
|
email:
|
57
85
|
- jkarayusuf@gmail.com
|
@@ -65,6 +93,8 @@ files:
|
|
65
93
|
- lib/esri_shapefile.rb
|
66
94
|
- lib/esri_shapefile/byte_model.rb
|
67
95
|
- lib/esri_shapefile/byte_model/field.rb
|
96
|
+
- lib/esri_shapefile/converter/svg.rb
|
97
|
+
- lib/esri_shapefile/converter/svg/polygon.rb
|
68
98
|
- lib/esri_shapefile/models/main_file_header.rb
|
69
99
|
- lib/esri_shapefile/models/record_header.rb
|
70
100
|
- lib/esri_shapefile/models/shapes.rb
|
@@ -82,6 +112,7 @@ files:
|
|
82
112
|
- lib/esri_shapefile/models/shapes/polygon.rb
|
83
113
|
- lib/esri_shapefile/models/shapes/polygon_m.rb
|
84
114
|
- lib/esri_shapefile/models/shapes/polygon_z.rb
|
115
|
+
- lib/esri_shapefile/models/utils/ring.rb
|
85
116
|
- lib/esri_shapefile/reader.rb
|
86
117
|
- lib/esri_shapefile/version.rb
|
87
118
|
- spec/esri_shapefile/field_spec.rb
|
@@ -89,6 +120,7 @@ files:
|
|
89
120
|
- spec/esri_shapefile/models/main_file_header_spec.rb
|
90
121
|
- spec/esri_shapefile/models/record_header_spec.rb
|
91
122
|
- spec/esri_shapefile/models/shapes/point_spec.rb
|
123
|
+
- spec/esri_shapefile/models/shapes/polygon_spec.rb
|
92
124
|
- spec/spec_helper.rb
|
93
125
|
homepage: ''
|
94
126
|
licenses:
|
@@ -110,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
142
|
version: '0'
|
111
143
|
requirements: []
|
112
144
|
rubyforge_project:
|
113
|
-
rubygems_version: 2.2.
|
145
|
+
rubygems_version: 2.2.2
|
114
146
|
signing_key:
|
115
147
|
specification_version: 4
|
116
148
|
summary: Library to read and write ESRI Shapefiles
|
@@ -120,4 +152,5 @@ test_files:
|
|
120
152
|
- spec/esri_shapefile/models/main_file_header_spec.rb
|
121
153
|
- spec/esri_shapefile/models/record_header_spec.rb
|
122
154
|
- spec/esri_shapefile/models/shapes/point_spec.rb
|
155
|
+
- spec/esri_shapefile/models/shapes/polygon_spec.rb
|
123
156
|
- spec/spec_helper.rb
|