contrek 1.3.0 → 1.3.2
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/CHANGELOG.md +10 -0
- data/Gemfile.lock +1 -1
- data/README.md +3 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +24 -10
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.cpp +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RawBitmap.cpp +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.cpp +1 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +4 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +6 -6
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.cpp +16 -10
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.h +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.cpp +16 -20
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.h +3 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.cpp +1 -9
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/GeoJsonStreamingMerger.h +81 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/InnerPolyline.cpp +9 -28
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/InnerPolyline.h +10 -11
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.cpp +30 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.h +8 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.cpp +41 -41
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.h +4 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.cpp +5 -3
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.h +7 -5
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.cpp +1 -1
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queueable.h +2 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.cpp +0 -14
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.h +0 -2
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.cpp +5 -5
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ShapePool.cpp +32 -26
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ShapePool.h +7 -7
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.cpp +12 -31
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.h +10 -8
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/SubPool.h +47 -0
- data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/SvgStreamingMerger.h +43 -0
- data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +2 -1
- data/lib/contrek/finder/concurrent/cluster.rb +6 -5
- data/lib/contrek/finder/concurrent/cursor.rb +2 -4
- data/lib/contrek/finder/concurrent/finder.rb +1 -12
- data/lib/contrek/finder/concurrent/inner_polyline.rb +8 -25
- data/lib/contrek/finder/concurrent/part.rb +25 -1
- data/lib/contrek/finder/concurrent/partitionable.rb +39 -34
- data/lib/contrek/finder/concurrent/sequence.rb +1 -17
- data/lib/contrek/version.rb +1 -1
- metadata +5 -2
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SubPool.h
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025-2026 Emanuele Cesaroni
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the GNU Affero General Public License v3 (AGPLv3).
|
|
7
|
+
* See the LICENSE file in this directory for the full license text.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#pragma once
|
|
11
|
+
#include <deque>
|
|
12
|
+
#include <memory>
|
|
13
|
+
#include <utility>
|
|
14
|
+
|
|
15
|
+
class ShapePool;
|
|
16
|
+
|
|
17
|
+
template <typename T>
|
|
18
|
+
class SubPool {
|
|
19
|
+
private:
|
|
20
|
+
std::unique_ptr<std::deque<T>> storage_;
|
|
21
|
+
uint32_t active_count_ = 0;
|
|
22
|
+
ShapePool* macro_pool_ = nullptr;
|
|
23
|
+
|
|
24
|
+
public:
|
|
25
|
+
explicit SubPool(ShapePool* macro_pool) : macro_pool_(macro_pool) {
|
|
26
|
+
storage_ = std::make_unique<std::deque<T>>();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
template <typename... Args>
|
|
30
|
+
T* acquire(Args&&... args) {
|
|
31
|
+
storage_->emplace_back(std::forward<Args>(args)...);
|
|
32
|
+
T* ptr = &storage_->back();
|
|
33
|
+
active_count_++;
|
|
34
|
+
return ptr;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
void decrement() {
|
|
38
|
+
active_count_--;
|
|
39
|
+
if (active_count_ == 0 && storage_ != nullptr) {
|
|
40
|
+
storage_.reset();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
bool is_released() const {
|
|
45
|
+
return storage_ == nullptr;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SvgStreamingMerger.h
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025-2026 Emanuele Cesaroni
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the GNU Affero General Public License v3 (AGPLv3).
|
|
7
|
+
* See the LICENSE file in this directory for the full license text.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#pragma once
|
|
11
|
+
#include <string>
|
|
12
|
+
#include "StreamingMerger.h"
|
|
13
|
+
|
|
14
|
+
class SvgStreamingMerger : public StreamingMerger {
|
|
15
|
+
private:
|
|
16
|
+
std::string svg_css() {
|
|
17
|
+
return ".out{fill:none;stroke:red;stroke-width:1;}.in{fill:none;stroke:green;stroke-width:1;}.out:hover{stroke:yellow;}";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
protected:
|
|
21
|
+
void write_header() override {
|
|
22
|
+
*stream << "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"" << total_width
|
|
23
|
+
<< "\" height=\"" << total_height << "\"><style>" << svg_css() << "</style>";
|
|
24
|
+
}
|
|
25
|
+
void write_footer() override {
|
|
26
|
+
*stream << "</svg>";
|
|
27
|
+
}
|
|
28
|
+
void write_outer_polygon_start() override {
|
|
29
|
+
*stream << "<polygon points=\"";
|
|
30
|
+
}
|
|
31
|
+
void write_outer_polygon_end() override {
|
|
32
|
+
*stream << "\" class=\"out\"/>";
|
|
33
|
+
}
|
|
34
|
+
void write_inner_polygon_start() override {
|
|
35
|
+
*stream << "<polygon points=\"";
|
|
36
|
+
}
|
|
37
|
+
void write_inner_polygon_end() override {
|
|
38
|
+
*stream << "\" class=\"in\"/>";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public:
|
|
42
|
+
using StreamingMerger::StreamingMerger;
|
|
43
|
+
};
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
#include "PolygonFinder/src/polygon/finder/concurrent/VerticalMerger.cpp"
|
|
97
97
|
#include "PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.h"
|
|
98
98
|
#include "PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.cpp"
|
|
99
|
+
#include "PolygonFinder/src/polygon/finder/concurrent/SvgStreamingMerger.h"
|
|
99
100
|
#include "PolygonFinder/src/polygon/finder/concurrent/ShapePool.h"
|
|
100
101
|
#include "PolygonFinder/src/polygon/finder/concurrent/ShapePool.cpp"
|
|
101
102
|
extern "C" {
|
|
@@ -315,7 +316,7 @@ StreamingMerger* create_streaming_merger(Object self,
|
|
|
315
316
|
int total_width,
|
|
316
317
|
int total_height) {
|
|
317
318
|
OfstreamWrapper* wrapper = Rice::detail::From_Ruby<OfstreamWrapper*>().convert(stream_obj.value());
|
|
318
|
-
return new
|
|
319
|
+
return new SvgStreamingMerger(number_of_threads, options, &wrapper->get_stream(), total_width, total_height);
|
|
319
320
|
}
|
|
320
321
|
|
|
321
322
|
OfstreamWrapper* create_ofstream(Object self, std::string path) {
|
|
@@ -5,7 +5,7 @@ module Contrek
|
|
|
5
5
|
class Cluster
|
|
6
6
|
attr_reader :tiles, :hub, :finder
|
|
7
7
|
|
|
8
|
-
def initialize(finder:, height
|
|
8
|
+
def initialize(finder:, height:)
|
|
9
9
|
@finder = finder
|
|
10
10
|
@tiles = []
|
|
11
11
|
@hub = Hub.new(height:)
|
|
@@ -57,23 +57,24 @@ module Contrek
|
|
|
57
57
|
new_inners = shape.inner_polylines
|
|
58
58
|
new_inner_polylines = []
|
|
59
59
|
tot_inner += Benchmark.measure do
|
|
60
|
-
new_inner_polylines = cursor.join_inners!(
|
|
60
|
+
new_inner_polylines = cursor.join_inners!(treemap)
|
|
61
61
|
new_inners += new_inner_polylines
|
|
62
62
|
if treemap
|
|
63
63
|
new_inner_polylines.each do |inner_polyline|
|
|
64
|
-
inner_polyline.
|
|
64
|
+
inner_polyline.compute_vertical_bounds!
|
|
65
65
|
all_new_inner_polylines += new_inner_polylines
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
new_inners += cursor.orphan_inners
|
|
69
69
|
end.real
|
|
70
|
+
shape.clear_inner!
|
|
70
71
|
|
|
71
72
|
polyline = Polyline.new(tile: tile, polygon: new_outer.to_a)
|
|
72
73
|
inserting_new_shape = Shape.init_by(polyline, new_inners)
|
|
73
74
|
new_shapes << inserting_new_shape
|
|
74
75
|
polyline.shape = inserting_new_shape
|
|
75
76
|
|
|
76
|
-
new_inner_polylines.each { |inner_polyline| inner_polyline.
|
|
77
|
+
new_inner_polylines.each { |inner_polyline| inner_polyline.shape = inserting_new_shape }
|
|
77
78
|
|
|
78
79
|
if treemap
|
|
79
80
|
cursor.shapes_sequence.each do |merged_shape|
|
|
@@ -115,7 +116,7 @@ module Contrek
|
|
|
115
116
|
private
|
|
116
117
|
|
|
117
118
|
def assign_ancestry(shape, inner_polyline)
|
|
118
|
-
shape.set_parent_shape(inner_polyline.
|
|
119
|
+
shape.set_parent_shape(inner_polyline.shape)
|
|
119
120
|
shape.parent_inner_polyline = inner_polyline
|
|
120
121
|
shape.fixed = true
|
|
121
122
|
end
|
|
@@ -40,7 +40,7 @@ module Contrek
|
|
|
40
40
|
outer_joined_polyline
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
def join_inners!(
|
|
43
|
+
def join_inners!(treemap)
|
|
44
44
|
return_inner_polylines = []
|
|
45
45
|
shape_index = 0
|
|
46
46
|
|
|
@@ -102,9 +102,6 @@ module Contrek
|
|
|
102
102
|
if act_part.is?(Part::EXCLUSIVE)
|
|
103
103
|
return if act_part.size == 0
|
|
104
104
|
while (position = act_part.next_position)
|
|
105
|
-
return if outer_joined_polyline.size > 1 &&
|
|
106
|
-
outer_joined_polyline.head.payload == position.payload &&
|
|
107
|
-
act_part == all_parts.first
|
|
108
105
|
outer_joined_polyline.add(position)
|
|
109
106
|
end
|
|
110
107
|
else
|
|
@@ -177,6 +174,7 @@ module Contrek
|
|
|
177
174
|
if !dest_part.polyline.on?(Polyline::TRACKED_OUTER)
|
|
178
175
|
@shapes_sequence << shape
|
|
179
176
|
@orphan_inners += shape.inner_polylines
|
|
177
|
+
shape.clear_inner!
|
|
180
178
|
end
|
|
181
179
|
dest_part.polyline.turn_on(Polyline::TRACKED_OUTER)
|
|
182
180
|
if !dest_part.touched
|
|
@@ -114,18 +114,7 @@ module Contrek
|
|
|
114
114
|
return
|
|
115
115
|
end
|
|
116
116
|
if (twin_tile = arriving_tiles.find { |b| (b.start_x == (tile.end_x - 1)) || ((b.end_x - 1) == tile.start_x) })
|
|
117
|
-
|
|
118
|
-
if twin_tile.start_x == (tile.end_x - 1)
|
|
119
|
-
start_x = tile.start_x
|
|
120
|
-
end_x = twin_tile.end_x
|
|
121
|
-
else
|
|
122
|
-
start_x = twin_tile.start_x
|
|
123
|
-
end_x = tile.end_x
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# puts "start = #{start_x} end = #{end_x}"
|
|
127
|
-
|
|
128
|
-
cluster = Cluster.new(finder: self, height: height, start_x:, end_x:)
|
|
117
|
+
cluster = Cluster.new(finder: self, height: height)
|
|
129
118
|
if twin_tile.start_x == (tile.end_x - 1)
|
|
130
119
|
cluster.add(tile)
|
|
131
120
|
cluster.add(twin_tile)
|
|
@@ -3,37 +3,20 @@
|
|
|
3
3
|
module Contrek
|
|
4
4
|
module Concurrent
|
|
5
5
|
class InnerPolyline
|
|
6
|
-
attr_reader :
|
|
6
|
+
attr_reader :raw, :vertical_bounds
|
|
7
|
+
attr_accessor :shape
|
|
7
8
|
|
|
8
9
|
def initialize(shape: nil, raw_coordinates: [], sequence: nil)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def raw
|
|
15
|
-
@sequence ? @sequence.to_a : @raw
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def vertical_bounds
|
|
19
|
-
if @sequence
|
|
20
|
-
@sequence.vertical_bounds
|
|
10
|
+
if sequence
|
|
11
|
+
@shape = sequence.shape
|
|
12
|
+
@raw = sequence.to_a
|
|
21
13
|
else
|
|
22
|
-
|
|
14
|
+
@shape = shape
|
|
15
|
+
@raw = raw_coordinates
|
|
23
16
|
end
|
|
24
17
|
end
|
|
25
18
|
|
|
26
|
-
def
|
|
27
|
-
if @sequence
|
|
28
|
-
@sequence.shape
|
|
29
|
-
else
|
|
30
|
-
@shape
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private
|
|
35
|
-
|
|
36
|
-
def raw_vertical_bounds
|
|
19
|
+
def compute_vertical_bounds!
|
|
37
20
|
@vertical_bounds ||= begin
|
|
38
21
|
min_y = Float::INFINITY
|
|
39
22
|
max_y = 0
|
|
@@ -10,11 +10,13 @@ module Contrek
|
|
|
10
10
|
ADDED = 2
|
|
11
11
|
|
|
12
12
|
attr_reader :polyline, :touched
|
|
13
|
-
attr_accessor :next, :circular_next, :prev, :type, :dead_end, :inverts,
|
|
13
|
+
attr_accessor :next, :circular_next, :prev, :type, :dead_end, :inverts,
|
|
14
|
+
:trasmuted, :versus, :mirror, :next_seam, :transmutation_skip
|
|
14
15
|
def initialize(type, polyline)
|
|
15
16
|
@type = type
|
|
16
17
|
@polyline = polyline
|
|
17
18
|
@next = nil
|
|
19
|
+
@next_seam = nil
|
|
18
20
|
@circular_next = nil
|
|
19
21
|
@prev = nil
|
|
20
22
|
@dead_end = false
|
|
@@ -23,6 +25,7 @@ module Contrek
|
|
|
23
25
|
@trasmuted = false
|
|
24
26
|
@versus = 0
|
|
25
27
|
@mirror = false
|
|
28
|
+
@transmutation_skip = false
|
|
26
29
|
end
|
|
27
30
|
|
|
28
31
|
def is?(type)
|
|
@@ -80,6 +83,27 @@ module Contrek
|
|
|
80
83
|
end
|
|
81
84
|
end
|
|
82
85
|
|
|
86
|
+
def try_transmutation!
|
|
87
|
+
head_queues = head.end_point.queues
|
|
88
|
+
return if head_queues.size == 1
|
|
89
|
+
other_head_part = head_queues.find { |part| part.polyline.tile == polyline.tile && part != self }
|
|
90
|
+
if other_head_part
|
|
91
|
+
tail_queues = tail.end_point.queues
|
|
92
|
+
if tail_queues.find { |part| part == other_head_part }
|
|
93
|
+
if (other_head_part.tail.payload[:y] == tail.payload[:y] && other_head_part.head.payload[:y] == head.payload[:y]) ||
|
|
94
|
+
(other_head_part.tail.payload[:y] == head.payload[:y] && other_head_part.head.payload[:y] == tail.payload[:y])
|
|
95
|
+
if self.next.nil? && other_head_part.prev.nil?
|
|
96
|
+
self.mirror = true
|
|
97
|
+
end
|
|
98
|
+
else
|
|
99
|
+
self.type = Part::EXCLUSIVE
|
|
100
|
+
self.trasmuted = true
|
|
101
|
+
other_head_part.transmutation_skip = true
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
83
107
|
def within?(other)
|
|
84
108
|
self_min, self_max = [head.payload[:y], tail.payload[:y]].minmax
|
|
85
109
|
other_min, other_max = [other.head.payload[:y], other.tail.payload[:y]].minmax
|
|
@@ -8,6 +8,8 @@ module Contrek
|
|
|
8
8
|
def initialize(*args, **kwargs, &block)
|
|
9
9
|
super
|
|
10
10
|
@parts = []
|
|
11
|
+
@first_seam = nil
|
|
12
|
+
@last_seam = nil
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
def add_part(new_part)
|
|
@@ -16,8 +18,14 @@ module Contrek
|
|
|
16
18
|
last.next = last.circular_next = new_part if last
|
|
17
19
|
new_part.circular_next = @parts.first
|
|
18
20
|
new_part.prev = last
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
if new_part.is?(Part::SEAM)
|
|
22
|
+
@first_seam ||= new_part
|
|
23
|
+
if !@last_seam.nil?
|
|
24
|
+
@last_seam.next_seam = new_part
|
|
25
|
+
end
|
|
26
|
+
@last_seam = new_part
|
|
27
|
+
new_part.orient!
|
|
28
|
+
end
|
|
21
29
|
end
|
|
22
30
|
|
|
23
31
|
def inspect_parts
|
|
@@ -27,6 +35,8 @@ module Contrek
|
|
|
27
35
|
def partition!
|
|
28
36
|
current_part = nil
|
|
29
37
|
@parts = []
|
|
38
|
+
@first_seam = nil
|
|
39
|
+
@last_seam = nil
|
|
30
40
|
|
|
31
41
|
@raw.each_with_index do |position, n|
|
|
32
42
|
if @tile.tg_border?(position)
|
|
@@ -49,7 +59,7 @@ module Contrek
|
|
|
49
59
|
end
|
|
50
60
|
add_part(current_part)
|
|
51
61
|
|
|
52
|
-
|
|
62
|
+
transmute_parts!
|
|
53
63
|
end
|
|
54
64
|
|
|
55
65
|
private
|
|
@@ -57,42 +67,37 @@ module Contrek
|
|
|
57
67
|
# If there are SEAM parts and one is canceled out by another within the same polyline,
|
|
58
68
|
# meaning that all its points are repeated in another, longer sequence,
|
|
59
69
|
# then the shorter one is converted to EXCLUSIVE and marked as transmuted
|
|
60
|
-
def
|
|
70
|
+
def transmute_parts!
|
|
61
71
|
transpose = tile.cluster.finder.transpose?
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
next unless inside.is?(Part::SEAM)
|
|
65
|
-
@parts.each do |inside_compare|
|
|
66
|
-
next if inside == inside_compare
|
|
67
|
-
next unless inside_compare.is?(Part::SEAM)
|
|
68
|
-
|
|
72
|
+
if (current_seam = @first_seam)
|
|
73
|
+
loop do
|
|
69
74
|
if transpose
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if count == inside_compare.size && inside.next.nil? && inside_compare.prev.nil?
|
|
92
|
-
inside.mirror = true
|
|
75
|
+
transmute_transposed_part(current_seam)
|
|
76
|
+
elsif !current_seam.transmutation_skip
|
|
77
|
+
current_seam.try_transmutation!
|
|
78
|
+
end
|
|
79
|
+
current_seam = current_seam.next_seam
|
|
80
|
+
break if current_seam.nil?
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def transmute_transposed_part(part)
|
|
86
|
+
if (current_seam = @first_seam)
|
|
87
|
+
loop do
|
|
88
|
+
if current_seam != part
|
|
89
|
+
if part.within?(current_seam)
|
|
90
|
+
if !part.same_length?(current_seam)
|
|
91
|
+
part.type = Part::EXCLUSIVE
|
|
92
|
+
part.trasmuted = true
|
|
93
|
+
part.head.end_point.queues.delete(part)
|
|
94
|
+
part.tail.end_point.queues.delete(part)
|
|
95
|
+
return
|
|
93
96
|
end
|
|
94
97
|
end
|
|
95
98
|
end
|
|
99
|
+
current_seam = current_seam.next_seam
|
|
100
|
+
break if current_seam.nil?
|
|
96
101
|
end
|
|
97
102
|
end
|
|
98
103
|
end
|
|
@@ -3,13 +3,9 @@
|
|
|
3
3
|
module Contrek
|
|
4
4
|
module Concurrent
|
|
5
5
|
class Sequence
|
|
6
|
-
attr_accessor :
|
|
6
|
+
attr_accessor :shape
|
|
7
7
|
prepend Queueable
|
|
8
8
|
|
|
9
|
-
def initialize
|
|
10
|
-
@vertical_bounds = nil
|
|
11
|
-
end
|
|
12
|
-
|
|
13
9
|
def is_not_vertical
|
|
14
10
|
return false if size < 2
|
|
15
11
|
x0 = head.payload[:x]
|
|
@@ -21,18 +17,6 @@ module Contrek
|
|
|
21
17
|
false
|
|
22
18
|
end
|
|
23
19
|
|
|
24
|
-
def compute_vertical_bounds!
|
|
25
|
-
return if size == 0
|
|
26
|
-
min_y = Float::INFINITY
|
|
27
|
-
max_y = 0
|
|
28
|
-
get_vector_cache.each do |pos|
|
|
29
|
-
y = pos[:y]
|
|
30
|
-
min_y = y if y < min_y
|
|
31
|
-
max_y = y if y > max_y
|
|
32
|
-
end
|
|
33
|
-
@vertical_bounds = {min: min_y, max: max_y}
|
|
34
|
-
end
|
|
35
|
-
|
|
36
20
|
def get_vector_cache
|
|
37
21
|
@vector_cache ||= to_a
|
|
38
22
|
end
|
data/lib/contrek/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: contrek
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Emanuele Cesaroni
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rspec
|
|
@@ -188,6 +188,7 @@ files:
|
|
|
188
188
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/FakeCluster.h
|
|
189
189
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.cpp
|
|
190
190
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.h
|
|
191
|
+
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/GeoJsonStreamingMerger.h
|
|
191
192
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/HorizontalMerger.cpp
|
|
192
193
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/HorizontalMerger.h
|
|
193
194
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Hub.cpp
|
|
@@ -218,6 +219,8 @@ files:
|
|
|
218
219
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ShapePool.h
|
|
219
220
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.cpp
|
|
220
221
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.h
|
|
222
|
+
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/SubPool.h
|
|
223
|
+
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/SvgStreamingMerger.h
|
|
221
224
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.cpp
|
|
222
225
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.h
|
|
223
226
|
- ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/VerticalMerger.cpp
|