Skip to content

Commit

Permalink
Add layer write and read commands.
Browse files Browse the repository at this point in the history
  • Loading branch information
jericks committed Jan 26, 2022
1 parent caca23e commit d366a2f
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ examples/mars/
src/main/docs/output/
src/main/docs/images/
src/main/docs/commands/

TODO.md
40 changes: 40 additions & 0 deletions src/main/docs/layer.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,46 @@ include::output/layer_remove_5_result.txt[]
include::output/layer_remove_6_command.txt[]
include::output/layer_remove_6_result.txt[]

==== Write

include::commands/layer_write_description.txt[]

include::output/layer_write_4_command.txt[]

include::commands/layer_write.txt[]

include::output/layer_write_0_command.txt[]
include::output/layer_write_0_result.txt[]

include::output/layer_write_1_command.txt[]
include::output/layer_write_1_result.txt[]

include::output/layer_write_2_command.txt[]
include::output/layer_write_2_result.txt[]

include::output/layer_write_3_command.txt[]
include::output/layer_write_3_result.txt[]

include::output/layer_write_4_command.txt[]
include::output/layer_write_4_result.txt[]

==== Read

include::commands/layer_read_description.txt[]

include::output/layer_read_1_command.txt[]

include::commands/layer_read.txt[]

include::output/layer_read_0_command.txt[]
include::output/layer_read_0_result.txt[]

include::output/layer_read_1_command.txt[]
include::output/layer_read_1_result.txt[]

include::output/layer_read_2_command.txt[]
include::output/layer_read_2_result.txt[]

==== Update Field

include::commands/layer_updatefield_description.txt[]
Expand Down
80 changes: 80 additions & 0 deletions src/main/groovy/org/geoshell/vector/LayerCommands.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,25 @@ import geoscript.geom.Point
import geoscript.layer.Graticule
import geoscript.layer.Layer
import geoscript.layer.Writer as LayerWriter
import geoscript.layer.io.CsvReader
import geoscript.layer.io.GeoJSONReader
import geoscript.layer.io.GeoRSSWriter
import geoscript.layer.io.GeobufWriter
import geoscript.layer.io.GmlWriter
import geoscript.layer.io.GpxWriter
import geoscript.layer.io.KmlWriter
import geoscript.layer.io.MvtWriter
import geoscript.layer.io.Reader
import geoscript.layer.io.Writer
import geoscript.layer.io.Writers
import geoscript.layer.io.YamlReader
import geoscript.proj.Projection
import geoscript.style.Style
import geoscript.style.io.CSSReader
import geoscript.style.io.SLDReader
import geoscript.style.io.SLDWriter
import geoscript.workspace.Workspace
import org.apache.commons.io.FilenameUtils
import org.geoshell.Catalog
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.shell.core.CommandMarker
Expand Down Expand Up @@ -1693,4 +1706,71 @@ class LayerCommands implements CommandMarker {
}
}

@CliCommand(value = "layer write", help = "Write a Layer to GeoJSON, CSV, or KML.")
String write(
@CliOption(key = "name", mandatory = true, help = "The Layer name") LayerName name,
@CliOption(key = "format", mandatory = true, help = "The format") String format,
@CliOption(key = "file", mandatory = false, help = "The output file") File file
) throws Exception {
Layer layer = catalog.layers[name]
if (layer) {
Writer writer = Writers.find(format)
if (file) {
writer.write(layer, file)
"Layer ${name} written to ${file} as ${format}"
} else {
writer.write(layer)
}
} else {
"Unable to find Layer ${name}"
}
}

@CliCommand(value = "layer read", help = "Read a Layer from a GeoJSON, KML, or YAML file.")
String read(
@CliOption(key = "workspace", mandatory = true, help = "The Workspace name") WorkspaceName workspaceName,
@CliOption(key = "name", mandatory = true, help = "The name") String name,
@CliOption(key = "file", mandatory = true, help = "The output file") File file
) throws Exception {
Workspace workspace = catalog.workspaces[workspaceName]
if (workspace) {
String fileExtension = FilenameUtils.getExtension(file.name)
Reader reader = getReaderForFileExtension(fileExtension)
if (reader) {
Layer layer = reader.read(file)
workspace.add(layer)
catalog.layers[new LayerName(name)] = layer
"Created Layer ${name} in Workspace ${workspaceName} for ${file}!"
} else {
"Unable to find reader for ${file}!"
}
} else {
"Unable to find Workspace ${workspaceName}"
}
}

