Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSource.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSource.java	(revision 26949)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSource.java	(revision 26950)
@@ -13,9 +13,9 @@
     private Map<String, String> headers = new HashMap<String, String>();
     
-    public static final String PATTERN_ZOOM    = "\\{zoom([+-]\\d+)?\\}";
+    public static final String PATTERN_ZOOM    = "\\{(?:(\\d+)-)?zoom([+-]\\d+)?\\}";
     public static final String PATTERN_X       = "\\{x\\}";
     public static final String PATTERN_Y       = "\\{y\\}";
     public static final String PATTERN_Y_YAHOO = "\\{!y\\}";
-    public static final String PATTERN_SWITCH  = "\\{switch:[^}]+\\}";
+    public static final String PATTERN_SWITCH  = "\\{switch:([^}]+)\\}";
     public static final String PATTERN_HEADER  = "\\{header\\(([^,]+),([^}]+)\\)\\}";
     
@@ -58,16 +58,22 @@
     @Override
     public String getTileUrl(int zoom, int tilex, int tiley) {
+        int finalZoom = zoom;
         Matcher m = Pattern.compile(".*"+PATTERN_ZOOM+".*").matcher(this.baseUrl);
-        if (m.matches() && !m.group(1).isEmpty()) {
-            String ofs = m.group(1);
-            if(ofs.startsWith("+"))
-                ofs = ofs.substring(1);
-            zoom += Integer.valueOf(ofs);
+        if (m.matches()) {
+            if(m.group(1) != null) {
+                finalZoom = Integer.valueOf(m.group(1))-zoom;
+            }
+            if(m.group(2) != null) {
+                String ofs = m.group(2);
+                if(ofs.startsWith("+"))
+                    ofs = ofs.substring(1);
+                finalZoom += Integer.valueOf(ofs);
+            }
         }
         String r = this.baseUrl
-            .replaceAll(PATTERN_ZOOM, Integer.toString(zoom))
+            .replaceAll(PATTERN_ZOOM, Integer.toString(finalZoom))
             .replaceAll(PATTERN_X, Integer.toString(tilex))
             .replaceAll(PATTERN_Y, Integer.toString(tiley))
-            .replaceAll(PATTERN_Y_YAHOO, Integer.toString((int)Math.pow(2, zoom)-1-tiley));
+            .replaceAll(PATTERN_Y_YAHOO, Integer.toString((int)Math.pow(2, zoom-1)-1-tiley));
         if (rand != null) {
             r = r.replaceAll(PATTERN_SWITCH, randomParts[rand.nextInt(randomParts.length)]);
