Files
Ai/location_data/models.py
T
2026-03-22 03:08:27 +03:30

117 lines
3.9 KiB
Python

from django.db import models
class SoilLocation(models.Model):
"""
مختصات جغرافیایی برای داده‌های خاک.
هر مختصات سه سطر در SoilDepthData دارد (۰–۵، ۵–۱۵، ۱۵–۳۰ سانتی‌متر).
"""
latitude = models.DecimalField(
max_digits=9,
decimal_places=6,
db_index=True,
help_text="عرض جغرافیایی (lat)",
)
longitude = models.DecimalField(
max_digits=9,
decimal_places=6,
db_index=True,
help_text="طول جغرافیایی (lon)",
)
task_id = models.CharField(
max_length=255,
blank=True,
help_text="شناسه تسک Celery در حال پردازش",
)
ideal_sensor_profile = models.JSONField(
default=dict,
blank=True,
help_text=(
"پروفایل ایده‌آل سنسورها برای این مزرعه/لوکیشن. "
'نمونه: {"moisture": {"ideal": 0.65, "min": 0.50, "max": 0.80}}'
),
)
farm_boundary = models.JSONField(
default=dict,
blank=True,
help_text=(
"مرز مزرعه برای درخواست‌های سنجش‌ازدور. "
'می‌تواند GeoJSON polygon یا bbox مثل {"type": "Polygon", "coordinates": [...]} باشد.'
),
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["latitude", "longitude"],
name="soil_location_unique_lat_lon",
)
]
ordering = ["-updated_at"]
def __str__(self):
return f"SoilLocation({self.latitude}, {self.longitude})"
@property
def is_complete(self):
"""آیا هر سه عمق ذخیره شده‌اند؟"""
return self.depths.count() == 3
class SoilDepthData(models.Model):
"""
داده‌های خاک برای یک عمق مشخص، مرتبط با یک SoilLocation.
مقادیر خام از API SoilGrids (قبل از اعمال d_factor).
"""
DEPTH_0_5 = "0-5cm"
DEPTH_5_15 = "5-15cm"
DEPTH_15_30 = "15-30cm"
DEPTH_CHOICES = [
(DEPTH_0_5, "۰–۵ سانتی‌متر"),
(DEPTH_5_15, "۵–۱۵ سانتی‌متر"),
(DEPTH_15_30, "۱۵–۳۰ سانتی‌متر"),
]
soil_location = models.ForeignKey(
SoilLocation,
on_delete=models.CASCADE,
related_name="depths",
)
depth_label = models.CharField(
max_length=10,
choices=DEPTH_CHOICES,
db_index=True,
)
# خواص خاک — مقادیر mean از API (raw)
bdod = models.FloatField(null=True, blank=True)
cec = models.FloatField(null=True, blank=True)
cfvo = models.FloatField(null=True, blank=True)
clay = models.FloatField(null=True, blank=True)
nitrogen = models.FloatField(null=True, blank=True)
ocd = models.FloatField(null=True, blank=True)
ocs = models.FloatField(null=True, blank=True)
phh2o = models.FloatField(null=True, blank=True)
sand = models.FloatField(null=True, blank=True)
silt = models.FloatField(null=True, blank=True)
soc = models.FloatField(null=True, blank=True)
wv0010 = models.FloatField(null=True, blank=True)
wv0033 = models.FloatField(null=True, blank=True)
wv1500 = models.FloatField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["soil_location", "depth_label"],
name="soil_depth_unique_location_depth",
)
]
ordering = ["soil_location", "depth_label"]
def __str__(self):
return f"SoilDepthData({self.soil_location_id}, {self.depth_label})"