2021-12-23 10:42:24 +00:00
|
|
|
package com.onthegomap.planetiler.examples;
|
2021-08-17 01:51:49 +00:00
|
|
|
|
2021-12-23 10:42:24 +00:00
|
|
|
import static com.onthegomap.planetiler.TestUtils.assertContains;
|
|
|
|
import static com.onthegomap.planetiler.TestUtils.newLineString;
|
2021-08-17 01:51:49 +00:00
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
|
|
2021-12-23 10:42:24 +00:00
|
|
|
import com.onthegomap.planetiler.FeatureCollector;
|
|
|
|
import com.onthegomap.planetiler.TestUtils;
|
|
|
|
import com.onthegomap.planetiler.VectorTile;
|
|
|
|
import com.onthegomap.planetiler.config.Arguments;
|
|
|
|
import com.onthegomap.planetiler.geo.GeoUtils;
|
|
|
|
import com.onthegomap.planetiler.mbtiles.Mbtiles;
|
|
|
|
import com.onthegomap.planetiler.reader.SimpleFeature;
|
|
|
|
import com.onthegomap.planetiler.reader.osm.OsmElement;
|
|
|
|
import com.onthegomap.planetiler.reader.osm.OsmReader;
|
2021-08-17 01:51:49 +00:00
|
|
|
import java.nio.file.Path;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
import org.junit.jupiter.api.io.TempDir;
|
|
|
|
import org.locationtech.jts.geom.LineString;
|
|
|
|
|
2022-04-23 10:36:24 +00:00
|
|
|
class BikeRouteOverlayTest {
|
2021-08-17 01:51:49 +00:00
|
|
|
|
|
|
|
private final BikeRouteOverlay profile = new BikeRouteOverlay();
|
|
|
|
|
|
|
|
@Test
|
2022-04-23 10:36:24 +00:00
|
|
|
void testSourceFeatureProcessing() {
|
2021-08-17 01:51:49 +00:00
|
|
|
// step 1) preprocess an example OSM relation
|
|
|
|
var relationResult = profile.preprocessOsmRelation(new OsmElement.Relation(1, Map.of(
|
|
|
|
"type", "route",
|
|
|
|
"route", "bicycle",
|
|
|
|
"name", "rail trail",
|
|
|
|
"network", "lcn",
|
|
|
|
"ref", "1"
|
|
|
|
), List.of(
|
|
|
|
new OsmElement.Relation.Member(OsmElement.Type.WAY, 2, "role")
|
|
|
|
)));
|
|
|
|
|
|
|
|
// step 2) process a way contained in that relation
|
2021-09-10 00:46:20 +00:00
|
|
|
var way = SimpleFeature.createFakeOsmFeature(TestUtils.newLineString(
|
2022-03-09 02:08:03 +00:00
|
|
|
10, 20, // point 1: 10 east 20 north
|
|
|
|
30, 40 // point 2: 30 east 40 north
|
|
|
|
), Map.of(), null, null, 2,
|
2021-09-10 00:46:20 +00:00
|
|
|
relationResult.stream().map(info -> new OsmReader.RelationMember<>("role", info)).toList());
|
2021-08-17 01:51:49 +00:00
|
|
|
List<FeatureCollector.Feature> mapFeatures = TestUtils.processSourceFeature(way, profile);
|
|
|
|
|
|
|
|
// verify output geometry
|
|
|
|
assertEquals(1, mapFeatures.size());
|
|
|
|
var feature = mapFeatures.get(0);
|
|
|
|
assertEquals("bicycle-route-local", feature.getLayer());
|
|
|
|
assertEquals(Map.of(
|
|
|
|
"name", "rail trail",
|
|
|
|
"ref", "1"
|
|
|
|
), feature.getAttrsAtZoom(14));
|
|
|
|
// output geometry is in world coordinates where 0,0 is top left and 1,1 is bottom right
|
|
|
|
assertEquals(0.085, feature.getGeometry().getLength(), 1e-2);
|
|
|
|
assertEquals(0, feature.getMinZoom());
|
|
|
|
assertEquals(14, feature.getMaxZoom());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2022-04-23 10:36:24 +00:00
|
|
|
void testTilePostProcessingMergesConnectedLines() {
|
2021-08-17 01:51:49 +00:00
|
|
|
String layer = "bicycle-route-local";
|
|
|
|
Map<String, Object> attrs = Map.of(
|
|
|
|
"name", "rail trail",
|
|
|
|
"ref", "1"
|
|
|
|
);
|
|
|
|
// segment 1: (0, 0) to (10, 0)
|
2021-09-10 00:46:20 +00:00
|
|
|
var line1 = new VectorTile.Feature(layer, 1, // id
|
|
|
|
VectorTile.encodeGeometry(newLineString(0, 0, 10, 0)),
|
2021-08-17 01:51:49 +00:00
|
|
|
attrs
|
|
|
|
);
|
|
|
|
// segment 2: (10, 0) to (20, 0)
|
2021-09-10 00:46:20 +00:00
|
|
|
var line2 = new VectorTile.Feature(layer, 2, // id
|
|
|
|
VectorTile.encodeGeometry(newLineString(10, 0, 20, 0)),
|
2021-08-17 01:51:49 +00:00
|
|
|
attrs
|
|
|
|
);
|
|
|
|
// merged: (0, 0) to (20, 0)
|
2021-09-10 00:46:20 +00:00
|
|
|
var connected = new VectorTile.Feature(layer, 1, // id
|
|
|
|
VectorTile.encodeGeometry(newLineString(0, 0, 20, 0)),
|
2021-08-17 01:51:49 +00:00
|
|
|
attrs
|
|
|
|
);
|
|
|
|
|
|
|
|
// ensure that 2 touching linestrings with same tags are merged
|
|
|
|
assertEquals(
|
|
|
|
List.of(connected),
|
|
|
|
profile.postProcessLayerFeatures(layer, 14, List.of(line1, line2))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2022-04-23 10:36:24 +00:00
|
|
|
void integrationTest(@TempDir Path tmpDir) throws Exception {
|
2021-08-17 01:51:49 +00:00
|
|
|
Path dbPath = tmpDir.resolve("output.mbtiles");
|
|
|
|
BikeRouteOverlay.run(Arguments.of(
|
|
|
|
// Override input source locations
|
2021-09-10 00:46:20 +00:00
|
|
|
"osm_path", TestUtils.pathToResource("monaco-latest.osm.pbf"),
|
2021-08-17 01:51:49 +00:00
|
|
|
// Override temp dir location
|
|
|
|
"tmp", tmpDir.toString(),
|
|
|
|
// Override output location
|
2023-03-18 18:38:04 +00:00
|
|
|
"output", dbPath.toString()
|
2021-08-17 01:51:49 +00:00
|
|
|
));
|
|
|
|
try (Mbtiles mbtiles = Mbtiles.newReadOnlyDatabase(dbPath)) {
|
2023-03-18 18:38:04 +00:00
|
|
|
Map<String, String> metadata = mbtiles.metadataTable().getAll();
|
2021-08-17 01:51:49 +00:00
|
|
|
assertEquals("Bike Paths Overlay", metadata.get("name"));
|
|
|
|
assertContains("openstreetmap.org/copyright", metadata.get("attribution"));
|
|
|
|
|
|
|
|
TestUtils
|
|
|
|
.assertNumFeatures(mbtiles, "bicycle-route-international", 14, Map.of(
|
|
|
|
"name", "EuroVelo 8 - Mediterranean Route - part Monaco",
|
|
|
|
"ref", "EV8"
|
|
|
|
), GeoUtils.WORLD_LAT_LON_BOUNDS, 25, LineString.class);
|
2023-01-14 21:03:50 +00:00
|
|
|
|
|
|
|
TestUtils.assertTileDuplicates(mbtiles, 0);
|
2021-08-17 01:51:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|