Sign up ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I have a 3GB raster layer, and I'd like to export it to KML for use with Google Earth.

When I use the "Layer to KML" conversion tool in ArcMap, I end up with a low-resolution overlay: looks like one 2000x2000 pixel image (give or take). I've tried messing with the "layer output scale" parameter, but it isn't having any effect.

share|improve this question
Relevant:… – blah238 Apr 18 '12 at 2:08
Also related if you go down the map tiling route:… – blah238 Apr 18 '12 at 3:30

3 Answers 3

up vote 5 down vote accepted

I see two possible options:

  1. Use Google Earth Pro to directly load the raster assuming it is in a supported file format. See Importing Geographic Information Systems (GIS) data in Google Earth

  2. Google Earth supports "super overlays" through the use of Region and NetworkLink elements which allows you to display a multi-megapixel image by subsetting it into tiles. KMLer Pro ($50) is an ArcGIS extension that purports to be able to create super overlays directly from ArcGIS maps. There are also several non-ArcGIS tools such as MapTiler, TileCache, and SuperOverlay (related to KMLer).

share|improve this answer

Save your money, buy nothing. Associate this script with a toolbox tool. Set it up with 4 parameters (Input Raster, Output Folder, Draw Order and Output Prefix). Run. Tried the SuperOverlay thing from GDAL and didn't think much of that horrible data structure. I never cleaned this up so it does processing it doesn't need to if I remember correctly, but it ran and created a working output. The kmz will even work on a Garmin (*MAP model or newer) as long as you make sure it complies with the models limitations for "Custom Maps".

#First crack at writing something to tile out a source image to
#conform to the Garmin Custom Maps KML format. For now I am not
#concerning myself with limitations of this format on various devices
#and just working on getting the output to always function in
#Google Earth
#To use the output kmz on most Garmin *MAP models open the kmz file in
#Google Earth. Delete tiles until there are only 100 remaining (maximum)
#Resave the resultant kmz to a new file and copy this to the "\Garmin\CustomMaps"
#folder on the GPS
#This image will display on the unit at different zoom levels based on the
#resolution of the image. If you want to use the imagery at a coarser scale
#you will have to resample the input image to a larger cell size and rerun
#this tool.
#Michael Stead, August 29, 2014

# Import arcpy module
import arcpy, arcgis, os, zipfile, shutil

# Get input parameters
source = arcpy.GetParameterAsText(0)
outfolder = arcpy.GetParameterAsText(1)
level = arcpy.GetParameterAsText(2)
outname = arcpy.GetParameterAsText(3)
kmzfile = outfolder + "\\" + outname + ".kmz"
workfile = "tmplayer.tif"

# Get projection of input raster... set output to wgs84
desc1 = arcpy.Describe(source)
sproj = arcpy.SpatialReference(4326)

#make temporary raster layer, ensuring 3 bands only
arcpy.env.workspace = outfolder
arcpy.MakeRasterLayer_management(source, workfile, "#", "#", "1;2;3")

#make sure 8 bit input as other bit depth creates empty output from Split Raster
spath = desc1.Path
if ":" in str(source):
    ddesc = arcpy.Describe(source+"\\Band_1")
if not ":" in str(source):
    ddesc = arcpy.Describe(spath+"\\"+source+"\\Band_1")
sourcedepth = ddesc.pixelType
if sourcedepth <> "U8":
    arcpy.AddMessage("Convert to 8 bit unsigned")
    arcpy.CopyRaster_management(workfile, "t_raster.tif","DEFAULTS","","","","","8_BIT_UNSIGNED")
    workfile = "t_raster.tif"
    arcpy.AddMessage("Already 8 bit unsigned") #but couldn't see how else to pass this as a variable
    #arcpy.CopyRaster_management ("tmplayer.tif", "t_raster.tif","DEFAULTS","","","","","8_BIT_UNSIGNED")

#check if the input is wgs84 already, if not reproject
if == arcpy.SpatialReference(4326).name:
    arcpy.AddMessage("Already WGS84")
    #arcpy.CopyRaster_management ("t_raster.tif", "p_raster.tif","DEFAULTS","","","","","8_BIT_UNSIGNED")

    # Reproject to WGS84
    arcpy.ProjectRaster_management(workfile, "p_raster.tif", sproj, "BILINEAR", "#","#", "#", "#")
    workfile = "p_raster.tif"

#Figure out size for tiles (must be less than 1024x1024)
if workfile == "tmplayer.tif":
    workfile = source
desc2 = arcpy.Describe(workfile+"\\Band_1")
if ":" in str(source):
    arcpy.AddMessage("Full Path")
    desc4 = arcpy.Describe(source+"\\Band_1")
if not ":" in str(source):
    arcpy.AddMessage("TOC Layer")
    desc4 = arcpy.Describe(spath+"\\"+source+"\\Band_1")

