Monday, 1 June 2015

Export ArcGIS tiles data to any image format



I've a raster dataset in Cache/Mixed format in ArcGIS. I need to export this into a georeferenced tiff or any other raster image format in order to use it as base map in some other desktop based GIS software like QGIS.


So far, I've only found a tool in ArcGIS named Export tile cache (Data management) which can only alter the tile format to either .tpk file or exploded/compact cache format. I couldn't find any tool to convert these tiles data into any image.


If I use the export data option present in ArcGIS, the resultant image is nothing other than just a black image.


Any one knows how I can export these tiles data into an image?.




Edited


The answer given by @felixIP can be a solution, but I'm looking for another work around. The tiles have some configuration files with them as in the image below


File structure of ArcGIS server cache tiles


The conf.cdi looks like below





8142366.0491449088
4370513.4222595459
8146042.4910550155
4375009.1735663339

PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0],AUTHORITY["EPSG",3857]]
-20037700
-30241100
148923141.92838538

-100000
10000
-100000
10000
0.001
0.001
0.001
true
102100
3857




While config.xml has following information






PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0],AUTHORITY["EPSG",3857]]
-20037700

-30241100
148923141.92838538
-100000
10000
-100000
10000
0.001
0.001
0.001
true

102100
3857


-20037508.342787001
20037508.342787001

256
256
96

96


0
591657527.591555
156543.03392799999


1
295828763.79577702

78271.516963999893


2
147914381.89788899
39135.758482000099


3
73957190.948944002

19567.879240999901


4
36978595.474472001
9783.9396204999593


5
18489297.737236001

4891.9698102499797


6
9244648.8686180003
2445.9849051249898


7
4622324.4343090001

1222.9924525624899


8
2311162.2171550002
611.49622628138002


9
1155581.108577

305.74811314055802


10
577790.55428899999
152.874056570411


11
288895.27714399999

76.437028285073197


12
144447.638572
38.218514142536598


13
72223.819285999998

19.109257071268299


14
36111.909642999999
9.5546285356341496


15
18055.954822

4.7773142679493699


16
9027.9774109999998
2.38865713397468


17
4513.9887049999998

1.1943285668550501


18
2256.994353
0.59716428355981699


19
1128.4971760000001

0.29858214164761698




MIXED
75
false



esriMapCacheStorageModeExploded
128



And there is tiles present in _alllayers folder. Actually, there is a link between this configuration information and naming conventions of folders and files in _allayers and I'm unable to find that link, once I get the actual point, it is not a big deal to mosaic the tiles together.



Answer



I've written a python script for this. This is the initial version of the script, so it needs to add certain values manually into the script. I've mentioned that in script. Here it is


import math
from pyproj import Proj, transform


from PIL import Image
import glob, os
import sys
from os import walk
from os.path import join, getsize

#this function would convert utm coordinates to lat lng
#function taken from http://gis.stackexchange.com/questions/78838/how-to-convert-projected-coordinates-to-lat-lon-using-python
def utmToLatLng(x,y):

inProj = Proj(init='epsg:3857')
outProj = Proj(init='epsg:4326')

x2,y2 = transform(inProj,outProj,x,y)
return (x2,y2)



#this function would take lat lng and return the tile number
#function taken from http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames

def deg2num(lat_deg, lon_deg, zoom):
lat_rad = math.radians(lat_deg)
n = 2.0 ** zoom
xtile = int((lon_deg + 180.0) / 360.0 * n)
ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n)
return (xtile, ytile)

#this function would take a number and return it in hexa format
#taken from http://stackoverflow.com/questions/16414559/trying-to-use-hex-without-0x
def inttohexa(x):

return format(x, 'x')


#this function would take a number and return a 9 letter word, the first letter
# would be static, should be R and C for folder and files respectivly
#this function can be improved further. Developed by muzaffar in hurry
#that's why you so see much if else in the function
def completeEightNumbers(number,letter):
if len(number)<8:
less_number = 8-len(number)

if less_number==1:
return letter+'0'+number
elif less_number==2:
return letter+'00'+number
elif less_number==3:
return letter+'000'+number
elif less_number==4:
return letter+'0000'+number
elif less_number==5:
return letter+'00000'+number

elif less_number==6:
return letter+'000000'+number
elif less_number==7:
return letter+'0000000'+number
elif less_number==8:
return letter+'00000000'+number
else:
return letter+number



#we need these four parameters
ymin = 4370513.4222595459
ymax = 4375009.1735663339
xmin = 8142366.0491449088
xmax = 8146042.4910550155

#resolution of the max zoom level
resolution = 0.59716428355981699
tile_diff = resolution * 256 #256 is the tile width




folders_name = [] #this list would contain the actual folders which have tiles inside
#storing ymax value in a variable for loop purpose only
ymax_loop = 4375009.1735663339
while (ymin < ymax_loop):#we would keep looping until the max value reach the ymin

#xmin value would remain same while ymax_loop would change for each loop
latlng = utmToLatLng(xmin, ymax_loop) #sample output 36.538723, 73.144095
tile_num = deg2num(latlng[1], latlng[0], 18) #18 here is zoom level

folder_name = inttohexa(tile_num[1])
exact_folder_name = completeEightNumbers(folder_name,'R')

#insert the folder name in list
folders_name.append(exact_folder_name)

#reduce the value of loop by tile_diff -- each time the loop execute
ymax_loop = ymax_loop - tile_diff

print folders_name



file1 = "C:\Users\A\Desktop\mosaic\output.png"
file, ext = os.path.splitext(file1)
outfile = file + ".PNG"

result_width = 25*256
result_height = 30*256
result = Image.new('RGB', (result_width, result_height))


root = "C:\Users\A\Desktop\mosaic"
folders_index = 0
for single_folder in folders_name:

print root+"\\"+single_folder
files = glob.glob(root+"\\"+single_folder+"\\*")

image_list = []
files_index = 0


for b in files:

image_list.append(Image.open(b))

result.paste(image_list[files_index], box=((files_index*256),(folders_index*256)))
files_index += 1
#print result

#print folders_index*256
folders_index +=1


result.save(outfile, "PNG")
print "done"

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...