Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't use longitude wraparound detection if it makes a contradictory geometry #176

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 2.39.0

* Don't use longitude wraparound detection if it makes a self-contradictory geometry

# 2.38.0

* Tolerate polygon rings with insuffiently many points in input
Expand Down
133 changes: 106 additions & 27 deletions serial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,40 +313,119 @@ serial_feature deserialize_feature(std::string &geoms, unsigned z, unsigned tx,
return sf;
}

static long long scale_geometry(struct serialization_state *sst, long long *bbox, drawvec &geom) {
long long offset = 0;
long long prev = 0;
bool has_prev = false;
static long long scale_geometry(struct serialization_state *sst, long long *bbox, drawvec &geom, int t) {
double scale = 1.0 / (1 << geometry_scale);

for (size_t i = 0; i < geom.size(); i++) {
if (geom[i].op == VT_MOVETO || geom[i].op == VT_LINETO) {
long long x = geom[i].x;
long long y = geom[i].y;
if (additional[A_DETECT_WRAPAROUND]) {
drawvec out;
bool outer = true; // first ring is expected to be outer

if (additional[A_DETECT_WRAPAROUND]) {
if (geom[i].op == VT_LINETO) {
x += offset;
if (has_prev) {
// jumps at least 180° but not exactly 360°,
// which in some data sets is an intentional
// line across the world
if (x - prev > (1LL << 31) && x - prev != (1LL << 32)) {
offset -= 1LL << 32;
x -= 1LL << 32;
} else if (prev - x > (1LL << 31) && prev - x != (1LL << 32)) {
offset += 1LL << 32;
x += 1LL << 32;
for (size_t i = 0; i < geom.size(); i++) {
if (geom[i].op == VT_MOVETO) {
size_t j = 0;
for (j = i + 1; j < geom.size(); j++) {
if (geom[j].op != VT_LINETO) {
break;
}
}

long long prev_x = geom[i].x;
long long offset = 0;
bool balanced = true;

drawvec ring;
bool changed = false;
for (size_t k = i; k < j; k++) {
draw op = geom[k];
op.x += offset;

// jumps at least 180° but not exactly 360°,
// which in some data sets is an intentional
// line across the world
if (op.x - prev_x > (1LL << 31) && op.x - prev_x != (1LL << 32)) {
if (offset < 0) {
// already shifted left, but seems to need another shift left
balanced = false;
break;
}

offset -= 1LL << 32;
op.x -= 1LL << 32;
changed = true;
} else if (prev_x - op.x > (1LL << 31) && prev_x - op.x != (1LL << 32)) {
if (offset > 0) {
// already shifted right, but seems to need another shift right
balanced = false;
break;
}

offset += 1LL << 32;
op.x += 1LL << 32;
changed = true;
}

has_prev = true;
prev = x;
} else {
offset = 0;
prev = x;
ring.push_back(op);
prev_x = op.x;
}

if (changed && balanced) {
// If this is a polygon, in which the first and last
// points of each ring are supposed to be identical,
// make sure the antimeridian wraparound detection
// preserves that expectation. If it doesn't, it means
// we have detected something wrongly.
if (geom[j - 1] == geom[i]) {
if (offset != 0) {
// first and last points are supposed to be the same
// but there is an unresolved antimeridian shift
balanced = false;
}
}

if (t == VT_POLYGON) {
// don't accept longitude corrections that would give
// a ring a winding counter to what the geojson structure
// says the winding should be

double area_after = get_area(ring, 0, ring.size());
if ((outer && area_after < 0) ||
(!outer && area_after > 0)) {
// wraparound detection gave a ring a winding different from
// what its position in the GeoJSON structure indicates that
// it should have.
balanced = false;
}
}
}

// If something contradictory happened in longitude
// wraparound detection, restore the original geometry
if (!balanced) {
ring.clear();
for (size_t k = i; k < j; k++) {
ring.push_back(geom[k]);
}
}

for (auto const &g : ring) {
out.push_back(g);
}

i = j - 1;
outer = false;
} else if (geom[i].op == VT_CLOSEPATH) {
out.push_back(geom[i]);
outer = true;
}
}

geom = std::move(out);
}

for (size_t i = 0; i < geom.size(); i++) {
if (geom[i].op == VT_MOVETO || geom[i].op == VT_LINETO) {
long long x = geom[i].x;
long long y = geom[i].y;

if (x < bbox[0]) {
bbox[0] = x;
Expand Down Expand Up @@ -464,7 +543,7 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf) {
// try to remind myself that the geometry in this function is in SCALED COORDINATES
drawvec scaled_geometry = sf.geometry;
sf.geometry.clear();
scale_geometry(sst, sf.bbox, scaled_geometry);
scale_geometry(sst, sf.bbox, scaled_geometry, sf.t);

// This has to happen after scaling so that the wraparound detection has happened first.
// Otherwise the inner/outer calculation will be confused by bad geometries.
Expand Down
1 change: 1 addition & 0 deletions tests/wraparound-gap/in.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "type": "Feature", "properties": { "felt:color": "#C93535", "felt:fillOpacity": 0.25, "felt:id": "fdd67048-a864-48d1-9596-fe332d5e2fd8", "felt:locked": 0, "felt:ordering": 1701884658553581, "felt:showArea": 0, "felt:strokeOpacity": 1, "felt:strokeStyle": "solid", "felt:strokeWidth": 2, "felt:type": "Polygon" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ 0.5081782, 22.9870329 ], [ -0.0738751, 24.2847819 ], [ -0.6691349, 25.571479 ], [ -1.27847, 26.846946 ], [ -1.9027968, 28.1109962 ], [ -2.5430829, 29.3634334 ], [ -3.2003511, 30.6040503 ], [ -3.8756828, 31.8326271 ], [ -4.5702221, 33.0489296 ], [ -5.2851804, 34.2527081 ], [ -6.0218407, 35.4436947 ], [ -6.7815616, 36.6216016 ], [ -7.5657823, 37.7861189 ], [ -8.3760274, 38.9369118 ], [ -9.2139111, 40.073618 ], [ -10.0811417, 41.1958448 ], [ -10.9795262, 42.3031659 ], [ -11.9109739, 43.3951181 ], [ -12.8774999, 44.4711972 ], [ -13.8812276, 45.5308545 ], [ -14.9243899, 46.5734923 ], [ -16.0093299, 47.5984594 ], [ -17.1384983, 48.6050467 ], [ -18.3144501, 49.5924819 ], [ -19.5398367, 50.5599248 ], [ -20.8173955, 51.5064616 ], [ -22.1499346, 52.4311004 ], [ -23.540312, 53.3327659 ], [ -24.9914084, 54.2102946 ], [ -26.5060921, 55.0624307 ], [ -28.0871763, 55.887823 ], [ -29.737365, 56.6850223 ], [ -31.4591894, 57.4524808 ], [ -33.2549322, 58.1885532 ], [ -35.12654, 58.8915003 ], [ -37.0755248, 59.5594957 ], [ -39.1028551, 60.1906358 ], [ -41.2088389, 60.7829536 ], [ -43.3930029, 61.3344378 ], [ -45.6539736, 61.8430557 ], [ -47.9893655, 62.3067817 ], [ -50.3956866, 62.7236299 ], [ -52.8682696, 63.0916915 ], [ -55.4012381, 63.4091742 ], [ -57.9875169, 63.6744443 ], [ -60.6188936, 63.8860685 ], [ -63.2861344, 64.0428524 ], [ -65.9791536, 64.1438757 ], [ -68.687232, 64.1885201 ], [ -71.3992725, 64.1764882 ], [ -74.1040795, 64.1078133 ], [ -76.7906446, 63.9828573 ], [ -79.4484197, 63.8022993 ], [ -82.067563, 63.5671136 ], [ -84.6391426, 63.2785398 ], [ -87.1552901, 62.9380471 ], [ -89.6092989, 62.547294 ], [ -91.9956692, 62.1080872 ], [ -94.3101039, 61.6223399 ], [ -96.549463, 61.0920327 ], [ -98.7116854, 60.5191781 ], [ -100.7956881, 59.9057889 ], [ -102.8012518, 59.2538513 ], [ -104.7289002, 58.5653032 ], [ -106.5797799, 57.8420165 ], [ -108.3555463, 57.0857848 ], [ -110.0582571, 56.2983138 ], [ -111.6902772, 55.4812158 ], [ -113.2541951, 54.6360068 ], [ -114.7527508, 53.7641057 ], [ -116.1887754, 52.8668357 ], [ -117.5651406, 51.9454264 ], [ -118.8847188, 51.0010179 ], [ -120.1503501, 50.0346645 ], [ -121.3648176, 49.0473396 ], [ -122.5308284, 48.039941 ], [ -123.6509997, 47.0132954 ], [ -124.7278497, 45.9681637 ], [ -125.7637908, 44.9052463 ], [ -126.7611269, 43.8251872 ], [ -127.7220517, 42.7285794 ], [ -128.6486497, 41.6159683 ], [ -129.5428978, 40.4878568 ], [ -130.4066684, 39.3447083 ], [ -131.2417324, 38.1869507 ], [ -132.0497639, 37.0149798 ], [ -132.8323442, 35.829162 ], [ -133.5909664, 34.6298374 ], [ -134.3270401, 33.4173223 ], [ -135.0418957, 32.1919118 ], [ -135.7367896, 30.9538818 ], [ -136.4129082, 29.7034911 ], [ -137.0713723, 28.4409832 ], [ -137.7132415, 27.1665881 ], [ -138.3395178, 25.8805239 ], [ -138.95115, 24.5829981 ], [ -139.5490368, 23.2742089 ], [ -140.1340309, 21.9543464 ], [ -140.7069416, 20.6235939 ], [ -141.2685386, 19.2821286 ], [ -141.8195545, 17.9301227 ], [ -142.3606881, 16.5677439 ], [ -142.8926067, 15.1951567 ], [ -143.415949, 13.8125227 ], [ -157.9356012, -6.1122922 ], [ -159.116992, -7.0063682 ], [ -160.2948114, -7.8977761 ], [ -161.4696087, -8.7861312 ], [ -162.6419267, -9.6710625 ], [ -163.8123021, -10.5522125 ], [ -164.9812652, -11.4292357 ], [ -166.149341, -12.3017988 ], [ -167.3170488, -13.1695799 ], [ -168.4849028, -14.0322678 ], [ -169.6534122, -14.8895615 ], [ -170.8230821, -15.7411698 ], [ -171.994413, -16.5868104 ], [ -173.1679018, -17.4262095 ], [ -174.3440416, -18.2591015 ], [ -175.5233227, -19.0852277 ], [ -176.7062321, -19.9043366 ], [ -177.8932543, -20.7161825 ], [ -179.0848716, -21.5205254 ], [ -179.0848716, -90.0 ], [ 179.7184362, -90.0 ], [ 179.7184362, -22.3171303 ], [ 178.5161908, -23.1057665 ], [ 177.3079159, -23.8862071 ], [ 176.0931365, -24.6582283 ], [ 174.8713794, -25.4216086 ], [ 173.6421725, -26.1761285 ], [ 172.4050452, -26.9215698 ], [ 171.1595285, -27.6577146 ], [ 169.9051549, -28.384345 ], [ 168.6414585, -29.1012424 ], [ 167.3679757, -29.8081866 ], [ 166.0842452, -30.5049554 ], [ 164.7898088, -31.1913237 ], [ 163.4842115, -31.8670632 ], [ 162.1670027, -32.5319413 ], [ 160.8377366, -33.1857206 ], [ 159.4959737, -33.8281584 ], [ 158.1412811, -34.459006 ], [ 156.7732345, -35.0780079 ], [ 155.3914193, -35.6849017 ], [ 153.9954323, -36.2794169 ], [ 152.5848832, -36.8612749 ], [ 151.1593968, -37.4301883 ], [ 149.7186153, -37.9858605 ], [ 148.2622002, -38.5279855 ], [ 146.7898353, -39.0562472 ], [ 145.301229, -39.5703198 ], [ 143.7961176, -40.0698671 ], [ 137.1909486, -41.5152352 ], [ 135.5467304, -41.7051681 ], [ 133.9013226, -41.8761156 ], [ 132.2553607, -42.0282118 ], [ 130.6094771, -42.161606 ], [ 128.9642978, -42.276462 ], [ 127.3204389, -42.3729568 ], [ 125.6785042, -42.4512795 ], [ 124.0390817, -42.5116301 ], [ 122.4027415, -42.5542183 ], [ 120.7700331, -42.5792621 ], [ 119.1414833, -42.5869867 ], [ 117.5175946, -42.5776231 ], [ 115.8988435, -42.5514069 ], [ 114.2856789, -42.508577 ], [ 112.6785214, -42.4493745 ], [ 111.0777626, -42.3740411 ], [ 109.4837643, -42.2828187 ], [ 107.8968585, -42.1759477 ], [ 106.3173472, -42.0536663 ], [ 104.745503, -41.9162092 ], [ 103.1815689, -41.7638075 ], [ 101.6257595, -41.5966869 ], [ 100.0782615, -41.415068 ], [ 98.5392343, -41.2191649 ], [ 97.0088117, -41.0091851 ], [ 95.4871024, -40.785329 ], [ 93.9741914, -40.5477895 ], [ 92.4701411, -40.2967516 ], [ 90.9749927, -40.0323925 ], [ 89.4887676, -39.7548812 ], [ 88.0114683, -39.4643788 ], [ 86.5430798, -39.1610381 ], [ 85.0835712, -38.8450043 ], [ 83.6328963, -38.5164145 ], [ 82.190995, -38.1753985 ], [ 80.7577946, -37.8220789 ], [ 79.3332105, -37.4565714 ], [ 77.9171474, -37.0789851 ], [ 76.5094999, -36.6894233 ], [ 75.1101536, -36.2879836 ], [ 73.7189857, -35.8747587 ], [ 72.3358656, -35.4498365 ], [ 70.9606556, -35.0133014 ], [ 69.5932114, -34.565234 ], [ 68.2333825, -34.1057126 ], [ 66.8810123, -33.6348129 ], [ 65.5359388, -33.1526095 ], [ 64.1979949, -32.6591758 ], [ 62.867008, -32.1545852 ], [ 61.5428006, -31.6389112 ], [ 60.2251903, -31.1122286 ], [ 58.9139895, -30.5746136 ], [ 57.6090059, -30.0261448 ], [ 56.310042, -29.4669037 ], [ 55.0168951, -28.896975 ], [ 53.7293574, -28.3164477 ], [ 52.4472155, -27.7254154 ], [ 51.1702505, -27.1239768 ], [ 49.8982375, -26.5122364 ], [ 48.6309458, -25.890305 ], [ 47.3681383, -25.2583001 ], [ 46.1095715, -24.6163467 ], [ 44.854995, -23.9645774 ], [ 43.6041515, -23.3031331 ], [ 42.3567766, -22.6321636 ], [ 41.1125983, -21.9518276 ], [ 39.8713369, -21.2622938 ], [ 38.6327046, -20.5637405 ], [ 37.3964057, -19.8563568 ], [ 36.1621359, -19.1403426 ], [ 34.9295822, -18.4159089 ], [ 33.6984229, -17.6832785 ], [ 32.4683271, -16.9426861 ], [ 31.2389549, -16.1943788 ], [ 30.0099567, -15.4386166 ], [ 28.7809737, -14.6756723 ], [ 27.5516372, -13.9058324 ], [ 26.3215688, -13.1293972 ], [ 25.0903803, -12.346681 ], [ 23.8576735, -11.5580128 ], [ 22.6230401, -10.7637362 ], [ 21.3860621, -9.9642103 ], [ 20.1463113, -9.1598096 ], [ 18.9033497, -8.3509245 ], [ 17.6567294, -7.5379618 ], [ 16.4434371, -6.7467394 ], [ 15.8260496, -5.4803404 ], [ 15.1920087, -4.1870889 ], [ 14.5570289, -2.8991695 ], [ 13.9205008, -1.616738 ], [ 13.2818199, -0.3399496 ], [ 12.6403841, 0.9310404 ], [ 11.9955916, 2.196076 ], [ 11.3468394, 3.4550004 ], [ 10.6935208, 4.707655 ], [ 10.0350242, 5.953879 ], [ 9.3707308, 7.1935089 ], [ 8.700013, 8.4263777 ], [ 8.0222329, 9.6523142 ], [ 7.3367401, 10.8711426 ], [ 6.6428705, 12.0826816 ], [ 5.9399441, 13.2867437 ], [ 5.2272637, 14.4831343 ], [ 4.5041128, 15.6716509 ], [ 3.7697543, 16.8520823 ], [ 0.5081782, 22.9870329 ] ] ] ] } }
20 changes: 20 additions & 0 deletions tests/wraparound-gap/out/-z0_--detect-longitude-wraparound.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{ "type": "FeatureCollection", "properties": {
"antimeridian_adjusted_bounds": "-179.084872,-42.586987,179.718436,64.188520",
"bounds": "-179.084872,-85.051129,179.718436,64.188520",
"center": "0.000000,0.000000,0",
"description": "tests/wraparound-gap/out/-z0_--detect-longitude-wraparound.json.check.mbtiles",
"format": "pbf",
"generator_options": "./tippecanoe -q -a@ -f -o tests/wraparound-gap/out/-z0_--detect-longitude-wraparound.json.check.mbtiles -z0 --detect-longitude-wraparound tests/wraparound-gap/in.json",
"json": "{\"vector_layers\":[{\"id\":\"in\",\"description\":\"\",\"minzoom\":0,\"maxzoom\":0,\"fields\":{\"felt:color\":\"String\",\"felt:fillOpacity\":\"Number\",\"felt:id\":\"String\",\"felt:locked\":\"Number\",\"felt:ordering\":\"Number\",\"felt:showArea\":\"Number\",\"felt:strokeOpacity\":\"Number\",\"felt:strokeStyle\":\"String\",\"felt:strokeWidth\":\"Number\",\"felt:type\":\"String\"}}],\"tilestats\":{\"layerCount\":1,\"layers\":[{\"layer\":\"in\",\"count\":1,\"geometry\":\"Polygon\",\"attributeCount\":10,\"attributes\":[{\"attribute\":\"felt:color\",\"count\":1,\"type\":\"string\",\"values\":[\"#C93535\"]},{\"attribute\":\"felt:fillOpacity\",\"count\":1,\"type\":\"number\",\"values\":[0.25],\"min\":0.25,\"max\":0.25},{\"attribute\":\"felt:id\",\"count\":1,\"type\":\"string\",\"values\":[\"fdd67048-a864-48d1-9596-fe332d5e2fd8\"]},{\"attribute\":\"felt:locked\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"felt:ordering\",\"count\":1,\"type\":\"number\",\"values\":[1701884658553581],\"min\":1701884658553581,\"max\":1701884658553581},{\"attribute\":\"felt:showArea\",\"count\":1,\"type\":\"number\",\"values\":[0],\"min\":0,\"max\":0},{\"attribute\":\"felt:strokeOpacity\",\"count\":1,\"type\":\"number\",\"values\":[1],\"min\":1,\"max\":1},{\"attribute\":\"felt:strokeStyle\",\"count\":1,\"type\":\"string\",\"values\":[\"solid\"]},{\"attribute\":\"felt:strokeWidth\",\"count\":1,\"type\":\"number\",\"values\":[2],\"min\":2,\"max\":2},{\"attribute\":\"felt:type\",\"count\":1,\"type\":\"string\",\"values\":[\"Polygon\"]}]}]}}",
"maxzoom": "0",
"minzoom": "0",
"name": "tests/wraparound-gap/out/-z0_--detect-longitude-wraparound.json.check.mbtiles",
"type": "overlay",
"version": "2"
}, "features": [
{ "type": "FeatureCollection", "properties": { "zoom": 0, "x": 0, "y": 0 }, "features": [
{ "type": "FeatureCollection", "properties": { "layer": "in", "version": 2, "extent": 4096 }, "features": [
{ "type": "Feature", "properties": { "felt:color": "#C93535", "felt:fillOpacity": 0.25, "felt:id": "fdd67048-a864-48d1-9596-fe332d5e2fd8", "felt:locked": 0, "felt:ordering": 1701884658553581, "felt:showArea": 0, "felt:strokeOpacity": 1, "felt:strokeStyle": "solid", "felt:strokeWidth": 2, "felt:type": "Polygon" }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -68.730469, 64.206377 ], [ -63.281250, 64.052978 ], [ -60.644531, 63.898731 ], [ -55.371094, 63.391522 ], [ -52.910156, 63.074866 ], [ -50.361328, 62.714462 ], [ -45.615234, 61.856149 ], [ -41.220703, 60.802064 ], [ -37.089844, 59.578851 ], [ -35.156250, 58.904646 ], [ -29.707031, 56.704506 ], [ -24.960938, 54.213861 ], [ -19.511719, 50.569283 ], [ -15.996094, 47.576526 ], [ -10.986328, 42.293564 ], [ -8.349609, 38.959409 ], [ -3.164062, 30.600094 ], [ 0.527344, 22.998852 ], [ 3.779297, 16.888660 ], [ 6.679688, 12.125264 ], [ 10.722656, 4.740675 ], [ 16.435547, -6.751896 ], [ 25.048828, -12.382928 ], [ 37.353516, -19.890723 ], [ 44.824219, -23.966176 ], [ 55.019531, -28.921631 ], [ 64.160156, -32.694866 ], [ 70.927734, -35.029996 ], [ 75.146484, -36.315125 ], [ 82.177734, -38.203655 ], [ 89.472656, -39.774769 ], [ 93.955078, -40.580585 ], [ 98.525391, -41.244772 ], [ 103.183594, -41.771312 ], [ 109.511719, -42.293564 ], [ 115.927734, -42.553080 ], [ 122.431641, -42.553080 ], [ 128.935547, -42.293564 ], [ 133.857422, -41.902277 ], [ 137.197266, -41.508577 ], [ 143.789062, -40.044438 ], [ 145.283203, -39.571822 ], [ 151.171875, -37.439974 ], [ 156.796875, -35.101934 ], [ 166.113281, -30.524413 ], [ 173.671875, -26.194877 ], [ 179.736328, -22.350076 ], [ 179.736328, -85.622069 ], [ -179.121094, -85.622069 ], [ -179.121094, -21.534847 ], [ -157.939453, -6.140555 ], [ -143.437500, 13.838080 ], [ -140.712891, 20.632784 ], [ -137.109375, 28.459033 ], [ -133.593750, 34.597042 ], [ -130.429688, 39.368279 ], [ -128.671875, 41.640078 ], [ -123.662109, 47.040182 ], [ -118.916016, 51.013755 ], [ -117.597656, 51.944265 ], [ -113.291016, 54.622978 ], [ -110.039062, 56.316537 ], [ -106.611328, 57.844751 ], [ -102.832031, 59.265881 ], [ -96.591797, 61.100789 ], [ -92.021484, 62.103883 ], [ -87.187500, 62.955223 ], [ -84.638672, 63.273182 ], [ -79.453125, 63.821288 ], [ -76.816406, 63.975961 ], [ -71.367188, 64.168107 ], [ -68.730469, 64.206377 ] ] ], [ [ [ 187.031250, -17.224758 ], [ 187.031250, -85.622069 ], [ 180.878906, -85.622069 ], [ 180.878906, -21.534847 ], [ 187.031250, -17.224758 ] ] ], [ [ [ -180.263672, -22.350076 ], [ -180.263672, -85.622069 ], [ -187.031250, -85.622069 ], [ -187.031250, -26.588527 ], [ -180.263672, -22.350076 ] ] ] ] } }
] }
] }
] }
2 changes: 1 addition & 1 deletion version.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#ifndef VERSION_HPP
#define VERSION_HPP

#define VERSION "v2.38.0"
#define VERSION "v2.39.0"

#endif