JTSOpCmdTest.java
package org.locationtech.jtstest.cmd;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.List;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKBReader;
import junit.framework.TestCase;
public class JTSOpCmdTest extends TestCase {
private boolean isVerbose = true;
public JTSOpCmdTest(String Name_) {
super(Name_);
}
public static void main(String[] args) {
String[] testCaseName = {JTSOpCmdTest.class.getName()};
junit.textui.TestRunner.main(testCaseName);
}
public void testErrorFileNotFoundA() {
runCmdError( args("-a", "missing.wkt"),
JTSOpRunner.ERR_FILE_NOT_FOUND );
}
public void testErrorFileNotFoundB() {
runCmdError( args("-b", "missing.wkt"),
JTSOpRunner.ERR_FILE_NOT_FOUND );
}
public void testErrorFunctioNotFound() {
runCmdError( args("-a", "POINT ( 1 1 )", "buffer" ),
JTSOpRunner.ERR_FUNCTION_NOT_FOUND );
}
public void testErrorMissingArgBuffer() {
runCmdError( args("-a", "POINT ( 1 1 )", "Buffer.buffer" ),
JTSOpRunner.ERR_WRONG_ARG_COUNT );
}
public void testErrorbadMultiArgsNoRParen() {
runCmdError( args("-a", "POINT ( 1 1 )", "Buffer.buffer", "(1,2,3" ),
JTSOpCmd.ERR_INVALID_ARG_PARAM );
}
public void testErrorbadMultiArgsNoLParen() {
runCmdError( args("-a", "POINT ( 1 1 )", "Buffer.buffer", "1,2,3)" ),
JTSOpCmd.ERR_INVALID_ARG_PARAM );
}
public void testErrorMissingGeomABuffer() {
runCmdError( args("Buffer.buffer", "10" ),
JTSOpRunner.ERR_REQUIRED_A );
}
/*
// Missing B check is disabled for now
public void testErrorMissingGeomBUnion() {
runCmdError( args("-a", "POINT ( 1 1 )", "Overlay.union" ),
JTSOpRunner.ERR_REQUIRED_B );
}
*/
public void testErrorMissingGeomAUnion() {
runCmdError( args("-b", "POINT ( 1 1 )", "Overlay.union" ),
JTSOpRunner.ERR_REQUIRED_A );
}
//===========================================
public void testOpEnvelope() {
runCmd( args("-a", "LINESTRING ( 1 1, 2 2)", "-f", "wkt", "envelope"),
"POLYGON" );
}
public void testOpLength() {
runCmd( args("-a", "LINESTRING ( 1 0, 2 0 )", "-f", "txt", "length"),
"1" );
}
public void testOpUnionLines() {
runCmd( args("-a", "LINESTRING ( 1 0, 2 0 )", "-b", "LINESTRING ( 2 0, 3 0 )", "-f", "wkt", "Overlay.union"),
"MULTILINESTRING ((1 0, 2 0), (2 0, 3 0))" );
}
public void testOpNoArg() {
runCmd( args("-f", "wkt", "CreateRandomShape.randomPoints", "10"),
"MULTIPOINT" );
}
public void testCollectUnion() {
runCmd( args("-a", "stdin",
"-collect",
"-f", "wkt", "Overlay.unaryUnion"),
stdin( "POLYGON ((1 3, 3 3, 3 1, 1 1, 1 3))",
"POLYGON ((5 3, 5 1, 3 1, 3 3, 5 3))"
),
"POLYGON ((1 3, 3 3, 5 3, 5 1, 3 1, 1 1, 1 3))" );
}
public void testCollectLimitUnion() {
runCmd( args("-a", "stdin",
"-collect",
"-limit", "2",
"-f", "wkt", "Overlay.unaryUnion"),
stdin( "POLYGON ((1 3, 3 3, 3 1, 1 1, 1 3))",
"POLYGON ((5 3, 5 1, 3 1, 3 3, 5 3))",
"POLYGON ((1 5, 5 5, 5 3, 1 3, 1 5))"
),
"POLYGON ((1 3, 3 3, 5 3, 5 1, 3 1, 1 1, 1 3))" );
}
//===========================================
public void testOpEachA() {
runCmd( args("-a", "MULTILINESTRING((0 0, 10 10), (100 100, 110 110))",
"-eacha",
"-f", "wkt", "envelope"),
"POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))\nPOLYGON ((100 100, 100 110, 110 110, 110 100, 100 100))" );
}
public void testOpEachAEachB() {
runCmd( args(
"-a", "MULTIPOINT((0 0), (0 1))",
"-b", "MULTIPOINT((9 9), (8 8))",
"-eacha", "-eachb",
"-f", "wkt", "Distance.nearestPoints"),
"LINESTRING (0 0, 9 9)\nLINESTRING (0 0, 8 8)\nLINESTRING (0 1, 9 9)\nLINESTRING (0 1, 8 8)" );
}
public void testOpEachB() {
runCmd( args(
"-a", "MULTIPOINT((0 0), (0 1))",
"-b", "MULTIPOINT((9 9), (8 8))",
"-eachb",
"-f", "wkt", "Distance.nearestPoints" ),
"LINESTRING (0 1, 9 9)\nLINESTRING (0 1, 8 8)" );
}
public void testOpEachAA() {
runCmd( args(
"-ab", "MULTIPOINT((0 0), (0 1))",
"-eacha",
"-f", "wkt", "Distance.nearestPoints"),
"LINESTRING (0 0, 0 0)\nLINESTRING (0 0, 0 1)\nLINESTRING (0 1, 0 0)\nLINESTRING (0 1, 0 1)" );
}
public void testOpEachABIndexed() {
runCmd( args(
"-a", "MULTILINESTRING((0 0, 5 5), (10 0, 15 5))",
"-b", "MULTIPOINT((1 1), (11 1))",
"-eacha", "-eachb",
"-index",
"-f", "wkt", "Distance.nearestPoints"),
"LINESTRING (1 1, 1 1)\nLINESTRING (11 1, 11 1)" );
}
public void testOpBufferVals() {
JTSOpCmd cmd = runCmd( args(
"-a", "POINT(0 0)",
"-f", "wkt",
"Buffer.buffer", "val(1,2,3,4)" ),
null, null );
List<Geometry> results = cmd.getResultGeometry();
assertTrue("Not enough results for arg values", results.size() == 4 );
assertEquals("Incorrect summary value for arg values", computeArea(results), 93.6, 1);
}
public void testOpBufferMultiArgParen() {
JTSOpCmd cmd = runCmd( args(
"-a", "POINT(0 0)",
"-f", "wkt",
"Buffer.buffer", "(1,2,3,4)" ),
null, null );
List<Geometry> results = cmd.getResultGeometry();
assertTrue("Not enough results for arg values", results.size() == 4 );
assertEquals("Incorrect summary value for arg values", computeArea(results), 93.6, 1);
}
public void testOpBufferMultiArgNoParen() {
JTSOpCmd cmd = runCmd( args(
"-a", "POINT(0 0)",
"-f", "wkt",
"Buffer.buffer", "1,2,3,4" ),
null, null );
List<Geometry> results = cmd.getResultGeometry();
assertTrue("Not enough results for arg values", results.size() == 4 );
assertEquals("Incorrect summary value for arg values", computeArea(results), 93.6, 1);
}
//----------------------------------------------------------------
public void testWhereValid() {
JTSOpCmd cmd = runCmd( args(
"-a", "POLYGON ((1 9, 9 9, 9 1, 1 1, 1 9))",
"-f", "wkt",
"-where", "eq", "1",
"isValid" ) );
List<Geometry> results = cmd.getResultGeometry();
assertTrue("Not enough results for arg values", results.size() == 1 );
}
public void testWhereInvalid() {
JTSOpCmd cmd = runCmd( args(
"-a", "POLYGON ((1 9, 9 1, 9 9, 1 1, 1 9))",
"-f", "wkt",
"-where","eq", "0",
"isValid" ) );
List<Geometry> results = cmd.getResultGeometry();
assertTrue("Not enough results for arg values", results.size() == 1 );
}
public void testWhereLength() {
JTSOpCmd cmd = runCmd( args(
"-a", "stdin",
"-f", "wkt",
"-where","gt", "1",
"Geometry.length" ),
stdin(
"LINESTRING ( 0 1, 0 1)",
"LINESTRING ( 0 1, 0 2)",
"LINESTRING ( 0 1, 0 3)",
"LINESTRING ( 0 1, 0 4)"
) );
List<Geometry> results = cmd.getResultGeometry();
assertTrue("Not enough results for arg values", results.size() == 2 );
}
//----------------------------------------------------------------
public void testSRIDBuffer() throws ParseException {
JTSOpCmd cmd = runCmd( args(
"-a", "POINT(0 0)",
"-srid", "4326",
"-f", "wkb",
"Buffer.buffer", "1" ),
null, null );
List<Geometry> results = cmd.getResultGeometry();
assertEquals("Incorrect SRID", 4326, results.get(0).getSRID());
Geometry outGeom = readWKB(cmd.getOutput());
assertEquals("Incorrect SRID in WKB", 4326, outGeom.getSRID());
}
public void testSRIDStdIn() throws ParseException {
JTSOpCmd cmd = runCmd( args(
"-a", "stdin",
"-srid", "4326",
"-f", "wkb",
"Buffer.buffer", "1" ),
stdin("POINT(0 0)"), null );
List<Geometry> results = cmd.getResultGeometry();
assertEquals("Incorrect SRID", 4326, results.get(0).getSRID());
Geometry outGeom = readWKB(cmd.getOutput());
assertEquals("Incorrect SRID in WKB", 4326, outGeom.getSRID());
}
public void testSRIDPolygonize() throws ParseException {
JTSOpCmd cmd = runCmd( args(
"-a", "MULTILINESTRING ((1 1, 9 9), (9 9, 9 1), (9 1, 1 1), (9 1, 16 9), (9 9, 16 9))",
"-srid", "4326",
"-explode",
"-f", "wkb",
"Polygonize.polygonize" ),
null, null );
List<Geometry> results = cmd.getResultGeometry();
assertEquals("Incorrect SRID", 4326, results.get(0).getSRID());
assertEquals("Incorrect SRID", 4326, results.get(1).getSRID());
String[] output = cmd.getOutputLines();
for (String out : output) {
Geometry outGeom = readWKB(out);
assertEquals("Incorrect SRID in WKB", outGeom.getSRID(), 4326);
}
}
//----------------------------------------------------------------
private Geometry readWKB(String wkbHex) throws ParseException {
byte[] wkb = WKBReader.hexToBytes(wkbHex);
WKBReader rdr = new WKBReader();
return rdr.read(wkb);
}
public void testExplode() {
JTSOpCmd cmd = runCmd( args(
"-a", "LINESTRING(0 0, 10 10)",
"-b", "LINESTRING(0 10, 10 0)",
"-explode",
"-f", "wkt",
"Overlay.union" ),
null, null );
List<Geometry> results = cmd.getResultGeometry();
assertEquals("Not enough results for explode", results.size(), 4 );
}
public void testLiteralEmptyLinestring() {
JTSOpCmd cmd = runCmd( args(
"-a", "LINESTRING EMPTY",
"-f", "wkt",
"Construction.boundary" ),
null, null );
List<Geometry> results = cmd.getResultGeometry();
assertEquals("Too many results for operation", results.size(), 1 );
assertTrue("Expected empty result", results.get(0).isEmpty() );
}
public void testLiteralEmptyPoint() {
JTSOpCmd cmd = runCmd( args(
"-a", "POINT EMPTY",
"-f", "wkt",
"Construction.boundary" ),
null, null );
List<Geometry> results = cmd.getResultGeometry();
assertEquals("Too many results for operation", results.size(), 1 );
assertTrue("Expected empty result", results.get(0).isEmpty() );
}
//===========================================
public void testFormatWKB() {
runCmd( args("-a", "LINESTRING ( 1 1, 2 2)", "-f", "wkb"),
"0000000002000000023FF00000000000003FF000000000000040000000000000004000000000000000" );
}
public void testFormatGeoJSON() {
runCmd( args("-a", "LINESTRING ( 1 1, 2 2)", "-f", "geojson"),
"{\"type\":\"LineString\",\"coordinates\":[[1,1],[2,2]]}" );
}
public void testFormatSVG() {
runCmd( args("-a", "LINESTRING ( 1 1, 2 2)", "-f", "svg"),
"<polyline" );
}
public void testFormatGML() {
runCmd( args("-a", "LINESTRING ( 1 1, 2 2)", "-f", "gml"),
"<gml:LineString>" );
}
//===========================================
public void testStdInWKT() {
runCmd( args("-a", "stdin", "-f", "wkt", "envelope"),
stdin("LINESTRING ( 1 1, 2 2)"),
"POLYGON" );
}
public void testStdInWKB() {
runCmd( args("-a", "stdin", "-f", "wkt", "envelope"),
stdin("000000000200000005405900000000000040590000000000004072C000000000004062C00000000000405900000000000040690000000000004072C00000000000406F40000000000040590000000000004072C00000000000"),
"POLYGON" );
}
/*
// no longer supporting this semantic
public void testGeomABStdIn() {
runCmd( args("-ab", "stdin", "-f", "wkt", "Overlay.intersection"),
stdin("MULTILINESTRING (( 1 1, 3 3), (1 3, 3 1))"),
"POINT (2 2)" );
}
*/
public void testErrorStdInBadFormat() {
runCmdError( args("-a", "stdin", "-f", "wkt", "envelope"),
stdin("<gml fdlfld >"),
JTSOpRunner.ERR_PARSE_GEOM );
}
private String[] args(String ... args) {
return args;
}
private static InputStream stdin(String data) {
InputStream instr = new ByteArrayInputStream(data.getBytes(Charset.forName("UTF-8")));
return instr;
}
private static InputStream stdin(String... dataArr) {
String data = String.join("\n", dataArr);
return stdin(data);
}
private static InputStream stdinFile(String filename) {
try {
return new FileInputStream(filename);
}
catch (FileNotFoundException ex) {
throw new RuntimeException("File not found: " + filename);
}
}
public void runCmd(String[] args, String expected)
{
runCmd(args, null, expected);
}
private JTSOpCmd runCmd(String[] args, InputStream stdin) {
return runCmd(args, stdin, null);
}
private JTSOpCmd runCmd(String[] args) {
return runCmd(args, null, null);
}
private JTSOpCmd runCmd(String[] args, InputStream stdin, String expected) {
JTSOpCmd cmd = new JTSOpCmd();
cmd.captureOutput();
cmd.captureResult();
if (stdin != null) cmd.replaceStdIn(stdin);
try {
JTSOpRunner.OpParams cmdArgs = cmd.parseArgs(args);
cmd.execute(cmdArgs);
} catch (Exception e) {
e.printStackTrace();
}
checkExpected( cmd.getOutput(), expected);
return cmd;
}
public void runCmdError(String[] args) {
runCmdError(args, null);
}
public void runCmdError(String[] args, String expected) {
runCmdError(args, null, expected);
}
public void runCmdError(String[] args, InputStream stdin, String expected)
{
JTSOpCmd cmd = new JTSOpCmd();
if (stdin != null) cmd.replaceStdIn(stdin);
try {
JTSOpRunner.OpParams cmdArgs = cmd.parseArgs(args);
cmd.execute(cmdArgs);
}
catch (CommandError e) {
if (expected != null) checkExpected( e.getMessage(), expected );
return;
}
catch (Exception e) {
e.printStackTrace();
}
assertTrue("Expected error but command completed successfully", false);
}
private void checkExpected(String actual, String expected) {
if (expected == null) return;
boolean found = actual.contains(expected);
if (isVerbose && ! found) {
System.out.println("Expected: " + expected);
System.out.println("Actual: " + actual);
}
assertTrue( "Output does not contain string " + expected, found );
}
private static double computeArea(List<Geometry> results) {
GeometryFactory fact = new GeometryFactory();
Geometry geom = fact.buildGeometry(results);
return geom.getArea();
}
}