├── earth.ico ├── readme.pdf ├── README.md ├── pdfword.py └── tiledonwload.py /earth.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadassimov/tiledownload/HEAD/earth.ico -------------------------------------------------------------------------------- /readme.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sadassimov/tiledownload/HEAD/readme.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #tiledownload 2 | 3 | ``` 4 | output = output folder 5 | shp = boundary shp data 6 | zoom = map level (there may only be 16 in Gaodeshan District, arcgis is relatively complete, Google requires you to understand) 7 | ``` 8 | 9 | ``` 10 | //Packaging command 11 | Pyinstaller -F -w tiledonwload.py -i earth.ico 12 | ``` 13 | 14 | Please use it in the folder, exe running depends on the proj folder. 15 | 16 | If it gets stuck, please leave it alone, because an error is thrown because the tiles are not acquired (personal level is limited). 17 | 18 | Temporary files are saved under /temp. Remember to delete them. They will also be cleared next time you download them. · 19 | 20 | The actual measured 3 GB Amap map takes 20 minutes to download tiles and 20 minutes to splice into tif. 21 | 22 | If the code is helpful to you, please follow the official account. ^-^ 23 | 24 | Mu who studied gis on a small island 25 | 26 | ## refer to 27 | 28 | https://github.com/jimutt/tiles-to-tiff 29 | #pdfword 30 | 40 lines of code to implement batch conversion of pdf to docx gadget 31 | ## refer to 32 | https://github.com/python-fan/pdf2word 33 | -------------------------------------------------------------------------------- /pdfword.py: -------------------------------------------------------------------------------- 1 | import os 2 | import PySimpleGUI as sg 3 | import sys 4 | from pdf2docx import Converter 5 | 6 | def pdf_to_word(pdf_file_path, word_file_path): 7 | cv = Converter(pdf_file_path) 8 | cv.convert(word_file_path) 9 | cv.close() 10 | 11 | def pdf2doc(pdf_folder): 12 | word_folder = pdf_folder 13 | for file in os.listdir(pdf_folder): 14 | extension_name = os.path.splitext(file)[1] 15 | if extension_name != ".pdf": 16 | continue 17 | file_name = os.path.splitext(file)[0] 18 | pdf_file = pdf_folder + "/" + file 19 | word_file = word_folder + "/" + file_name + ".docx" 20 | print("正在处理: ", file) 21 | pdf_to_word(pdf_file, word_file) 22 | sg.popup('转换完成!word保存于同级目录下') 23 | sys.exit(0) 24 | 25 | def gui(): 26 | layout = [[sg.FolderBrowse('选择pdf文件夹', key='folder', target='file'), sg.Button('开始'), sg.Button('关闭')], 27 | [sg.Text('输出文件夹为:', font=("宋体", 10)), 28 | sg.Text('', key='file', size=(50, 1), font=("宋体", 10))], 29 | [sg.Output(size=(70, 5), font=("宋体", 10))]] 30 | window = sg.Window('pdf转word -_-', layout, font=("宋体", 10), default_element_size=(50, 1), icon='./earth.ico') 31 | while True: 32 | event, values = window.read() 33 | if event in (None, '关闭'): # 如果用户关闭窗口或点击`关闭` 34 | break 35 | if event == '开始': 36 | output = values['folder'] 37 | pdf2doc(output) 38 | 39 | if __name__ == '__main__': 40 | gui() 41 | -------------------------------------------------------------------------------- /tiledonwload.py: -------------------------------------------------------------------------------- 1 | import PySimpleGUI as sg 2 | import urllib.request 3 | import os 4 | import glob 5 | import shutil 6 | from osgeo import gdal 7 | from osgeo import ogr, osr 8 | from math import log, tan, radians, cos, pi, floor, degrees, atan, sinh 9 | 10 | 11 | temp_dir = os.path.join(os.path.dirname(__file__), 'temp') 12 | os.environ['PROJ_LIB'] = r'./proj' 13 | 14 | 15 | def sec(x): 16 | return (1 / cos(x)) 17 | 18 | 19 | def latlon_to_xyz(lat, lon, z): 20 | tile_count = pow(2, z) 21 | x = (lon + 180) / 360 22 | y = (1 - log(tan(radians(lat)) + sec(radians(lat))) / pi) / 2 23 | return (tile_count * x, tile_count * y) 24 | 25 | 26 | def bbox_to_xyz(lon_min, lon_max, lat_min, lat_max, z): 27 | x_min, y_max = latlon_to_xyz(lat_min, lon_min, z) 28 | x_max, y_min = latlon_to_xyz(lat_max, lon_max, z) 29 | return (floor(x_min), floor(x_max), 30 | floor(y_min), floor(y_max)) 31 | 32 | 33 | def mercatorToLat(mercatorY): 34 | return (degrees(atan(sinh(mercatorY)))) 35 | 36 | 37 | def y_to_lat_edges(y, z): 38 | tile_count = pow(2, z) 39 | unit = 1 / tile_count 40 | relative_y1 = y * unit 41 | relative_y2 = relative_y1 + unit 42 | lat1 = mercatorToLat(pi * (1 - 2 * relative_y1)) 43 | lat2 = mercatorToLat(pi * (1 - 2 * relative_y2)) 44 | return (lat1, lat2) 45 | 46 | 47 | def x_to_lon_edges(x, z): 48 | tile_count = pow(2, z) 49 | unit = 360 / tile_count 50 | lon1 = -180 + x * unit 51 | lon2 = lon1 + unit 52 | return (lon1, lon2) 53 | 54 | 55 | def tile_edges(x, y, z): 56 | lat1, lat2 = y_to_lat_edges(y, z) 57 | lon1, lon2 = x_to_lon_edges(x, z) 58 | return [lon1, lat1, lon2, lat2] 59 | 60 | 61 | def fetch_tile(x, y, z, tile_source): 62 | url = tile_source.replace( 63 | "{x}", str(x)).replace( 64 | "{y}", str(y)).replace( 65 | "{z}", str(z)) 66 | 67 | if not tile_source.startswith("http"): 68 | return url.replace("file:///", "") 69 | 70 | path = f'{temp_dir}/{x}_{y}_{z}.png' 71 | urllib.request.urlretrieve(url, path) 72 | return path 73 | 74 | 75 | def merge_tiles(input_pattern, output_path): 76 | vrt_path = temp_dir + "/tiles.vrt" 77 | gdal.BuildVRT(vrt_path, glob.glob(input_pattern)) 78 | gdal.Translate(output_path, vrt_path) 79 | 80 | 81 | def georeference_raster_tile(x, y, z, path): 82 | bounds = tile_edges(x, y, z) 83 | gdal.Translate(os.path.join(temp_dir, f'{temp_dir}/{x}_{y}_{z}.tif'), 84 | path, 85 | outputSRS='EPSG:4326', 86 | outputBounds=bounds) 87 | 88 | 89 | def donwload(tile_source, output_dir, bounding_box, zoom): 90 | lon_min, lat_min, lon_max, lat_max = bounding_box 91 | 92 | # Script start: 93 | if not os.path.exists(temp_dir): 94 | os.makedirs(temp_dir) 95 | 96 | if not os.path.exists(output_dir): 97 | os.makedirs(output_dir) 98 | 99 | x_min, x_max, y_min, y_max = bbox_to_xyz( 100 | lon_min, lon_max, lat_min, lat_max, zoom) 101 | alltiles = (x_max - x_min + 1) * (y_max - y_min + 1) 102 | print(f"总共:{alltiles} 瓦片") 103 | i = 0 104 | for x in range(x_min, x_max + 1): 105 | for y in range(y_min, y_max + 1): 106 | try: 107 | i = i + 1 108 | png_path = fetch_tile(x, y, zoom, tile_source) 109 | print(f"{x},{y} 下载进度{i}/{alltiles}") 110 | georeference_raster_tile(x, y, zoom, png_path) 111 | except OSError: 112 | print(f"错误, failed to get {x},{y}") 113 | pass 114 | 115 | print("下载与转换瓦片成功") 116 | print("整合瓦片中请稍后。。。") 117 | merge_tiles(temp_dir + '/*.tif', output_dir + '/out.tif') 118 | print(f"整合完成!输出至{output_dir}/out.tif'") 119 | shutil.rmtree(temp_dir) 120 | 121 | 122 | def VectorTranslategetexent( 123 | shapeFilePath, 124 | format="GeoJSON", 125 | accessMode=None, 126 | dstSrsESPG=4326, 127 | selectFields=None, 128 | geometryType="POLYGON", 129 | dim="XY", 130 | ): 131 | ogr.RegisterAll() 132 | gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES") 133 | data = ogr.Open(shapeFilePath) 134 | layer = data.GetLayer() 135 | spatial = layer.GetSpatialRef() 136 | layerName = layer.GetName() 137 | data.Destroy() 138 | dstSRS = osr.SpatialReference() 139 | dstSRS.ImportFromEPSG(int(dstSrsESPG)) 140 | dataname = layerName + ".shp" 141 | saveFolderPath = shapeFilePath.replace(dataname, '') 142 | if format == "GeoJSON": 143 | destDataName = layerName + ".json" 144 | destDataPath = os.path.join(saveFolderPath, destDataName) 145 | print(destDataName) 146 | elif format == "ESRI Shapefile": 147 | destDataName = os.path.join(saveFolderPath, layerName) 148 | flag = os.path.exists(destDataName) 149 | os.makedirs(destDataName) if not flag else None 150 | destDataPath = os.path.join(destDataName, layerName + ".shp") 151 | else: 152 | print("不支持该格式!") 153 | return 154 | options = gdal.VectorTranslateOptions( 155 | format=format, 156 | accessMode=accessMode, 157 | srcSRS=spatial, 158 | dstSRS=dstSRS, 159 | reproject=True, 160 | selectFields=selectFields, 161 | layerName=layerName, 162 | geometryType=geometryType, 163 | dim=dim 164 | ) 165 | gdal.VectorTranslate( 166 | destDataPath, 167 | srcDS=shapeFilePath, 168 | options=options 169 | ) 170 | 171 | return extent 172 | 173 | 174 | def gui(): 175 | layout = [ 176 | [sg.FolderBrowse('选择输出文件夹', key='folder', target='file'), sg.Button('开始'), sg.Button('关闭')], 177 | [sg.Text('输出文件夹为:', font=("宋体", 10)), sg.Text('', key='file', size=(50, 1), font=("宋体", 10))], 178 | [sg.Combo(['高德地图', '谷歌地图', '自定义xyz地址'], key='tile_source', default_value='自定义xyz地址', size=(21, 1)), 179 | sg.Text('下载地图级别'), 180 | sg.InputText(size=(20, 1), key='zoom')], 181 | [sg.InputText(size=(70, 1), key='xyzlink')], 182 | [sg.FileBrowse('选择边界shp', key='fileshp', target='shp')], 183 | [sg.Text('输出边界shp为:', font=("宋体", 10)), sg.Text('', key='shp', size=(50, 1), font=("宋体", 10))], 184 | [sg.Output(size=(70, 5), font=("宋体", 10))] 185 | ] 186 | 187 | window = sg.Window('在线地图下载器 -_-', layout, font=("宋体", 10), default_element_size=(50, 1), icon='./proj/earth.ico') 188 | 189 | while True: 190 | event, values = window.read() 191 | if event in (None, '关闭'): # 如果用户关闭窗口或点击`关闭` 192 | break 193 | if event == '开始': 194 | if values['tile_source'] == '高德地图': 195 | tile_source = 'https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}' 196 | elif values['tile_source'] == '谷歌地图': 197 | tile_source = 'http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}' 198 | elif values['tile_source'] == '自定义xyz地址': 199 | tile_source = values['xyzlink'] 200 | output = values['folder'] 201 | zoom = int(values['zoom']) 202 | fileshp = values['fileshp'] 203 | jsonFilePath = fileshp.replace('.shp', '.json') 204 | data = ogr.Open(jsonFilePath) 205 | layer = data.GetLayer() 206 | extent = layer.GetExtent() 207 | donwload(tile_source, output, [extent[0], extent[2], extent[1], extent[3]], zoom) 208 | 209 | 210 | if __name__ == '__main__': 211 | gui() 212 | 213 | VectorTranslategetexent(fileshp) 214 | --------------------------------------------------------------------------------