akashub
fix: re-adding local code files
6afc01a
raw
history blame
4.21 kB
"""Soil Properties Server using Google Earth Engine with lazy initialization"""
import ee
import os
import json
from typing import Dict, Any
class SoilPropertiesServer:
"""Google Earth Engine Soil Server with lazy initialization"""
def __init__(self):
"""Initialize server (GEE will be initialized on first use)"""
self._gee_initialized = False
self.layers = {
"clay": "OpenLandMap/SOL/SOL_CLAY-WFRACTION_USDA-3A1A1A_M/v02",
"sand": "OpenLandMap/SOL/SOL_SAND-WFRACTION_USDA-3A1A1A_M/v02",
"phh2o": "OpenLandMap/SOL/SOL_PH-H2O_USDA-4C1A2A_M/v02",
"soc": "OpenLandMap/SOL/SOL_ORGANIC-CARBON_USDA-6A1C_M/v02"
}
self.depth_band = "b0"
def _initialize_gee(self):
"""Initialize GEE lazily (only when first request is made)"""
if self._gee_initialized:
return
try:
# Check if service account key is provided
service_account_key = os.environ.get('GEE_SERVICE_ACCOUNT_KEY')
if service_account_key:
# Parse JSON key
credentials_dict = json.loads(service_account_key)
credentials = ee.ServiceAccountCredentials(
credentials_dict['client_email'],
key_data=service_account_key
)
ee.Initialize(credentials)
print("✅ GEE initialized with service account (lazy)")
else:
# Fallback to default credentials (for local development)
ee.Initialize(project='MCPprototypeGEE')
print("✅ GEE initialized with default credentials (lazy)")
self._gee_initialized = True
except Exception as e:
print(f"⚠️ GEE lazy initialization failed: {str(e)}")
raise
async def get_data(self, lat: float, lon: float) -> Dict[str, Any]:
"""Get soil properties at coordinate"""
# Initialize GEE on first request (lazy loading)
if not self._gee_initialized:
self._initialize_gee()
try:
point = ee.Geometry.Point([lon, lat])
results = {}
for prop_name, image_id in self.layers.items():
try:
image = ee.Image(image_id).select(self.depth_band)
value = image.sample(point, 250).first().get(self.depth_band).getInfo()
if value is not None:
if prop_name in ['clay', 'sand']:
results[prop_name] = round(value / 10, 1)
elif prop_name == 'phh2o':
results[prop_name] = round(value / 10, 1)
elif prop_name == 'soc':
results[prop_name] = round(value / 10, 1)
else:
results[prop_name] = None
except:
results[prop_name] = None
if not any(v is not None for v in results.values()):
return {
"status": "error",
"error": "No soil data available"
}
silt = None
if results.get("clay") and results.get("sand"):
silt = round(100 - results["clay"] - results["sand"], 1)
return {
"status": "success",
"data": {
"clay_percent": results.get("clay"),
"sand_percent": results.get("sand"),
"silt_percent": silt,
"pH": results.get("phh2o"),
"organic_carbon_g_kg": results.get("soc"),
"data_source": "Google Earth Engine (OpenLandMap)",
"location": {"latitude": lat, "longitude": lon},
"depth": "0-5cm"
}
}
except Exception as e:
return {
"status": "error",
"error": str(e)
}