// License: GPL. For details, see LICENSE file.
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.openstreetmap.josm.data.Preferences;
import org.openstreetmap.josm.data.imagery.ImageryInfo;
import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryBounds;
import org.openstreetmap.josm.data.imagery.Shape;
import org.openstreetmap.josm.data.preferences.JosmBaseDirectories;
import org.openstreetmap.josm.data.preferences.JosmUrls;
import org.openstreetmap.josm.data.projection.Projections;
import org.openstreetmap.josm.data.sources.SourceInfo;
import org.openstreetmap.josm.data.validation.routines.DomainValidator;
import org.openstreetmap.josm.io.imagery.ImageryReader;
import org.openstreetmap.josm.spi.preferences.Config;
import org.openstreetmap.josm.tools.ImageProvider;
import org.openstreetmap.josm.tools.JosmRuntimeException;
import org.openstreetmap.josm.tools.Logging;
import org.openstreetmap.josm.tools.OptionParser;
import org.openstreetmap.josm.tools.OptionParser.OptionCount;
import org.openstreetmap.josm.tools.ReflectionUtils;
import org.openstreetmap.josm.tools.Utils;
import org.xml.sax.SAXException;
import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonNumber;
import jakarta.json.JsonObject;
import jakarta.json.JsonReader;
import jakarta.json.JsonString;
import jakarta.json.JsonValue;
/**
* Compare and analyse the differences of the editor layer index and the JOSM imagery list.
* The goal is to keep both lists in sync.
*
* The editor layer index project
* provides also a version in the JOSM format, but the GEOJSON is the original source format, so we read that.
*
* For running, the main JOSM binary needs to be in classpath, e.g.
*
* {@code $ java -cp ../dist/josm-custom.jar SyncEditorLayerIndex}
*
* Add option {@code -h} to show the available command line flags.
*/
@SuppressWarnings("unchecked")
public class SyncEditorLayerIndex {
private static final int MAXLEN = 140;
private List josmEntries;
private JsonArray eliEntries;
private JsonArray idEntries;
private JsonArray rapidEntries;
private final Map eliUrls = new HashMap<>();
private final Map idUrls = new HashMap<>();
private final Map rapidUrls = new HashMap<>();
private final Map josmUrls = new HashMap<>();
private final Map josmMirrors = new HashMap<>();
private static final Map oldproj = new HashMap<>();
private static final List ignoreproj = new LinkedList<>();
private static String eliInputFile = "imagery_eli.geojson";
private static String idInputFile = "imagery_id.geojson";
private static String rapidInputFile = "imagery_rapid.geojson";
private static String josmInputFile = "imagery_josm.imagery.xml";
private static String ignoreInputFile = "imagery_josm.ignores.txt";
private static Writer outputStream;
private static String optionOutput;
private static boolean optionShorten;
private static boolean optionNoSkip;
private static boolean optionXhtmlBody;
private static boolean optionXhtml;
private static String optionEliXml;
private static String optionJosmXml;
private static String optionEncoding;
private static boolean optionNoEli;
private final Map skip = new HashMap<>();
private final Map skipStart = new HashMap<>();
/**
* Main method.
* @param args program arguments
* @throws IOException if any I/O error occurs
* @throws ReflectiveOperationException if any reflective operation error occurs
* @throws SAXException if any SAX error occurs
*/
public static void main(String[] args) throws IOException, SAXException, ReflectiveOperationException {
Locale.setDefault(Locale.ROOT);
parseCommandLineArguments(args);
Config.setUrlsProvider(JosmUrls.getInstance());
Preferences pref = new Preferences(JosmBaseDirectories.getInstance());
Config.setPreferencesInstance(pref);
pref.init(false);
SyncEditorLayerIndex script = new SyncEditorLayerIndex();
script.setupProj();
script.loadSkip();
script.start();
script.loadJosmEntries();
if (optionJosmXml != null) {
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(optionJosmXml), UTF_8)) {
script.printentries(script.josmEntries, writer);
}
}
script.loadELIEntries();
script.loadELIUsers();
if (optionEliXml != null) {
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(optionEliXml), UTF_8)) {
script.printentries(script.eliEntries, writer);
}
}
script.checkInOneButNotTheOther();
script.checkCommonEntries();
script.end();
if (outputStream != null) {
outputStream.close();
}
}
/**
* Displays help on the console
*/
private static void showHelp() {
System.out.println(getHelp());
System.exit(0);
}
static String getHelp() {
return "usage: java -cp build SyncEditorLayerIndex\n" +
"-c,--encoding output encoding (defaults to UTF-8 or cp850 on Windows)\n" +
"-e,--eli_input Input file for the editor layer index (geojson). " +
"Default is imagery_eli.geojson (current directory).\n" +
"-d,--id_input Input file for the id index (geojson). " +
"Default is imagery_id.geojson (current directory).\n" +
"-h,--help show this help\n" +
"-i,--ignore_input Input file for the ignore list. Default is imagery_josm.ignores.txt (current directory).\n" +
"-j,--josm_input Input file for the JOSM imagery list (xml). " +
"Default is imagery_josm.imagery.xml (current directory).\n" +
"-m,--noeli don't show output for ELI, Rapid or iD problems\n" +
"-n,--noskip don't skip known entries\n" +
"-o,--output