What is the proper way for "drop polyline layer if present"
I have a dataset that is supposed to contain only areas, in case of polylines being present my program should complain loudly and discard polylines.
As first step I tried: mapshaper -i combine-files in.geojson -target type=polyline -drop -o out.geojson
But in case of valid data it will error with [target] Error: No layers were matched (pattern: * type: polyline)
In addition it seems that there is no good way to check (by script) whatever given layer is present in the first place.
It seems that to solve need I will need to iterate over geojson using some other tool (what may be needed anyway to list offending lines). Or is it possible to do it with Mapshaper itself? I am likely missing something but I am staring at documentation and unable to discover what is going wrong.
This issue is related to the question of how to process files that are inconsistent or heterogeneous in some way. In this case, some of your files contain polyline features and others don't. I've had this problem in my work too.
I can think of a few possible solutions, but they all require writing some new code.
One solution could be to allow null (or missing) command targets, and skip running any commands with a null target. This would allow your example command (mapshaper -i combine-files in.geojson -target type=polyline -drop -o out.geojson) to run, although it wouldn't complain the way you want.
Another solution i've thought about is to add "flow control" commands, which would run a set of commands if a certain condition is met. Flow control commands might have names like -if -elif -else and -endif (or -fi). It could work like this:
mapshaper in.geojson \
-if 'target.type == "polyline"' \
-drop \
-endif \
-o out.geojson
Another solution would be to write a new command line program for testing if a GeoJSON file satisfies a variety of conditions. You could use such a program in shell scripts to conditionally run mapshaper (or another CLI program, like ogr2ogr). This approach would have the advantage of working with any command line program that accepts GeoJSON input. You could use it like this:
if geojson-test data.geojson --has-linestrings ; then \
echo STRIPPING POLYLINES; \
mapshaper data.geojson -target type=polyline -drop -o data.geojson force \
fi
Thanks for reply and confirmation that I am not missing something in docs/code. If anyone is curious following is my Ruby-based solution (not truly universal, assumes single geometry collection without nesting). (feel free to delete/edit this comment if it is offtopic).
def keep_area_only(input_geojson_file, output_geojson)
# https://github.com/rgeo/rgeo-geojson/issues/51
# https://github.com/mbloch/mapshaper/issues/463
assert_that_file_exists(input_geojson_file)
geojson_text = File.open(input_geojson_file).read
geom = JSON.parse(geojson_text)
# assumes one feature collection, collecting directly all geometries
if geom["type"] != "FeatureCollection"
raise "unexpected structure, #{geom["type"]} unexpectedly appeared"
end
only_areas = true
geom["features"].each do |element|
if ["Polygon", "MultiPolygon"].include?(element["geometry"]["type"]) == false
puts "Not an area! #{element["geometry"]["type"]}"
only_areas = false
end
end
command = "mapshaper -i combine-files #{input_geojson_file} -target type=polyline -drop -o #{output_geojson}"
if only_areas
command = "mapshaper -i combine-files #{input_geojson_file} -o combine-layers #{output_geojson}"
end
execute_command(command)
assert_that_file_exists(output_geojson, "executing: " + command)
detect_unexpected_datatypes(output_geojson, areas_expected: true)
end
If anyone cares, code above is CC0/MIT licensed.