Index: applications/editors/josm/plugins/tag2link/resources/tag2link_sources.xml
===================================================================
--- applications/editors/josm/plugins/tag2link/resources/tag2link_sources.xml	(revision 35147)
+++ applications/editors/josm/plugins/tag2link/resources/tag2link_sources.xml	(revision 35148)
@@ -201,12 +201,8 @@
             <link name="View INSEE explanation of %name% code" href="http://recherche-naf.insee.fr/SIRENET_ClassesNaf/%v%.htm" />
         </rule>
+        <!--  lat/lon of selected object works, but this website does not. Kept as an example
         <rule>
             <condition k="ref:FR:NAF" v="[A-Z0-9-]{5}" />
-            <link name="View a map of %name% items" href="https://sidjy.github.io/ape.html?ape=%v%" />
-        </rule>
-        <!--  TODO map lat/lon of selected object
-        <rule>
-            <condition k="ref:FR:NAF" v="[A-Z0-9-]{5}" />
-            <link name="View a map of %name% items" href="https://sidjy.github.io/ape.html?ape=%v%#%zoom%/%lat%/%lon%" />
+            <link name="View a map of %name% items" href="https://sidjy.github.io/ape.html?ape=%v%#15/%lat%/%lon%" />
         </rule> -->
     </src>
Index: applications/editors/josm/plugins/tag2link/src/org/openstreetmap/josm/plugins/tag2link/Tag2LinkRuleChecker.java
===================================================================
--- applications/editors/josm/plugins/tag2link/src/org/openstreetmap/josm/plugins/tag2link/Tag2LinkRuleChecker.java	(revision 35147)
+++ applications/editors/josm/plugins/tag2link/src/org/openstreetmap/josm/plugins/tag2link/Tag2LinkRuleChecker.java	(revision 35148)
@@ -27,4 +27,5 @@
 import java.util.regex.Pattern;
 
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.IPrimitive;
 import org.openstreetmap.josm.data.osm.Tag;
@@ -73,5 +74,5 @@
     }
 
