- Timestamp:
- 2020-01-10T22:48:20+01:00 (5 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/MainInitialization.java
r15147 r15677 26 26 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets; 27 27 import org.openstreetmap.josm.gui.util.GuiHelper; 28 import org.openstreetmap.josm.gui.util.Tag2Link; 28 29 import org.openstreetmap.josm.io.FileWatcher; 29 30 import org.openstreetmap.josm.io.OsmApi; … … 117 118 new InitializationTask(tr("Initializing presets"), TaggingPresets::initialize), 118 119 new InitializationTask(tr("Initializing map styles"), MapPaintPreference::initialize), 120 new InitializationTask(tr("Initializing Tag2Link rules"), Tag2Link::initialize), 119 121 new InitializationTask(tr("Loading imagery preferences"), ImageryPreference::initialize) 120 122 ); -
trunk/src/org/openstreetmap/josm/gui/util/Tag2Link.java
r15673 r15677 3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 import static org.openstreetmap.josm.tools.I18n.trn; 5 6 7 import java.io.BufferedReader; 8 import java.io.IOException; 9 import java.net.MalformedURLException; 10 import java.net.URL; 6 11 import java.util.regex.Matcher; 7 12 import java.util.regex.Pattern; 13 import java.util.stream.Stream; 8 14 15 import javax.json.Json; 16 import javax.json.JsonArray; 17 import javax.json.JsonValue; 18 19 import com.drew.lang.Charsets; 9 20 import org.openstreetmap.josm.data.osm.OsmUtils; 21 import org.openstreetmap.josm.io.CachedFile; 22 import org.openstreetmap.josm.tools.Logging; 23 import org.openstreetmap.josm.tools.MultiMap; 10 24 import org.openstreetmap.josm.tools.Utils; 11 25 … … 13 27 * Extracts web links from OSM tags. 14 28 * 15 * @since xxx29 * @since 15673 16 30 */ 17 final class Tag2Link {31 public final class Tag2Link { 18 32 19 33 // Related implementations: 20 34 // - https://github.com/openstreetmap/openstreetmap-website/blob/master/app/helpers/browse_tags_helper.rb 35 36 /** 37 * Maps OSM keys to formatter URLs from Wikidata where {@code "$1"} has to be replaced by a value. 38 */ 39 protected static MultiMap<String, String> wikidataRules = new MultiMap<>(); 21 40 22 41 private Tag2Link() { … … 27 46 interface LinkConsumer { 28 47 void acceptLink(String name, String url); 48 } 49 50 /** 51 * Initializes the tag2link rules 52 */ 53 public static void initialize() { 54 try { 55 fetchRulesFromWikidata(); 56 } catch (Exception e) { 57 Logging.error("Failed to initialize tag2link rules"); 58 Logging.error(e); 59 } 60 } 61 62 /** 63 * Fetches rules from Wikidata using a SPARQL query. 64 * 65 * @throws IOException in case of I/O error 66 */ 67 private static void fetchRulesFromWikidata() throws IOException { 68 final String sparql = new String(new CachedFile("resource://data/tag2link.sparql").getByteContent(), Charsets.UTF_8); 69 final CachedFile sparqlFile = new CachedFile("https://query.wikidata.org/sparql?query=" + Utils.encodeUrl(sparql)) 70 .setHttpAccept("application/json"); 71 72 final JsonArray rules; 73 try (BufferedReader reader = sparqlFile.getContentReader()) { 74 rules = Json.createReader(reader).read().asJsonObject().getJsonObject("results").getJsonArray("bindings"); 75 } 76 77 for (JsonValue rule : rules) { 78 final String key = rule.asJsonObject().getJsonObject("OSM_key").getString("value"); 79 final String url = rule.asJsonObject().getJsonObject("formatter_URL").getString("value"); 80 if (key.startsWith("Key:")) { 81 wikidataRules.put(key.substring("Key:".length()), url); 82 } 83 } 84 // We handle those keys ourselves 85 Stream.of("image", "url", "website", "wikidata", "wikimedia_commons") 86 .forEach(wikidataRules::remove); 87 88 Logging.info(trn( 89 "Obtained {0} Tag2Link rule from {1}", 90 "Obtained {0} Tag2Link rules from {1}", 91 wikidataRules.size(), wikidataRules.size(), "Wikidata")); 29 92 } 30 93 … … 41 104 final boolean valueIsURL = value.matches("^(http:|https:|www\\.).*"); 42 105 if (key.matches("^(.+[:_])?website([:_].+)?$") && valueIsURL) { 43 linkConsumer.acceptLink( tr("View website"), value);106 linkConsumer.acceptLink(getLinkName(value, key), value); 44 107 } 45 108 if (key.matches("^(.+[:_])?source([:_].+)?$") && valueIsURL) { 46 linkConsumer.acceptLink( tr("View website"), value);109 linkConsumer.acceptLink(getLinkName(value, key), value); 47 110 } 48 111 if (key.matches("^(.+[:_])?url([:_].+)?$") && valueIsURL) { 49 linkConsumer.acceptLink( tr("View URL"), value);112 linkConsumer.acceptLink(getLinkName(value, key), value); 50 113 } 51 114 if (key.matches("image") && valueIsURL) { … … 61 124 if (key.matches("(.*:)?wikidata")) { 62 125 OsmUtils.splitMultipleValues(value) 63 .forEach(q -> linkConsumer.acceptLink(tr("View Wikidata item "), "https://www.wikidata.org/wiki/" + q));126 .forEach(q -> linkConsumer.acceptLink(tr("View Wikidata item {0}", q), "https://www.wikidata.org/wiki/" + q)); 64 127 } 65 if (key.matches("species")) { 66 linkConsumer.acceptLink(tr("View Wikispecies page"), "https://species.wikimedia.org/wiki/" + value); 128 if (key.matches("(.*:)?species")) { 129 final String url = "https://species.wikimedia.org/wiki/" + value; 130 linkConsumer.acceptLink(getLinkName(url, key), url); 67 131 } 68 132 if (key.matches("wikimedia_commons|image") && value.matches("(?i:File):.*")) { … … 73 137 } 74 138 75 // WHC 76 if (key.matches("ref:whc") && (valueMatcher = Pattern.compile("(?<id>[0-9]+)(-.*)?").matcher(value)).matches()) { 77 linkConsumer.acceptLink(tr("View UNESCO sheet"), "http://whc.unesco.org/en/list/" + valueMatcher.group("id")); 78 } 139 wikidataRules.getValues(key).forEach(urlFormatter -> { 140 final String url = urlFormatter.replace("$1", value); 141 linkConsumer.acceptLink(getLinkName(url, key), url); 142 }); 143 } 79 144 80 // Mapillary 81 if (key.matches("((ref|source):)?mapillary") && value.matches("[0-9a-zA-Z-_]+")) { 82 linkConsumer.acceptLink(tr("View {0} image", "Mapillary"), "https://www.mapillary.com/map/im/" + value); 83 } 84 85 // MMSI 86 if (key.matches("seamark:(virtual_aton|radio_station):mmsi") && value.matches("[0-9]+")) { 87 // https://en.wikipedia.org/wiki/Maritime_Mobile_Service_Identity 88 linkConsumer.acceptLink(tr("View MMSI on MarineTraffic"), 89 "https://www.marinetraffic.com/en/ais/details/ships/shipid:/mmsi:" + value); 145 private static String getLinkName(String url, String fallback) { 146 try { 147 return tr("Open {0}", new URL(url).getHost()); 148 } catch (MalformedURLException e) { 149 return tr("Open {0}", fallback); 90 150 } 91 151 }
Note:
See TracChangeset
for help on using the changeset viewer.