geospatial / lib.py
blitzkrieg0000's picture
Update lib.py
8cea36d verified
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