import os import ee import folium import folium.plugins as plugins # GEE Authentication GEE_CREDENTIALS_FILE = "./data/key/geospatial.json" if not os.path.exists(GEE_CREDENTIALS_FILE): credentials = ee.ServiceAccountCredentials(None, key_data=os.getenv("geospatial_api_key")) else: credentials = ee.ServiceAccountCredentials(None, GEE_CREDENTIALS_FILE) ee.Initialize(credentials) # Constants CLASSES = { "names": ["Water", "Trees", "Flooded Vegetation", "Crops", "Built Area", "Bare Ground", "Snow/Ice", "Clouds", "Rangeland"], "colors": ["1a5bab", "358221", "87d19e", "ffdb5c", "ed022a", "ede9e4", "f2faff", "c8c8c8", "c6ad8d"], } CLOUDY_PIXEL_PERCENTAGE = 12 S2_START_DATE = "2023-08-01" S2_END_DATE = "2023-08-31" S2_LULC_START_DATE = "2023-01-01" S2_LULC_END_DATE = "2023-12-31" S2_VIS_PARAMS = {"bands": ["B4", "B3", "B2"], "min": 0, "max": 3000, "gamma": [1, 1, 1]} # UTILS def ApplyBitwiseS2CloudMask(image): """QA60 bandı üzerinden bitwise bulut maskesi uygular.""" qa = image.select("QA60") cloudBitMask = 1 << 10 # Bit 10: yoğun bulut cirrusBitMask = 1 << 11 # Bit 11: cirrus bulut mask = qa.bitwiseAnd(cloudBitMask).eq(0).And(qa.bitwiseAnd(cirrusBitMask).eq(0)) return image.updateMask(mask) def ReColormap(image, old_colors: list, new_colors: list): """LULC sınıf değerlerini yeniden eşler.""" return image.remap(old_colors, new_colors) def CalculateIntersectionArea(image, roi: ee.Geometry): """Görüntü geometrisi ile ROI arasındaki kesişim alanını hesaplar.""" convex_hull = image.geometry().convexHull() intersection = convex_hull.intersection(roi) return image.set("INTERSECTION_AREA", intersection.area()) def FilterBestAreaOfMGRSJoin(image): """Aynı MGRS tile içinden en büyük kesişim alanına sahip görüntüyü seçer.""" return ee.ImageCollection.fromImages(image.get("mgrs_tile_match")).sort("INTERSECTION_AREA", False).first() def AddGEELayer(fmap: folium.Map, ee_image, vis_params: dict, name: str, show: bool = True): """GEE imajını folium haritasına tile katmanı olarak ekler.""" map_id = ee_image.getMapId(vis_params) tile_url = map_id["tile_fetcher"].url_format folium.TileLayer(tiles=tile_url, attr="Google Earth Engine", name=name, overlay=True, control=True, show=show).add_to(fmap) def RequestFunction(roi_coords: list) -> folium.Map: """ Verilen koordinat listesinden Sentinel-2 ve ESRI LULC katmanlarını içeren bir Folium haritası döndürür. """ if not roi_coords: return None roi = ee.Geometry.Polygon(roi_coords) # ROI merkezini hesapla (harita başlangıç konumu) centroid = roi.centroid().getInfo()["coordinates"] center_lat = centroid[1] center_lon = centroid[0] # Sentinel-2 koleksiyonu S2Collection = ( ee.ImageCollection("COPERNICUS/S2_HARMONIZED") .filterBounds(roi) .filterDate(S2_START_DATE, S2_END_DATE) .filter(ee.Filter.lt("CLOUDY_PIXEL_PERCENTAGE", CLOUDY_PIXEL_PERCENTAGE)) .sort("CLOUDY_PIXEL_PERCENTAGE", ascending=True) ) # ESRI LULC koleksiyonu esriLULCCollection = ee.ImageCollection("projects/sat-io/open-datasets/landcover/ESRI_Global-LULC_10m_TS").filterDate( S2_LULC_START_DATE, S2_LULC_END_DATE ) esriLULCCollection = ee.ImageCollection(esriLULCCollection.mosaic().clip(roi)).map( lambda img: ReColormap(img, [1, 2, 4, 5, 7, 8, 9, 10, 11], [1, 2, 3, 4, 5, 6, 7, 8, 9]) ) # Bulut maskeleme S2Collection = S2Collection.map(ApplyBitwiseS2CloudMask) # Alan hesaplama ve MGRS tile eşleştirme S2Collection = S2Collection.map(lambda img: CalculateIntersectionArea(img, roi)).sort("INTERSECTION_AREA", False) joinCol = ee.Join.saveAll("mgrs_tile_match").apply( primary=S2Collection.distinct("MGRS_TILE"), secondary=S2Collection, condition=ee.Filter.equals(leftField="MGRS_TILE", rightField="MGRS_TILE"), ) bestCollection = ee.ImageCollection(joinCol.map(FilterBestAreaOfMGRSJoin)) s2Image = bestCollection.mosaic().clip(roi) # LULC maskesi: yalnızca geçerli S2 piksellerini göster esriLULCImage = esriLULCCollection.first().updateMask(s2Image.select("B4").gt(0)) # Folium MAP fmap = folium.Map(location=[center_lat, center_lon], zoom_start=10, tiles=None) # Temel katman folium.TileLayer(tiles="https://tile.openstreetmap.org/{z}/{x}/{y}.png", attr="OpenStreetMap", name="OpenStreetMap", show=True).add_to( fmap ) folium.TileLayer( tiles="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}", attr="Esri", name="Esri Uydu" ).add_to(fmap) # ROI sınırı roi_geojson = roi.getInfo() folium.GeoJson(roi_geojson, name="Pilot Bölge", style_function=lambda x: {"color": "black", "weight": 2, "fillOpacity": 0}).add_to(fmap) # GEE katmanları AddGEELayer(fmap, s2Image, S2_VIS_PARAMS, "Sentinel-2 RGB") AddGEELayer(fmap, esriLULCImage, {"min": 1, "max": 9, "palette": CLASSES["colors"]}, "ESRI LULC") folium.LayerControl(position="bottomleft").add_to(fmap) plugins.Fullscreen(position="topright").add_to(fmap) return fmap