contrek 1.3.6 → 1.3.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6e79871127e3d6aff04c8bd1e6ea9765d47542249a188b0cf151ce8a005ea29a
4
- data.tar.gz: '055817b3638fcf582584e45e0ffef001305961321f8a05beb5998399b0be7bc6'
3
+ metadata.gz: 60aa8f5e3cfb43291e3dcce9921d77e84ce289bffd974dca7a4b2ed4c07124c0
4
+ data.tar.gz: 98ccefa7a9de3fa2ea0922d09c18fa45470ccb6ad0072c0b85d6203f025a7f11
5
5
  SHA512:
6
- metadata.gz: e3007307485a1ce6902f4f95b452b3ef2622fd2c59a0a27d8ee2564e0d8b512bdf8acc15ad5fac30b472b8d14263800324ac19ad74932eb220366860ad7ec60b
7
- data.tar.gz: 38289075bb92eb56229f1206ff595a0ea65d6bcbbf271dcdc035d60ef8b1c7609cbae687367803ff3d2cb39eae9f8fe670fb893afdcff87df77d8c0ce7b1c928
6
+ metadata.gz: 57731f61f8afc63f459b2fd349cd34e151406943c51628f80d0ac06dd29c360323adead860da8e2f9b9fb4579b6f29987c5a681175db7315d999d78039f4811f
7
+ data.tar.gz: 8420ba829bd714492b95249c567bdc1be27c8559bd11fbcdaf48ee9d975dc719891db23fd5d2f54d832e4f79f3dc335b1da557a53382f713d3c478094004f3d6
data/CHANGELOG.md CHANGED
@@ -139,7 +139,7 @@ All notable changes to this project will be documented in this file.
139
139
  ## [1.3.4] - 2026-07-19
140
140
  - Refactored core topology from a top-left point model to a 4-vertex pixel-cell model, natively eliminating diagonal ambiguities and rewriting part of the stripe-merging algorithm to ensure perfect geometric stitching on shared nodes. Removed Strict Bounds mode. Added a Douglas-Peucker and a custom raster-compression algorithm that shifts top/right pixel boundaries by 1px to ensure flawless surface rendering as bitmap image.
141
141
 
142
- ## [1.3.6] - 2026-07-26
142
+ ## [1.3.6] - 2026-07-27
143
143
  - Removed optionparser.h and the legacy options argument mechanism, replacing them with the new OptionValue.h and Options.h
144
144
  - Added polygon compression to the progressive streaming pipeline (StreamingMerger).
145
145
  - Added strict validation in progressive streaming. Results passed to add_tile() are now validated to ensure they contain compatible settings (such as versus conventions and compression options).
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- contrek (1.3.6)
4
+ contrek (1.3.7)
5
5
  chunky_png (~> 1.4)
6
6
  concurrent-ruby (~> 1.3.5)
7
7
  rice (= 4.5.0)
@@ -43,28 +43,33 @@ ProcessResult* StreamingMerger::process_info() {
43
43
 
44
44
  void StreamingMerger::stream_polygons(Tile* tile, bool flush) {
45
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](Shape* shape) {
49
- if (flush || shape->outer_polyline->max_x() < (tile_end_x - 1)) {
50
- this->moved++;
51
- Polygon polygon = shape->to_raw_polygon();
52
- if (this->options().any_compression()) {
53
- std::list<Polygon> polygons;
54
- polygons.push_back(polygon);
55
- FakeCluster fake_cluster(polygons, this->options());
56
- fake_cluster.compress_coords(polygons, this->options());
57
- polygon = std::move(polygons.front());
58
- }
59
- this->stream_raw_polygon(polygon);
60
- shape->detach_from_pool();
61
- return true;
62
- }
63
- return false;
64
- }),
65
- tile->shapes().end());
46
+
47
+ const int safe_boundary_x = tile->end_x() - 1;
48
+ auto& shapes = tile->shapes();
49
+ std::list<Polygon> polygons_to_stream;
50
+ shapes.erase(
51
+ std::remove_if(shapes.begin(), shapes.end(), [this, flush, safe_boundary_x, &polygons_to_stream](Shape* shape) {
52
+ const bool is_ready = flush || (shape->outer_polyline->max_x() < safe_boundary_x);
53
+ if (is_ready) {
54
+ this->moved++;
55
+ polygons_to_stream.push_back(std::move(shape->to_raw_polygon()));
56
+ shape->detach_from_pool();
57
+ return true;
58
+ }
59
+ return false;
60
+ }),
61
+ shapes.end()
62
+ );
63
+ if (this->options().any_compression() && !polygons_to_stream.empty()) {
64
+ FakeCluster fake_cluster(polygons_to_stream, this->options());
65
+ fake_cluster.compress_coords(polygons_to_stream, this->options());
66
+ }
67
+ for (Polygon& polygon : polygons_to_stream) {
68
+ this->stream_raw_polygon(std::move(polygon));
66
69
  }
