5
0

slice.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. import json
  2. import os
  3. import piexif
  4. from starearth import Filename, Scene, GridFactory
  5. from starearth import Nodata, Slicer
  6. from starearth.coordinate import EPSG, Coordinate
  7. from starearth.output.raw import OutputRAW
  8. from starearth.output.png import OutputPNG
  9. from starearth.output.jpeg import OutputJPEG
  10. from starearth.renderer.greyscale import RendererGreyscale
  11. from starearth.renderer.rgb import RendererRGB
  12. from starearth.sheet import Sheet
  13. from starearth.utils.general_utils import print_log
  14. def get_size(path):
  15. total_size = 0
  16. for dirpath, dirnames, filenames in os.walk(path):
  17. for f in filenames:
  18. fp = os.path.join(dirpath, f)
  19. # skip if it is symbolic link
  20. if not os.path.islink(fp):
  21. total_size += os.path.getsize(fp)
  22. return total_size
  23. class Accessory:
  24. def __init__(self):
  25. pass
  26. def structure_exif_dict(self, properties):
  27. """构造一个exif_dict字典,这样不用写多条exif信息"""
  28. date = properties.get('date', '')
  29. date_time = properties.get('date_time', '')
  30. eoc = properties.get('eoc', '')
  31. eop = properties.get('eop', '')
  32. eoi = properties.get('eoi', '')
  33. res = properties.get('res', '')
  34. eopd = properties.get('eopd', '')
  35. eopc = properties.get('eopc', '')
  36. user = properties.get('user', '')
  37. disp = properties.get('disp', 0)
  38. bk1 = properties.get('bk1', '')
  39. bk2 = properties.get('bk2', '')
  40. bk3 = properties.get('bk3', '')
  41. exif_dict = {'Exif': {}, '0th': {}, 'Interop': {}, '1st': {}, 'thumbnail': None, 'GPS': {}}
  42. _time = date or date_time or 'defalut'
  43. description = '%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s' % (eoc, eop, eoi, res, eopd, eopc, user, bk1, bk2, bk3, disp)
  44. zeroth_ifd = {
  45. piexif.ImageIFD.ImageDescription: description.encode('unicode_escape').decode('ascii'),
  46. piexif.ImageIFD.DateTime: date_time,
  47. }
  48. add_exif_dict = {"0th": zeroth_ifd} # 使用0th这个key
  49. exif_dict = dict(exif_dict, **add_exif_dict) # 将构造的exif_dict添加到照片原有的exif_dict中
  50. return piexif.dump(exif_dict), _time # 返回最终的exif_dicttile_content
  51. def get_coordinate(coordinates, all_coordinates):
  52. for coordinate in coordinates:
  53. if not isinstance(coordinate[0], list):
  54. all_coordinates.append(coordinate)
  55. pass
  56. else:
  57. get_coordinate(coordinate, all_coordinates)
  58. pass
  59. pass
  60. def calc_bbox(coordinates):
  61. longitude_max = -180
  62. longitude_min = 180
  63. latitude_max = -90
  64. latitude_min = 90
  65. # 获取所有单独的coordinate
  66. all_coordinate = []
  67. get_coordinate(coordinates, all_coordinate)
  68. # 获取bbox范围
  69. for coordinate in all_coordinate:
  70. longitude_max = max(longitude_max, coordinate[0])
  71. longitude_min = min(longitude_min, coordinate[0])
  72. latitude_max = max(latitude_max, coordinate[1])
  73. latitude_min = min(latitude_min, coordinate[1])
  74. bbox = [longitude_min, latitude_min, longitude_max, latitude_max]
  75. return bbox
  76. def slice \
  77. (
  78. input_file, tile_grid, tile_size, tmp_tiles, epsg=None,
  79. nodata=None, tile_format='png', min_zoom=None, max_zoom=None,
  80. enable_msmt=0, channels=None, lut=None, render_type=None
  81. ):
  82. sliceTiler = GridFactory.create(tile_grid)
  83. # 格式化
  84. tile_format = tile_format.strip().lower()
  85. if render_type:
  86. render_type = render_type.strip().upper()
  87. # new_input_file = filesystem.resolve(input_file)
  88. filename = Filename(input_file)
  89. base_name = os.path.splitext(input_file)[0]
  90. geojsonl = base_name + '.geojsonl'
  91. scene = Scene()
  92. scene.load(filename)
  93. coordinate = None
  94. if sliceTiler.identifier == 'WGS1984Quad':
  95. pass
  96. elif sliceTiler.identifier == 'WebMercatorQuad':
  97. coordinate = Coordinate.EPSG_3857
  98. elif sliceTiler.identifier == 'GoogleEarthQuad':
  99. coordinate = Coordinate.EPSG_4326
  100. # 瓦片成果是否携带时相信息
  101. msmt_accessory = Accessory() if enable_msmt else None
  102. # min_zoom, max_zoom = 12, 13 # 测试用,手动设置一个级别范围
  103. print_log('min-max:%s-%s' % (min_zoom, max_zoom))
  104. # star_time = time.time()
  105. # 选择不同的渲染类型
  106. if render_type == 'RGB':
  107. # 彩色渲染
  108. renderer = RendererRGB(scene.datatype, channels, nodata)
  109. elif render_type == 'GREYSCALE':
  110. # 灰度图的渲染
  111. renderer = RendererGreyscale(scene.datatype, lut, nodata)
  112. else:
  113. renderer = None
  114. if tile_format == 'png':
  115. output = OutputPNG \
  116. (
  117. tmp_tiles,
  118. msmt_accessory,
  119. renderer=renderer
  120. )
  121. pass
  122. elif tile_format == 'jpeg':
  123. output = OutputJPEG \
  124. (
  125. tmp_tiles,
  126. msmt_accessory,
  127. renderer=renderer
  128. )
  129. else:
  130. output = OutputRAW \
  131. (
  132. tmp_tiles,
  133. msmt_accessory,
  134. nodata=Nodata([nodata for _ in range(scene.bands)]),
  135. )
  136. square = tile_size
  137. slicer = Slicer(scene, square, output, sliceTiler)
  138. sheets = None
  139. if filename.geojsonl:
  140. sheets = Sheet.parse_geojsonl(filename.geojsonl)
  141. if isinstance(epsg, str):
  142. epsg_id = int(epsg.split(':')[-1])
  143. else:
  144. epsg_id = epsg
  145. slicer.slice(min_zoom, max_zoom, epsg_id, sheets, coordinate=coordinate)
  146. # slicer._slice_sp(min_zoom, max_zoom, epsg_id, sheets)
  147. # 瓦片列表写入文件
  148. with open(geojsonl, 'r') as f:
  149. new_feature = json.loads(f.read())
  150. date = new_feature['properties']['date']
  151. tiles = sliceTiler.tiles([new_feature], min_zoom, max_zoom)
  152. tiles_list_json = tmp_tiles.path(date).resolve('tiles_list.json')
  153. exist_tiles_list_json = []
  154. if os.path.exists(tiles_list_json):
  155. with open(tiles_list_json, 'r', encoding='utf-8') as fp:
  156. exist_tiles_list_json = json.load(fp)
  157. with open(tiles_list_json, 'w') as fp:
  158. if exist_tiles_list_json:
  159. for tile in exist_tiles_list_json:
  160. if tile not in tiles:
  161. tiles.append(tile)
  162. json.dump(tiles, fp)
  163. # tiles_nums = 0
  164. # tiles_nums += len(tiles)
  165. # end_time = time.time()
  166. # print_log('切片数量为:{} 个'.format(tiles_nums))
  167. # print_log("切片用时: {}'s".format(end_time - star_time))