// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.opendata.core.datasets; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.regex.Pattern; import javax.swing.ImageIcon; import org.openstreetmap.josm.actions.JosmAction; import org.openstreetmap.josm.data.Bounds; import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.data.osm.IPrimitive; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.gui.preferences.SourceEditor.ExtendedSourceEntry; import org.openstreetmap.josm.io.AbstractReader; import org.openstreetmap.josm.plugins.opendata.core.OdConstants; import org.openstreetmap.josm.plugins.opendata.core.io.archive.ArchiveHandler; import org.openstreetmap.josm.plugins.opendata.core.io.archive.DefaultArchiveHandler; import org.openstreetmap.josm.plugins.opendata.core.io.geographic.DefaultGmlHandler; import org.openstreetmap.josm.plugins.opendata.core.io.geographic.DefaultShpHandler; import org.openstreetmap.josm.plugins.opendata.core.io.geographic.GmlHandler; import org.openstreetmap.josm.plugins.opendata.core.io.geographic.MifHandler; import org.openstreetmap.josm.plugins.opendata.core.io.geographic.ShpHandler; import org.openstreetmap.josm.plugins.opendata.core.io.tabular.CsvHandler; import org.openstreetmap.josm.plugins.opendata.core.io.tabular.DefaultCsvHandler; import org.openstreetmap.josm.plugins.opendata.core.io.tabular.SpreadSheetHandler; import org.openstreetmap.josm.plugins.opendata.core.licenses.License; import org.openstreetmap.josm.plugins.opendata.core.util.NamesFrUtils; import org.openstreetmap.josm.plugins.opendata.core.util.OdUtils; import org.openstreetmap.josm.tools.Pair; public abstract class AbstractDataSetHandler { public abstract boolean acceptsFilename(String filename); public boolean acceptsFile(File file) { return acceptsFilename(file.getName()); } public abstract void updateDataSet(DataSet ds); public void checkDataSetSource(DataSet ds) { if (ds != null) { for (OsmPrimitive p : ds.allPrimitives()) { if (p.hasKeys() || p.getReferrers().isEmpty()) { if (getSource() != null && p.get("source") == null) { p.put("source", getSource()); } if (sourceDate != null && p.get("source:date") == null) { p.put("source:date", sourceDate); } } } } } public void checkNames(DataSet ds) { if (ds != null) { for (OsmPrimitive p : ds.allPrimitives()) { if (p.get("name") != null) { p.put("name", NamesFrUtils.checkDictionary(p.get("name"))); } } } } private String name; private DataSetCategory category; private String sourceDate; private File associatedFile; private ImageIcon menuIcon; public AbstractDataSetHandler() { setShpHandler(new DefaultShpHandler()); setArchiveHandler(new DefaultArchiveHandler()); setCsvHandler(new DefaultCsvHandler()); setGmlHandler(new DefaultGmlHandler()); } private boolean acceptsFilename(String filename, String[] expected, String ... extensions) { if (filename != null) { for (String name : expected) { for (String ext : extensions) { if (Pattern.compile(name+"\\."+ext, Pattern.CASE_INSENSITIVE).matcher(filename).matches()) { //if (filename.equalsIgnoreCase(name+"."+ext)) { return true; } } } } return false; } protected final boolean acceptsCsvFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.CSV_EXT); } protected final boolean acceptsXlsFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.XLS_EXT); } protected final boolean acceptsOdsFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.ODS_EXT); } protected final boolean acceptsShpFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.SHP_EXT); } protected final boolean acceptsMifFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.MIF_EXT); } protected final boolean acceptsMifTabFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.MIF_EXT, OdConstants.TAB_EXT); } protected final boolean acceptsShpMifFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.SHP_EXT, OdConstants.MIF_EXT); } protected final boolean acceptsKmlFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.KML_EXT); } protected final boolean acceptsKmzFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.KMZ_EXT); } protected final boolean acceptsKmzShpFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.KMZ_EXT, OdConstants.SHP_EXT); } protected final boolean acceptsKmzTabFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.KMZ_EXT, OdConstants.TAB_EXT); } protected final boolean acceptsZipFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.ZIP_EXT); } protected final boolean accepts7ZipFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.SEVENZIP_EXT); } protected final boolean acceptsCsvKmzFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.CSV_EXT, OdConstants.KMZ_EXT); } protected final boolean acceptsCsvKmzTabFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.CSV_EXT, OdConstants.KMZ_EXT, OdConstants.TAB_EXT); } protected final boolean acceptsCsvXlsFilename(String filename, String ... expected) { return acceptsFilename(filename, expected, OdConstants.CSV_EXT, OdConstants.XLS_EXT); } // -------------------- License -------------------- private License license; public License getLicense() { return license; } public final void setLicense(License license) { this.license = license; } // --------------------- URLs --------------------- private URL dataURL; private URL wikiURL; private URL localPortalURL; private URL nationalPortalURL; public URL getDataURL() { return dataURL; } public final void setDataURL(URL dataURL) { this.dataURL = dataURL; } public final void setDataURL(String dataURL) throws MalformedURLException { setDataURL(new URL(dataURL)); } public URL getWikiURL() { return wikiURL; } public final void setWikiURL(URL wikiURL) { this.wikiURL = wikiURL; } public final void setWikiURL(String wikiURL) throws MalformedURLException { setWikiURL(new URL(wikiURL)); } public URL getLocalPortalURL() { return localPortalURL; } public final void setLocalPortalURL(URL localPortalURL) { this.localPortalURL = localPortalURL; } public final void setLocalPortalURL(String localPortalURL) throws MalformedURLException { setLocalPortalURL(new URL(localPortalURL)); } public URL getNationalPortalURL() { return nationalPortalURL; } public final void setNationalPortalURL(URL nationalPortalURL) { this.nationalPortalURL = nationalPortalURL; } public final void setNationalPortalURL(String nationalPortalURL) throws MalformedURLException { setNationalPortalURL(new URL(nationalPortalURL)); } public List<Pair<String, URL>> getDataURLs() { return null; } public AbstractReader getReaderForUrl(String url) { return null; } private boolean hasLicenseToBeAccepted = true; public final boolean hasLicenseToBeAccepted() { return hasLicenseToBeAccepted; } public final void setHasLicenseToBeAccepted(boolean hasLicenseToBeAccepted) { this.hasLicenseToBeAccepted = hasLicenseToBeAccepted; } public final DataSetCategory getCategory() { return category; } public final void setCategory(DataSetCategory category) { this.category = category; } public final Collection<String> getOsmXapiRequests(Bounds bounds) { return getOsmXapiRequests(LatLon.roundToOsmPrecision(bounds.getMin().lon())+","+ LatLon.roundToOsmPrecision(bounds.getMin().lat())+","+ LatLon.roundToOsmPrecision(bounds.getMax().lon())+","+ LatLon.roundToOsmPrecision(bounds.getMax().lat())); } protected Collection<String> getOsmXapiRequests(String bbox) { return null; } public final String getOverpassApiRequest(Bounds bounds) { return getOverpassApiRequest("w=\""+LatLon.roundToOsmPrecision(bounds.getMin().lon())+"\" "+ "s=\""+LatLon.roundToOsmPrecision(bounds.getMin().lat())+"\" "+ "e=\""+LatLon.roundToOsmPrecision(bounds.getMax().lon())+"\" "+ "n=\""+LatLon.roundToOsmPrecision(bounds.getMax().lat())+"\""); } protected String getOverpassApiRequest(String bbox) { return null; } public boolean equals(IPrimitive p1, IPrimitive p2) { return false; } public boolean isRelevant(IPrimitive p) { return false; } public final Collection<IPrimitive> extractRelevantPrimitives(DataSet ds) { ArrayList<IPrimitive> result = new ArrayList<>(); for (IPrimitive p : ds.allPrimitives()) { if (isRelevant(p)) { result.add(p); } } return result; } public boolean isForbidden(IPrimitive p) { return false; } public boolean hasForbiddenTags() { return false; } public interface ValueReplacer { String replace(String value); } protected final void replace(IPrimitive p, String dataKey, String osmKey) { addOrReplace(p, dataKey, osmKey, null, null, null, true); } protected final void replace(IPrimitive p, String dataKey, String osmKey, ValueReplacer replacer) { addOrReplace(p, dataKey, osmKey, null, null, replacer, true); } protected final void replace(IPrimitive p, String dataKey, String osmKey, String[] dataValues, String[] osmValues) { addOrReplace(p, dataKey, osmKey, dataValues, osmValues, null, true); } protected final void add(IPrimitive p, String dataKey, String osmKey, ValueReplacer replacer) { addOrReplace(p, dataKey, osmKey, null, null, replacer, false); } protected final void add(IPrimitive p, String dataKey, String osmKey, String[] dataValues, String[] osmValues) { addOrReplace(p, dataKey, osmKey, dataValues, osmValues, null, false); } private void addOrReplace(IPrimitive p, String dataKey, String osmKey, String[] dataValues, String[] osmValues, ValueReplacer replacer, boolean replace) { String value = p.get(dataKey); if (value != null) { int index = -1; for (int i = 0; dataValues != null && index == -1 && i < dataValues.length; i++) { if (Pattern.compile(dataValues[i], Pattern.CASE_INSENSITIVE).matcher(value).matches()) { index = i; } /*if (value.equalsIgnoreCase(csvValues[i])) { index = i; }*/ } if (index > -1 && osmValues != null) { doAddReplace(p, dataKey, osmKey, osmValues[index], replace); } else if (replacer != null) { doAddReplace(p, dataKey, osmKey, replacer.replace(value), replace); } else if (dataValues == null || osmValues == null) { doAddReplace(p, dataKey, osmKey, value, replace); } } } private void doAddReplace(IPrimitive p, String dataKey, String osmKey, String osmValue, boolean replace) { if (replace) { p.remove(dataKey); } p.put(osmKey, osmValue); } public String getSource() { return null; } public final String getSourceDate() { return sourceDate; } public final void setSourceDate(String sourceDate) { this.sourceDate = sourceDate; } public final String getName() { return name; } public final void setName(String name) { this.name = name; } public String getLocalPortalIconName() { return OdConstants.ICON_CORE_24; } public String getNationalPortalIconName() { return OdConstants.ICON_CORE_24; } public String getDataLayerIconName() { return OdConstants.ICON_CORE_16; } public ExtendedSourceEntry getMapPaintStyle() { return null; } public ExtendedSourceEntry getTaggingPreset() { return null; } protected final ExtendedSourceEntry getMapPaintStyle(String displayName) { return getMapPaintStyle(displayName, this.getClass().getSimpleName().replace("Handler", "")); } protected final ExtendedSourceEntry getMapPaintStyle(String displayName, String fileNameWithoutExtension) { return new ExtendedSourceEntry(displayName, OdConstants.PROTO_RSRC+//"/"+ this.getClass().getPackage().getName().replace(".", "/")+"/"+ fileNameWithoutExtension+"."+OdConstants.MAPCSS_EXT); } public final ImageIcon getMenuIcon() { return menuIcon; } public final void setMenuIcon(ImageIcon icon) { this.menuIcon = icon; } public final void setMenuIcon(String iconName) { setMenuIcon(OdUtils.getImageIcon(iconName)); } public final void setAssociatedFile(File associatedFile) { this.associatedFile = associatedFile; } public final File getAssociatedFile() { return this.associatedFile; } public boolean acceptsUrl(String url) { URL dataURL = getDataURL(); if (dataURL != null && url.equals(dataURL.toString())) { return true; } List<Pair<String, URL>> dataURLs = getDataURLs(); if (dataURLs != null) { for (Pair<String, URL> pair : dataURLs) { if (pair.b != null && url.equals(pair.b.toString())) { return true; } } } return false; } // --------- Shapefile handling --------- private ShpHandler shpHandler; public final void setShpHandler(ShpHandler handler) { shpHandler = handler; } public final ShpHandler getShpHandler() { return shpHandler; } // --------- MIF handling --------- private MifHandler mifHandler; public final void setMifHandler(MifHandler handler) { mifHandler = handler; } public final MifHandler getMifHandler() { return mifHandler; } // --------- GML handling --------- private GmlHandler gmlHandler; public final void setGmlHandler(GmlHandler handler) { gmlHandler = handler; } public final GmlHandler getGmlHandler() { return gmlHandler; } // ------------ Archive handling ------------ private ArchiveHandler archiveHandler; public final void setArchiveHandler(ArchiveHandler handler) { archiveHandler = handler; } public ArchiveHandler getArchiveHandler() { return archiveHandler; } // ------ Spreadsheet handling ---------- private SpreadSheetHandler ssHandler; public final void setSpreadSheetHandler(SpreadSheetHandler handler) { ssHandler = handler; } public final SpreadSheetHandler getSpreadSheetHandler() { return ssHandler; } public final void setCsvHandler(CsvHandler handler) { setSpreadSheetHandler(handler); } public final CsvHandler getCsvHandler() { if (ssHandler instanceof CsvHandler) { return (CsvHandler) ssHandler; } else { return null; } } // Tools private final Collection<JosmAction> tools = new ArrayList<>(); public final Collection<JosmAction> getTools() { return tools; } public final boolean addTool(JosmAction tool) { return tool != null ? tools.add(tool) : false; } public final boolean removeTool(JosmAction tool) { return tool != null ? tools.remove(tool) : false; } public void notifyActive() { // To be overriden when the handler has specific treatments to perform when its layer becomes active } }