Index: /trunk/data/tag2link.sophox.sparql
===================================================================
--- /trunk/data/tag2link.sophox.sparql	(revision 15679)
+++ /trunk/data/tag2link.sophox.sparql	(revision 15679)
@@ -0,0 +1,5 @@
+SELECT (CONCAT("Key:", ?permanent_key_ID) as ?OSM_key) ?formatter_URL WHERE {
+  ?item osmdt:P2 osmd:Q7.
+  ?item osmdt:P16 ?permanent_key_ID.
+  ?item osmdt:P8 ?formatter_URL.
+}
Index: unk/data/tag2link.sparql
===================================================================
--- /trunk/data/tag2link.sparql	(revision 15678)
+++ 	(revision )
@@ -1,11 +1,0 @@
-SELECT ?OSM_key ?formatter_URL WHERE {
-  { ?item wdt:P1282 ?OSM_key. }
-  FILTER(STRSTARTS(?OSM_key, 'Key:')) .
-
-  {
-    { ?item wdt:P1630 ?formatter_URL. }
-    UNION
-    { ?item wdt:P3303 ?formatter_URL. }
-  }
-}
-ORDER BY LCASE(?OSM_tag_or_key)
Index: /trunk/data/tag2link.wikidata.sparql
===================================================================
--- /trunk/data/tag2link.wikidata.sparql	(revision 15679)
+++ /trunk/data/tag2link.wikidata.sparql	(revision 15679)
@@ -0,0 +1,10 @@
+SELECT ?OSM_key ?formatter_URL WHERE {
+  { ?item wdt:P1282 ?OSM_key. }
+  FILTER(STRSTARTS(?OSM_key, 'Key:')) .
+
+  {
+    { ?item wdt:P1630 ?formatter_URL. }
+    UNION
+    { ?item wdt:P3303 ?formatter_URL. }
+  }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/util/Tag2Link.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/util/Tag2Link.java	(revision 15678)
+++ /trunk/src/org/openstreetmap/josm/gui/util/Tag2Link.java	(revision 15679)
@@ -26,4 +26,11 @@
 /**
  * Extracts web links from OSM tags.
+ * <p></p>
+ * The following rules are used:
+ * <ul>
+ * <li>internal rules for basic tags</li>
+ * <li>rules from Wikidata based on OSM tag or key (P1282); formatter URL (P1630); third-party formatter URL (P3303)</li>
+ * <li>rules from OSM Sophox based on permanent key ID (P16); formatter URL (P8)</li>
+ * </ul>
  *
  * @since 15673
@@ -35,5 +42,5 @@
 
     /**
-     * Maps OSM keys to formatter URLs from Wikidata where {@code "$1"} has to be replaced by a value.
+     * Maps OSM keys to formatter URLs from Wikidata and OSM Sophox where {@code "$1"} has to be replaced by a value.
      */
     protected static MultiMap<String, String> wikidataRules = new MultiMap<>();
@@ -53,5 +60,7 @@
     public static void initialize() {
         try {
-            fetchRulesFromWikidata();
+            wikidataRules.clear();
+            fetchRulesViaSPARQL("resource://data/tag2link.wikidata.sparql", "https://query.wikidata.org/sparql");
+            fetchRulesViaSPARQL("resource://data/tag2link.sophox.sparql", "https://sophox.org/sparql");
         } catch (Exception e) {
             Logging.error("Failed to initialize tag2link rules");
@@ -63,9 +72,12 @@
      * Fetches rules from Wikidata using a SPARQL query.
      *
+     * @param query the SPARQL query
+     * @param server the query server
      * @throws IOException in case of I/O error
      */
-    private static void fetchRulesFromWikidata() throws IOException {
-        final String sparql = new String(new CachedFile("resource://data/tag2link.sparql").getByteContent(), Charsets.UTF_8);
-        final CachedFile sparqlFile = new CachedFile("https://query.wikidata.org/sparql?query=" + Utils.encodeUrl(sparql))
+    private static void fetchRulesViaSPARQL(final String query, final String server) throws IOException {
+        final int initialSize = wikidataRules.size();
+        final String sparql = new String(new CachedFile(query).getByteContent(), Charsets.UTF_8);
+        final CachedFile sparqlFile = new CachedFile(server + "?query=" + Utils.encodeUrl(sparql))
                 .setHttpAccept("application/json");
 
@@ -86,8 +98,9 @@
                 .forEach(wikidataRules::remove);
 
+        final int size = wikidataRules.size() - initialSize;
         Logging.info(trn(
                 "Obtained {0} Tag2Link rule from {1}",
                 "Obtained {0} Tag2Link rules from {1}",
-                wikidataRules.size(), wikidataRules.size(), "Wikidata"));
+                size, size, server));
     }
 
Index: /trunk/test/unit/org/openstreetmap/josm/gui/util/Tag2LinkTestIT.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/util/Tag2LinkTestIT.java	(revision 15679)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/util/Tag2LinkTestIT.java	(revision 15679)
@@ -0,0 +1,30 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.util;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import org.junit.Assert;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
+
+/**
+ * Integration tests for the {@link Tag2Link}
+ */
+public class Tag2LinkTestIT {
+
+    /**
+     * Setup rule
+     */
+    @ClassRule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public static JOSMTestRules test = new JOSMTestRules();
+
+    /**
+     * Integration test of function {@link Tag2Link#initialize()}.
+     */
+    @Test
+    public void testInitialize() {
+        Tag2Link.initialize();
+        Assert.assertTrue("obtails at least 40 rules", Tag2Link.wikidataRules.size() > 40);
+    }
+}
