contrek 1.2.8 → 1.2.9

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.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rubocop.yml +11 -0
  4. data/CHANGELOG.md +7 -1
  5. data/Gemfile +2 -0
  6. data/Gemfile.lock +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +2 -0
  9. data/contrek.gemspec +2 -0
  10. data/ext/cpp_polygon_finder/PolygonFinder/CMakeLists.txt +2 -4
  11. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +108 -1
  12. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.h +1 -0
  13. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +0 -1
  14. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +70 -297
  15. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.h +1 -1
  16. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.cpp +6 -6
  17. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.h +3 -2
  18. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.cpp +114 -0
  19. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.h +41 -0
  20. data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +52 -2
  21. data/ext/cpp_polygon_finder/extconf.rb +2 -0
  22. data/lib/contrek/bitmaps/bitmap.rb +2 -0
  23. data/lib/contrek/bitmaps/chunky_bitmap.rb +2 -0
  24. data/lib/contrek/bitmaps/painting.rb +2 -0
  25. data/lib/contrek/bitmaps/png_bitmap.rb +2 -0
  26. data/lib/contrek/bitmaps/raw_bitmap.rb +2 -0
  27. data/lib/contrek/bitmaps/rgb_color.rb +2 -0
  28. data/lib/contrek/bitmaps/rgb_cpp_color.rb +2 -0
  29. data/lib/contrek/bitmaps/sample_generator.rb +2 -0
  30. data/lib/contrek/cpp/cpp_concurrent_finder.rb +2 -0
  31. data/lib/contrek/cpp/cpp_concurrent_horizontal_merger.rb +2 -0
  32. data/lib/contrek/cpp/cpp_concurrent_merger.rb +2 -0
  33. data/lib/contrek/cpp/cpp_concurrent_streaming_merger.rb +11 -0
  34. data/lib/contrek/cpp/cpp_concurrent_vertical_merger.rb +2 -0
  35. data/lib/contrek/cpp/cpp_result.rb +2 -0
  36. data/lib/contrek/cpp/cpp_tempfile.rb +28 -0
  37. data/lib/contrek/finder/bounds.rb +2 -0
  38. data/lib/contrek/finder/concurrent/clipped_polygon_finder.rb +2 -0
  39. data/lib/contrek/finder/concurrent/cluster.rb +2 -0
  40. data/lib/contrek/finder/concurrent/cursor.rb +2 -0
  41. data/lib/contrek/finder/concurrent/end_point.rb +2 -0
  42. data/lib/contrek/finder/concurrent/fake_cluster.rb +2 -0
  43. data/lib/contrek/finder/concurrent/finder.rb +2 -0
  44. data/lib/contrek/finder/concurrent/horizontal_merger.rb +2 -0
  45. data/lib/contrek/finder/concurrent/hub.rb +2 -0
  46. data/lib/contrek/finder/concurrent/inner_polyline.rb +2 -0
  47. data/lib/contrek/finder/concurrent/listable.rb +2 -0
  48. data/lib/contrek/finder/concurrent/merger.rb +3 -0
  49. data/lib/contrek/finder/concurrent/part.rb +2 -0
  50. data/lib/contrek/finder/concurrent/partitionable.rb +2 -0
  51. data/lib/contrek/finder/concurrent/polyline.rb +2 -0
  52. data/lib/contrek/finder/concurrent/poolable.rb +2 -0
  53. data/lib/contrek/finder/concurrent/position.rb +2 -0
  54. data/lib/contrek/finder/concurrent/queueable.rb +2 -0
  55. data/lib/contrek/finder/concurrent/sequence.rb +2 -0
  56. data/lib/contrek/finder/concurrent/shape.rb +2 -0
  57. data/lib/contrek/finder/concurrent/streaming_merger.rb +89 -0
  58. data/lib/contrek/finder/concurrent/tile.rb +2 -0
  59. data/lib/contrek/finder/concurrent/vertical_merger.rb +4 -2
  60. data/lib/contrek/finder/list.rb +2 -0
  61. data/lib/contrek/finder/list_entry.rb +2 -0
  62. data/lib/contrek/finder/listable.rb +2 -0
  63. data/lib/contrek/finder/lists.rb +2 -0
  64. data/lib/contrek/finder/node.rb +2 -0
  65. data/lib/contrek/finder/node_cluster.rb +3 -1
  66. data/lib/contrek/finder/polygon_finder.rb +2 -0
  67. data/lib/contrek/finder/result.rb +2 -0
  68. data/lib/contrek/map/mercator_projection.rb +2 -0
  69. data/lib/contrek/matchers/matcher.rb +2 -0
  70. data/lib/contrek/matchers/matcher_hsb.rb +2 -0
  71. data/lib/contrek/matchers/value_not_matcher.rb +2 -0
  72. data/lib/contrek/reducers/linear_reducer.rb +2 -0
  73. data/lib/contrek/reducers/reducer.rb +2 -0
  74. data/lib/contrek/reducers/uniq_reducer.rb +2 -0
  75. data/lib/contrek/reducers/visvalingam_reducer.rb +2 -0
  76. data/lib/contrek/shared/result.rb +2 -0
  77. data/lib/contrek/version.rb +3 -1
  78. data/lib/contrek.rb +5 -0
  79. metadata +11 -5