70
+
67
71
  stream->flush();
72
+
68
73
  if (flush) {
69
74
  ensure_footer();
70
75
  }
@@ -19,31 +19,32 @@ LinearReducer::LinearReducer(std::vector<Point>& list_of_points)
19
19
  }
20
20
 
21
21
  void LinearReducer::reduce() {
22
- if (points.size() < 2) return;
23
-
24
- Point start_p = points[0];
25
- Point end_p = points[1];
26
- auto dir = seq_dir(start_p, end_p);
22
+ if (points.size() < 3) return;
27
23
 
24
+ size_t write_idx = 1;
28
25
  for (size_t i = 2; i < points.size(); ++i) {
29
- Point point = points[i];
30
- auto act_seq = seq_dir(end_p, point);
31
- if (act_seq == dir) {
32
- auto it = std::find_if(points.begin(), points.end(), [&](const Point& p) { // TODO(ema): optimize...
33
- return p.x == end_p.x && p.y == end_p.y;
34
- });
35
- if (it != points.end()) {
36
- size_t removed_idx = std::distance(points.begin(), it);
37
- points.erase(it);
38
- if (removed_idx <= i) i--;
39
- }
26
+ const Point& start_p = points[write_idx - 1];
27
+ const Point& end_p = points[write_idx];
28
+ const Point& curr_p = points[i];
29
+
30
+ int dx1 = end_p.x - start_p.x;
31
+ int dy1 = end_p.y - start_p.y;
32
+
33
+ int dx2 = curr_p.x - end_p.x;
34
+ int dy2 = curr_p.y - end_p.y;
35
+
36
+ int sx1 = (0 < dx1) - (dx1 < 0);
37
+ int sy1 = (0 < dy1) - (dy1 < 0);
38
+
39
+ int sx2 = (0 < dx2) - (dx2 < 0);
40
+ int sy2 = (0 < dy2) - (dy2 < 0);
41
+
42
+ if (sx1 == sx2 && sy1 == sy2) {
43
+ points[write_idx] = curr_p;
40
44
  } else {
41
- dir = act_seq;
45
+ write_idx++;
46
+ points[write_idx] = curr_p;
42
47
  }
43
- end_p = point;
44
48
  }
45
- }
46
-
47
- std::array<int, 2> LinearReducer::seq_dir(const Point& a, const Point& b)
48
- { return { b.x - a.x, b.y - a.y };
49
+ points.resize(write_idx + 1);
49
50
  }
@@ -16,7 +16,4 @@ class LinearReducer : public Reducer {
16
16
  public:
17
17
  explicit LinearReducer(std::vector<Point>& list_of_points);
18
18
  void reduce();
19
-
20
- private:
21
- std::array<int, 2> seq_dir(const Point& a, const Point& b);
22
19
  };
@@ -30,21 +30,26 @@ module Contrek
30
30
  def stream_polygons!(tile, flush = false)
31
31
  ensure_header
32
32
 
33
+ safe_boundary_x = tile.end_x - 1
34
+ polygons_to_stream = []
35
+
33
36
  tile.shapes.select! do |shape|
34
37
  bounds = shape.outer_polyline.get_bounds
35
- if flush || bounds[:max_x] < tile.end_x - 1
38
+ if flush || bounds[:max_x] < safe_boundary_x
36
39
  @moved += 1
37
40
  polygon = shape.to_raw_polygon
38
- if @options.has_key?(:compress)
39
- FakeCluster.new([polygon], @options).compress_coords
40
- end
41
- stream_raw_polygon(polygon)
41
+ polygons_to_stream << polygon
42
42
  false
43
43
  else
44
44
  true
45
45
  end
46
46
  end
47
-
47
+ if @options.has_key?(:compress) && polygons_to_stream.any?
48
+ FakeCluster.new(polygons_to_stream, @options).compress_coords
49
+ end
50
+ polygons_to_stream.each do |polygon|
51
+ stream_raw_polygon(polygon)
52
+ end
48
53
  ensure_footer if flush
49
54
  end
50
55
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Contrek
4
- VERSION = "1.3.6"
4
+ VERSION = "1.3.7"
5
5
  end
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.6
4
+ version: 1.3.7
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-07-27 00:00:00.000000000 Z
11
+ date: 2026-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec