Skip to content

Commit 177b6f7

Browse files
committed
Support auto-detection of .shp file inside the provided directory
#1567
1 parent 69e1ff5 commit 177b6f7

File tree

2 files changed

+54
-1
lines changed
  • dataframe-geo/src
    • main/kotlin/org/jetbrains/kotlinx/dataframe/geo/io
    • test/kotlin/org/jetbrains/kotlinx/dataframe/geo/io

2 files changed

+54
-1
lines changed

dataframe-geo/src/main/kotlin/org/jetbrains/kotlinx/dataframe/geo/io/read.kt

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import org.jetbrains.kotlinx.dataframe.DataFrame
77
import org.jetbrains.kotlinx.dataframe.geo.GeoDataFrame
88
import org.jetbrains.kotlinx.dataframe.geo.geotools.toGeoDataFrame
99
import org.jetbrains.kotlinx.dataframe.io.asUrl
10+
import java.io.File
1011
import java.net.URL
1112

1213
fun GeoDataFrame.Companion.readGeoJson(path: String): GeoDataFrame<*> = readGeoJson(asUrl(path))
@@ -21,9 +22,30 @@ fun DataFrame.Companion.readGeoJson(path: String): GeoDataFrame<*> = GeoDataFram
2122

2223
fun DataFrame.Companion.readGeoJson(url: URL): GeoDataFrame<*> = GeoDataFrame.readGeoJson(url)
2324

24-
fun GeoDataFrame.Companion.readShapefile(path: String): GeoDataFrame<*> = readShapefile(asUrl(path))
25+
/**
26+
* Examples:
27+
* ```
28+
* GeoDataFrame.readShapefile("simple_points")
29+
* GeoDataFrame.readShapefile("simple_points/simple_points.shp")
30+
* ```
31+
*
32+
* @param path path to *.shp or *.shp.gz file, or to a directory containing such a file
33+
*/
34+
fun GeoDataFrame.Companion.readShapefile(path: String): GeoDataFrame<*> {
35+
val url = resolveShapefileUrl(path)
36+
return readShapeFileImpl(url)
37+
}
2538

2639
fun GeoDataFrame.Companion.readShapefile(url: URL): GeoDataFrame<*> {
40+
val resolvedUrl = if (url.protocol == "file") {
41+
resolveShapefileUrl(url.path)
42+
} else {
43+
url
44+
}
45+
return readShapeFileImpl(resolvedUrl)
46+
}
47+
48+
private fun readShapeFileImpl(url: URL): GeoDataFrame<*> {
2749
val dataStore = ShapefileDataStoreFactory().createDataStore(url)
2850
try {
2951
return dataStore.featureSource.features.toGeoDataFrame()
@@ -32,6 +54,20 @@ fun GeoDataFrame.Companion.readShapefile(url: URL): GeoDataFrame<*> {
3254
}
3355
}
3456

57+
private fun resolveShapefileUrl(path: String): URL {
58+
val file = File(path)
59+
val shpFile = when {
60+
file.isDirectory -> findShapefileInDirectory(file)
61+
else -> file
62+
}
63+
return shpFile.toURI().toURL()
64+
}
65+
66+
private fun findShapefileInDirectory(dir: File): File =
67+
File(dir, "${dir.name}.shp").takeIf { it.exists() }
68+
?: File(dir, "${dir.name}.shp.gz").takeIf { it.exists() }
69+
?: throw IllegalArgumentException("No shapefile found in directory: ${dir.absolutePath}")
70+
3571
fun DataFrame.Companion.readShapefile(path: String): GeoDataFrame<*> = GeoDataFrame.readShapefile(path)
3672

3773
fun DataFrame.Companion.readShapefile(url: URL): GeoDataFrame<*> = GeoDataFrame.readShapefile(url)

dataframe-geo/src/test/kotlin/org/jetbrains/kotlinx/dataframe/geo/io/IOTest.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,21 @@ class IOTest {
6565
assertEquals(simplePointsGeoDf, GeoDataFrame.readShapefile(shapefile.toURI().toURL()))
6666
tempDir.deleteOnExit()
6767
}
68+
69+
@Test
70+
fun readShapefileDirectory() {
71+
val shapefileURL = classLoader.getResource("./simple_points")!!
72+
val geodf = GeoDataFrame.readShapefile(shapefileURL)
73+
74+
assertEquals(simplePointsDf, geodf.df)
75+
assert(geodf.crs == null)
76+
}
77+
78+
@Test
79+
fun readShapefileDirectoryFile() {
80+
val geodf = GeoDataFrame.readShapefile("src/test/resources/simple_points")
81+
82+
assertEquals(simplePointsDf, geodf.df)
83+
assert(geodf.crs == null)
84+
}
6885
}

0 commit comments

Comments
 (0)