utils.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. # -*- coding: utf-8 -*-
  2. """
  3. Utils functions GEE
  4. """
  5. import json
  6. import qgis
  7. from qgis.core import QgsProject
  8. from qgis.core import QgsRasterLayer
  9. from qgis.core import QgsMessageLog
  10. from qgis.core import QgsCoordinateReferenceSystem, QgsCoordinateTransform
  11. from qgis.core import QgsPointXY, QgsRectangle
  12. from qgis.core import QgsDataProvider
  13. from qgis.utils import iface
  14. import ee
  15. import ee_plugin
  16. def get_ee_image_url(image):
  17. map_id = ee.data.getMapId({'image': image})
  18. url = map_id['tile_fetcher'].url_format
  19. return url
  20. def update_ee_layer_properties(layer, eeObject, visParams, shown, opacity):
  21. layer.dataProvider().set_ee_object(eeObject)
  22. layer.setCustomProperty('ee-layer', True)
  23. if not (opacity is None):
  24. renderer = layer.renderer()
  25. if renderer:
  26. renderer.setOpacity(opacity)
  27. # serialize EE code
  28. ee_object = eeObject.serialize()
  29. ee_object_vis = json.dumps(visParams)
  30. layer.setCustomProperty('ee-plugin-version', ee_plugin.ee_plugin.VERSION)
  31. layer.setCustomProperty('ee-object', ee_object)
  32. layer.setCustomProperty('ee-object-vis', ee_object_vis)
  33. # update EE script in provider
  34. if eeObject.getInfo()['type'] == 'Image': # TODO
  35. layer.dataProvider().set_ee_object(eeObject)
  36. def add_ee_image_layer(image, name, shown, opacity):
  37. check_version()
  38. url = "type=xyz&url=" + get_ee_image_url(image)
  39. # EE raster data provider
  40. if image.ee_type == ee.Image:
  41. layer = QgsRasterLayer(url, name, "EE")
  42. # EE vector data provider
  43. if image.ee_type in [ee.Geometry, ee.Feature]:
  44. # TODO
  45. layer = QgsRasterLayer(url, name, "wms")
  46. # EE raster collection data provider
  47. if image.ee_type == ee.ImageCollection:
  48. # TODO
  49. layer = QgsRasterLayer(url, name, "wms")
  50. # EE vector collection data provider
  51. if image.ee_type == ee.FeatureCollection:
  52. # TODO
  53. layer = QgsRasterLayer(url, name, "wms")
  54. QgsProject.instance().addMapLayer(layer)
  55. if not (shown is None):
  56. QgsProject.instance().layerTreeRoot().findLayer(
  57. layer.id()).setItemVisibilityChecked(shown)
  58. return layer
  59. def update_ee_image_layer(image, layer, shown=True, opacity=1.0):
  60. check_version()
  61. url = "type=xyz&url=" + get_ee_image_url(image)
  62. root = QgsProject.instance().layerTreeRoot()
  63. layer_node = root.findLayer(layer) # layer is a QgsMapLayer
  64. parent_group = layer_node.parent()
  65. # Get layer index
  66. idx = parent_group.children().index(layer_node)
  67. # new layer
  68. layer_new = QgsRasterLayer(url, layer.name(), "EE")
  69. # Remove old layer
  70. QgsProject.instance().removeMapLayers([layer.id()])
  71. QgsProject.instance().addMapLayer(layer_new, False)
  72. root.insertLayer(idx, layer_new)
  73. layer = layer_new
  74. item = QgsProject.instance().layerTreeRoot().findLayer(layer.id())
  75. if not (shown is None):
  76. item.setItemVisibilityChecked(shown)
  77. return layer
  78. def get_layer_by_name(name):
  79. layers = QgsProject.instance().mapLayers().values()
  80. for l in layers:
  81. if l.name() == name:
  82. return l
  83. return None
  84. def add_or_update_ee_layer(eeObject, visParams, name, shown, opacity):
  85. if visParams is None:
  86. visParams = {}
  87. if isinstance(eeObject, ee.Image):
  88. image = eeObject.visualize(**visParams)
  89. elif isinstance(eeObject, (ee.Geometry, ee.Feature, ee.ImageCollection, ee.FeatureCollection)):
  90. features = ee.FeatureCollection(eeObject)
  91. if 'width' in visParams:
  92. width = visParams['width']
  93. else:
  94. width = 2
  95. if 'color' in visParams:
  96. color = visParams['color']
  97. else:
  98. color = '000000'
  99. image_fill = features.style(**{'fillColor': color}).updateMask(ee.Image.constant(0.5))
  100. image_outline = features.style(**{'color': color, 'fillColor': '00000000', 'width': width})
  101. image = image_fill.blend(image_outline)
  102. else:
  103. err_str = "\n\nThe image argument in 'addLayer' function must be an instance of one of ee.Image, ee.Geometry, " \
  104. "ee.Feature, ee.ImageCollection or ee.FeatureCollection."
  105. raise AttributeError(err_str)
  106. if name is None:
  107. # extract name from id
  108. try:
  109. name = json.loads(eeObject.id().serialize())[
  110. "scope"][0][1]["arguments"]["id"]
  111. except:
  112. name = "untitled"
  113. image.ee_type = type(eeObject)
  114. layer = add_or_update_ee_image_layer(image, name, shown, opacity)
  115. update_ee_layer_properties(layer, eeObject, visParams, shown, opacity)
  116. def add_or_update_ee_image_layer(image, name, shown=True, opacity=1.0):
  117. layer = get_layer_by_name(name)
  118. if layer:
  119. if not layer.customProperty('ee-layer'):
  120. raise Exception('Layer is not an EE layer: ' + name)
  121. layer = update_ee_image_layer(image, layer, shown, opacity)
  122. else:
  123. layer = add_ee_image_layer(image, name, shown, opacity)
  124. return layer
  125. def add_ee_catalog_image(name, asset_name, visParams, collection_props):
  126. image = None
  127. if collection_props:
  128. raise Exception('Not supported yet')
  129. else:
  130. image = ee.Image(asset_name).visualize(visParams)
  131. add_or_update_ee_image_layer(image, name)
  132. def check_version():
  133. # check if we have the latest version only once plugin is used, not once it is loaded
  134. qgis.utils.plugins['ee_plugin'].check_version()
  135. def geom_to_geo(geom):
  136. crs_src = QgsCoordinateReferenceSystem(QgsProject.instance().crs())
  137. crs_dst = QgsCoordinateReferenceSystem('EPSG:4326')
  138. proj2geo = QgsCoordinateTransform(crs_src, crs_dst, QgsProject.instance())
  139. if isinstance(geom, QgsPointXY):
  140. return proj2geo.transform(geom)
  141. elif isinstance(geom, QgsRectangle):
  142. return proj2geo.transformBoundingBox(geom)
  143. else:
  144. return geom.transform(proj2geo)