Skip to content

Commit 65204df

Browse files
committed
Fix polygonization
1 parent a144428 commit 65204df

File tree

9 files changed

+404
-203
lines changed

9 files changed

+404
-203
lines changed

baremaps-core/src/main/java/org/apache/baremaps/tilestore/raster/ContourTileStore.java

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import java.awt.image.BufferedImage;
2121
import java.io.ByteArrayOutputStream;
22-
import java.io.IOException;
2322
import java.nio.ByteBuffer;
2423
import java.util.ArrayList;
2524
import java.util.List;
@@ -46,40 +45,42 @@ public ContourTileStore(TileStore<BufferedImage> tileStore) {
4645

4746
@Override
4847
public ByteBuffer read(TileCoord tileCoord) throws TileStoreException {
49-
var image = tileStore.read(tileCoord);
50-
var onion = BufferedImageTileStore.onion(tileStore, tileCoord, 1);
51-
image = onion.getSubimage(
52-
image.getWidth() - 4,
53-
image.getHeight() - 4,
54-
image.getWidth() + 8,
55-
image.getHeight() + 8);
48+
try {
49+
var image = tileStore.read(tileCoord);
50+
var onion = BufferedImageTileStore.onion(tileStore, tileCoord, 1);
51+
image = onion.getSubimage(
52+
image.getWidth() - 4,
53+
image.getHeight() - 4,
54+
image.getWidth() + 8,
55+
image.getHeight() + 8);
5656

57-
var grid = ElevationUtils.imageToGrid(image, ElevationUtils::pixelToElevationTerrarium);
58-
var features = new ArrayList<Feature>();
59-
for (int level = -10000; level < 10000; level += 100) {
60-
var contours = new ContourTracer(grid, image.getWidth(), image.getHeight(), false, false)
61-
.traceContours(level);
62-
for (var contour : contours) {
63-
contour = AffineTransformation
64-
.translationInstance(-4, -4)
65-
.scale(16, 16)
66-
.transform(contour);
67-
features.add(new Feature(level, Map.of("level", String.valueOf(level)), contour));
57+
var grid = ElevationUtils.imageToGrid(image, ElevationUtils::pixelToElevationTerrarium);
58+
var features = new ArrayList<Feature>();
59+
for (int level = -10000; level < 10000; level += 100) {
60+
61+
var contours = new ContourTracer(grid, image.getWidth(), image.getHeight(), false, true)
62+
.traceContours(level);
63+
for (var contour : contours) {
64+
contour = AffineTransformation
65+
.translationInstance(-4, -4)
66+
.scale(16, 16)
67+
.transform(contour);
68+
features.add(new Feature(level, Map.of("level", String.valueOf(level)), contour));
69+
}
6870
}
69-
}
7071

71-
var layer = new Layer("elevation", 4096, features);
72-
var tile = new Tile(List.of(layer));
73-
var vectorTile = new VectorTileEncoder().encodeTile(tile);
74-
try (var baos = new ByteArrayOutputStream()) {
75-
var gzip = new GZIPOutputStream(baos);
76-
vectorTile.writeTo(gzip);
77-
gzip.close();
78-
return ByteBuffer.wrap(baos.toByteArray());
79-
} catch (IOException e) {
72+
var layer = new Layer("elevation", 4096, features);
73+
var tile = new Tile(List.of(layer));
74+
var vectorTile = new VectorTileEncoder().encodeTile(tile);
75+
try (var baos = new ByteArrayOutputStream()) {
76+
var gzip = new GZIPOutputStream(baos);
77+
vectorTile.writeTo(gzip);
78+
gzip.close();
79+
return ByteBuffer.wrap(baos.toByteArray());
80+
}
81+
} catch (Exception e) {
8082
throw new TileStoreException(e);
8183
}
82-
8384
}
8485

8586
@Override

baremaps-raster/src/main/java/org/apache/baremaps/raster/ContourTracer.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.locationtech.jts.geom.*;
2424
import org.locationtech.jts.geom.util.GeometryTransformer;
2525
import org.locationtech.jts.operation.linemerge.LineMerger;
26+
import org.locationtech.jts.operation.polygonize.Polygonizer;
2627

2728
/**
2829
* Provides methods for generating contour lines and contour polygons from digital elevation models
@@ -80,16 +81,16 @@ public List<Geometry> traceContours(double level) {
8081
}
8182
}
8283

83-
// Merge segments into line strings
84-
LineMerger segmentMerger = new LineMerger();
85-
segmentMerger.add(segments);
86-
List<Geometry> contours = new ArrayList<>(segmentMerger.getMergedLineStrings());
87-
8884
// Polygonize the line strings
89-
if (polygonize) {
90-
contours = contours.stream()
91-
.map(geometry -> (Geometry) GEOMETRY_FACTORY.createPolygon(geometry.getCoordinates()))
92-
.toList();
85+
List<Geometry> contours;
86+
if (!polygonize) {
87+
LineMerger segmentMerger = new LineMerger();
88+
segmentMerger.add(segments);
89+
contours = new ArrayList<>(segmentMerger.getMergedLineStrings());
90+
} else {
91+
Polygonizer polygonizer = new Polygonizer();
92+
polygonizer.add(segments);
93+
contours = new ArrayList<>(polygonizer.getPolygons());
9394
}
9495

9596
// Normalize the coordinates
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.baremaps.raster;
19+
20+
import java.io.IOException;
21+
import java.net.URL;
22+
import javax.imageio.ImageIO;
23+
import javax.swing.*;
24+
import org.locationtech.jts.geom.util.AffineTransformation;
25+
26+
class ContourTileStoreTest {
27+
28+
public static void main(String[] args) throws IOException {
29+
var image = ImageIO
30+
.read(new URL("https://s3.amazonaws.com/elevation-tiles-prod/terrarium/8/131/89.png"));
31+
var grid = ElevationUtils.imageToGrid(image, ElevationUtils::pixelToElevationTerrarium);
32+
var tracer = new ContourTracer(grid, image.getWidth(), image.getHeight(), false, true);
33+
34+
var contours = tracer.traceContours(200).stream()
35+
.map(AffineTransformation
36+
.scaleInstance(4, 4)
37+
.translate(10, 10)::transform)
38+
.toList();
39+
40+
JFrame frame = new JFrame("Geometry Drawer");
41+
GeometryDrawer drawer = new GeometryDrawer(contours);
42+
frame.add(drawer);
43+
frame.setSize(1200, 1200);
44+
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
45+
frame.setLocationRelativeTo(null); // Center the frame on the screen
46+
frame.setVisible(true);
47+
}
48+
}

baremaps-raster/src/test/java/org/apache/baremaps/raster/ContourTracerLineStringTest.java

Lines changed: 16 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -29,69 +29,45 @@ class ContourTracerLineStringTest {
2929
@Test
3030
@DisplayName("Test case 0")
3131
void testProcessCellWithCase00() {
32-
var grid = new double[] {
33-
0, 0,
34-
0, 0,
35-
};
36-
var lines = trace(grid);
32+
var lines = trace(MarchingSquareCases.CASE_00);
3733
assertTrue(lines.isEmpty());
3834
}
3935

4036
@Test
4137
@DisplayName("Test case 1")
4238
void testProcessCellWithCase01() {
43-
var grid = new double[] {
44-
1, 0,
45-
0, 0,
46-
};
47-
var lines = trace(grid);
39+
var lines = trace(MarchingSquareCases.CASE_01);
4840
assertEquals("LINESTRING (0 0.5, 0.5 0)", lines.get(0).toString());
4941
}
5042

5143
@Test
5244
@DisplayName("Test case 2")
5345
void testProcessCellWithCase02() {
54-
var grid = new double[] {
55-
0, 1,
56-
0, 0,
57-
};
58-
var lines = trace(grid);
46+
var lines = trace(MarchingSquareCases.CASE_02);
5947
assertEquals(1, lines.size());
6048
assertEquals("LINESTRING (0.5 0, 1 0.5)", lines.get(0).toString());
6149
}
6250

6351
@Test
6452
@DisplayName("Test case 3")
6553
void testProcessCellWithCase03() {
66-
var grid = new double[] {
67-
1, 1,
68-
0, 0,
69-
};
70-
var lines = trace(grid);
54+
var lines = trace(MarchingSquareCases.CASE_03);
7155
assertEquals(1, lines.size());
7256
assertEquals("LINESTRING (0 0.5, 1 0.5)", lines.get(0).toString());
7357
}
7458

7559
@Test
7660
@DisplayName("Test case 4")
7761
void testProcessCellWithCase04() {
78-
var grid = new double[] {
79-
0, 0,
80-
0, 1,
81-
};
82-
var lines = trace(grid);
62+
var lines = trace(MarchingSquareCases.CASE_04);
8363
assertEquals(1, lines.size());
8464
assertEquals("LINESTRING (1 0.5, 0.5 1)", lines.get(0).toString());
8565
}
8666

8767
@Test
8868
@DisplayName("Test case 5")
8969
void testProcessCellWithCase05() {
90-
var grid = new double[] {
91-
1, 0,
92-
0, 1,
93-
};
94-
var lines = trace(grid);
70+
var lines = trace(MarchingSquareCases.CASE_05);
9571
assertEquals(2, lines.size());
9672
assertEquals("LINESTRING (0 0.5, 0.5 1)", lines.get(0).toString());
9773
assertEquals("LINESTRING (1 0.5, 0.5 0)", lines.get(1).toString());
@@ -100,59 +76,39 @@ void testProcessCellWithCase05() {
10076
@Test
10177
@DisplayName("Test case 6")
10278
void testProcessCellWithCase06() {
103-
var grid = new double[] {
104-
0, 1,
105-
0, 1,
106-
};
107-
var lines = trace(grid);
79+
var lines = trace(MarchingSquareCases.CASE_06);
10880
assertEquals(1, lines.size());
10981
assertEquals("LINESTRING (0.5 0, 0.5 1)", lines.get(0).toString());
11082
}
11183

11284
@Test
11385
@DisplayName("Test case 7")
11486
void testProcessCellWithCase07() {
115-
var grid = new double[] {
116-
1, 1,
117-
0, 1,
118-
};
119-
var lines = trace(grid);
87+
var lines = trace(MarchingSquareCases.CASE_07);
12088
assertEquals(1, lines.size());
12189
assertEquals("LINESTRING (0 0.5, 0.5 1)", lines.get(0).toString());
12290
}
12391

12492
@Test
12593
@DisplayName("Test case 8")
12694
void testProcessCellWithCase08() {
127-
var grid = new double[] {
128-
0, 0,
129-
1, 0,
130-
};
131-
var lines = trace(grid);
95+
var lines = trace(MarchingSquareCases.CASE_08);
13296
assertEquals(1, lines.size());
13397
assertEquals("LINESTRING (0.5 1, 0 0.5)", lines.get(0).toString());
13498
}
13599

136100
@Test
137101
@DisplayName("Test case 9")
138102
void testProcessCellWithCase09() {
139-
var grid = new double[] {
140-
1, 0,
141-
1, 0,
142-
};
143-
var lines = trace(grid);
103+
var lines = trace(MarchingSquareCases.CASE_09);
144104
assertEquals(1, lines.size());
145105
assertEquals("LINESTRING (0.5 1, 0.5 0)", lines.get(0).toString());
146106
}
147107

148108
@Test
149109
@DisplayName("Test case 10")
150110
void testProcessCellWithCase10() {
151-
var grid = new double[] {
152-
0, 1,
153-
1, 0,
154-
};
155-
var lines = trace(grid);
111+
var lines = trace(MarchingSquareCases.CASE_10);
156112
assertEquals(2, lines.size());
157113
assertEquals("LINESTRING (0.5 0, 0 0.5)", lines.get(0).toString());
158114
assertEquals("LINESTRING (0.5 1, 1 0.5)", lines.get(1).toString());
@@ -161,59 +117,39 @@ void testProcessCellWithCase10() {
161117
@Test
162118
@DisplayName("Test case 11")
163119
void testProcessCellWithCase11() {
164-
var grid = new double[] {
165-
1, 1,
166-
1, 0,
167-
};
168-
var lines = trace(grid);
120+
var lines = trace(MarchingSquareCases.CASE_11);
169121
assertEquals(1, lines.size());
170122
assertEquals("LINESTRING (0.5 1, 1 0.5)", lines.get(0).toString());
171123
}
172124

173125
@Test
174126
@DisplayName("Test case 12")
175127
void testProcessCellWithCase12() {
176-
var grid = new double[] {
177-
0, 0,
178-
1, 1,
179-
};
180-
var lines = trace(grid);
128+
var lines = trace(MarchingSquareCases.CASE_12);
181129
assertEquals(1, lines.size());
182130
assertEquals("LINESTRING (1 0.5, 0 0.5)", lines.get(0).toString());
183131
}
184132

185133
@Test
186134
@DisplayName("Test case 13")
187135
void testProcessCellWithCase13() {
188-
var grid = new double[] {
189-
1, 0,
190-
1, 1,
191-
};
192-
var lines = trace(grid);
136+
var lines = trace(MarchingSquareCases.CASE_13);
193137
assertEquals(1, lines.size());
194138
assertEquals("LINESTRING (1 0.5, 0.5 0)", lines.get(0).toString());
195139
}
196140

197141
@Test
198142
@DisplayName("Test case 14")
199143
void testProcessCellWithCase14() {
200-
var grid = new double[] {
201-
0, 1,
202-
1, 1,
203-
};
204-
var lines = trace(grid);
144+
var lines = trace(MarchingSquareCases.CASE_14);
205145
assertEquals(1, lines.size());
206146
assertEquals("LINESTRING (0.5 0, 0 0.5)", lines.get(0).toString());
207147
}
208148

209149
@Test
210150
@DisplayName("Test case 15")
211151
void testProcessCellWithCase15() {
212-
var grid = new double[] {
213-
1, 1,
214-
1, 1,
215-
};
216-
var lines = trace(grid);
152+
var lines = trace(MarchingSquareCases.CASE_15);
217153
assertTrue(lines.isEmpty());
218154
}
219155

0 commit comments

Comments
 (0)