-    private static String replaceParams(String s, EvalResult eval) {
+    private static String replaceParams(String s, Collection<MatchingTag> matchingTags, LatLon latLon) {
         String result = s;
         Matcher m = PLACEHOLDERS.matcher(s);
@@ -80,29 +81,21 @@
             
             // Search for a standard value
-            String val = findValue(arg, eval.matchingTags);
+            String val = findValue(arg, matchingTags);
             
             // No standard value found: test lang() function
             if (val == null) {
-                Matcher lm = LANG.matcher(arg);
-                if (lm.matches()) {
-                    String josmLang = Config.getPref().get("language");
-                    String jvmLang = (josmLang.isEmpty() ? Locale.getDefault().getLanguage() : josmLang).split("_")[0];
-                    if (lm.groupCount() == 0) {
-                        val = jvmLang;
-                    } else {
-                        for (int i = 1; i<=lm.groupCount() && val == null; i++) {
-                            if (jvmLang.equals(lm.group(i))) {
-                                val = jvmLang;
-                            }
-                        }
-                    }
-                }
-            }
-            
+                val = replaceLang(arg);
+            }
+
+            // No standard value found: test lat/lon
+            if (val == null && latLon != null) {
+                val = replaceLatLon(arg, latLon);
+            }
+
             // Find a default value if set after ":"
             if (val == null && arg.contains(":")) {
                 String[] vars = arg.split(":");
                 for (int i = 0; val == null && i < vars.length-1; i++) {
-                    val = findValue(vars[i], eval.matchingTags);
+                    val = findValue(vars[i], matchingTags);
                 }
                 if (val == null) {
@@ -135,10 +128,36 @@
     }
 
-    private static void replaceMapParams(Map<String, String> map, EvalResult eval) {
+    private static String replaceLang(String arg) {
+        Matcher lm = LANG.matcher(arg);
+        if (lm.matches()) {
+            String josmLang = Config.getPref().get("language");
+            String jvmLang = (josmLang.isEmpty() ? Locale.getDefault().getLanguage() : josmLang).split("_")[0];
+            if (lm.groupCount() == 0) {
+                return jvmLang;
+            } else {
+                for (int i = 1; i <= lm.groupCount(); i++) {
+                    if (jvmLang.equals(lm.group(i))) {
+                        return jvmLang;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private static String replaceLatLon(String arg, LatLon ll) {
+        switch (arg) {
+            case "lat": return Double.toString(ll.lat());
+            case "lon": return Double.toString(ll.lon());
+            default: return null;
+        }
+    }
+
+    private static void replaceMapParams(Map<String, String> map, Collection<MatchingTag> matchingTags, LatLon latLon) {
         for (Entry<String, String> e : map.entrySet()) {
             String key = e.getKey();
             String value = e.getValue();
-            String key2 = replaceParams(key, eval);
-            String value2 = replaceParams(value, eval);
+            String key2 = replaceParams(key, matchingTags, latLon);
+            String value2 = replaceParams(value, matchingTags, latLon);
             if (key.equals(key2) && value.equals(value2)) {
                 // Nothing to do
@@ -154,5 +173,5 @@
     }
 
-    private static Collection<Link> processEval(EvalResult eval, Rule rule, Source source) {
+    private static Collection<Link> processEval(EvalResult eval, Rule rule, Source source, LatLon latLon) {
         Collection<Link> result = new ArrayList<>();
         if (eval.matches()) {
@@ -161,9 +180,9 @@
                     Link copy = (Link) link.clone();
                     copy.name = copy.name.replaceAll("%name%", source.name);
-                    copy.url = replaceParams(copy.url, eval);
+                    copy.url = replaceParams(copy.url, eval.matchingTags, latLon);
                     if (copy instanceof LinkPost) {
                         LinkPost lp = (LinkPost) copy;
-                        replaceMapParams(lp.headers, eval);
-                        replaceMapParams(lp.params, eval);
+                        replaceMapParams(lp.headers, eval.matchingTags, latLon);
+                        replaceMapParams(lp.params, eval.matchingTags, latLon);
                     }
                     result.add(copy);
@@ -176,9 +195,9 @@
     }
 
-    private static <T> Collection<Link> doGetLinks(BiFunction<Rule, T, EvalResult> evaluator, T obj) {
+    private static <T> Collection<Link> doGetLinks(BiFunction<Rule, T, EvalResult> evaluator, T obj, LatLon latLon) {
         Collection<Link> result = new ArrayList<>();
         for (Source source : sources) {
             for (Rule rule : source.rules) {
-                result.addAll(processEval(evaluator.apply(rule, obj), rule, source));
+                result.addAll(processEval(evaluator.apply(rule, obj), rule, source, latLon));
             }
         }
@@ -192,5 +211,5 @@
      */
     public static Collection<Link> getLinks(IPrimitive p) {
-        return doGetLinks(Rule::evaluates, p);
+        return doGetLinks(Rule::evaluates, p, p.getBBox().getCenter());
     }
 
@@ -198,8 +217,9 @@
      * Replies the links relevant to the given OSM tag.
      * @param tag The OSM tag
+     * @param tags The latlon center, or null
      * @return the links relevant to the {@code tag}.
      */
-    public static Collection<Link> getLinks(Tag tag) {
-        return doGetLinks(Rule::evaluates, tag);
+    public static Collection<Link> getLinks(Tag tag, LatLon latLon) {
+        return doGetLinks(Rule::evaluates, tag, latLon);
     }
 
@@ -207,8 +227,9 @@
      * Replies the links relevant to the given OSM tags.
      * @param tags The OSM tags
+     * @param tags The latlon center, or null
      * @return the links relevant to the {@code tags}.
      */
-    public static Collection<Link> getLinks(Tags tags) {
-        return doGetLinks(Rule::evaluates, tags);
+    public static Collection<Link> getLinks(Tags tags, LatLon latLon) {
+        return doGetLinks(Rule::evaluates, tags, latLon);
     }
 }
Index: applications/editors/josm/plugins/tag2link/src/org/openstreetmap/josm/plugins/tag2link/data/Rule.java
===================================================================
--- applications/editors/josm/plugins/tag2link/src/org/openstreetmap/josm/plugins/tag2link/data/Rule.java	(revision 35147)
+++ applications/editors/josm/plugins/tag2link/src/org/openstreetmap/josm/plugins/tag2link/data/Rule.java	(revision 35148)
@@ -32,5 +32,5 @@
     public final Collection<Condition> conditions = new ArrayList<>();
     public final Collection<Link> links = new ArrayList<>();
-    
+
     public static class MatchingTag {
         public String key;
@@ -46,5 +46,5 @@
         }
         public void addParams(Matcher m, String paramName) {
-            for (int i = 1; i<=m.groupCount(); i++) {
+            for (int i = 1; i <= m.groupCount(); i++) {
                 params.put(prefix+paramName+"."+i, m.group(i));
             }
@@ -62,9 +62,9 @@
             return "MatchingTag [" + (key != null ? "key=" + key + ", " : "")
                     + (value != null ? "value=" + value + ", " : "")
-                    + (params != null ? "params=" + params + ", " : "")
-                    + (prefix != null ? "prefix=" + prefix : "") + "]";
+                    + "params=" + params + ", "
+                    + (prefix != null ? "prefix=" + prefix : "") + ']';
         }
     }
-    
+
     public static class EvalResult {
         private final int conditionsNumber;
@@ -79,5 +79,5 @@
         public String toString() {
             return "EvalResult [conditionsNumber=" + conditionsNumber
-                    + ", matchingTags=" + matchingTags + "]";
+                    + ", matchingTags=" + matchingTags + ']';
         }
     }
Index: applications/editors/josm/plugins/tag2link/src/org/openstreetmap/josm/plugins/tag2link/listeners/PropertyPopupListener.java
===================================================================
--- applications/editors/josm/plugins/tag2link/src/org/openstreetmap/josm/plugins/tag2link/listeners/PropertyPopupListener.java	(revision 35147)
+++ applications/editors/josm/plugins/tag2link/src/org/openstreetmap/josm/plugins/tag2link/listeners/PropertyPopupListener.java	(revision 35148)
@@ -16,8 +16,13 @@
 package org.openstreetmap.josm.plugins.tag2link.listeners;
 
+import java.util.Optional;
+
 import javax.swing.JPopupMenu;
 import javax.swing.event.PopupMenuEvent;
 
+import org.openstreetmap.josm.data.osm.BBox;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Tags;
+import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.plugins.tag2link.Tag2LinkRuleChecker;
@@ -35,5 +40,7 @@
         if (tags != null) {
             JPopupMenu popup = (JPopupMenu) e.getSource();
-            for (Link link : Tag2LinkRuleChecker.getLinks(tags)) {
+            Optional<BBox> bbox = MainApplication.getLayerManager().getEditDataSet().getSelected()
+                .stream().filter(x -> x.hasTag(tags.getKey(), tags.getValues())).map(OsmPrimitive::getBBox).findAny();
+            for (Link link : Tag2LinkRuleChecker.getLinks(tags, bbox.isPresent() ? bbox.get().getCenter() : null)) {
                 addLink(popup, link);
             }
Index: applications/editors/josm/plugins/tag2link/test/unit/org/openstreetmap/josm/plugins/tag2link/Tag2LinkRuleCheckerTest.java
===================================================================
--- applications/editors/josm/plugins/tag2link/test/unit/org/openstreetmap/josm/plugins/tag2link/Tag2LinkRuleCheckerTest.java	(revision 35147)
+++ applications/editors/josm/plugins/tag2link/test/unit/org/openstreetmap/josm/plugins/tag2link/Tag2LinkRuleCheckerTest.java	(revision 35148)
@@ -19,8 +19,8 @@
     @Test
     public void testImageCommons() {
-        Collection<Link> links = Tag2LinkRuleChecker.getLinks(new Tag("image", "File:Witten Brücke Gasstraße.jpg"));
+        Collection<Link> links = Tag2LinkRuleChecker.getLinks(new Tag("image", "File:Witten Brücke Gasstraße.jpg"), null);
         assertEquals(1, links.size());
         assertEquals("https://commons.wikimedia.org/wiki/File%3AWitten_Br%C3%BCcke_Gasstra%C3%9Fe.jpg", links.iterator().next().url);
-        links = Tag2LinkRuleChecker.getLinks(new Tag("image", "category:JOSM"));
+        links = Tag2LinkRuleChecker.getLinks(new Tag("image", "category:JOSM"), null);
         assertEquals(1, links.size());
         assertEquals("https://commons.wikimedia.org/wiki/category%3AJOSM", links.iterator().next().url);
@@ -29,5 +29,5 @@
     @Test
     public void testBrandWikidata() {
-        final Collection<Link> links = Tag2LinkRuleChecker.getLinks(new Tag("brand:wikidata", "Q259340"));
+        final Collection<Link> links = Tag2LinkRuleChecker.getLinks(new Tag("brand:wikidata", "Q259340"), null);
         assertEquals(1, links.size());
         assertEquals("https://www.wikidata.org/wiki/Q259340", links.iterator().next().url);
@@ -36,5 +36,5 @@
     @Test
     public void testArchipelagoWikidata() {
-        final Collection<Link> links = Tag2LinkRuleChecker.getLinks(new Tag("archipelago:wikidata", "Q756987"));
+        final Collection<Link> links = Tag2LinkRuleChecker.getLinks(new Tag("archipelago:wikidata", "Q756987"), null);
         assertEquals(1, links.size());
         assertEquals("https://www.wikidata.org/wiki/Q756987", links.iterator().next().url);
