kopia lustrzana https://github.com/onthegomap/planetiler
handle empty geopackage geometries (#561)
rodzic
fba875f968
commit
738e181657
|
@ -25,11 +25,14 @@ import org.geotools.referencing.CRS;
|
||||||
import org.locationtech.jts.geom.Geometry;
|
import org.locationtech.jts.geom.Geometry;
|
||||||
import org.opengis.referencing.FactoryException;
|
import org.opengis.referencing.FactoryException;
|
||||||
import org.opengis.referencing.operation.MathTransform;
|
import org.opengis.referencing.operation.MathTransform;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility that reads {@link SourceFeature SourceFeatures} from the vector geometries contained in a GeoPackage file.
|
* Utility that reads {@link SourceFeature SourceFeatures} from the vector geometries contained in a GeoPackage file.
|
||||||
*/
|
*/
|
||||||
public class GeoPackageReader extends SimpleReader<SimpleFeature> {
|
public class GeoPackageReader extends SimpleReader<SimpleFeature> {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(GeoPackageReader.class);
|
||||||
|
|
||||||
private final boolean keepUnzipped;
|
private final boolean keepUnzipped;
|
||||||
private Path extractedPath = null;
|
private Path extractedPath = null;
|
||||||
|
@ -122,6 +125,7 @@ public class GeoPackageReader extends SimpleReader<SimpleFeature> {
|
||||||
public void readFeatures(Consumer<SimpleFeature> next) throws Exception {
|
public void readFeatures(Consumer<SimpleFeature> next) throws Exception {
|
||||||
var latLonCRS = CRS.decode("EPSG:4326");
|
var latLonCRS = CRS.decode("EPSG:4326");
|
||||||
long id = 0;
|
long id = 0;
|
||||||
|
boolean loggedMissingGeometry = false;
|
||||||
|
|
||||||
for (var featureName : geoPackage.getFeatureTables()) {
|
for (var featureName : geoPackage.getFeatureTables()) {
|
||||||
FeatureDao features = geoPackage.getFeatureDao(featureName);
|
FeatureDao features = geoPackage.getFeatureDao(featureName);
|
||||||
|
@ -136,11 +140,16 @@ public class GeoPackageReader extends SimpleReader<SimpleFeature> {
|
||||||
|
|
||||||
for (var feature : features.queryForAll()) {
|
for (var feature : features.queryForAll()) {
|
||||||
GeoPackageGeometryData geometryData = feature.getGeometry();
|
GeoPackageGeometryData geometryData = feature.getGeometry();
|
||||||
if (geometryData == null) {
|
byte[] wkb;
|
||||||
|
if (geometryData == null || (wkb = geometryData.getWkb()).length == 0) {
|
||||||
|
if (!loggedMissingGeometry) {
|
||||||
|
loggedMissingGeometry = true;
|
||||||
|
LOGGER.warn("Geopackage file contains empty geometry: {}", geoPackage.getPath());
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Geometry featureGeom = (new WKBReader()).read(geometryData.getWkb());
|
Geometry featureGeom = (new WKBReader()).read(wkb);
|
||||||
Geometry latLonGeom = (transform.isIdentity()) ? featureGeom : JTS.transform(featureGeom, transform);
|
Geometry latLonGeom = (transform.isIdentity()) ? featureGeom : JTS.transform(featureGeom, transform);
|
||||||
|
|
||||||
FeatureColumns columns = feature.getColumns();
|
FeatureColumns columns = feature.getColumns();
|
||||||
|
|
|
@ -4,7 +4,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import com.onthegomap.planetiler.TestUtils;
|
import com.onthegomap.planetiler.TestUtils;
|
||||||
import com.onthegomap.planetiler.collection.IterableOnce;
|
|
||||||
import com.onthegomap.planetiler.geo.GeoUtils;
|
import com.onthegomap.planetiler.geo.GeoUtils;
|
||||||
import com.onthegomap.planetiler.stats.Stats;
|
import com.onthegomap.planetiler.stats.Stats;
|
||||||
import com.onthegomap.planetiler.util.FileUtils;
|
import com.onthegomap.planetiler.util.FileUtils;
|
||||||
|
@ -13,7 +12,8 @@ import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.Timeout;
|
import org.junit.jupiter.api.Timeout;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
@ -45,9 +45,7 @@ class GeoPackageReaderTest {
|
||||||
List<Geometry> points = new ArrayList<>();
|
List<Geometry> points = new ArrayList<>();
|
||||||
List<String> names = new ArrayList<>();
|
List<String> names = new ArrayList<>();
|
||||||
WorkerPipeline.start("test", Stats.inMemory())
|
WorkerPipeline.start("test", Stats.inMemory())
|
||||||
.readFromTiny("files", List.of(Path.of("dummy-path")))
|
.fromGenerator("geopackage", reader::readFeatures, 1)
|
||||||
.addWorker("geopackage", 1,
|
|
||||||
(IterableOnce<Path> p, Consumer<SimpleFeature> next) -> reader.readFeatures(next))
|
|
||||||
.addBuffer("reader_queue", 100, 1)
|
.addBuffer("reader_queue", 100, 1)
|
||||||
.sinkToConsumer("counter", 1, elem -> {
|
.sinkToConsumer("counter", 1, elem -> {
|
||||||
assertTrue(elem.getTag("name") instanceof String);
|
assertTrue(elem.getTag("name") instanceof String);
|
||||||
|
@ -67,4 +65,27 @@ class GeoPackageReaderTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Timeout(30)
|
||||||
|
void testReadEmptyGeoPackage() throws IOException {
|
||||||
|
Path path = TestUtils.pathToResource("empty-geom.gpkg");
|
||||||
|
|
||||||
|
try (
|
||||||
|
var reader = new GeoPackageReader(null, "test", path, tmpDir, false)
|
||||||
|
) {
|
||||||
|
for (int iter = 0; iter < 2; iter++) {
|
||||||
|
String id = "iter=" + iter;
|
||||||
|
assertEquals(1, reader.getFeatureCount(), id);
|
||||||
|
AtomicInteger found = new AtomicInteger(0);
|
||||||
|
WorkerPipeline.start("test", Stats.inMemory())
|
||||||
|
.fromGenerator("geopackage", reader::readFeatures, 1)
|
||||||
|
.addBuffer("reader_queue", 100, 1)
|
||||||
|
.sinkToConsumer("counter", 1, elem -> {
|
||||||
|
found.incrementAndGet();
|
||||||
|
}).await();
|
||||||
|
assertEquals(0, found.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Plik binarny nie jest wyświetlany.
Ładowanie…
Reference in New Issue