Index: /applications/editors/josm/plugins/pmtiles/src/main/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesImageLayer.java
===================================================================
--- /applications/editors/josm/plugins/pmtiles/src/main/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesImageLayer.java	(revision 36114)
+++ /applications/editors/josm/plugins/pmtiles/src/main/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesImageLayer.java	(revision 36115)
@@ -59,3 +59,13 @@
         return new PMTilesImageSource((PMTilesImageryInfo) this.info);
     }
+
+    @Override
+    public PMTilesImageryInfo getInfo() {
+        return (PMTilesImageryInfo) super.getInfo();
+    }
+
+    @Override
+    public String getChangesetSourceTag() {
+        return PMTilesLayer.super.getChangesetSourceTag();
+    }
 }
Index: /applications/editors/josm/plugins/pmtiles/src/main/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesLayer.java
===================================================================
--- /applications/editors/josm/plugins/pmtiles/src/main/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesLayer.java	(revision 36114)
+++ /applications/editors/josm/plugins/pmtiles/src/main/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesLayer.java	(revision 36115)
@@ -1,4 +1,10 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.plugins.pmtiles.gui.layers;
+
+import static org.openstreetmap.josm.tools.Utils.getSystemProperty;
+
+import org.openstreetmap.josm.plugins.pmtiles.data.imagery.PMTilesImageryInfo;
+import org.openstreetmap.josm.tools.TextUtils;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -6,3 +12,40 @@
  */
 interface PMTilesLayer {
+
+    /**
+     * Returns imagery info.
+     * @return imagery info
+     */
+    PMTilesImageryInfo getInfo();
+
+    /**
+     * Get the source tag for the layer
+     * @return The source tag
+     */
+    default String getChangesetSourceTag() {
+        final var sb = new StringBuilder();
+        final var info = getInfo();
+        if (info.hasAttribution()) {
+            sb.append(getInfo().getAttributionText(0, null, null)
+                    .replaceAll("<a [^>]*>|</a>", "")
+                    .replaceAll("  +", " "));
+        }
+        if (info.getName() != null) {
+            if (!sb.isEmpty()) {
+                sb.append(" - ");
+            }
+            sb.append(info.getName());
+        }
+        if (sb.isEmpty()) {
+            final var location = info.header().location().toString();
+            if (Utils.isLocalUrl(location)) {
+                final String userName = getSystemProperty("user.name");
+                final String userNameAlt = "<user.name>";
+                sb.append(location.replace(userName, userNameAlt));
+            } else {
+                sb.append(TextUtils.stripUrl(location));
+            }
+        }
+        return sb.toString();
+    }
 }
Index: /applications/editors/josm/plugins/pmtiles/src/main/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesMVTLayer.java
===================================================================
--- /applications/editors/josm/plugins/pmtiles/src/main/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesMVTLayer.java	(revision 36114)
+++ /applications/editors/josm/plugins/pmtiles/src/main/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesMVTLayer.java	(revision 36115)
@@ -60,3 +60,13 @@
         return new PMTilesMVTTileSource((PMTilesImageryInfo) this.info);
     }
+
+    @Override
+    public PMTilesImageryInfo getInfo() {
+        return (PMTilesImageryInfo) super.getInfo();
+    }
+
+    @Override
+    public String getChangesetSourceTag() {
+        return PMTilesLayer.super.getChangesetSourceTag();
+    }
 }
Index: /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/PMTestUtils.java
===================================================================
--- /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/PMTestUtils.java	(revision 36115)
+++ /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/PMTestUtils.java	(revision 36115)
@@ -0,0 +1,23 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.pmtiles;
+
+import java.io.File;
+import java.net.URI;
+
+/**
+ * Utils for testing
+ */
+public final class PMTestUtils {
+    private PMTestUtils() { /* Hide constructor */ }
+    /** A sample vector tileset */
+
+    public static final URI ODBL_VECTOR_FIRENZE = new File("protomaps(vector)ODbL_firenze.pmtiles").exists() ?
+            new File("protomaps(vector)ODbL_firenze.pmtiles").toURI() :
+            URI.create("https://github.com/protomaps/PMTiles/raw/main/spec/v3/protomaps(vector)ODbL_firenze.pmtiles");
+
+    /** A sample raster tileset */
+    public static final URI ODBL_RASTER_STAMEN = new File("stamen_toner(raster)CC-BY%2BODbL_z3.pmtiles").exists() ?
+            new File("stamen_toner(raster)CC-BY%2BODbL_z3.pmtiles").toURI() :
+            URI.create("https://github.com/protomaps/PMTiles/raw/main/spec/v3/stamen_toner(raster)CC-BY%2BODbL_z3.pmtiles");
+
+}
Index: /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesImageLayerTest.java
===================================================================
--- /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesImageLayerTest.java	(revision 36115)
+++ /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesImageLayerTest.java	(revision 36115)
@@ -0,0 +1,14 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.pmtiles.gui.layers;
+
+import org.openstreetmap.josm.plugins.pmtiles.data.imagery.PMTilesImageryInfo;
+
+/**
+ * Test class for {@link PMTilesImageLayer}
+ */
+class PMTilesImageLayerTest implements PMTilesLayerTest {
+    @Override
+    public PMTilesImageLayer getLayer(PMTilesImageryInfo info) {
+        return new PMTilesImageLayer(info);
+    }
+}
Index: /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesLayerTest.java
===================================================================
--- /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesLayerTest.java	(revision 36115)
+++ /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesLayerTest.java	(revision 36115)
@@ -0,0 +1,35 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.pmtiles.gui.layers;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.openstreetmap.josm.plugins.pmtiles.PMTestUtils.ODBL_RASTER_STAMEN;
+import static org.openstreetmap.josm.plugins.pmtiles.PMTestUtils.ODBL_VECTOR_FIRENZE;
+
+import java.io.IOException;
+
+import org.junit.jupiter.api.Test;
+import org.openstreetmap.josm.plugins.pmtiles.data.imagery.PMTilesImageryInfo;
+import org.openstreetmap.josm.plugins.pmtiles.lib.PMTiles;
+import org.openstreetmap.josm.tools.TextUtils;
+import org.openstreetmap.josm.tools.Utils;
+
+/**
+ * Test class for {@link PMTilesLayer}
+ */
+interface PMTilesLayerTest {
+    PMTilesLayer getLayer(PMTilesImageryInfo info);
+
+    @Test
+    default void testSource() throws IOException {
+        final var layerRaster = getLayer(new PMTilesImageryInfo(PMTiles.readHeader(ODBL_RASTER_STAMEN)));
+        final var layerVector = getLayer(new PMTilesImageryInfo(PMTiles.readHeader(ODBL_VECTOR_FIRENZE)));
+        if (Utils.isLocalUrl(ODBL_RASTER_STAMEN.toString())) {
+            assertEquals(ODBL_RASTER_STAMEN.toString().replace(System.getProperty("user.name"), "<user.name>"),
+                    layerRaster.getChangesetSourceTag());
+        } else {
+            assertEquals(TextUtils.stripUrl(ODBL_RASTER_STAMEN.toString()), layerRaster.getChangesetSourceTag());
+        }
+        assertEquals("Protomaps © OpenStreetMap - protomaps 2023-01-18T07:49:39Z", layerVector.getChangesetSourceTag());
+    }
+
+}
Index: /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesMVTLayerTest.java
===================================================================
--- /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesMVTLayerTest.java	(revision 36115)
+++ /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/gui/layers/PMTilesMVTLayerTest.java	(revision 36115)
@@ -0,0 +1,14 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.plugins.pmtiles.gui.layers;
+
+import org.openstreetmap.josm.plugins.pmtiles.data.imagery.PMTilesImageryInfo;
+
+/**
+ * Test class for {@link PMTilesMVTLayer}
+ */
+class PMTilesMVTLayerTest implements PMTilesLayerTest {
+    @Override
+    public PMTilesMVTLayer getLayer(PMTilesImageryInfo info) {
+        return new PMTilesMVTLayer(info);
+    }
+}
Index: /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/lib/PMTilesTest.java
===================================================================
--- /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/lib/PMTilesTest.java	(revision 36114)
+++ /applications/editors/josm/plugins/pmtiles/src/test/java/org/openstreetmap/josm/plugins/pmtiles/lib/PMTilesTest.java	(revision 36115)
@@ -7,8 +7,8 @@
 import static org.junit.jupiter.api.Assertions.assertSame;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.openstreetmap.josm.plugins.pmtiles.PMTestUtils.ODBL_RASTER_STAMEN;
+import static org.openstreetmap.josm.plugins.pmtiles.PMTestUtils.ODBL_VECTOR_FIRENZE;
 
-import java.io.File;
 import java.io.IOException;
-import java.net.URI;
 
 import org.junit.jupiter.api.Test;
@@ -18,12 +18,4 @@
  */
 class PMTilesTest {
-    private static final URI ODBL_VECTOR_FIRENZE = new File("protomaps(vector)ODbL_firenze.pmtiles").exists() ?
-            new File("protomaps(vector)ODbL_firenze.pmtiles").toURI() :
-            URI.create("https://github.com/protomaps/PMTiles/raw/main/spec/v3/protomaps(vector)ODbL_firenze.pmtiles");
-
-    private static final URI ODBL_RASTER_STAMEN = new File("stamen_toner(raster)CC-BY%2BODbL_z3.pmtiles").exists() ?
-            new File("stamen_toner(raster)CC-BY%2BODbL_z3.pmtiles").toURI() :
-            URI.create("https://github.com/protomaps/PMTiles/raw/main/spec/v3/stamen_toner(raster)CC-BY%2BODbL_z3.pmtiles");
-
     @Test
     void testHeader() {
