Skip to content

Commit 4da4eb3

Browse files
committed
Create a Directory from a zipped shapefile URL
1 parent 19da1ca commit 4da4eb3

File tree

5 files changed

+95
-2
lines changed

5 files changed

+95
-2
lines changed

src/main/groovy/geoscript/GeoScript.groovy

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import geoscript.layer.Layer
1616
import geoscript.filter.Color
1717
import geoscript.proj.Projection
1818
import geoscript.workspace.Workspace
19-
import org.geotools.data.DataUtilities
2019

2120
import java.util.zip.ZipEntry
2221
import java.util.zip.ZipFile
@@ -354,4 +353,26 @@ class GeoScript {
354353
}
355354
dir
356355
}
356+
357+
/**
358+
* Download a URL to a File
359+
* @param options Optional named parameters:
360+
* <ul>
361+
* <li>overwrite = Whether to overwrite the existing file or not (defaults to true) </li>
362+
* </ul>
363+
* @param url The URL
364+
* @param file The File
365+
* @return The downloaded File
366+
*/
367+
static File download(Map options = [:], URL url, File file) {
368+
boolean overwrite = options.get('overwrite', true) as boolean
369+
if (overwrite == true || (overwrite == false && !file.exists())) {
370+
url.withInputStream { InputStream inputStream ->
371+
file.withOutputStream { OutputStream outputStream ->
372+
new BufferedOutputStream(outputStream) << inputStream
373+
}
374+
}
375+
}
376+
file
377+
}
357378
}

src/main/groovy/geoscript/workspace/Directory.groovy

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package geoscript.workspace
22

3+
import geoscript.GeoScript
34
import geoscript.layer.Layer
45
import org.geotools.data.DataStore
56
import org.geotools.data.DataUtilities
@@ -102,6 +103,26 @@ class Directory extends Workspace {
102103
"Directory[${getFile().absolutePath}]"
103104
}
104105

106+
/**
107+
* Get a Directory from a zipped Shapefile
108+
* @param options Optional named parameters:
109+
* <ul>
110+
* <li>overwrite = Whether to overwrite the existing file or not (defaults to true) </li>
111+
* </ul>
112+
* @param url The URL of the zipped Shapefile
113+
* @param dir The File directory where we will unzip the zip file
114+
* @return A Directory Workspace
115+
*/
116+
static Directory fromURL(Map options = [:], URL url, File dir) {
117+
if (!dir.exists()) {
118+
dir.mkdir()
119+
}
120+
File file = File.createTempFile("download",".zip")
121+
GeoScript.download(url, file, overwrite: options.get("overwrite", true) as boolean)
122+
GeoScript.unzip(file, dir)
123+
new Directory(dir)
124+
}
125+
105126
/**
106127
* The Directory WorkspaceFactory
107128
*/
@@ -129,6 +150,16 @@ class Directory extends Workspace {
129150
if (type.equalsIgnoreCase('shapefile') && params.containsKey('file')) {
130151
File file = params.get('file') instanceof File ? params.get('file') : new File(params.get('file'))
131152
super.create([url: DataUtilities.fileToURL(file.absoluteFile)])
153+
} else if (type.equalsIgnoreCase('shapefile') && params.containsKey('url') && params.containsKey("dir")) {
154+
URL url = params.get('url') instanceof URL ? params.get('url') : new URL(params.get('url'))
155+
File dir = params.get('dir') instanceof File ? params.get('dir') : new File(params.get('dir'))
156+
if (!dir.exists()) {
157+
dir.mkdir()
158+
}
159+
File file = File.createTempFile("download",".zip")
160+
GeoScript.download(url, file, overwrite: params.get("overwrite", true) as boolean)
161+
GeoScript.unzip(file, dir)
162+
super.create([url: DataUtilities.fileToURL(dir.absoluteFile)])
132163
} else {
133164
null
134165
}

src/main/groovy/geoscript/workspace/Workspace.groovy

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import geoscript.feature.Schema
77
import geoscript.layer.Cursor
88
import geoscript.layer.Layer
99
import org.geotools.data.DataStore
10+
import org.geotools.data.DataUtilities
1011
import org.geotools.feature.FeatureCollection
1112
import org.geotools.data.collection.ListFeatureCollection
1213
import org.geotools.data.DataStoreFinder
@@ -315,7 +316,19 @@ class Workspace {
315316
value = value.substring(1, value.length() - 1)
316317
}
317318
if (key.equalsIgnoreCase("url")) {
318-
value = new File(value).absoluteFile.toURL()
319+
try {
320+
// URLs with a protocol (file: http:)
321+
value = new URL(value)
322+
File file = DataUtilities.urlToFile(value)
323+
if (file != null) {
324+
value = DataUtilities.fileToURL(file.absoluteFile)
325+
} else {
326+
value = new URL(value)
327+
}
328+
} catch(MalformedURLException e) {
329+
// Files without a protocol
330+
value = new File(value).absoluteFile.toURL()
331+
}
319332
}
320333
params.put(key, value)
321334
}

src/test/groovy/geoscript/GeoScriptTestCase.groovy

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,4 +253,12 @@ class GeoScriptTestCase {
253253
assertEquals "123", f.text
254254
}
255255
}
256+
257+
@Test void download() {
258+
URL url = getClass().getClassLoader().getResource("points.zip")
259+
File file = folder.newFile("zipped_points")
260+
GeoScript.download(url, file)
261+
assertTrue file.exists()
262+
assertTrue file.length() > 100
263+
}
256264
}

src/test/groovy/geoscript/workspace/DirectoryTestCase.groovy

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,5 +145,25 @@ class DirectoryTestCase {
145145
assertTrue dir.names.contains("states")
146146
}
147147

148+
@Test void fromUrl() {
149+
URL url = getClass().getClassLoader().getResource("points.zip")
150+
File dir = folder.newFolder("points")
151+
Directory directory = Directory.fromURL(url, dir)
152+
assertTrue directory.names.contains("points")
153+
}
154+
155+
@Test void zippedUrlParamMap() {
156+
URL url = getClass().getClassLoader().getResource("points.zip")
157+
File dir = folder.newFolder("points")
158+
Directory directory = Workspace.getWorkspace([type: "shapefile", url: url, dir: dir])
159+
assertTrue directory.names.contains("points")
160+
}
161+
162+
@Test void zippedUrlParamString() {
163+
URL url = getClass().getClassLoader().getResource("points.zip")
164+
File dir = folder.newFolder("points")
165+
Directory directory = Workspace.getWorkspace("type=shapefile url='${url}' dir='${dir}'")
166+
assertTrue directory.names.contains("points")
167+
}
148168
}
149169

0 commit comments

Comments
 (0)