This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 7ad7021f800b01581fd523b3ff62eded1e7eb94c Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Wed Nov 29 11:26:54 2023 +0100 Add a "sis-shell" command for launching jshell with Apache SIS libraries. It implies adding a `SIS` static class for easy invocations from JShell. --- .../main/org/apache/sis/console/SIS.java | 754 +++++++++++++++++++++ .../src/org.apache.sis.gui/bundle/bin/sis_shell | 29 + .../org.apache.sis.gui/bundle/bin/sis_shell.bat | 25 + .../src/org.apache.sis.gui/bundle/conf/imports.jsh | 299 ++++++++ 4 files changed, 1107 insertions(+) diff --git a/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/SIS.java b/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/SIS.java new file mode 100644 index 0000000000..2f78e06b7e --- /dev/null +++ b/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/SIS.java @@ -0,0 +1,754 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.console; + +import java.util.EnumMap; +import java.io.PrintWriter; +import org.apache.sis.io.wkt.Colors; +import org.apache.sis.util.Static; +import org.apache.sis.util.CharSequences; +import org.apache.sis.util.resources.Errors; +import org.apache.sis.util.internal.X364; +import org.apache.sis.io.wkt.FormattableObject; +import org.apache.sis.io.wkt.WKTFormat; + + +/** + * Entry point for {@code SIS} commands from JShell. + * This class provides the same commands than the {@code SIS} shell script, but from Java code. + * Each method accepts an arbitrary number of arguments of type {@link Object}. + * The actual argument values should be instances of {@link String}, + * but the arguments that are input or output files can also be instances of + * {@link java.io.File}, {@link java.nio.file.Path}, {@link java.net.URL}, {@link java.net.URI} + * or any other type recognized by {@link org.apache.sis.storage.StorageConnector}. + * + * <p>This class should not be used in Java applications. + * This class is provided for usage in JShell environment.</p> + * + * @author Martin Desruisseaux (Geomatys) + * @version 1.5 + * @since 1.5 + */ +public final class SIS extends Static { + /* + * Usages of `Console#writer()` within JShell seems incompatible with JShell own writer. + * Problems observed with Java 21 on Linux when printing non-ASCII characters. + */ + static { + CommandRunner.avoidConsoleWriter(); + } + + /** + * Builder for calls to the SIS command-line. Each sub-command is represented by a subclasses of {@code Builder}. + * A unique instance for each command is provided as fields in {@link SIS}, and that instance is cloned when the + * user wants to add options. + * + * @param <C> the sub-class for the command builder. + */ + private static abstract class Builder<C extends Builder<C>> implements Cloneable { + /** + * Name of the sub-command. Shall be one of the names recognized by {@link Command}. + */ + private final String command; + + /** + * The options added by the user, or {@code null} if this instance is a field of the {@link SIS} class. + * In the latter case, this builder shall be considered immutable and options shall be added in a clone. + */ + private EnumMap<Option,Object> options; + + /** + * Creates a new builder for an immutable instance to be assigned to a {@code SIS} field. + * + * @param command name of the sub-command. Shall be one of the names recognized by {@link Command}. + */ + Builder(final String command) { + this.command = command; + } + + /** + * Sets the value of an option. + * + * @param key the option. + * @param value value for the specified option. + * @return the builder on which to perform chained method calls. + */ + @SuppressWarnings({"unchecked", "null"}) + final C set(final Option key, Object value) { + if (key.hasValue && (value = trim(value)) == null) { + final String option = key.label(); + throw new IllegalArgumentException(Errors.format(Errors.Keys.MissingValueForOption_1, option)); + } + Builder<C> target = this; + if (options == null) try { + target = (Builder<C>) clone(); + target.options = new EnumMap<>(Option.class); + } catch (CloneNotSupportedException e) { + throw new AssertionError(e); + } + target.options.put(key, value); + return (C) target; + } + + /** + * If the given value is a character string, trims it and returns either a non-empty string or null. + * Otherwise returns the value unchanged. + */ + private static Object trim(final Object value) { + if (value instanceof CharSequence) { + final String s = value.toString().trim(); + return s.isBlank() ? null : s; + } + return value; + } + + /** + * Prints full stack trace in case of failure. + * + * @return a new builder or {@code this}, for method call chaining. + */ + public C debug() { + return set(Option.DEBUG, null); + } + + /** + * Lists the options available for the sub-command. + * + * @return a new builder or {@code this}, for method call chaining. + */ + public C help() { + return set(Option.HELP, null); + } + + /** + * Executes the command with the given arguments. The arguments are usually {@link String} instances, + * but may also be instances of {@link java.io.File}, {@link java.nio.file.Path}, {@link java.net.URL}, + * {@link java.net.URI} or other types accepted by {@link org.apache.sis.storage.StorageConnector} if + * the corresponding argument specifies an input or output. + * + * @param name name of the sub-command to execute. + * @param args the arguments to pass to the sub-command. + * @throws Exception if an error occurred while executing the command. + */ + @SuppressWarnings("UseOfSystemOutOrSystemErr") + public void run(final Object... args) throws Exception { + /* + * Count the number of arguments to insert at the beginning, + * including the argument for the sub-command name. + */ + int i = 1; + if (options != null) { + for (Option key : options.keySet()) { + i += (key.hasValue ? 2 : 1); + } + } + /* + * Copy the sub-command name, the options, then the arguments specified to this method. + */ + final var allArgs = new Object[args.length + i]; + i = 0; + allArgs[i++] = command; + if (options != null) { + for (final EnumMap.Entry<Option,Object> entry : options.entrySet()) { + final Option key = entry.getKey(); + allArgs[i++] = Option.PREFIX.concat(key.label()); + if (key.hasValue) { + allArgs[i++] = entry.getValue(); + } + } + } + System.arraycopy(args, 0, allArgs, i, args.length); + /* + * Prints an echo of the command to execute, then execute. + * The operation may fail without throwing an exception. + */ + var c = new Command(allArgs); + final PrintWriter out = c.writer(false); + out.print("> sis"); + for (i=0; i < allArgs.length; i++) { + final String arg = allArgs[i].toString(); + final int start = arg.startsWith(Option.PREFIX) ? Option.PREFIX.length() : 0; + final boolean quote = !CharSequences.isUnicodeIdentifier(arg.substring(start)); + out.print(' '); + if (quote) out.print('"'); + out.print(arg.replace("\"", "\\\"")); + if (quote) out.print('"'); + } + out.println(); + int status = c.run(); + if (status != 0) { + c.writer(true).println("Error code " + status); + } + } + + /** + * {@return the command with all options that have been set}. + */ + @Override + public String toString() { + if (options == null) return command; + final var sb = new StringBuilder(command); + options.forEach((key, value) -> sb.append(' ').append(Option.PREFIX).append(key.label()).append(' ').append(value)); + return sb.toString(); + } + } + + /** + * Do not allow instantiation of this class. + */ + private SIS() { + } + + + + + /** + * Shows a help overview. + * This sub-command prints the same text than when {@code SIS} is invoked on the command-line without arguments. + * Usage example: + * + * {@snippet lang="java" : + * SIS.HELP.run(); + * } + */ + public static final Help HELP = new Help(); + + /** + * Builder for the "help" sub-command. This builder provides convenience methods + * for setting options before to execute the command by a call to {@link #run(Object...)}. + * + * @see #HELP + */ + public static final class Help extends Builder<Help> { + /** Creates the unique instance. */ + Help() {super("help");} + + /** + * Sets the locale to use for the command output. + * + * @param value the language and country code. + * @return a new builder or {@code this}, for method call chaining. + */ + public Help locale(String value) { + return set(Option.LOCALE, value); + } + + /** + * Sets encoding to use for the command outputs. + * This option rarely needs to be specified. + * + * @param value the character set name. + * @return a new builder or {@code this}, for method call chaining. + */ + public Help encoding(String value) { + return set(Option.ENCODING, value); + } + } + + + + + /** + * Shows information about Apache SIS and system configuration. + * By default this sub-command prints all information except the section about dependencies. + * Some available options are: + * + * <ul> + * <li>{@code --brief}: prints only Apache SIS version number.</li> + * <li>{@code --verbose}: prints all information including the libraries.</li> + * </ul> + * + * Usage example: + * + * {@snippet lang="java" : + * SIS.ABOUT.verbose().run(); + * } + */ + public static final About ABOUT = new About(); + + /** + * Builder for the "about" sub-command. This builder provides convenience methods + * for setting options before to execute the command by a call to {@link #run(Object...)}. + * + * @see #ABOUT + */ + public static final class About extends Builder<About> { + /** Creates the unique instance. */ + About() {super("about");} + + /** + * Sets the locale to use for the command output. + * + * @param value the language and country code. + * @return a new builder or {@code this}, for method call chaining. + */ + public About locale(String value) { + return set(Option.LOCALE, value); + } + + /** + * Sets the timezone for the dates to be formatted. + * + * @param value the time zone identifier. + * @return a new builder or {@code this}, for method call chaining. + */ + public About timezone(String value) { + return set(Option.TIMEZONE, value); + } + + /** + * Sets encoding to use for the command outputs. + * This option rarely needs to be specified. + * + * @param value the character set name. + * @return a new builder or {@code this}, for method call chaining. + */ + public About encoding(String value) { + return set(Option.ENCODING, value); + } + + /** + * Reduces the output to only brief information. + * + * @return a new builder or {@code this}, for method call chaining. + */ + public About brief() { + return set(Option.BRIEF, null); + } + + /** + * Requests the output to contain more detailed information. + * + * @return a new builder or {@code this}, for method call chaining. + */ + public About verbose() { + return set(Option.VERBOSE, null); + } + } + + + + + /** + * Shows MIME type for the given file. + * This sub-command reproduces the functionality of the following Unix command, + * except that {@code MimeTypeCommand} uses the SIS detection mechanism instead of the OS one. + * + * {@snippet lang="shell" : + * file --mime-type <files> + * } + * + * Arguments other than options are files, usually as character strings but can also be + * {@link java.io.File}, {@link java.nio.file.Path} or {@link java.net.URL} for example. + * Usage example: + * + * {@snippet lang="java" : + * SIS.MIME_TYPE.run("data.xml"); + * } + */ + public static final MimeType MIME_TYPE = new MimeType(); + + /** + * Builder for the "mime-type" sub-command. This builder provides convenience methods + * for setting options before to execute the command by a call to {@link #run(Object...)}. + * + * @see #MIME_TYPE + */ + public static final class MimeType extends Builder<MimeType> { + /** Creates the unique instance. */ + MimeType() {super("mime-type");} + + /** + * Sets encoding to use for the command outputs. + * This option rarely needs to be specified. + * + * @param value the character set name. + * @return a new builder or {@code this}, for method call chaining. + */ + public MimeType encoding(String value) { + return set(Option.ENCODING, value); + } + } + + /** + * Shows ISO 19115 metadata information for the given file. + * Some available options are: + * + * <ul> + * <li>{@code --format}: the output format (text, XML or GPX).</li> + * </ul> + * + * Arguments other than options are files, usually as character strings but can also be + * {@link java.io.File}, {@link java.nio.file.Path} or {@link java.net.URL} for example. + * Usage example: + * + * {@snippet lang="java" : + * SIS.METADATA.format("xml").run("data.xml"); + * } + */ + public static final Metadata METADATA = new Metadata("metadata"); + + /** + * Shows Coordinate Reference System (CRS) information for the given file. + * CRS are considered as a kind of metadata. + * Some available options are: + * + * <ul> + * <li>{@code --format}: the output format (WKT or XML).</li> + * </ul> + * + * Arguments other than options are files, usually as character strings but can also be + * {@link java.io.File}, {@link java.nio.file.Path} or {@link java.net.URL} for example. + * Usage example: + * + * {@snippet lang="java" : + * SIS.CRS.format("wkt").run("data.xml"); + * } + */ + public static final Metadata CRS = new Metadata("crs"); + + /** + * Builder for the "metadata" and "crs" sub-commands. This builder provides convenience methods + * for setting options before to execute the command by a call to {@link #run(Object...)}. + * + * @see #METADATA + * @see #CRS + */ + public static final class Metadata extends Builder<Metadata> { + /** Creates the instance for metadata or CRS. */ + Metadata(String command) {super(command);} + + /** + * Sets the output format. + * + * @param value the format. Examples: xml, wkt, wkt1 or text. + * @return a new builder or {@code this}, for method call chaining. + */ + public Metadata format(String value) { + return set(Option.FORMAT, value); + } + + /** + * Sets the locale to use for the command output. + * + * @param value the language and country code. + * @return a new builder or {@code this}, for method call chaining. + */ + public Metadata locale(String value) { + return set(Option.LOCALE, value); + } + + /** + * Sets the timezone for the dates to be formatted. + * + * @param value the time zone identifier. + * @return a new builder or {@code this}, for method call chaining. + */ + public Metadata timezone(String value) { + return set(Option.TIMEZONE, value); + } + + /** + * Sets encoding to use for the command outputs. + * This option rarely needs to be specified. + * + * @param value the character set name. + * @return a new builder or {@code this}, for method call chaining. + */ + public Metadata encoding(String value) { + return set(Option.ENCODING, value); + } + + /** + * Sets whether colorized output shall be enabled. + * + * @param enabled whether colors are enabled. + * @return a new builder or {@code this}, for method call chaining. + */ + public Metadata colors(boolean enabled) { + return set(Option.COLORS, enabled); + } + + /** + * Requests the output to contain more detailed information. + * + * @return a new builder or {@code this}, for method call chaining. + */ + public Metadata verbose() { + return set(Option.VERBOSE, null); + } + } + + + + + /** + * Shows identifiers for metadata and referencing systems in the given file. + * Arguments other than options are files, usually as character strings but can also be + * {@link java.io.File}, {@link java.nio.file.Path} or {@link java.net.URL} for example. + * Usage example: + * + * {@snippet lang="java" : + * SIS.IDENTIFIER.run("data.xml"); + * } + */ + public static final Identifier IDENTIFIER = new Identifier(); + + /** + * Builder for the "identifier" sub-command. This builder provides convenience methods + * for setting options before to execute the command by a call to {@link #run(Object...)}. + * + * @see #IDENTIFIER + */ + public static final class Identifier extends Builder<Identifier> { + /** Creates the unique instance. */ + Identifier() {super("identifier");} + + /** + * Sets the locale to use for the command output. + * + * @param value the language and country code. + * @return a new builder or {@code this}, for method call chaining. + */ + public Identifier locale(String value) { + return set(Option.LOCALE, value); + } + + /** + * Sets encoding to use for the command outputs. + * This option rarely needs to be specified. + * + * @param value the character set name. + * @return a new builder or {@code this}, for method call chaining. + */ + public Identifier encoding(String value) { + return set(Option.ENCODING, value); + } + + /** + * Sets whether colorized output shall be enabled. + * + * @param enabled whether colors are enabled. + * @return a new builder or {@code this}, for method call chaining. + */ + public Identifier colors(boolean enabled) { + return set(Option.COLORS, enabled); + } + + /** + * Requests the output to contain more detailed information. + * + * @return a new builder or {@code this}, for method call chaining. + */ + public Identifier verbose() { + return set(Option.VERBOSE, null); + } + } + + + + + /** + * Converts or transform coordinates from given source CRS to target CRS. + * The output uses comma separated values (CSV) format, + * with {@code '#'} as the first character of comment lines. + * The source and target CRS are mandatory and can be specified + * as EPSG codes, WKT strings, or metadata read from data files. + * Those information are passed as options: + * + * <ul> + * <li>{@code --sourceCRS}: the coordinate reference system of input points.</li> + * <li>{@code --targetCRS}: the coordinate reference system of output points.</li> + * </ul> + * + * Arguments other than options are files, usually as character strings but can also be + * {@link java.io.File}, {@link java.nio.file.Path} or {@link java.net.URL} for example. + * Usage example: + * + * {@snippet lang="java" : + * SIS.TRANSFORM.sourceCRS("EPSG:3395").targetCRS("EPSG:4326").run("data.txt"); + * } + */ + public static final Transform TRANSFORM = new Transform(); + + /** + * Builder for the "transform" sub-command. This builder provides convenience methods + * for setting options before to execute the command by a call to {@link #run(Object...)}. + * + * @see #TRANSFORM + */ + public static final class Transform extends Builder<Transform> { + /** Creates the unique instance. */ + Transform() {super("transform");} + + /** + * Sets Coordinate Reference System of input data. + * + * @param value the EPSG code, WKT or file from which to get the CRS. + * @return a new builder or {@code this}, for method call chaining. + */ + public Transform sourceCRS(Object value) { + return set(Option.SOURCE_CRS, value); + } + + /** + * Sets Coordinate Reference System of output data. + * + * @param value the EPSG code, WKT or file from which to get the CRS. + * @return a new builder or {@code this}, for method call chaining. + */ + public Transform targetCRS(Object value) { + return set(Option.TARGET_CRS, value); + } + + /** + * Sets the locale to use for the command output. + * + * @param value the language and country code. + * @return a new builder or {@code this}, for method call chaining. + */ + public Transform locale(String value) { + return set(Option.LOCALE, value); + } + + /** + * Sets the timezone for the dates to be formatted. + * + * @param value the time zone identifier. + * @return a new builder or {@code this}, for method call chaining. + */ + public Transform timezone(String value) { + return set(Option.TIMEZONE, value); + } + + /** + * Sets encoding to use for the command outputs. + * This option rarely needs to be specified. + * + * @param value the character set name. + * @return a new builder or {@code this}, for method call chaining. + */ + public Transform encoding(String value) { + return set(Option.ENCODING, value); + } + + /** + * Sets whether colorized output shall be enabled. + * + * @param enabled whether colors are enabled. + * @return a new builder or {@code this}, for method call chaining. + */ + public Transform colors(boolean enabled) { + return set(Option.COLORS, enabled); + } + + /** + * Requests the output to contain more detailed information. + * + * @return a new builder or {@code this}, for method call chaining. + */ + public Transform verbose() { + return set(Option.VERBOSE, null); + } + } + + + + + /** + * Rewrites a data file in another format. + * If more than one source file is specified, then all those files are aggregated in the output file. + * This is possible only if the output format supports the storage of an arbitrary number of resources. + * Some options are: + * + * <ul> + * <li>{@code --output}: the file where to write the image.</li> + * </ul> + * + * Arguments are usually character strings but can also be + * {@link java.io.File}, {@link java.nio.file.Path} or {@link java.net.URL} for example. + * Usage example: + * + * {@snippet lang="java" : + * SIS.TRANSLATE.output("data.tiff").run("data.png"); + * } + */ + public static final Translate TRANSLATE = new Translate(); + + /** + * Builder for the "translate" sub-command. This builder provides convenience methods + * for setting options before to execute the command by a call to {@link #run(Object...)}. + * + * @see #TRANSLATE + */ + public static final class Translate extends Builder<Translate> { + /** Creates the unique instance. */ + Translate() {super("translate");} + + /** + * Sets the destination file. + * + * @param value the output file. + * @return a new builder or {@code this}, for method call chaining. + */ + public Translate output(Object value) { + return set(Option.OUTPUT, value); + } + + /** + * Sets the output format. + * + * @param value the format. Examples: xml, wkt, wkt1 or text. + * @return a new builder or {@code this}, for method call chaining. + */ + public Translate format(String value) { + return set(Option.FORMAT, value); + } + } + + + + + /** + * The object to use for formatting WKT objects, created when first needed. + */ + private static WKTFormat wktFormat; + + /** + * Prints the given object to the standard output stream. + * + * @param value the object to print. + */ + @SuppressWarnings("UseOfSystemOutOrSystemErr") + public static void print(final Object value) { + final PrintWriter out = CommandRunner.writer(System.console(), System.out); + if (value instanceof FormattableObject) { + synchronized (SIS.class) { + if (wktFormat == null) { + wktFormat = new WKTFormat(null, null); + if (X364.isAnsiSupported()) { + wktFormat.setColors(Colors.DEFAULT); + } + } + out.print(wktFormat.format(value)); + } + } else { + out.println(value); + } + out.flush(); + } +} diff --git a/optional/src/org.apache.sis.gui/bundle/bin/sis_shell b/optional/src/org.apache.sis.gui/bundle/bin/sis_shell new file mode 100755 index 0000000000..4559adf68f --- /dev/null +++ b/optional/src/org.apache.sis.gui/bundle/bin/sis_shell @@ -0,0 +1,29 @@ +#!/bin/sh +# ------------------------------------------------------------------------ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to you under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ------------------------------------------------------------------------ + +set -o errexit + +SIS_HOME="`dirname "$( readlink -e "$0"; )";`/.." +SIS_DATA="${SIS_DATA:-$SIS_HOME/data}" +export SIS_DATA +export SIS_HOME + +jshell --module-path "$SIS_HOME/lib:$SIS_HOME/lib/app/org.apache.sis.console.jar" \ + --add-module org.apache.sis.console \ + --startup "$SIS_HOME/conf/imports.jsh" \ + "$@" diff --git a/optional/src/org.apache.sis.gui/bundle/bin/sis_shell.bat b/optional/src/org.apache.sis.gui/bundle/bin/sis_shell.bat new file mode 100644 index 0000000000..5e526285c4 --- /dev/null +++ b/optional/src/org.apache.sis.gui/bundle/bin/sis_shell.bat @@ -0,0 +1,25 @@ +@echo off + +REM Licensed to the Apache Software Foundation (ASF) under one or more +REM contributor license agreements. See the NOTICE file distributed with +REM this work for additional information regarding copyright ownership. +REM The ASF licenses this file to you under the Apache License, Version 2.0 +REM (the "License"); you may not use this file except in compliance with the +REM License. You may obtain a copy of the License at +REM +REM http://www.apache.org/licenses/LICENSE-2.0 +REM +REM Unless required by applicable law or agreed to in writing, software +REM distributed under the License is distributed on an "AS IS" BASIS, +REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +REM See the License for the specific language governing permissions and +REM limitations under the License. + + +SET SIS_HOME=%~dp0\.. +SET SIS_DATA=%SIS_HOME%\data + +jshell --module-path "%SIS_HOME%\lib;%SIS_HOME%\lib\app\org.apache.sis.console.jar"^ + --add-module org.apache.sis.console^ + --startup "%SIS_HOME%\conf\imports.jsh"^ + %* diff --git a/optional/src/org.apache.sis.gui/bundle/conf/imports.jsh b/optional/src/org.apache.sis.gui/bundle/conf/imports.jsh new file mode 100644 index 0000000000..ddf130cb4b --- /dev/null +++ b/optional/src/org.apache.sis.gui/bundle/conf/imports.jsh @@ -0,0 +1,299 @@ +// Only math functions working on floating point numbers. +import static java.lang.Math.E; +import static java.lang.Math.PI; +import static java.lang.Math.abs; +import static java.lang.Math.acos; +import static java.lang.Math.asin; +import static java.lang.Math.atan; +import static java.lang.Math.atan2; +import static java.lang.Math.cbrt; +import static java.lang.Math.ceil; +import static java.lang.Math.copySign; +import static java.lang.Math.cos; +import static java.lang.Math.cosh; +import static java.lang.Math.exp; +import static java.lang.Math.expm1; +import static java.lang.Math.floor; +import static java.lang.Math.fma; +import static java.lang.Math.hypot; +import static java.lang.Math.log; +import static java.lang.Math.log10; +import static java.lang.Math.log1p; +import static java.lang.Math.max; +import static java.lang.Math.min; +import static java.lang.Math.nextAfter; +import static java.lang.Math.nextDown; +import static java.lang.Math.nextUp; +import static java.lang.Math.rint; +import static java.lang.Math.round; +import static java.lang.Math.scalb; +import static java.lang.Math.signum; +import static java.lang.Math.sin; +import static java.lang.Math.sinh; +import static java.lang.Math.sqrt; +import static java.lang.Math.tan; +import static java.lang.Math.tanh; +import static java.lang.Math.toDegrees; +import static java.lang.Math.toRadians; +import static java.lang.Math.ulp; + +// Arbitrary precision arithmetic. +import java.math.*; + +// Main I/O objects. +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.CharArrayReader; +import java.io.CharArrayWriter; +import java.io.Closeable; +import java.io.DataInput; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.Flushable; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.nio.file.AccessMode; +import java.nio.file.CopyOption; +import java.nio.file.DirectoryStream; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.FileStore; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitOption; +import java.nio.file.FileVisitor; +import java.nio.file.FileVisitResult; +import java.nio.file.InvalidPathException; +import java.nio.file.LinkOption; +import java.nio.file.LinkPermission; +import java.nio.file.NoSuchFileException; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; +import java.nio.file.StandardOpenOption; +import java.net.URL; +import java.net.URI; + +// Most interesting utilities, excluding calendar. +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Collections; +import java.util.Comparator; +import java.util.Currency; +import java.util.Date; +import java.util.Deque; +import java.util.DoubleSummaryStatistics; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.IdentityHashMap; +import java.util.IntSummaryStatistics; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Locale; +import java.util.LongSummaryStatistics; +import java.util.Map; +import java.util.NavigableMap; +import java.util.NavigableSet; +import java.util.Objects; +import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; +import java.util.OptionalLong; +import java.util.PrimitiveIterator; +import java.util.PriorityQueue; +import java.util.Properties; +import java.util.Queue; +import java.util.Random; +import java.util.Scanner; +import java.util.Set; +import java.util.SortedMap; +import java.util.SortedSet; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.StringJoiner; +import java.util.TimeZone; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.UUID; +import java.util.WeakHashMap; +import java.util.regex.*; +import java.util.stream.*; +import java.util.function.*; + +// Time objects preferred to calendar. +import java.time.DayOfWeek; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Month; +import java.time.MonthDay; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.Period; +import java.time.Year; +import java.time.YearMonth; +import java.time.ZonedDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; + +// Unit of measurement. +import javax.measure.Quantity; +import javax.measure.Unit; +import javax.measure.UnitConverter; + +// GeoAPI main objects. +import org.opengis.util.CodeList +import org.opengis.util.FactoryException +import org.opengis.util.GenericName +import org.opengis.util.InternationalString +import org.opengis.metadata.Identifier; +import org.opengis.metadata.Metadata; +import org.opengis.metadata.citation.Citation; +import org.opengis.metadata.extent.GeographicBoundingBox; +import org.opengis.metadata.extent.GeographicDescription; +import org.opengis.metadata.extent.GeographicExtent; +import org.opengis.metadata.extent.SpatialTemporalExtent; +import org.opengis.metadata.extent.TemporalExtent; +import org.opengis.metadata.extent.VerticalExtent; +import org.opengis.metadata.identification.DataIdentification; +import org.opengis.metadata.identification.Identification; +import org.opengis.metadata.quality.DataQuality; +import org.opengis.metadata.quality.PositionalAccuracy; +import org.opengis.parameter.GeneralParameterDescriptor; +import org.opengis.parameter.GeneralParameterValue; +import org.opengis.parameter.ParameterDescriptor; +import org.opengis.parameter.ParameterValue; +import org.opengis.geometry.DirectPosition; +import org.opengis.geometry.Envelope; +import org.opengis.referencing.crs.CompoundCRS; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.crs.DerivedCRS; +import org.opengis.referencing.crs.GeodeticCRS; +import org.opengis.referencing.crs.EngineeringCRS; +import org.opengis.referencing.crs.GeneralDerivedCRS; +import org.opengis.referencing.crs.GeographicCRS; +import org.opengis.referencing.crs.ProjectedCRS; +import org.opengis.referencing.crs.SingleCRS; +import org.opengis.referencing.crs.TemporalCRS; +import org.opengis.referencing.crs.VerticalCRS; +import org.opengis.referencing.cs.AxisDirection; +import org.opengis.referencing.cs.CoordinateSystem; +import org.opengis.referencing.cs.CoordinateSystemAxis; +import org.opengis.referencing.cs.RangeMeaning; +import org.opengis.referencing.datum.Datum; +import org.opengis.referencing.datum.Ellipsoid; +import org.opengis.referencing.datum.GeodeticDatum; +import org.opengis.referencing.datum.PixelInCell; +import org.opengis.referencing.datum.PrimeMeridian; +import org.opengis.referencing.operation.ConcatenatedOperation; +import org.opengis.referencing.operation.CoordinateOperation; +import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.MathTransform1D; +import org.opengis.referencing.operation.MathTransform2D; +import org.opengis.referencing.operation.Matrix; +import org.opengis.referencing.operation.OperationMethod; +import org.opengis.referencing.operation.SingleOperation; +import org.opengis.referencing.operation.TransformException; + +// Apache SIS. +import org.apache.sis.math.Fraction; +import org.apache.sis.measure.Angle; +import org.apache.sis.measure.Latitude; +import org.apache.sis.measure.Longitude; +import org.apache.sis.measure.MeasurementRange; +import org.apache.sis.measure.NumberRange; +import org.apache.sis.measure.Quantities; +import org.apache.sis.measure.Range; +import org.apache.sis.measure.Units; +import org.apache.sis.util.collection.TableColumn; +import org.apache.sis.util.collection.TreeTable; +import org.apache.sis.util.iso.Names; +import org.apache.sis.xml.NilObject; +import org.apache.sis.xml.NilReason; +import org.apache.sis.xml.XML; +import org.apache.sis.geometry.GeneralDirectPosition; +import org.apache.sis.geometry.GeneralEnvelope; +import org.apache.sis.geometry.Envelopes; +import org.apache.sis.referencing.CommonCRS; +import org.apache.sis.referencing.CRS; +import org.apache.sis.referencing.GeodeticCalculator; +import org.apache.sis.referencing.IdentifiedObjects; +import org.apache.sis.referencing.crs.AbstractCRS; +import org.apache.sis.referencing.cs.AxesConvention; +import org.apache.sis.referencing.operation.matrix.Matrices; +import org.apache.sis.referencing.operation.transform.MathTransforms; +import org.apache.sis.feature.builder.AssociationRoleBuilder; +import org.apache.sis.feature.builder.AttributeRole; +import org.apache.sis.feature.builder.AttributeTypeBuilder; +import org.apache.sis.feature.builder.CharacteristicTypeBuilder; +import org.apache.sis.feature.builder.FeatureTypeBuilder; +import org.apache.sis.feature.builder.PropertyTypeBuilder; +import org.apache.sis.feature.builder.TypeBuilder; +import org.apache.sis.filter.DefaultFilterFactory; +import org.apache.sis.coverage.BandedCoverage; +import org.apache.sis.coverage.Category; +import org.apache.sis.coverage.CoverageCombiner; +import org.apache.sis.coverage.RegionOfInterest; +import org.apache.sis.coverage.SampleDimension; +import org.apache.sis.coverage.grid.GridClippingMode; +import org.apache.sis.coverage.grid.GridCoverage; +import org.apache.sis.coverage.grid.GridCoverage2D; +import org.apache.sis.coverage.grid.GridCoverageBuilder; +import org.apache.sis.coverage.grid.GridCoverageProcessor; +import org.apache.sis.coverage.grid.GridExtent; +import org.apache.sis.coverage.grid.GridGeometry; +import org.apache.sis.coverage.grid.GridOrientation; +import org.apache.sis.coverage.grid.GridRoundingMode; +import org.apache.sis.storage.Aggregate; +import org.apache.sis.storage.CoverageQuery; +import org.apache.sis.storage.DataSet; +import org.apache.sis.storage.DataStore; +import org.apache.sis.storage.DataStores; +import org.apache.sis.storage.FeatureQuery; +import org.apache.sis.storage.FeatureSet; +import org.apache.sis.storage.GridCoverageResource; +import org.apache.sis.storage.Query; +import org.apache.sis.storage.RasterLoadingStrategy; +import org.apache.sis.storage.Resource; +import org.apache.sis.storage.StorageConnector; +import org.apache.sis.storage.WritableAggregate; +import org.apache.sis.storage.WritableFeatureSet; +import org.apache.sis.storage.WritableGridCoverageResource; +import org.apache.sis.console.SIS; +import static org.apache.sis.console.SIS.print; + +// Initialization +org.apache.sis.console.Command.configureLogging()