Skip to content

Commit

Permalink
feat: support loading single Shapefile from folder
Browse files Browse the repository at this point in the history
Support for identifying and loading a single Shapefile if the source set
for the ShapeSchemaReader is a folder.

ING-4416
  • Loading branch information
stempler committed Aug 6, 2024
1 parent 34f8fd9 commit 5f51fcb
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import static org.junit.Assert.assertNotNull
import static org.junit.Assert.assertTrue

import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.util.function.Consumer

import org.apache.commons.io.IOUtils
import org.junit.Test
import org.locationtech.jts.geom.Geometry

Expand All @@ -47,6 +49,9 @@ import groovy.transform.TypeCheckingMode
@CompileStatic
class ShapeInstanceReaderTest {

/**
* Test reading Shapefile instances using the Shapefile as schema.
*/
@Test
void testReadShapeInstances() {
Schema xmlSchema = TestUtil.loadSchema(getClass().getClassLoader().getResource("testdata/arokfnp/ikg.shp").toURI())
Expand All @@ -63,6 +68,38 @@ class ShapeInstanceReaderTest {
validateArokFnpIkg(list, 'the_geom')
}

/**
* Test reading a single Shapefile from a folder.
*/
@Test
void testReadFromFolder() {
Schema xmlSchema = TestUtil.loadSchema(getClass().getClassLoader().getResource("testdata/arokfnp/ikg.shp").toURI())

File tempDir = Files.createTempDirectory("read-shape").toFile()
try {
def ext = ['shp', 'dbf', 'prj', 'shx']
ext.each {
IOUtils.copy(getClass().getClassLoader().getResource("testdata/arokfnp/ikg.$it"), new File(tempDir, "ikg.$it"))
}

InstanceCollection instances = loadInstances(xmlSchema, tempDir.toURI())

assertNotNull(instances)
List<Instance> list = instances.toList()

// test count
assertThat(list).hasSize(14)

// instance validation
validateArokFnpIkg(list, 'the_geom')
} finally {
tempDir.deleteDir()
}
}

/**
* Test reading Shapefile instances using an XML schema.
*/
@Test
void testReadXsdInstances() {
Schema xmlSchema = TestUtil.loadSchema(getClass().getClassLoader().getResource("testdata/arokfnp/arok-fnp.xsd").toURI())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
*/
package eu.esdihumboldt.hale.io.shp.reader.internal;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.text.MessageFormat;
import java.util.Collection;
Expand All @@ -36,6 +38,7 @@
import eu.esdihumboldt.hale.common.core.io.report.IOReport;
import eu.esdihumboldt.hale.common.core.io.report.IOReporter;
import eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl;
import eu.esdihumboldt.hale.common.core.io.supplier.DefaultInputSupplier;
import eu.esdihumboldt.hale.common.core.parameter.AbstractParameterValueDescriptor;
import eu.esdihumboldt.hale.common.instance.io.InstanceReader;
import eu.esdihumboldt.hale.common.instance.io.impl.AbstractInstanceReader;
Expand Down Expand Up @@ -98,7 +101,34 @@ protected IOReport execute(ProgressIndicator progress, IOReporter reporter)
throws IOProviderConfigurationException, IOException {
progress.begin(Messages.getString("ShapeSchemaProvider.1"), ProgressIndicator.UNKNOWN); //$NON-NLS-1$

ShapefileDataStore store = new ShapefileDataStore(getSource().getLocation().toURL());
URI loc = getSource().getLocation();
try {
File file = new File(loc);

// special handling for directory as source -> load single Shapefile
if (file.exists() && file.isDirectory()) {
File[] candidates = file
.listFiles(f -> f.isFile() && f.getName().toLowerCase().endsWith(".shp"));
if (candidates != null && candidates.length > 0) {
// use first Shapefile found in folder
loc = candidates[0].toURI();

if (candidates.length > 1) {
reporter.warn(
"Picked file {} to load from folder, other Shapefiles in folder found but ignored",
candidates[0].getName());
}
else {
reporter.info("Picked file {} to load from folder",
candidates[0].getName());
}
}
}
} catch (IllegalArgumentException e) {
// ignore
}

ShapefileDataStore store = new ShapefileDataStore(loc.toURL());
store.setCharset(getCharset());

progress.setCurrentTask("Extracting shape instances");
Expand Down Expand Up @@ -136,7 +166,8 @@ protected IOReport execute(ProgressIndicator progress, IOReporter reporter)
reporter.info(new IOMessageImpl(
"No type name supplied as parameter, trying to auto-detect the schema type.",
null));
TypeDefinition dataType = ShapeSchemaReader.readShapeType(getSource());
TypeDefinition dataType = ShapeSchemaReader
.readShapeType(new DefaultInputSupplier(loc));
if (dataType == null) {
throw new IOException("Could not read shapefile structure information");
}
Expand Down

0 comments on commit 5f51fcb

Please sign in to comment.