@@ -21,7 +21,7 @@ Polyline::Polyline(Tile* tile, const std::vector<Point*>& polygon, const std::op
21
21
  tile(tile)
22
22
  { if (bounds.has_value()) {
23
23
  min_x = bounds->min_x;
24
- max_x = bounds->max_x;
24
+ max_x_ = bounds->max_x;
25
25
  min_y_ = bounds->min_y;
26
26
  max_y_ = bounds->max_y;
27
27
  } else {
@@ -32,17 +32,17 @@ Polyline::Polyline(Tile* tile, const std::vector<Point*>& polygon, const std::op
32
32
 
33
33
  int Polyline::width() {
34
34
  if (raw_.empty()) return 0;
35
- return(max_x - min_x);
35
+ return(max_x_ - min_x);
36
36
  }
37
37
 
38
38
  bool Polyline::boundary() {
39
- return( tile->tg_border(Point{min_x, 0}) || tile->tg_border(Point{max_x, 0}));
39
+ return( tile->tg_border(Point{min_x, 0}) || tile->tg_border(Point{max_x_, 0}));
40
40
  }
41
41
 
42
42
  void Polyline::find_boundary() {
43
43
  if (raw_.empty()) return;
44
44
  min_x = std::numeric_limits<int>::max();
45
- max_x = -std::numeric_limits<int>::max();
45
+ max_x_ = -std::numeric_limits<int>::max();
46
46
  min_y_ = std::numeric_limits<int>::max();
47
47
  max_y_ = -std::numeric_limits<int>::max();
48
48
  for (Point* p : raw_) {
@@ -50,7 +50,7 @@ void Polyline::find_boundary() {
50
50
  int x = p->x;
51
51
  int y = p->y;
52
52
  if (x < min_x) min_x = x;
53
- if (x > max_x) max_x = x;
53
+ if (x > max_x_) max_x_ = x;
54
54
  if (y < min_y_) min_y_ = y;
55
55
  if (y > max_y_) max_y_ = y;
56
56
  }
@@ -98,7 +98,7 @@ std::string Polyline::named() {
98
98
 
99
99
  void Polyline::fill_bounds(RectBounds& target_bounds) const {
100
100
  target_bounds.min_x = this->min_x;
101
- target_bounds.max_x = this->max_x;
101
+ target_bounds.max_x = this->max_x_;
102
102
  target_bounds.min_y = this->min_y_;
103
103
  target_bounds.max_y = this->max_y_;
104
104
  }
@@ -40,10 +40,11 @@ class Polyline : public Partitionable {
40
40
  int width();
41
41
  Tile *tile = nullptr;
42
42
  Shape* shape = nullptr;
43
- std::vector<Point*> raw() const { return raw_; }
43
+ const std::vector<Point*>& raw() const { return raw_; }
44
44
  const std::vector<Part*>& parts() const { return parts_; }
45
45
  const int max_y() const { return max_y_; }
46
46
  const int min_y() const { return min_y_; }
47
+ const int max_x() const { return max_x_; }
47
48
  void clear();
48
49
  bool is_empty();
49
50
  bool any_ancients = false;
@@ -56,7 +57,7 @@ class Polyline : public Partitionable {
56
57
 
57
58
  private:
58
59
  std::vector<Point*> raw_;
59
- int min_x, max_x, min_y_, max_y_;
60
+ int min_x, max_x_, min_y_, max_y_;
60
61
  void find_boundary();
61
62
  uint32_t flags_ = 0;
62
63
  std::string named_;
@@ -0,0 +1,114 @@
1
+ /*
2
+ * StreamingMerger.cpp
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
+ #include "StreamingMerger.h"
11
+ #include <sstream>
12
+ #include <algorithm>
13
+ #include <vector>
14
+ #include <string>
15
+
16
+ StreamingMerger::StreamingMerger(int number_of_threads,
17
+ std::vector<std::string>* options,
18
+ std::ofstream* stream_to,
19
+ int total_width, int total_height)
20
+ : VerticalMerger(number_of_threads, options), stream(stream_to), total_width(total_width), total_height(total_height) {
21
+ if (!stream) {
22
+ throw std::invalid_argument("Streaming requires a valid destination output. stream_to cannot be null.");
23
+ }
24
+ if (total_width <= 0 || total_height <= 0) {
25
+ throw std::invalid_argument("Streaming requires valid canvas dimensions (width and height must be > 0).");
26
+ }
27
+ }
28
+
29
+ void StreamingMerger::add_tile(ProcessResult& result, bool flush)
30
+ { VerticalMerger::add_tile(result);
31
+ if (tiles_.size() == 2) {
32
+ this->process_tiles();
33
+ this->tiles_.queue_push(this->whole_tile);
34
+ this->stream_polygons(this->whole_tile, flush);
35
+ }
36
+ }
37
+
38
+ ProcessResult* StreamingMerger::process_info() {
39
+ ProcessResult *pr = VerticalMerger::process_info();
40
+ pr->groups = this->moved;
41
+ return(pr);
42
+ }
43
+
44
+ void StreamingMerger::stream_polygons(Tile* tile, bool flush) {
45
+ ensure_header();
46
+ if (int tile_end_x = tile->end_x(); true) {
47
+ tile->shapes().erase(
48
+ std::remove_if(tile->shapes().begin(), tile->shapes().end(), [this, flush, tile_end_x](const Shape* shape) {
49
+ if (flush || shape->outer_polyline->max_x() < (tile_end_x - 1)) {
50
+ this->moved++;
51
+ this->stream_raw_polygon(shape);
52
+ return true;
53
+ }
54
+ return false;
55
+ }),
56
+ tile->shapes().end());
57
+ }
58
+ if (flush) {
59
+ ensure_footer();
60
+ }
61
+ }
62
+
63
+ void StreamingMerger::stream_raw_polygon(const Shape* shape) {
64
+ std::ostringstream outer_oss;
65
+ const std::vector<Point*> points = shape->outer_polyline->raw();
66
+ for (size_t i = 0; i < points.size(); ++i) {
67
+ outer_oss << points[i]->y << "," << points[i]->x;
68
+ if (i < points.size() - 1) outer_oss << " ";
69
+ }
70
+ *stream << svg_outer_polygon_string(outer_oss.str());
71
+
72
+ for (const auto& inner_polyline : shape->inner_polylines) {
73
+ std::ostringstream inner_oss;
74
+ const std::vector<Point*> inner_points = inner_polyline->raw();
75
+ for (size_t i = 0; i < inner_points.size(); ++i) {
76
+ inner_oss << inner_points[i]->y << "," << inner_points[i]->x;
77
+ if (i < inner_points.size() - 1) inner_oss << " ";
78
+ }
79
+ *stream << svg_inner_polygon_string(inner_oss.str());
80
+ }
81
+ }
82
+
83
+ void StreamingMerger::ensure_header() {
84
+ if (stream && stream->tellp() == 0) {
85
+ *stream << svg_header_string();
86
+ }
87
+ }
88
+
89
+ void StreamingMerger::ensure_footer() {
90
+ if (stream) {
91
+ *stream << svg_footer_string();
92
+ }
93
+ }
94
+
95
+ std::string StreamingMerger::svg_css() {
96
+ return ".out{fill:none;stroke:red;stroke-width:1;}.in{fill:none;stroke:green;stroke-width:1;}.out:hover{stroke:yellow;}";
97
+ }
98
+
99
+ std::string StreamingMerger::svg_header_string() {
100
+ return "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"" + std::to_string(total_width) +
101
+ "\" height=\"" + std::to_string(total_height) + "\"><style>" + svg_css() + "</style>";
102
+ }
103
+
104
+ std::string StreamingMerger::svg_footer_string() {
105
+ return "</svg>";
106
+ }
107
+
108
+ std::string StreamingMerger::svg_outer_polygon_string(std::string_view points) {
109
+ return "<polygon points=\"" + std::string(points) + "\" class=\"out\"/>";
110
+ }
111
+
112
+ std::string StreamingMerger::svg_inner_polygon_string(std::string_view points) {
113
+ return "<polygon points=\"" + std::string(points) + "\" class=\"in\"/>";
114
+ }
@@ -0,0 +1,41 @@
1
+ /*
2
+ * StreamingMerger.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 "VerticalMerger.h"
12
+ #include <fstream>
13
+ #include <string>
14
+ #include <string_view>
15
+ #include <stdexcept>
16
+ #include <vector>
17
+
18
+ class StreamingMerger : public VerticalMerger {
19
+ private:
20
+ std::ofstream* stream;
21
+ int total_width;
22
+ int total_height;
23
+ int moved = 0;
24
+ void ensure_header();
25
+ void ensure_footer();
26
+ void stream_polygons(Tile* tile, bool flush = false);
27
+ void stream_raw_polygon(const Shape* shape);
28
+ virtual std::string svg_css();
29
+ virtual std::string svg_header_string();
30
+ virtual std::string svg_footer_string();
31
+ virtual std::string svg_outer_polygon_string(std::string_view points);
32
+ virtual std::string svg_inner_polygon_string(std::string_view points);
33
+
34
+ public:
35
+ StreamingMerger(int number_of_threads,
36
+ std::vector<std::string>* options,
37
+ std::ofstream* stream_to,
38
+ int total_width, int total_height);
39
+ void add_tile(ProcessResult& result, bool flush = false);
40
+ ProcessResult* process_info() override;
41
+ };
@@ -96,6 +96,8 @@
96
96
  #include "PolygonFinder/src/polygon/finder/concurrent/HorizontalMerger.cpp"
97
97
  #include "PolygonFinder/src/polygon/finder/concurrent/VerticalMerger.h"
98
98
  #include "PolygonFinder/src/polygon/finder/concurrent/VerticalMerger.cpp"
99
+ #include "PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.h"
100
+ #include "PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.cpp"
99
101
  #include "PolygonFinder/src/polygon/finder/concurrent/ShapePool.h"
100
102
  #include "PolygonFinder/src/polygon/finder/concurrent/ShapePool.cpp"
101
103
  extern "C" {
@@ -290,6 +292,36 @@ ProcessResult ruby_result_to_process_result(Rice::Object rb_result) {
290
292
 
291
293
  } // namespace Rice::detail
292
294
 
295
+ struct OfstreamWrapper {
296
+ std::string path;
297
+ std::ofstream stream;
298
+ OfstreamWrapper(std::string p) : path(p), stream(p, std::ios::out) {}
299
+ void close() { stream.close(); }
300
+ bool closed() { return !stream.is_open(); }
301
+ void rewind() { /* noop */ }
302
+ std::string read() {
303
+ stream.flush();
304
+ std::ifstream in(path);
305
+ return std::string((std::istreambuf_iterator<char>(in)),
306
+ std::istreambuf_iterator<char>());
307
+ }
308
+ std::ofstream& get_stream() { return stream; }
309
+ };
310
+
311
+ StreamingMerger* create_streaming_merger(Object self,
312
+ int number_of_threads,
313
+ std::vector<std::string>* options,
314
+ Object stream_obj,
315
+ int total_width,
316
+ int total_height) {
317
+ OfstreamWrapper* wrapper = Rice::detail::From_Ruby<OfstreamWrapper*>().convert(stream_obj.value());
318
+ return new StreamingMerger(number_of_threads, options, &wrapper->get_stream(), total_width, total_height);
319
+ }
320
+
321
+ OfstreamWrapper* create_ofstream(Object self, std::string path) {
322
+ return new OfstreamWrapper(path);
323
+ }
324
+
293
325
  extern "C"
294
326
  void Init_cpp_polygon_finder() {
295
327
  #ifdef HAVE_TCMALLOC
@@ -384,9 +416,27 @@ void Init_cpp_polygon_finder() {
384
416
  define_class<HorizontalMerger, Merger>("CPPHorizontalMerger")
385
417
  .define_constructor(Constructor<HorizontalMerger, int, std::vector<std::string>*>(), Arg("number_of_threads"), Arg("options") = nullptr, Arg("yield_gvl") = true);
386
418
 
387
- Data_Type<VerticalMerger> rb_cVerticalMerger =
419
+ Data_Type<VerticalMerger> rb_cVerticalMerger =
388
420
  define_class<VerticalMerger, Merger>("CPPVerticalMerger")
389
- .define_constructor(Constructor<VerticalMerger, int, std::vector<std::string>*>(), Arg("number_of_threads"), Arg("options") = nullptr, Arg("yield_gvl") = true);
421
+ .define_constructor(Constructor<VerticalMerger, int, std::vector<std::string>*>(), Arg("number_of_threads"), Arg("options") = nullptr, Arg("yield_gvl") = true)
422
+ .define_method("add_tile", [](VerticalMerger& self, Object rb_result) {
423
+ ProcessResult pr = Rice::detail::ruby_result_to_process_result(rb_result);
424
+ self.add_tile(pr);
425
+ });
426
+
427
+ Data_Type<OfstreamWrapper> rb_cstd_ofstream = define_class<OfstreamWrapper>("CPPOfstream");
428
+ rb_cstd_ofstream.define_singleton_method("new", &create_ofstream);
429
+ rb_cstd_ofstream.define_method("close", [](OfstreamWrapper& self) { self.close(); });
430
+ rb_cstd_ofstream.define_method("closed?", [](OfstreamWrapper& self) { return self.closed(); });
431
+ rb_cstd_ofstream.define_method("rewind", [](OfstreamWrapper& self) { self.rewind(); });
432
+ rb_cstd_ofstream.define_method("read", [](OfstreamWrapper& self) { return self.read(); });
433
+
434
+ Data_Type<StreamingMerger> rb_cstreaming_merger = define_class<StreamingMerger, VerticalMerger>("CPPStreamingMerger");
435
+ rb_cstreaming_merger.define_method("add_tile", [](StreamingMerger& self, Object rb_result, bool flush) {
436
+ ProcessResult pr = Rice::detail::ruby_result_to_process_result(rb_result);
437
+ self.add_tile(pr, flush);
438
+ });
439
+ rb_cstreaming_merger.define_singleton_method("new", &create_streaming_merger);
390
440
 
391
441
  Module mContrek = define_module("Contrek");
392
442
  Module mCpp = define_module_under(mContrek, "Cpp");
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "mkmf-rice"
2
4
 
3
5
  has_tcmalloc = find_library("tcmalloc", "malloc")
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Bitmaps
3
5
  class Bitmap
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Bitmaps
3
5
  class ChunkyBitmap < Bitmap
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Bitmaps
3
5
  module Painting
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "chunky_png"
2
4
 
3
5
  module Contrek
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Bitmaps
3
5
  class RawBitmap < PngBitmap
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Bitmaps
3
5
  class RgbColor
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Bitmaps
3
5
  class RgbCppColor
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Bitmaps
3
5
  class SampleGenerator
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Cpp
3
5
  class CPPConcurrentFinder < CPPFinder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Cpp
3
5
  class CPPConcurrentHorizontalMerger < CPPHorizontalMerger
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Cpp
3
5
  class CPPConcurrentMerger < CPPMerger
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Contrek
4
+ module Cpp
5
+ class CPPConcurrentStreamingMerger < CPPStreamingMerger
6
+ def self.new(stream_to:, total_width:, total_height:, number_of_threads: 0, options: nil)
7
+ super(number_of_threads, options, stream_to, total_width, total_height)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Cpp
3
5
  class CPPConcurrentVerticalMerger < CPPVerticalMerger
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Cpp
3
5
  class CPPResult
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Contrek
4
+ module Cpp
5
+ class CPPTempfile < CPPOfstream
6
+ def self.new(name)
7
+ require "tempfile"
8
+ tempfile = Tempfile.new(name)
9
+ instance = super(tempfile.path)
10
+ instance.instance_variable_set(:@tempfile, tempfile)
11
+ instance
12
+ end
13
+
14
+ def path
15
+ @tempfile.path
16
+ end
17
+
18
+ def close
19
+ super
20
+ @tempfile.close
21
+ end
22
+
23
+ def unlink
24
+ @tempfile.unlink
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Bounds = Struct.new(:min_x, :max_x, :min_y, :max_y) do
2
4
  def self.empty
3
5
  new(Float::INFINITY, -Float::INFINITY, Float::INFINITY, -Float::INFINITY)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class ClippedPolygonFinder < Finder::PolygonFinder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class Cluster
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class Cursor
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class EndPoint
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class FakeCluster < Finder::NodeCluster
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class Finder
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class HorizontalMerger < Merger
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class Hub
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class InnerPolyline
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  module Listable
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class Merger < Finder
6
+ attr_reader :tiles
4
7
  prepend Poolable
5
8
 
6
9
  def initialize(options: {})
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class Part
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  module Partitionable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class Polyline
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "concurrent-ruby"
2
4
 
3
5
  module Contrek
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class Position
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  module Queueable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class Sequence
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Contrek
2
4
  module Concurrent
3
5
  class Shape