cellsize = desc4.MeanCellHeight
columnfactor = int((desc2.width)/1024)+1
rowfactor = int((desc2.height)/1024)+1
columnwidth = int(desc2.width/columnfactor)+1
rowheight = int(desc2.height/rowfactor)+1
arcpy.AddMessage("Height: %d" % rowheight)
arcpy.AddMessage("Width: %d" % columnwidth)
tilesize = "%d %d" % (columnwidth, rowheight)

# Create "files" folder for tiled images
arcpy.AddMessage("Creating Folder")
tilefolder =  (outfolder +'\\files\\')   

# Split unprojected raster into a folder of 1024 by 1024 (or less to minimize "no data" tile area) jpg tiles
arcpy.AddMessage("Tiling Input")
arcpy.SplitRaster_management(workfile, tilefolder, outname,"SIZE_OF_TILE","JPG","CUBIC","1 1",tilesize,"0","PIXELS","#","#")

#Create empty doc.kml file
arcpy.AddMessage("Create KML")
kml_file = (outfolder +'\\doc.kml')
f = open(kml_file,"a+")

#Add header to empty doc.kml
arcpy.AddMessage("Build KML Header")
text_file = open(kml_file, "a+")
text_file.write('<?xml version="1.0" encoding="UTF-8"?>\n')
text_file.write('<kml xmlns="" xmlns:gx="" xmlns:kml="" xmlns:atom="">\n')
text_file.write('  <Document>\n')
text_file.write('    <Name>MikesKMZs</Name>\n')

#Loop through folder of tiled rasters and write the extents to the doc.kml file
arcpy.AddMessage("Create KML Tile Extent")
arcpy.env.workspace = tilefolder
rasterList = arcpy.ListRasters("*", "JPG")
for raster in rasterList:
    loopath = tilefolder+'\\'+raster
    describeimg = arcpy.Describe(loopath)
    ##### QUESTION - the west and east values might need to get swapped for eastern hemisphere, and the north and south for the southern hemisphere
    North = describeimg.extent.YMax
    South = describeimg.extent.YMin
    West = describeimg.extent.XMin
    East = describeimg.extent.XMax
    text_file = open(kml_file, "a+")
    text_file.write('    <GroundOverlay>\n')
    text_file.write('      <name>'+raster+'</name>\n')
    text_file.write('      <drawOrder>'+str(level)+'</drawOrder>\n')
    text_file.write('      <color>ffffffff</color>\n')
    text_file.write('      <Description>\n')
    text_file.write('      </Description>\n')
    text_file.write('      <Icon>\n')
    text_file.write('        <href>files/'+str(raster)+'</href>\n')
    text_file.write('      </Icon>\n')
    text_file.write('      <LatLonBox>\n')
    text_file.write('        <north>'+str(North)+'</north>\n')
    text_file.write('        <south>'+str(South)+'</south>\n')
    text_file.write('        <east>'+str(East)+'</east>\n')
    text_file.write('        <west>'+str(West)+'</west>\n')
    text_file.write('        <rotation>0</rotation>\n')    
    text_file.write('      </LatLonBox>\n')
    text_file.write('    </GroundOverlay>\n')

#Add footer to doc.kml file\
arcpy.AddMessage("Add KML Footer")
text_file = open(kml_file, "a+")
text_file.write('  </Document>\n')

#Create kmz and compress kml and jpgs
zip = zipfile.ZipFile(kmzfile,'w')
JPGList = arcpy.ListFiles("*.JPG")
for JPGs in JPGList:

#Clean up working file debris
arcpy.env.workspace = outfolder
if arcpy.Exists("p_raster.tif"):
if arcpy.Exists("t_raster.tif"):
if arcpy.Exists("tmplayer.tif"):

Edit - In 10.2 the line:

arcpy.SplitRaster_management(workfile, tilefolder, outname,"SIZE_OF_TILE","JPG","CUBIC","1 1",tilesize,"0","PIXELS","#","#")

Must be modified to:

arcpy.SplitRaster_management(workfile, tilefolder, outname,"SIZE_OF_TILE","JPEG","CUBIC","1 1",tilesize,"0","PIXELS","#","#")
share|improve this answer
Works AWESOME! Can't believe this answer does not have any votes. – Jakub May 26 at 15:55
Thanks Jakub... Canada rocks eh?... If you use it for Garmin backgrounds you will soon figure out some limitations that Garmin have placed on their format (mainly the lack of a pyramid type rendering for different display levels). That's the catch with Garmins... All the proprietary formats. They want to sell you jnx capability.... That comes with a subscription to their imagery. It does work though. I have created files at different resolutions and stuck them each on a separate SD card. Some are different, but with some you can have multiple on the same card and select one at a time. – Mike May 30 at 23:08
  1. Download Shape2Earth and apply it to your add-in manager.
  2. Convert your raster to a feature.
  3. Work with Shape2Earth
  4. Save your money.
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.