Google/OSM to TMS tile renamer
About
This is a simple BASH script to rename map tiles from Google Maps/OpenStreetMap format to
Tile Map Service format.
Click here to skip the background info and
go straight to the script.
There are several standards for serving slippy map tiles from a standard web server. Two common
ones are
Google Maps format (also used by Yahoo Maps, OpenStreetMap,
and OpenAerialMap) and
Tile Map Service
(used by OpenLayers, TileCache, and applications such as MyTrails; the Web Map Tiling Service specification is
also very similar).
A third, related, format called
QuadTree
is used by Microsoft Virtual Earth and uses the same projection and file format but has a different
naming scheme; this format is not covered here.
The Google and TMS formats are very similar.
Both store the tiles in /ROOT/Z/X/Y format where Z is the zoom level (0..23), and X and Y are the
tile coordinates. The naming scheme is the same for both except that the Y coordinate uses a
different origin. The following equation converts a Y-coordinate from Google to TMS format:
YTMS = 2zoom - YGoogle - 1
Comments are welcome, see the email link at the bottom of the page.
Using the script
Download the script, make it executable (
chmod +x
google_to_tms.sh), and copy it to somewhere in your PATH (e.g. to
/usr/local/bin/).
Basic usage is
google_to_tms.sh /path/to/tiles/root (change the path as appropriate)
By default the script displays the name of each directory as it is processed, give the -q flag
(quiet) to suppress this.
Give the -v flag (verbose) to have the rename commands displayed as they are run.
Give the -n flag (no-act) to not actually do any renaming; this is useful as a sanity check.
Note that all flags must appear at the end of the commandline.
Source
#!/bin/bash
# google_to_tms.sh
# Copyright 2015 Alexander Hajnal
# http://alephnull.net/software/gis/google_to_tms.shtml
# Usage
# ------------------------------------------------------------------------------
# google_to_tms.sh /path/to/tiles/root [ -q ] [ -v ] [ -n ]
#
# -q -> Quieter output
# -v -> Verbose output
# -n -> Don't actually do any renaming, instead just say what would be done
#
# Root directory should contain the numbered level directories (0..23).
# Note that this script does _not_ check which file naming convention is
# currently being used.
# Warranty
# ------------------------------------------------------------------------------
# I make no warranty or representation, either express or implied, with respect
# the behavior of this script, its quality, performance, accuracy, merchantability,
# or fitness for a particular purpose. This script is provided 'as is', and
# you, by making use thereof, are assuming the entire risk. That said,
# I hope you this script useful. Have fun!
Usage() {
echo "Usage: $0 /path/to/tiles/root [ -q ] [ -v ] [ -n ]"
echo "Rename tiles from Google Maps/OpenStreetMap format to Tile Map Service format"
echo "Copyright 2015 Alexander Hajnal"
echo
echo "-q -> Quieter output"
echo "-v -> Verbose output"
echo "-n -> Don't actually do any renaming, instead just say what would be done"
echo
echo "Root directory should contain the numbered level directories (0..23)."
echo "Note that this script does _not_ check which file naming convention is "
echo "currently being used."
}
if [ "$#" -eq 0 ]; then
Usage
exit
fi
ROOT=`echo "$1"|sed 's/\/*$//'`
VERBOSE=0
QUIET=0
NO_ACT=0
if [[ $2 == '-v' || $3 == '-v' || $4 == '-v' ]] ; then
VERBOSE=1
fi
if [[ $2 == '-q' || $3 == '-q' || $4 == '-q' ]] ; then
QUIET=1
fi
if [[ $2 == '-n' || $3 == '-n' || $4 == '-n' ]] ; then
NO_ACT=1
fi
if [[ ! -d "$ROOT" ]]; then
echo "FATAL: \`$ROOT' is not a directory"
echo
Usage
exit
fi
ProcessImageLevel() {
SUBLEVEL_PATH=$1
if [[ $QUIET == 0 ]] ; then
echo "$SUBLEVEL_PATH"
fi
ls "$SUBLEVEL_PATH" | while IFS= read entry; do
if [ -f "$SUBLEVEL_PATH/$entry" ]; then
# Only process files...
image_regex='^([0-9]+)(\..+)?$'
if [[ $entry =~ $image_regex ]] ; then
# ...that look like valid tiles ( NUMBERS or NUMBERS.EXTENSION )
y=${BASH_REMATCH[1]}
ext=${BASH_REMATCH[2]}
new_y=$(((1<<zoom) - y - 1))
if [[ $NO_ACT == 1 || $VERBOSE == 1 ]] ; then
echo mv \""$ROOT"/$zoom/$x/$y$ext\" \""$ROOT"/$zoom/$x/$new_y$ext\"
fi
if [[ $NO_ACT == 0 ]] ; then
mv "$ROOT/$zoom/$x/$y$ext" "$ROOT/$zoom/$x/$new_y$ext"
fi
fi
fi
done
}
ProcessTopLevel() {
LEVEL_PATH=$1
ls "$LEVEL_PATH" | while IFS= read x; do
if [ -d "$LEVEL_PATH/$x" ]; then
# Only process directories...
numbers_regex='^[0-9]+$'
if [[ $x =~ $numbers_regex ]] ; then
# ...consisting of all numbers
ProcessImageLevel "$LEVEL_PATH/$x"
fi
fi
done
}
if [[ $QUIET == 0 ]] ; then
echo "Renaming tiles in $ROOT"
fi
ls "$ROOT" | while IFS= read zoom; do
if [ -d "$ROOT/$zoom" ]; then
# Only process directories...
regex='^([0-9])|([1-9][0-9]))$'
if [[ $zoom =~ $regex ]] ; then
# ...numbered from 0 through 99
ProcessTopLevel "$ROOT/$zoom"
fi
fi
done
Other GIS pages on this site
-
Useful GIS commands
A set of commands for common GIS tasks using GDAL, OGR, and QGIS.
-
Slippy map tile generator for QGIS
Python script to generate slippy map tiles from within QGIS.
Similar in functionality to the QTiles plugin but faster and
without the annoying rendering errors at tile edges.
-
Geo::Index (offsite link)
Perl module for creating and searching in-memory geographic point indices.
I make no warranty or representation, either express or implied, with respect the behavior of this script, its quality, performance, accuracy, merchantability, or fitness for a particular purpose. This script is provided 'as is', and you, by making use thereof, are assuming the entire risk. That said, I hope you this script useful. Have fun!
Last modified 2015-08-24
© 2009-2025 Alexander Hajnal