Skip to content

Instantly share code, notes, and snippets.

@kinseytamsin
Created May 12, 2025 17:15
Show Gist options
  • Save kinseytamsin/6d5a58ae5102cff3484a25db9153c1cd to your computer and use it in GitHub Desktop.
Save kinseytamsin/6d5a58ae5102cff3484a25db9153c1cd to your computer and use it in GitHub Desktop.
PowerShell script to backup and restore JOSM Bing attribution file
Param([Parameter(Mandatory=$true, Position=0)][string]$Mode, [switch]$DryRun)
$modes = "backup", "restore"
if (!($Mode -in $modes)) {
Write-Error "Invalid mode: $Mode. Valid modes are `"backup`" and `"restore`"."
exit 1
}
$josmCachePath = "${env:LOCALAPPDATA}\JOSM\cache"
$bingFilename = "bing.attribution.xml"
$bingBackupFilename = "$bingFilename.bak"
$bingExtraBackupFilename = "$bingFilename.bak.0"
$bingBadBackupFilename = "$bingFilename.bad.bak"
$bingPath = "$josmCachePath\$bingFilename"
$bingBackupPath = "$josmCachePath\$bingBackupFilename"
$bingExtraBackupPath = "$josmCachePath\$bingExtraBackupFilename"
$bingBadBackupPath = "$josmCachePath\$bingBadBackupFilename"
$extraBackup = $false
function MaybeMove-File ($source, $destination) {
Write-Output "[Move] $source -> $destination"
if (!$DryRun) {
Move-Item $source $destination
}
}
function MaybeRemove-File ($path) {
Write-Output "[Delete] $path"
if (!$DryRun) {
Remove-Item $path
}
}
function MaybeCopy-File ($source, $destination) {
Write-Output "[Copy] $source -> $destination"
if (!$DryRun) {
Copy-Item $source $destination
}
}
function Test-BingBackup {
if ($Mode -ieq "backup") {
Write-Output "Checking whether $bingBackupFilename already exists."
} elseif ($Mode -ieq "restore") {
Write-Output "Checking for Bing attribution file backup."
}
return (Test-Path $bingBackupPath)
}
if ($DryRun) {
Write-Output "Performing dry run. No files will be modified."
}
if ($Mode -ieq "backup") {
Write-Output "Checking for Bing attribution file."
if (!(Test-Path $bingPath)) {
Write-Error "Bing attribution file $bingFilename not found."
exit 1
} else {
Write-Output "Bing attribution file found."
}
Write-Output "Checking whether $bingBackupFilename already exists."
if (Test-BingBackup) {
Write-Output "$bingBackupFilename found."
Write-Output "Moving existing backup file."
MaybeMove-File $bingBackupPath $bingExtraBackupPath
$extraBackup = $true
} else {
Write-Output "$bingBackupFilename not found."
}
Write-Output "Backing up Bing attribution file."
MaybeCopy-File $bingPath $bingBackupPath
if ($extraBackup) {
Write-Output "Deleting old backup file."
MaybeRemove-File $bingExtraBackupPath
}
} elseif ($Mode -ieq "restore") {
if (!(Test-BingBackup)) {
Write-Error "Bing attribution file backup $bingBackupFilename not found."
exit 1
}
if (Test-Path $bingPath) {
if (Test-Path $bingBadBackupPath) {
Write-Output "Deleting existing `"bad`" Bing attribution file backup."
MaybeRemove-File $bingBadBackupPath
}
Write-Output "Moving existing Bing attribution file to $bingBadBackupFilename."
MaybeMove-File $bingPath $bingBadBackupPath
}
Write-Output "Restoring Bing attribution file from backup."
MaybeCopy-File $bingBackupPath $bingPath
}
@kinseytamsin
Copy link
Author

Usage is .\attribution-backup.ps1 backup or .\attribution-backup.ps1 restore, and you can add -DryRun to get just the output describing what would be done without actually touching any files.

Still needs some refinement and documentation, and obviously only works on Windows as is, but basically:

At a time when the Bing imagery is working, run .\attribution-backup.ps1 backup. Then, at a later time when you get tiles stuck on "Error: Attribution is not loaded yet":

  1. Close JOSM.
  2. Run .\attribution-backup.ps1 restore.
  3. Reopen JOSM.
  4. Before loading the Bing imagery layer, disable cache updates by opening [File] > [Work Offline...] and choosing [Cache updates]. This prevents JOSM from trying to overwrite your working Bing attribution file with a non-working one again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment