Wednesday 21 August 2019

JtsOp - a CLI for JTS

Since inception JTS has provided two client tools to aid in using the library.  They are the TestBuilder and the TestRunner

  • The TestBuilder is a GUI tool with many powerful capabilities for loading, editing and visualizing geometry.  It also provides the ability to run numerous geometric functions which expose (and in some cases enhance) the JTS library functionality.
  • The TestRunner is a command-line tool which runs tests in the JTS XML test format. 

But there's a gap which these two tools don't fill.  It's often required to run JTS operations on geometry data for purposes of testing, debugging or timing operations.  This can be done in the TestBuilder, but being a GUI it's highly manual process, and tedious to repeat multiple times.  It is (just) possible to use the TestRunner for this, but that introduces the awkwardness of wrapping the input data in XML.  The only other option up until now was to write a Java program, which is overkill for quick tests, and not very accessible for some.

What's really needed is a JTS equivalent of the UNIX expr. It should have the ability to accept geometry inputs, run an operation on them, and output the results.  (Another comparison might be to a very small subset of  GDAL/OGR, focussed on geometry only - and of course running in Java).

The TestBuilder already provides a rich framework for most of this functionality, so it turned out to be simple to expose this as a command-line tool.  Behold - the jtsop command!

jtsop has the following capabilities:
  • read geometries from files or command-line
  • input formats include WKT, WKB, GeoJSON, GML and SHP
  • execute any TestBuilder operation on the geometry input (which includes all JTS Geometry methods)
  • output the result as WKT, WKB, GeoJSON, GML or SVG
  • report metrics for geometry and execution times
  • dynamically load and run geometry functions provided in external Java classes 

Compute the area of a WKT geometry and output it as text
jtsop -a some-geom.wkt -f txt area 

Compute the unary union of a WKT geometry and output as WKB
jtsop -a some-geom.wkt -f wkb Overlay.unaryUnion 

Compute the union of two geometries in WKT and WKB and output as WKT
jtsop -a some-geom.wkt -b some-other-geom.wkb -f wkt Overlay.Union

Compute the buffer of distance 10 of a WKT geometry and output as GeoJSON
jtsop -a some-geom.wkt -f geojson Buffer.buffer 10

Compute the buffer of a literal geometry and output as WKT
jtsop -a "POINT (10 10)" -f wkt Buffer.buffer 10

Output a literal geometry as GeoJSON
jtsop -a "POINT (10 10)" -f geojson

Compute an operation on a geometry and output only geometry metrics and timing
jtsop -v -a some-geom.wkt Buffer.buffer 10


jtsop is already proving its worth in the JTS development process.  Some other use cases come to mind:
  • Converting geometry between formats (e.g. WKT to GeoJSON)
  • Filtering and extracting subsets of geometry data (there are various selection functions available to do this)
  • Computing summary statistics of geometry data  

Further Work

There's some interesting enhancements that could be added:
  • provide options to refine the input such as spatial filtering or geometry type coercion
  • allowing chaining multiple operations together using a little DSL (this is possible via shell piping, but doing this internally would be more efficient).  This could use the pipe operator a la Elixir.
  • Include the Proj4J library to allow coordinate system conversions (this can be done now as a simple extension using the dynamic function loading, but it would be nice to have it built in)
  • output geometry as images (using the TestBuilder rendering pipeline)