• Google Map Tile 下载脚本


    http://bbs.esrichina-bj.cn/ESRI/viewthread.php?tid=65904 (我没有用过,有环境的朋友可以试试)

    早就写了,一直都有问题没好意思放出来,自己最近这段时间着迷于python编程,但进步缓慢,昨晚看《可爱的python》,得到启发,还是拿出来让大家一起帮忙修改完善。
    毛病很多,比如:线程,不太会用,下载进度计数上面有问题;又如:不能暂停下载后接着下载。
    总之希望大家多多交流,把这个小工具修改完善。
    dmc.py源代码:

    代码
    1 #coding=utf-8
    2
    3 #Filename:dmc.py
    4
    5 import cmath,urllib,os,math,random,sys,time,threading
    6
    7
    8
    9 class Cdt:
    10
    11 def __str__(self):
    12
    13 return '{x = %s,y = %s}'%(self.x,self.y)
    14
    15
    16
    17 def createName(num,type):
    18
    19 #'''创建文件夹/文件名称'''
    20
    21 temp = '00000000'+str(hex(int(num)))[2:]
    22
    23 return type + temp[::-1][0:8][::-1]
    24
    25
    26
    27 def getPixelFromCdt(x,y,z):
    28
    29 #'''根据经纬度坐标以及缩放等级获取像素坐标'''
    30
    31 pixel = Cdt()
    32
    33 sinLatitude = cmath.sin(y * cmath.pi / 180)
    34
    35 pixel.x = ((x + 180) / 360) * 256 * (2**z)
    36
    37 temp = cmath.log((1+sinLatitude)/(1-sinLatitude))
    38
    39 pixel.y = abs((0.5 - temp / (4 * cmath.pi))*256*(2**z))
    40
    41 return pixel
    42
    43
    44
    45 def getTileFromPixel(pixel):
    46
    47 #'''根据像素坐标获取切片'''
    48
    49 tile = Cdt()
    50
    51 tile.x = math.floor(pixel.x / 256)
    52
    53 tile.y = math.floor(pixel.y / 256)
    54
    55 return tile
    56
    57
    58
    59 def getTileFromCdt(x,y,z):
    60
    61 #'''根据经纬度坐标以及缩放等级获取切片'''
    62
    63 return getTileFromPixel(getPixelFromCdt(x,y,z))
    64
    65
    66
    67 def downloadTile(remoteFile,localFile):
    68
    69 #'''下载远程文件到本地'''
    70
    71 urllib.urlretrieve(remoteFile,localFile)
    72
    73
    74
    75 def createDir(dirPath):
    76
    77 #'''创建文件夹'''
    78
    79 if not os.path.exists(dirPath):
    80
    81 os.makedirs(dirPath)
    82
    83
    84
    85 def createRemoteUrl(x,y,z):
    86
    87 #'''创建远程tile地址'''
    88
    89 port = str(random.randint(0,3))
    90
    91 x = str(x)
    92
    93 y = str(y)
    94
    95 z = str(z)
    96
    97 return 'http://mt'+port+'.google.cn/vt/v=w2.115&hl=zh-CN&gl=cn&x='+x+'&s=&y='+y+'&z='+z
    98
    99
    100
    101 def createLocalFile(x,y,z,lvRange,cacheDir):
    102
    103 #'''创建缓存本地路径'''
    104
    105 #计算<等级目录>名称
    106
    107 i = int(z) - lvRange[0]
    108
    109 l = ''
    110
    111 if i < 10:
    112
    113 l = 'L0' + str(i)
    114
    115 elif i >= 10 and i <= lvRange[len(lvRange) - 1]:
    116
    117 l = 'L' + str(i)
    118
    119 #计算<行目录>和<(列)图片>名称
    120
    121 r = createName(y,'R')
    122
    123 c = createName(x,'C')
    124
    125 #拼装本地路径
    126
    127 return cacheDir + os.sep + l + os.sep + r + os.sep + c + '.png'
    128
    129
    130
    131 def createCacheDir(rowName,lv,row,xRange):
    132
    133 #'''创建缓存目录'''
    134
    135 createDir(rowName)#创建行文件夹
    136
    137 for col in xRange:
    138
    139 #localTile = rowName + os.sep + createName(col,'C') + '.png'
    140
    141 tempTask.append('%s,%s,%s'%(lv,row,col))
    142
    143
    144
    145 def createLvCache(extent,lv,dir):
    146
    147 #'''创建某一等级下一行cache'''
    148
    149 startTile = getTileFromCdt(extent[0],extent[1],lv)
    150
    151 endTile = getTileFromCdt(extent[2],extent[3],lv)
    152
    153 xRange = range(int(startTile.x),int(endTile.x))
    154
    155 yRange = range(int(startTile.y),int(endTile.y))
    156
    157 for row in yRange:
    158
    159 rowName = dir + os.sep + createName(row,'R')
    160
    161 createCacheDir(rowName,lv,row,xRange)
    162
    163
    164
    165 def createCacheStruc(extent,lvRange,cacheDir):
    166
    167 #'''创建缓存目录结构及计算tile'''
    168
    169 global tempTask
    170
    171 tempTask=[]#存储cache下载列表
    172
    173 count = 0
    174
    175 print '创建Cache目录及计算tile数目...'
    176
    177 for lv in lvRange:
    178
    179 lvName = 'L0' + str(count)#lvName:等级文件夹名
    180
    181 createDir(cacheDir +os.sep + lvName)#创建lv等级的文件夹,例如:lv01,lv02...
    182
    183 createLvCache(extent,lv,cacheDir +os.sep + lvName)#创建完等级文件夹后,添加该等级的行文件夹,例如:R000001a0
    184
    185 count += 1
    186
    187
    188
    189 def loadErrorFile(url):
    190
    191 '''
    192
    193 加载错误任务
    194
    195 '''
    196
    197 os.rename(url,url+'bak')
    198
    199 f = open(url+'bak')
    200
    201 return f.readlines()
    202
    203
    204
    205
    206
    207 def loadTask(task,threadNum):
    208
    209 global failureTask
    210
    211 failureTask = []
    212
    213 tasksize = len(task)
    214
    215 threadTask = tasksize//int(threadNum) #取整除 返回商的整数部分
    216
    217 print '待下载Tile总计:%s,下载线程数:%s'%(tasksize,sys.argv[5])
    218
    219
    220
    221 for i in range(len(task)):
    222
    223 #log('开启线程:%s'%i,False)
    224
    225 st = i * int(threadTask)
    226
    227 ed = st + int(threadTask) + 1
    228
    229 if ed > len(task) - 1:
    230
    231 download = Download(task[st:len(task) - 1])
    232
    233 download.start()
    234
    235 break
    236
    237 download = Download(task[st:ed])
    238
    239 download.start()
    240
    241 time.sleep(0.5)
    242
    243
    244
    245
    246
    247 class Download(threading.Thread):
    248
    249 sucessCount = 0
    250
    251 failureCount = 0
    252
    253 def __init__(self,tasks):
    254
    255 threading.Thread.__init__(self)
    256
    257 self.tasks = tasks
    258
    259 self.lock = threading.RLock()
    260
    261 def run(self):
    262
    263 #log('start download',False)
    264
    265 for task in self.tasks:
    266
    267 valueAry = task.split(",")
    268
    269 lv = valueAry[0]
    270
    271 row = valueAry[1]
    272
    273 col = valueAry[2]
    274
    275 remoteFile = createRemoteUrl(col,row,lv)
    276
    277 localFile = createLocalFile(col,row,lv,lvRange,cacheDir)
    278
    279 try:
    280
    281 downloadTile(remoteFile,localFile)
    282
    283 self.lock.acquire()
    284
    285 Download.sucessCount += 1
    286
    287 log('已经下载:%s / %s ,失败: %s / %s'%(Download.sucessCount,len(tempTask),Download.failureCount,len(failureTask)),False)
    288
    289 self.lock.release()
    290
    291 except:
    292
    293 logStr = '%s,%s,%s'%(lv,row,col)
    294
    295 f = file(cacheDir+os.sep+'error.log','a')#在日志文件中打印失败记录
    296
    297 f.write(logStr+'\n')
    298
    299 f.close()
    300
    301 self.lock.acquire()
    302
    303 Download.failureCount += 1
    304
    305 self.lock.release()
    306
    307 failureTask.append(logStr)
    308
    309
    310
    311 def log(event,b):
    312
    313 #'''打印消息或日志'''
    314
    315 try:
    316
    317 logStr = str(event)
    318
    319 if b:#在日志文件中打印消息
    320
    321 f = file(cacheDir+os.sep+str(time.strftime('%Y%m%d%H'))+'.log','a')
    322
    323 f.write(logStr+'\n')
    324
    325 f.close()
    326
    327 sys.stdout.write('\r'+logStr)#在控制台中打印消息
    328
    329 sys.stdout.flush()
    330
    331 except:
    332
    333 pass
    334
    335
    336
    337
    338
    339 if __name__ == '__main__':
    340
    341
    342
    343 extent = sys.argv[1]
    344
    345 maxLv = sys.argv[2]
    346
    347 minLv = sys.argv[3]
    348
    349
    350
    351 global extAry,lvRange,cacheDir,threadNum
    352
    353 ext = [float(i) for i in extent.split(' ')]
    354
    355 extAry = [ext[0],ext[3],ext[2],ext[1]] #区域范围
    356
    357 lvRange = range(int(minLv),int(maxLv) + 1) #等级范围
    358
    359 cacheDir = sys.argv[4] #下载目录
    360
    361 threadNum = sys.argv[5] #下载线程
    362
    363
    364
    365 if sys.argv[1] == 'loadError':
    366
    367 errorTask = loadErrorFile(sys.argv[2]+os.sep+'error.log')
    368
    369 loadTask(tempTask,sys.argv[3])
    370
    371 else:
    372
    373 createCacheStruc(extAry,lvRange,cacheDir) #创建缓存目录结构
    374
    375 loadTask(tempTask,threadNum) #下载
    376
    377

    我的python版本是2.5,装过ArcMap的都默认安装了这个版本。
    执行以上脚本可以在同目录下新建一个批处理文件,内容如下:

    1. python dmc.py "118.411792548134 31.5176549981089 119.43094617187 32.3386680868215" 16 10 c:\caches\jn 20
    2. pause
    复制代码

    "118.411792548134 31.5176549981089 119.43094617187 32.3386680868215" 是待下载的区域范围
    16 10 是下载的等级范围
    c:\caches\jn 是存储目录
    20 是线程数 我的python版本是2.5,装过ArcMap的都默认安装了这个版本。
    执行以上脚本可以在同目录下新建一个批处理文件,内容如下:

    1. python dmc.py "118.411792548134 31.5176549981089 119.43094617187 32.3386680868215" 16 10 c:\caches\jn 20
    2. pause

    "118.411792548134 31.5176549981089 119.43094617187 32.3386680868215" 是待下载的区域范围
    16 10 是下载的等级范围
    c:\caches\jn 是存储目录
    20 是线程数

  • 相关阅读:
    【Docker】命令 restart
    【Docker】命令 rename
    小知识点笔记一(原始版)
    Java常用类——匿名对象
    Java常用类——Arrays工具类
    Java常用类——Scanner类
    Python怎么测试异步接口
    接口测试面试题
    Pycharm使用常见问题
    接口测试命令Httpie的使用
  • 原文地址:https://www.cnblogs.com/liongis/p/1724937.html
Copyright © 2020-2023  润新知