From 8538c48a11d18875606a0d2b75c82bfe709a0c3c Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Tue, 9 Jun 2020 16:58:24 -0600 Subject: [PATCH] Allow for multiple categories in MapWithAIInfo This fixes #73. Signed-off-by: Taylor Smock --- .../data/mapwithai/MapWithAIInfo.java | 57 +++++++++++++++---- .../mapwithai/MapWithAIProvidersPanel.java | 18 ++++-- .../io/mapwithai/ESRISourceReader.java | 12 ++-- 3 files changed, 67 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/data/mapwithai/MapWithAIInfo.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/data/mapwithai/MapWithAIInfo.java index 5e502fa..7f54c90 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/data/mapwithai/MapWithAIInfo.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/data/mapwithai/MapWithAIInfo.java @@ -29,6 +29,7 @@ import org.openstreetmap.josm.data.sources.ISourceCategory; import org.openstreetmap.josm.data.sources.ISourceType; import org.openstreetmap.josm.data.sources.SourceInfo; import org.openstreetmap.josm.data.sources.SourcePreferenceEntry; +import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets; import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIInfo.MapWithAIPreferenceEntry; import org.openstreetmap.josm.spi.preferences.Config; import org.openstreetmap.josm.tools.CheckParameterUtil; @@ -81,6 +82,8 @@ public class MapWithAIInfo extends BUILDING("data/closedway", "buildings", marktr("Buildings")), HIGHWAY("presets/transport/way/way_road", "highways", marktr("Roads")), ADDRESS("presets/misc/housenumber_small", "addresses", marktr("Addresses")), + POWER("presets/power/pole", "pole", marktr("Power")), PRESET("dialogs/search", "presets", marktr("Presets")), + FEATURED("presets/service/network-wireless.svg", "featured", marktr("Featured")), OTHER(null, "other", marktr("Other")); private static final Map> iconCache = Collections @@ -119,17 +122,22 @@ public class MapWithAIInfo extends return category; } } - // fuzzy match if (s != null && !s.trim().isEmpty()) { - s = s.toLowerCase(Locale.ROOT); + // fuzzy match + String tmp = s.toLowerCase(Locale.ROOT); for (MapWithAICategory type : MapWithAICategory.values()) { - if (s.contains(type.getDescription().toLowerCase(Locale.ROOT)) - || type.getDescription().toLowerCase(Locale.ROOT).contains(s)) { + if (tmp.contains(type.getDescription().toLowerCase(Locale.ROOT)) + || type.getDescription().toLowerCase(Locale.ROOT).contains(tmp)) { return type; } } + // Check if it matches a preset + if (TaggingPresets.getPresetKeys().stream().map(String::toLowerCase) + .anyMatch(m -> tmp.contains(m) || m.contains(tmp))) { + return PRESET; + } } - return null; + return OTHER; } public static class DescriptionComparator implements Comparator { @@ -151,6 +159,7 @@ public class MapWithAIInfo extends } } + private List categories; private JsonArray parameters; private Map replacementTags; private boolean conflate; @@ -178,6 +187,8 @@ public class MapWithAIInfo extends String conflationUrl; @StructEntry String conflationParameters; + @StructEntry + List categories; /** * Constructs a new empty {@MapWithAIPreferenceEntry} @@ -205,6 +216,10 @@ public class MapWithAIInfo extends } conflate = i.conflate; conflationUrl = i.conflationUrl; + if (i.categories != null) { + categories = i.categories.stream().map(MapWithAICategory::getCategoryString) + .collect(Collectors.toList()); + } } @Override @@ -317,6 +332,10 @@ public class MapWithAIInfo extends setCountryCode(e.country_code); setIcon(e.icon); setCategory(MapWithAICategory.fromString(e.category)); + if (e.categories != null) { + setAdditionalCategories( + e.categories.stream().map(MapWithAICategory::fromString).distinct().collect(Collectors.toList())); + } setConflation(e.conflate); setConflationUrl(e.conflationUrl); if (e.conflationParameters != null) { @@ -353,17 +372,13 @@ public class MapWithAIInfo extends this.setIcon(i.icon); this.setCustomHttpHeaders(i.customHttpHeaders); this.category = i.category; + this.categories = i.categories; this.replacementTags = i.replacementTags; this.conflate = i.conflate; this.conflationUrl = i.conflationUrl; this.conflationParameters = i.conflationParameters; } - @Override - public int hashCode() { - return Objects.hash(url, sourceType); - } - public boolean equalsPref(MapWithAIInfo other) { if (other == null) { return false; @@ -372,7 +387,8 @@ public class MapWithAIInfo extends // CHECKSTYLE.OFF: BooleanExpressionComplexity return super.equalsPref(other) && Objects.equals(this.replacementTags, other.replacementTags) && Objects.equals(this.conflationUrl, other.conflationUrl) - && Objects.equals(this.conflationParameters, other.conflationParameters); + && Objects.equals(this.conflationParameters, other.conflationParameters) + && Objects.equals(this.categories, other.categories); // CHECKSTYLE.ON: BooleanExpressionComplexity } @@ -501,7 +517,26 @@ public class MapWithAIInfo extends this.conflationUrl = conflationUrl; } + /** + * @param parameters Set the conflation parameters + */ public void setConflationParameters(JsonArray parameters) { this.conflationParameters = parameters; } + + /** + * Set any additional categories + * + * @param categories The categories to set + */ + public void setAdditionalCategories(List categories) { + this.categories = categories; + } + + /** + * @return Any additional categories + */ + public List getAdditionalCategories() { + return this.categories != null ? Collections.unmodifiableList(this.categories) : Collections.emptyList(); + } } diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/gui/preferences/mapwithai/MapWithAIProvidersPanel.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/gui/preferences/mapwithai/MapWithAIProvidersPanel.java index 9ccf234..154efcf 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/gui/preferences/mapwithai/MapWithAIProvidersPanel.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/gui/preferences/mapwithai/MapWithAIProvidersPanel.java @@ -20,6 +20,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -238,11 +239,11 @@ public class MapWithAIProvidersPanel extends JPanel { * class to render the country information of MapWithAI source */ private static class MapWithAITypeTableCellRenderer - extends MapWithAIProvidersPanel.MapWithAITableCellRenderer { + extends MapWithAIProvidersPanel.MapWithAITableCellRenderer> { private static final long serialVersionUID = 5975643008500799758L; MapWithAITypeTableCellRenderer(MapWithAIProvidersPanel panel) { - super(panel, MapWithAICategory::getDescription, i -> null, MapWithAICategory::getDescription, null, false); + super(panel, list -> String.join(",", list), i -> null, list -> String.join(",", list), null, false); } } @@ -891,12 +892,19 @@ public class MapWithAIProvidersPanel extends JPanel { public MapWithAIDefaultLayerTableModel() { setColumnIdentifiers(new String[] { "", tr("Menu Name (Default)"), tr("Type"), tr("MapWithAI URL (Default)"), tr("Provider") }); - columnTypes = Stream.of(MapWithAICategory.class, MapWithAIInfo.class, MapWithAICategory.class, String.class, - String.class).collect(Collectors.toCollection(ArrayList::new)); + columnTypes = Stream + .of(MapWithAICategory.class, MapWithAIInfo.class, List.class, String.class, String.class) + .collect(Collectors.toCollection(ArrayList::new)); columnDataRetrieval = new ArrayList<>(); columnDataRetrieval.add(info -> Optional.ofNullable(info.getCategory()).orElse(MapWithAICategory.OTHER)); columnDataRetrieval.add(info -> info); - columnDataRetrieval.add(info -> Optional.ofNullable(info.getCategory()).orElse(MapWithAICategory.OTHER)); + columnDataRetrieval.add(info -> { + List categories = Stream + .concat(Stream.of(info.getCategory()), info.getAdditionalCategories().stream()) + .filter(Objects::nonNull).map(MapWithAICategory::getDescription).collect(Collectors.toList()); + return categories.isEmpty() ? Collections.singletonList(MapWithAICategory.OTHER.getDescription()) + : categories; + }); columnDataRetrieval.add(MapWithAIInfo::getUrl); columnDataRetrieval.add(i -> i.getAttributionText(0, null, null)); } diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ESRISourceReader.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ESRISourceReader.java index 1c92fe1..05c145d 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ESRISourceReader.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/io/mapwithai/ESRISourceReader.java @@ -131,11 +131,15 @@ public class ESRISourceReader implements Closeable { source.getUrl() + "content/items/" + newInfo.getId() + "/info/" + feature.getString("thumbnail")); } if (feature.containsKey("groupCategories")) { - MapWithAICategory category = feature.getJsonArray("groupCategories").getValuesAs(JsonString.class).stream() - .map(JsonString::getString).map(s -> s.replace("/Categories/", "")) - .map(MapWithAICategory::fromString).filter(Objects::nonNull).findFirst() - .orElse(MapWithAICategory.OTHER); + List categories = feature.getJsonArray("groupCategories").getValuesAs(JsonString.class) + .stream().map(JsonString::getString).map(s -> s.replace("/Categories/", "")) + .map(MapWithAICategory::fromString).filter(Objects::nonNull) + .collect(Collectors.toCollection(ArrayList::new)); + MapWithAICategory category = categories.stream().filter(c -> !MapWithAICategory.FEATURED.equals(c)) + .findFirst().orElse(MapWithAICategory.OTHER); newInfo.setCategory(category); + categories.remove(category); + newInfo.setAdditionalCategories(categories); } if (feature.containsKey("accessInformation")) {