Index: trunk/src/org/openstreetmap/josm/data/imagery/GetCapabilitiesParseHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/GetCapabilitiesParseHelper.java	(revision 11791)
+++ trunk/src/org/openstreetmap/josm/data/imagery/GetCapabilitiesParseHelper.java	(revision 11792)
@@ -64,4 +64,5 @@
     static final QName QN_OWS_OPERATIONS_METADATA = new QName(OWS_NS_URL, "OperationsMetadata");
     static final QName QN_OWS_SUPPORTED_CRS       = new QName(OWS_NS_URL, "SupportedCRS");
+    static final QName QN_OWS_TITLE               = new QName(OWS_NS_URL, "Title");
     static final QName QN_OWS_VALUE               = new QName(OWS_NS_URL, "Value");
     // CHECKSTYLE.ON: SingleSpaceSeparator
Index: trunk/src/org/openstreetmap/josm/data/imagery/WMTSTileSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/WMTSTileSource.java	(revision 11791)
+++ trunk/src/org/openstreetmap/josm/data/imagery/WMTSTileSource.java	(revision 11792)
@@ -144,5 +144,6 @@
     private static class Layer {
         private String format;
-        private String name;
+        private String identifier;
+        private String title;
         private TileMatrixSet tileMatrixSet;
         private String baseUrl;
@@ -153,5 +154,6 @@
             Objects.requireNonNull(l);
             format = l.format;
-            name = l.name;
+            identifier = l.identifier;
+            title = l.title;
             baseUrl = l.baseUrl;
             style = l.style;
@@ -160,4 +162,15 @@
 
         Layer() {
+        }
+
+        /**
+         * Get title of the layer for user display.
+         *
+         * This is either the content of the Title element (if available) or
+         * the layer identifier (as fallback)
+         * @return title of the layer for user display
+         */
+        public String getUserTitle() {
+            return title != null ? title : identifier;
         }
     }
@@ -179,5 +192,5 @@
                                 return SelectLayerDialog.this.layers.get(rowIndex).getValue()
                                         .stream()
-                                        .map(x -> x.name)
+                                        .map(x -> x.getUserTitle())
                                         .collect(Collectors.joining(", ")); //this should be only one
                             case 1:
@@ -231,5 +244,5 @@
             }
             Layer selectedLayer = layers.get(index).getValue().get(0);
-            return new WMTSDefaultLayer(selectedLayer.name, selectedLayer.tileMatrixSet.identifier);
+            return new WMTSDefaultLayer(selectedLayer.identifier, selectedLayer.tileMatrixSet.identifier);
         }
     }
@@ -269,8 +282,8 @@
      */
     public DefaultLayer userSelectLayer() {
-        Map<String, List<Layer>> layerByName = layers.stream().collect(
-                Collectors.groupingBy(x -> x.name));
-        if (layerByName.size() == 1) { // only one layer
-            List<Layer> ls = layerByName.entrySet().iterator().next().getValue()
+        Map<String, List<Layer>> layerById = layers.stream().collect(
+                Collectors.groupingBy(x -> x.identifier));
+        if (layerById.size() == 1) { // only one layer
+            List<Layer> ls = layerById.entrySet().iterator().next().getValue()
                     .stream().filter(
                             u -> u.tileMatrixSet.crs.equals(Main.getProjection().toCode()))
@@ -279,5 +292,5 @@
                 // only one tile matrix set with matching projection - no point in asking
                 Layer selectedLayer = ls.get(0);
-                return new WMTSDefaultLayer(selectedLayer.name, selectedLayer.tileMatrixSet.identifier);
+                return new WMTSDefaultLayer(selectedLayer.identifier, selectedLayer.tileMatrixSet.identifier);
             }
         }
@@ -304,5 +317,5 @@
     private static List<Entry<String, List<Layer>>> groupLayersByNameAndTileMatrixSet(Collection<Layer> layers) {
         Map<String, List<Layer>> layerByName = layers.stream().collect(
-                Collectors.groupingBy(x -> x.name + '\u001c' + x.tileMatrixSet.identifier));
+                Collectors.groupingBy(x -> x.identifier + '\u001c' + x.tileMatrixSet.identifier));
         return layerByName.entrySet().stream().sorted(Map.Entry.comparingByKey()).collect(Collectors.toList());
     }
@@ -412,5 +425,7 @@
                         }
                     } else if (GetCapabilitiesParseHelper.QN_OWS_IDENTIFIER.equals(reader.getName())) {
-                        layer.name = reader.getElementText();
+                        layer.identifier = reader.getElementText();
+                    } else if (GetCapabilitiesParseHelper.QN_OWS_TITLE.equals(reader.getName())) {
+                        layer.title = reader.getElementText();
                     } else if (QN_RESOURCE_URL.equals(reader.getName()) &&
                             "tile".equals(reader.getAttributeValue("", "resourceType"))) {
@@ -444,5 +459,5 @@
             // no format found - it's mandatory parameter - can't use this layer
             Main.warn(tr("Can''t use layer {0} because no supported formats where found. Layer is available in formats: {1}",
-                    layer.name,
+                    layer.getUserTitle(),
                     String.join(", ", unsupportedFormats)));
             return null;
@@ -581,5 +596,5 @@
         // so we will not ask the user again to chose the layer, if he just changes projection
         Collection<Layer> candidates = getLayers(
-                currentLayer != null ? new WMTSDefaultLayer(currentLayer.name, currentLayer.tileMatrixSet.identifier) : defaultLayer,
+                currentLayer != null ? new WMTSDefaultLayer(currentLayer.identifier, currentLayer.tileMatrixSet.identifier) : defaultLayer,
                 proj.toCode());
 
@@ -602,7 +617,7 @@
         } else if (candidates.size() > 1) {
             Main.warn("More than one layer WMTS available: {0} for projection {1} and name {2}. Do not know which to process",
-                    candidates.stream().map(x -> x.name + ": " + x.tileMatrixSet.identifier).collect(Collectors.joining(", ")),
+                    candidates.stream().map(x -> x.getUserTitle() + ": " + x.tileMatrixSet.identifier).collect(Collectors.joining(", ")),
                     proj.toCode(),
-                    currentLayer != null ? currentLayer.name : defaultLayer
+                    currentLayer != null ? currentLayer.getUserTitle() : defaultLayer
                     );
         }
@@ -621,5 +636,5 @@
             for (Layer layer: this.layers) {
                 if ((searchLayer == null || (// if it's null, then accept all layers
-                        searchLayer.getLayerName().equals(layer.name)))
+                        searchLayer.getLayerName().equals(layer.identifier)))
                         && (projectionCode == null || // if it's null, then accept any projection
                         projectionCode.equals(layer.tileMatrixSet.crs))) {
@@ -673,5 +688,5 @@
         }
 
-        return url.replaceAll("\\{layer\\}", this.currentLayer.name)
+        return url.replaceAll("\\{layer\\}", this.currentLayer.identifier)
                 .replaceAll("\\{format\\}", this.currentLayer.format)
                 .replaceAll("\\{TileMatrixSet\\}", this.currentTileMatrixSet.identifier)
@@ -845,5 +860,5 @@
         } else {
             for (Layer layer: this.layers) {
-                if (currentLayer.name.equals(layer.name)) {
+                if (currentLayer.identifier.equals(layer.identifier)) {
                     ret.add(layer.tileMatrixSet.crs);
                 }
