Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JtsOpCmd limit and offset options #617

Merged
merged 3 commits into from
Oct 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@ public class CommandOptions {
public static final String FORMAT_GEOJSON = "geojson";
public static final String FORMAT_SVG = "svg";
public static final String TIME = "time";
public static final String LIMIT = "limit";
public static final String OFFSET = "offset";

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKTConstants;
import org.locationtech.jtstest.cmd.JTSOpRunner.OpParams;
import org.locationtech.jtstest.command.CommandLine;
import org.locationtech.jtstest.command.Option;
import org.locationtech.jtstest.command.OptionSpec;
Expand All @@ -37,6 +38,9 @@
* --- Compute the area of a WKT geometry, output it
* jtsop -a some-file-with-geom.wkt -f txt area
*
* --- Validate geometries from a WKT file using limit and offset
* jtsop -a some-file-with-geom.wkt -limit 100 -offset 40 -f txt isValid
*
* --- Compute the unary union of a WKT geometry, output as WKB
* jtsop -a some-file-with-geom.wkt -f wkb Overlay.unaryUnion
*
Expand Down Expand Up @@ -75,7 +79,7 @@ public static void main(String[] args)
JTSOpCmd cmd = new JTSOpCmd();
int rc = 1;
try {
JTSOpRunner.OpParams cmdArgs = cmd.parseArgs(args);
OpParams cmdArgs = cmd.parseArgs(args);
cmd.execute(cmdArgs);
rc = 0;
}
Expand Down Expand Up @@ -104,12 +108,14 @@ private static CommandLine createCmdLine() {
.addOptionSpec(new OptionSpec(CommandOptions.GEOMA, 1))
.addOptionSpec(new OptionSpec(CommandOptions.GEOMB, 1))
.addOptionSpec(new OptionSpec(CommandOptions.GEOMAB, 1))
.addOptionSpec(new OptionSpec(CommandOptions.SRID, 1))
.addOptionSpec(new OptionSpec(CommandOptions.EACH, 1))
.addOptionSpec(new OptionSpec(CommandOptions.INDEX, 0))
.addOptionSpec(new OptionSpec(CommandOptions.EXPLODE, 0))
.addOptionSpec(new OptionSpec(CommandOptions.FORMAT, 1))
.addOptionSpec(new OptionSpec(CommandOptions.LIMIT, 1))
.addOptionSpec(new OptionSpec(CommandOptions.OFFSET, 1))
.addOptionSpec(new OptionSpec(CommandOptions.REPEAT, 1))
.addOptionSpec(new OptionSpec(CommandOptions.SRID, 1))
.addOptionSpec(new OptionSpec(CommandOptions.VALIDATE, 0))
.addOptionSpec(new OptionSpec(OptionSpec.OPTION_FREE_ARGS, OptionSpec.NARGS_ONE_OR_MORE));
return commandLine;
Expand All @@ -121,37 +127,45 @@ private static CommandLine createCmdLine() {
" [ -a <wkt> | <wkb> | stdin | <filename.ext> ]",
" [ -b <wkt> | <wkb> | stdin | <filename.ext> ]",
" [ -ab <wkt> | <wkb> | stdin | <filename.ext> ]",
" [ -srid <SRID> ]",
" [ -limit <n> ]",
" [ -offset <n> ]",
" [ -each ( a | b | ab | aa ) ]",
" [ -index ]",
" [ -repeat <num> ]",
" [ -validate ]",
" [ -explode",
" [ -srid <SRID> ]",
" [ -f ( txt | wkt | wkb | geojson | gml | svg ) ]",
" [ -geomfunc <classname> ]",
" [ -time ]",
" [ -v, -verbose ]",
" [ -help ]",
" [ -geomfunc <classname> ]",
" [ -op ]",
" [ op [ args... ]]",
" op name of the operation (Category.op)",
" op name of the operation (in format Category.op)",
" args one or more scalar arguments to the operation",
" - To run over multiple arguments use v1,v2,v3 OR val(v1,v2,v3,..)",
"",
"===== Input options:",
" -a Geometry A: literal, stdin (WKT or WKB), or filename (extension: WKT, WKB, GeoJSON, GML, SHP)",
" -b Geometry A: literal, stdin (WKT or WKB), or filename (extension: WKT, WKB, GeoJSON, GML, SHP)",
" -srid Sets the SRID on output geometries",
" -limit Limits the number of geometries read from A, or B if specified",
" -offset Uses an offset to read geometries from A, or B if specified",
"===== Operation options:",
" -each execute op on each component of A, B, both A & B, or A & A",
" -index index geometry B",
" -repeat repeat the operation N times",
" -validate validate the result of each operation",
" -geomfunc specifies class providing geometry operations",
" -op separator to delineate operation arguments",
"===== Output options:",
" -srid Sets the SRID on output geometries",
" -explode output atomic geometries",
" -f output format to use. If omitted output is silent",
" -geomfunc specifies class providing geometry operations",
"===== Logging options:",
" -time display execution time",
" -v, -verbose display information about execution",
" -help print a list of available operations",
" -op separator for op arguments"
" -help print a list of available operations"
};

private void printHelp(boolean showFunctions) {
Expand Down Expand Up @@ -243,7 +257,7 @@ private static boolean isWKT(String arg) {
if (arg.toUpperCase().endsWith(" " + WKTConstants.EMPTY)) return true;
return false;
}

void execute(JTSOpRunner.OpParams cmdArgs) {
if (isHelp || isHelpWithFunctions) {
printHelp(isHelpWithFunctions);
Expand All @@ -261,7 +275,7 @@ JTSOpRunner.OpParams parseArgs(String[] args) throws ParseException, ClassNotFou
}
commandLine.parse(args);

JTSOpRunner.OpParams cmdArgs = new JTSOpRunner.OpParams();
OpParams cmdArgs = new JTSOpRunner.OpParams();

String argA = commandLine.getOptionArg(CommandOptions.GEOMA, 0);
if (argA != null) {
Expand Down Expand Up @@ -294,6 +308,14 @@ JTSOpRunner.OpParams parseArgs(String[] args) throws ParseException, ClassNotFou

cmdArgs.isExplode = commandLine.hasOption(CommandOptions.EXPLODE);

int paramLimit = commandLine.hasOption(CommandOptions.LIMIT)
? commandLine.getOptionArgAsInt(CommandOptions.LIMIT, 0)
: -1;

int paramOffset = commandLine.hasOption(CommandOptions.OFFSET)
? commandLine.getOptionArgAsInt(CommandOptions.OFFSET, 0)
: 0;

cmdArgs.format = commandLine.getOptionArg(CommandOptions.FORMAT, 0);

cmdArgs.srid = commandLine.hasOption(CommandOptions.SRID)
Expand Down Expand Up @@ -358,9 +380,28 @@ else if (each.equalsIgnoreCase("aa")) {
cmdArgs.argList = parseOpArg(freeArgs[1]);
}
}

/**
* ====== Apply extra parameter logic
*/
//--- apply limit to A if no B, or else to B
// This allows applying a binary op with a fixed LHS to a limited set of RHS geoms
if (OpParams.isGeometryInput(cmdArgs.fileB, cmdArgs.geomB)) {
cmdArgs.limitB = paramLimit;
cmdArgs.offsetB = paramOffset;
}
else {
cmdArgs.limitA = paramLimit;
cmdArgs.offsetA = paramOffset;
}

return cmdArgs;
}

private void applyParameters() {

}

private String[] parseOpArg(String arg) {
if (isArgMultiValues(arg)) {
return parseValues(arg);
Expand Down Expand Up @@ -420,7 +461,4 @@ private String[] parseMacroArgs(String macroTerm) {
String args = macroTerm.substring(indexLeft + 1, indexRight);
return args.split(",");
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@
import org.locationtech.jtstest.geomfunction.GeometryFunction;
import org.locationtech.jtstest.geomfunction.GeometryFunctionRegistry;
import org.locationtech.jtstest.testbuilder.ui.SwingUtil;
import org.locationtech.jtstest.util.io.IOUtil;
import org.locationtech.jtstest.util.io.MultiFormatBufferedReader;
import org.locationtech.jtstest.util.io.MultiFormatFileReader;
import org.locationtech.jtstest.util.io.MultiFormatReader;

/**
Expand Down Expand Up @@ -82,23 +82,43 @@ public class JTSOpRunner {
private boolean isTime;

static class OpParams {
String operation;
static final int OFFSET_DEFAULT = 0;
static final int LIMIT_DEFAULT = -1;

public String fileA;
String geomA;
public int limitA = LIMIT_DEFAULT;
public int offsetA = OFFSET_DEFAULT;

public String fileB;
public String geomB;
public int limitB = LIMIT_DEFAULT;
public int offsetB = OFFSET_DEFAULT;

public boolean isGeomAB = false;
//public String[] arg1;
String format = null;
public Integer repeat;
public boolean eachA = false;
public boolean eachB = false;
public boolean eachAA = false;
public String[] argList;
public boolean validate = false;
public boolean isIndexed = false;
public boolean isExplode = false;
public int srid;

String operation;
public String[] argList;

/**
* Tests whether an input geometry has been supplied.
*
* @param file
* @param geom
* @return true if an input geometry is present
*/
static boolean isGeometryInput(String file, String geom) {
return file != null || geom != null;
}
}

public JTSOpRunner() {
Expand Down Expand Up @@ -144,10 +164,10 @@ void execute(OpParams param) {

loadGeometry();
if (geomA != null) {
printGeometrySummary("A", geomA, param.fileA);
printGeometrySummary("A", geomA, fileInfo(param.fileA, param.limitA, param.offsetA) );
}
if (geomB != null) {
printGeometrySummary("B", geomB, param.fileB);
printGeometrySummary("B", geomB, fileInfo(param.fileB, param.limitB, param.offsetB) );
}

//--- If -each aa specified, use A for B
Expand Down Expand Up @@ -179,16 +199,17 @@ private GeometryFactory createGeometryFactory(int srid) {

private void loadGeometry() {
if (param.isGeomAB) {
//--- limiting is not used for AB reading
loadGeometryAB();
}
else {
geomA = readGeometry("A", param.fileA, param.geomA);
geomB = readGeometry("B", param.fileB, param.geomB);
geomA = readGeometry("A", param.fileA, param.geomA, param.limitA, param.offsetA);
geomB = readGeometry("B", param.fileB, param.geomB, param.limitB, param.offsetB);
}
}

private void loadGeometryAB() {
Geometry geomAB = readGeometry("AB", param.fileA, param.geomA);
Geometry geomAB = readGeometry("AB", param.fileA, param.geomA, OpParams.LIMIT_DEFAULT, OpParams.OFFSET_DEFAULT);
if (geomAB.getNumGeometries() < 2) {
throw new CommandError(ERR_REQUIRED_B);
}
Expand Down Expand Up @@ -351,19 +372,19 @@ private void validate(Object result) {
logError("Result is invalid");
}
}

/**
* Reads a geometry from a literal or a filename.
* If neither are provided this geometry is not present.
*
* @param geomLabel label for geometry being read
* @param filename the filename to read from, if present
* @param geom the geometry literal, if present
* @param filename the filename to read from, if present, or <code>null</code>
* @param geom the geometry literal, if present, or <code>null</code>
* @param geomA2
* @return the geometry read, or null
* @throws Exception
*/
private Geometry readGeometry(String geomLabel, String filename, String geom) {
private Geometry readGeometry(String geomLabel, String filename, String geom, int limit, int offset) {
String geomDesc = " " + geomLabel + " ";
if (geom != null) {
// read a literal from the argument
Expand All @@ -387,7 +408,7 @@ private Geometry readGeometry(String geomLabel, String filename, String geom) {
}

try {
return IOUtil.readFile(filename, geomFactory );
return MultiFormatFileReader.readFile(filename, limit, offset, geomFactory );
}
catch (FileNotFoundException ex) {
throw new CommandError(ERR_FILE_NOT_FOUND, filename);
Expand Down Expand Up @@ -466,6 +487,14 @@ private void printGeometrySummary(String label, Geometry geom, String source) {
printlnInfo( GeometryOutput.writeGeometrySummary(label, geom) + srcname);
}

private static String fileInfo(String filename, int limit, int offset) {
if (filename == null) return null;
String info = filename;
if (limit > OpParams.LIMIT_DEFAULT) info += " LIMIT " + limit;
if (offset > OpParams.OFFSET_DEFAULT) info += " OFFSET " + offset;
return info;
}

private void checkFunctionArgs(GeometryFunction func, Geometry geomB, String[] argList) {
Class[] paramTypes = func.getParameterTypes();
int nParam = paramTypes.length;
Expand Down
Loading