private Reader getReaderForFileExtension(String fileExtension) {
Reader reader
if (fileExtension.equalsIgnoreCase("csv")) {
reader = new CsvReader()
} else if (fileExtension.equalsIgnoreCase("json")) {
reader = new GeoJSONReader()
} else if (fileExtension.equalsIgnoreCase("yml") || fileExtension.equalsIgnoreCase("yaml")) {
reader = new YamlReader()
} else if (fileExtension.equalsIgnoreCase("geobuf") || fileExtension.equalsIgnoreCase("pbf")) {
reader = new GeobufWriter()
} else if (fileExtension.equalsIgnoreCase("mvt")) {
reader = new MvtWriter()
} else if (fileExtension.equalsIgnoreCase("gml")) {
reader = new GmlWriter()
} else if (fileExtension.equalsIgnoreCase("kml")) {
reader = new KmlWriter()
} else if (fileExtension.equalsIgnoreCase("rss")) {
reader = new GeoRSSWriter()
} else if (fileExtension.equalsIgnoreCase("gpx")) {
reader = new GpxWriter()
}
reader
}

}
20 changes: 20 additions & 0 deletions src/test/groovy/org/geoshell/docs/LayerDocTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,26 @@ class LayerDocTest extends AbstractDocTest {
])
}

@Test
void write() {
run("layer_write", [
'workspace open --name mem --params memory',
'layer create --workspace mem --name points --fields "the_geom=Point EPSG:4326|fid=Int|name=String"',
'layer add --name points --values "the_geom=POINT (-122.333056 47.609722)|fid=1|name=Seattle"',
'layer add --name points --values "the_geom=POINT (-122.459444 47.241389)|fid=2|name=Tacoma"',
'layer write --name points --format geojson --file src/main/docs/output/points.json'
])
}

@Test
void read() {
run("layer_read", [
'workspace open --name mem --params memory',
'layer read --workspace mem --name points --file src/test/resources/points.json',
'layer features --name points'
])
}

@Test
void updateField() {
run("layer_updatefield", [
Expand Down
31 changes: 31 additions & 0 deletions src/test/groovy/org/geoshell/vector/LayerCommandsTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -1235,4 +1235,35 @@ class LayerCommandsTest {
Layer layer = catalog.layers[new LayerName("hexagons")]
assertEquals 219, layer.count
}

@Test void write() {
Catalog catalog = new Catalog()
catalog.workspaces[new WorkspaceName("mem")] = new Memory()
LayerCommands cmds = new LayerCommands(catalog: catalog)

cmds.create(new WorkspaceName("mem"), "points", "geom=Point EPSG:4326|id=Int|name=String")
cmds.add(new LayerName("points"), "geom=POINT(1 1)|id=1|name=Home")
cmds.add(new LayerName("points"), "geom=POINT(2 2)|id=2|name=Work")

File file = new File(folder, "points.json")
String results = cmds.write(new LayerName("points"), "geojson", file)
assertTrue(results.startsWith("Layer points written to"))
assertTrue(results.endsWith("points.json as geojson"))
assertTrue(file.text.startsWith("""{"type":"FeatureCollection"""))
println file.text
}

@Test void read() {
Catalog catalog = new Catalog()
catalog.workspaces[new WorkspaceName("mem")] = new Memory()
LayerCommands cmds = new LayerCommands(catalog: catalog)

File file = new File(getClass().getClassLoader().getResource("points.json").toURI())
String result = cmds.read(new WorkspaceName("mem"), "points", file)
assertTrue(result.startsWith("Created Layer points in Workspace mem for"))
assertTrue(result.endsWith("points.json!"))

Layer layer = catalog.layers[new LayerName("points")]
assertEquals(2, layer.count)
}
}
35 changes: 35 additions & 0 deletions src/test/resources/points.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
1,
1
]
},
"properties": {
"id": 1,
"name": "Home"
},
"id": "1"
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
2,
2
]
},
"properties": {
"id": 2,
"name": "Work"
},
"id": "2"
}
]
}

0 comments on commit d366a2f

Please sign in to comment.