Skip to content

Commit f9af9d5

Browse files
committed
Add a fix command for vector layers with invalid geometry
1 parent 1bb6c10 commit f9af9d5

File tree

5 files changed

+92
-0
lines changed

5 files changed

+92
-0
lines changed

src/main/docs/layer.adoc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,32 @@ include::output/layer_validity_1_result.txt[]
480480
include::output/layer_validity_2_command.txt[]
481481
include::output/layer_validity_2_result.txt[]
482482

483+
==== Fix
484+
485+
include::commands/layer_fix_description.txt[]
486+
487+
include::output/layer_fix_4_command.txt[]
488+
489+
include::commands/layer_fix.txt[]
490+
491+
include::output/layer_fix_0_command.txt[]
492+
include::output/layer_fix_0_result.txt[]
493+
494+
include::output/layer_fix_1_command.txt[]
495+
include::output/layer_fix_1_result.txt[]
496+
497+
include::output/layer_fix_2_command.txt[]
498+
include::output/layer_fix_2_result.txt[]
499+
500+
include::output/layer_fix_3_command.txt[]
501+
include::output/layer_fix_3_result.txt[]
502+
503+
include::output/layer_fix_4_command.txt[]
504+
include::output/layer_fix_4_result.txt[]
505+
506+
include::output/layer_fix_5_command.txt[]
507+
include::output/layer_fix_5_result.txt[]
508+
483509
=== Geoprocessing
484510

485511
==== Clip

src/main/groovy/org/geoshell/vector/LayerCommands.groovy

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,41 @@ class LayerCommands implements CommandMarker {
12181218
}
12191219
}
12201220

1221+
@CliCommand(value = "layer fix", help = "Fix the geometries of the features of the input Layer and save them to the output Layer")
1222+
String fix(
1223+
@CliOption(key = "input-name", mandatory = true, help = "The Layer name") LayerName inputLayerName,
1224+
@CliOption(key = "output-workspace", mandatory = true, help = "The output Layer Workspace") WorkspaceName workspaceName,
1225+
@CliOption(key = "output-name", mandatory = true, help = "The output Layer name") String outputLayerName
1226+
) throws Exception {
1227+
Layer inputLayer = catalog.layers[inputLayerName]
1228+
if (inputLayer) {
1229+
Workspace outputWorkspace = catalog.workspaces[workspaceName]
1230+
if (outputWorkspace) {
1231+
Schema schema = new Schema(outputLayerName, inputLayer.schema.fields)
1232+
Layer outputLayer = outputWorkspace.create(schema)
1233+
outputLayer.withWriter { geoscript.layer.Writer w ->
1234+
inputLayer.eachFeature { Feature f ->
1235+
Map values = [:]
1236+
f.attributes.each { k, v ->
1237+
if (v instanceof geoscript.geom.Geometry) {
1238+
values[k] = f.geom.fix()
1239+
} else {
1240+
values[k] = v
1241+
}
1242+
}
1243+
w.add(outputLayer.schema.feature(values, f.id))
1244+
}
1245+
}
1246+
catalog.layers[new LayerName(outputLayerName)] = outputWorkspace.get(outputLayerName)
1247+
"Done!"
1248+
} else {
1249+
"Unable to find Workspace ${workspaceName}"
1250+
}
1251+
} else {
1252+
"Unable to find Layer ${inputLayerName}"
1253+
}
1254+
}
1255+
12211256
@CliCommand(value = "layer delete", help = "Delete features from the Layer")
12221257
String delete(
12231258
@CliOption(key = "name", mandatory = true, help = "The Layer name") LayerName layerName,

src/test/groovy/org/geoshell/docs/LayerDocTest.groovy

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,17 @@ class LayerDocTest extends AbstractDocTest {
11401140
copyFile(new File("examples/layer_union.png"), new File("src/main/docs/images"))
11411141
}
11421142

1143+
@Test
1144+
void fix() {
1145+
run("layer_fix", [
1146+
'workspace open --name mem --params memory',
1147+
'layer create --workspace mem --name lines --fields "the_geom=LineString EPSG:4326|fid=Int|name=String"',
1148+
'layer add --name lines --values "the_geom=LINESTRING (0 0, 0 0, 0 0, 1 1)|fid=1|name=Location 1"',
1149+
'layer add --name lines --values "the_geom=LINESTRING (1 1, 2 2, 2 2, 2 2, 3 3)|fid=2|name=Location 2"',
1150+
'layer fix --input-name lines --output-workspace mem --output-name lines_fixed',
1151+
'layer features --name lines_fixed'
1152+
])
1153+
}
11431154

11441155

11451156
}

src/test/groovy/org/geoshell/vector/LayerCommandsTest.groovy

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,23 @@ class LayerCommandsTest {
838838
}
839839
}
840840

841+
@Test void fix() {
842+
Layer layer = new Property(new File(getClass().getClassLoader().getResource("fixable.properties").toURI()))
843+
Catalog catalog = new Catalog()
844+
catalog.workspaces[new WorkspaceName("mem")] = new Memory()
845+
catalog.layers[new LayerName("lines")] = layer
846+
LayerCommands cmds = new LayerCommands(catalog: catalog)
847+
String result = cmds.fix(new LayerName("lines"), new WorkspaceName("mem"), "fixed_lines")
848+
assertEquals "Done!", result
849+
assertNotNull catalog.layers[new LayerName("fixed_lines")]
850+
Layer outLayer = catalog.layers[new LayerName("fixed_lines")]
851+
assertEquals layer.count, outLayer.count
852+
assertEquals "LineString", outLayer.schema.geom.typ
853+
(0..<layer.count).each { int i ->
854+
assertTrue outLayer.features[i].geom.numPoints < layer.features[i].geom.numPoints
855+
}
856+
}
857+
841858
@Test void delete() {
842859
Catalog catalog = new Catalog()
843860
catalog.workspaces[new WorkspaceName("mem")] = new Memory()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
_=id:String,name:String,geom:LineString
2+
road.1360815594529=1|Road 1|LINESTRING (0 0, 0 0, 0 0, 1 1))
3+
road.1360815594538=2|Road 2|LINESTRING (1 1, 0 0, 0 0, 0 0, 2 2)

0 commit comments

Comments
 (0)