UPDATE
This commit is contained in:
@@ -0,0 +1,371 @@
|
||||
# ساختار فعلی `location_data`
|
||||
|
||||
این فایل وضعیت فعلی اپ `location_data` را توضیح میدهد؛ هم از نظر ساختار فایلها و هم از نظر مدلها، APIها و جریان داده.
|
||||
|
||||
## هدف فعلی اپ
|
||||
|
||||
اپ `location_data` فعلاً این مسئولیتها را دارد:
|
||||
|
||||
- نگهداری موقعیت زمین با `lat` و `lon`
|
||||
- نگهداری مرز مزرعه در `farm_boundary`
|
||||
- نگهداری ساختار بلوکهای زمین در `block_layout`
|
||||
- نگهداری دادههای خاک برای عمقهای مختلف در `SoilDepthData`
|
||||
- نگهداری مشاهدات NDVI در `NdviObservation`
|
||||
- برگرداندن ساختار بلوکهای زمین از API محلی بدون نیاز به API خارجی در فاز فعلی
|
||||
|
||||
نکته مهم:
|
||||
|
||||
- در فاز فعلی، endpoint اصلی `location_data` برای ساختار زمین، فقط داده را در دیتابیس میخواند/ذخیره میکند.
|
||||
- فعلاً برای بلوکها، زیربلوکها و دادههای ماهوارهای هیچ درخواست خارجی زده نمیشود.
|
||||
|
||||
## ساختار فایلها
|
||||
|
||||
```text
|
||||
location_data/
|
||||
├── admin.py
|
||||
├── apps.py
|
||||
├── models.py
|
||||
├── serializers.py
|
||||
├── views.py
|
||||
├── urls.py
|
||||
├── tasks.py
|
||||
├── soil_adapters.py
|
||||
├── remote_sensing.py
|
||||
├── ndvi.py
|
||||
├── test_soil_api.py
|
||||
├── test_soil_adapters.py
|
||||
├── test_ndvi_health_api.py
|
||||
├── postman/
|
||||
│ └── soil_data.json
|
||||
├── management/
|
||||
│ └── commands/
|
||||
└── migrations/
|
||||
├── 0001_initial.py
|
||||
├── 0002_soildepthdata_refactor.py
|
||||
├── 0002_soillocation_ideal_sensor_profile.py
|
||||
├── 0003_rename_app_label.py
|
||||
├── 0004_soillocation_farm_boundary.py
|
||||
├── 0005_merge_20260327_0840.py
|
||||
├── 0006_remove_soillocation_ideal_sensor_profile.py
|
||||
├── 0007_ndviobservation.py
|
||||
└── 0008_soillocation_block_layout.py
|
||||
```
|
||||
|
||||
## مدلها و جدولها
|
||||
|
||||
### 1) `SoilLocation`
|
||||
|
||||
مدل اصلی اپ است و نماینده یک موقعیت یکتا برای زمین یا مرکز زمین محسوب میشود.
|
||||
|
||||
فیلدهای اصلی:
|
||||
|
||||
| فیلد | نوع | توضیح |
|
||||
|---|---|---|
|
||||
| `id` | `BigAutoField` | شناسه داخلی رکورد |
|
||||
| `latitude` | `DecimalField(9,6)` | عرض جغرافیایی |
|
||||
| `longitude` | `DecimalField(9,6)` | طول جغرافیایی |
|
||||
| `task_id` | `CharField` | شناسه تسک Celery برای جریان قدیمی واکشی خاک |
|
||||
| `farm_boundary` | `JSONField` | مرز مزرعه به شکل Polygon یا corners |
|
||||
| `input_block_count` | `PositiveIntegerField` | تعداد بلوک اولیهای که از ورودی کشاورز میآید |
|
||||
| `block_layout` | `JSONField` | ساختار بلوکها و زیربلوکهای زمین |
|
||||
| `created_at` | `DateTimeField` | زمان ایجاد |
|
||||
| `updated_at` | `DateTimeField` | زمان آخرین تغییر |
|
||||
|
||||
قیدها:
|
||||
|
||||
- روی ترکیب `latitude` و `longitude` یکتا است.
|
||||
|
||||
رفتار مهم:
|
||||
|
||||
- اگر `input_block_count` ارسال نشود، مقدار پیشفرض `1` است.
|
||||
- اگر `block_layout` خالی باشد، به صورت خودکار با یک بلوک کامل ساخته میشود.
|
||||
- متد `set_input_block_count()` ساختار اولیه بلوکها را میسازد.
|
||||
|
||||
### 2) `SoilDepthData`
|
||||
|
||||
این مدل دادههای خاک را برای هر عمق نگه میدارد و به `SoilLocation` وصل است.
|
||||
|
||||
عمقهای فعلی:
|
||||
|
||||
- `0-5cm`
|
||||
- `5-15cm`
|
||||
- `15-30cm`
|
||||
|
||||
فیلدهای مهم:
|
||||
|
||||
| فیلد | نوع | توضیح |
|
||||
|---|---|---|
|
||||
| `soil_location` | `ForeignKey` | ارتباط با `SoilLocation` |
|
||||
| `depth_label` | `CharField` | برچسب عمق |
|
||||
| `bdod` تا `wv1500` | `FloatField` | پارامترهای مختلف خاک |
|
||||
| `created_at` | `DateTimeField` | زمان ثبت رکورد |
|
||||
|
||||
قیدها:
|
||||
|
||||
- برای هر `soil_location` و هر `depth_label` فقط یک رکورد وجود دارد.
|
||||
|
||||
### 3) `NdviObservation`
|
||||
|
||||
این مدل برای ذخیره مشاهدههای NDVI استفاده میشود.
|
||||
|
||||
فیلدهای مهم:
|
||||
|
||||
| فیلد | نوع | توضیح |
|
||||
|---|---|---|
|
||||
| `location` | `ForeignKey` | ارتباط با `SoilLocation` |
|
||||
| `observation_date` | `DateField` | تاریخ مشاهده |
|
||||
| `mean_ndvi` | `FloatField` | میانگین NDVI |
|
||||
| `ndvi_map` | `JSONField` | داده مکانی NDVI |
|
||||
| `vegetation_health_class` | `CharField` | کلاس سلامت پوشش گیاهی |
|
||||
| `satellite_source` | `CharField` | منبع تصویر ماهوارهای |
|
||||
| `cloud_cover` | `FloatField` | درصد ابر |
|
||||
| `metadata` | `JSONField` | داده تکمیلی |
|
||||
|
||||
## ساختار `block_layout`
|
||||
|
||||
فیلد `block_layout` فعلاً ساختار پایه تقسیم زمین را نگه میدارد.
|
||||
|
||||
نمونه پیشفرض وقتی کل زمین یک بلوک باشد:
|
||||
|
||||
```json
|
||||
{
|
||||
"input_block_count": 1,
|
||||
"default_full_farm": true,
|
||||
"algorithm_status": "pending",
|
||||
"blocks": [
|
||||
{
|
||||
"block_code": "block-1",
|
||||
"order": 1,
|
||||
"source": "default",
|
||||
"needs_subdivision": null,
|
||||
"sub_blocks": []
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
نمونه وقتی ورودی مثلاً `block_count = 3` باشد:
|
||||
|
||||
```json
|
||||
{
|
||||
"input_block_count": 3,
|
||||
"default_full_farm": false,
|
||||
"algorithm_status": "pending",
|
||||
"blocks": [
|
||||
{
|
||||
"block_code": "block-1",
|
||||
"order": 1,
|
||||
"source": "input",
|
||||
"needs_subdivision": null,
|
||||
"sub_blocks": []
|
||||
},
|
||||
{
|
||||
"block_code": "block-2",
|
||||
"order": 2,
|
||||
"source": "input",
|
||||
"needs_subdivision": null,
|
||||
"sub_blocks": []
|
||||
},
|
||||
{
|
||||
"block_code": "block-3",
|
||||
"order": 3,
|
||||
"source": "input",
|
||||
"needs_subdivision": null,
|
||||
"sub_blocks": []
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
معنای فیلدها:
|
||||
|
||||
| فیلد | توضیح |
|
||||
|---|---|
|
||||
| `input_block_count` | تعداد بلوک اولیه |
|
||||
| `default_full_farm` | آیا کل زمین هنوز یک بلوک کامل است یا نه |
|
||||
| `algorithm_status` | وضعیت اجرای الگوریتم تقسیمبندی |
|
||||
| `blocks` | لیست بلوکهای فعلی |
|
||||
| `block_code` | کد بلوک |
|
||||
| `order` | ترتیب بلوک |
|
||||
| `source` | منشأ بلوک: `default` یا `input` |
|
||||
| `needs_subdivision` | آیا الگوریتم تشخیص داده که این بلوک باید خردتر شود یا نه |
|
||||
| `sub_blocks` | لیست زیربلوکها |
|
||||
|
||||
## Serializerها
|
||||
|
||||
### `SoilDataRequestSerializer`
|
||||
|
||||
ورودی endpoint اصلی `location_data`:
|
||||
|
||||
| فیلد | اجباری | توضیح |
|
||||
|---|---|---|
|
||||
| `lat` | بله | عرض جغرافیایی |
|
||||
| `lon` | بله | طول جغرافیایی |
|
||||
| `block_count` | خیر | تعداد بلوک اولیه، پیشفرض `1` |
|
||||
|
||||
### `SoilLocationResponseSerializer`
|
||||
|
||||
خروجی اصلی برای یک location:
|
||||
|
||||
- `id`
|
||||
- `lat`
|
||||
- `lon`
|
||||
- `input_block_count`
|
||||
- `block_layout`
|
||||
- `depths`
|
||||
|
||||
### `SoilDepthDataSerializer`
|
||||
|
||||
لیست پارامترهای خاک برای هر عمق را برمیگرداند.
|
||||
|
||||
### `NdviHealthRequestSerializer` و `NdviHealthResponseSerializer`
|
||||
|
||||
برای endpoint مربوط به NDVI استفاده میشوند.
|
||||
|
||||
## Viewها و APIها
|
||||
|
||||
### 1) `SoilDataView`
|
||||
|
||||
مسیر:
|
||||
|
||||
- `GET /api/soil-data/`
|
||||
- `POST /api/soil-data/`
|
||||
|
||||
وظیفه فعلی:
|
||||
|
||||
- گرفتن `lat` و `lon`
|
||||
- گرفتن `block_count` در صورت وجود
|
||||
- ساخت یا پیدا کردن `SoilLocation`
|
||||
- ذخیره `input_block_count`
|
||||
- ساخت `block_layout`
|
||||
- برگرداندن پاسخ با `source = local`
|
||||
|
||||
رفتار فعلی:
|
||||
|
||||
- اگر location وجود نداشته باشد، ساخته میشود.
|
||||
- اگر `block_count` تغییر کند، ساختار `block_layout` دوباره ساخته میشود.
|
||||
- فعلاً هیچ fetch خارجی برای اطلاعات خاک یا ماهوارهای انجام نمیشود.
|
||||
|
||||
### 2) `SoilDataTaskStatusView`
|
||||
|
||||
مسیر:
|
||||
|
||||
- `GET /api/soil-data/tasks/<task_id>/status/`
|
||||
|
||||
وضعیت فعلی:
|
||||
|
||||
- هنوز در کد وجود دارد.
|
||||
- برای جریان قدیمی مبتنی بر Celery طراحی شده است.
|
||||
- با تغییر اخیر، endpoint اصلی `location_data` دیگر بهطور پیشفرض task جدیدی صف نمیکند.
|
||||
|
||||
### 3) `NdviHealthView`
|
||||
|
||||
مسیر:
|
||||
|
||||
- `POST /api/soil-data/ndvi-health/`
|
||||
|
||||
وظیفه:
|
||||
|
||||
- دریافت `farm_uuid`
|
||||
- خواندن داده NDVI از سرویس داخلی NDVI
|
||||
- برگرداندن اطلاعات سلامت پوشش گیاهی
|
||||
|
||||
## فایل `tasks.py`
|
||||
|
||||
این فایل هنوز منطق قدیمی واکشی داده خاک را نگه میدارد.
|
||||
|
||||
اجزای اصلی:
|
||||
|
||||
- `fetch_soil_data_for_coordinates()`
|
||||
- `fetch_soil_data_task()`
|
||||
|
||||
نکته:
|
||||
|
||||
- این بخش هنوز برای سازگاری و جریانهای قدیمی در پروژه باقی مانده است.
|
||||
- ولی در فاز فعلی تقسیم بلوکها، از این task برای endpoint اصلی `location_data` استفاده نمیشود.
|
||||
|
||||
## فایل `soil_adapters.py`
|
||||
|
||||
این فایل abstraction مربوط به تامین داده خاک را نگه میدارد.
|
||||
|
||||
کاربرد آن:
|
||||
|
||||
- mock provider
|
||||
- live soil provider
|
||||
- ساختار depth-based data fetch
|
||||
|
||||
در وضعیت فعلی:
|
||||
|
||||
- برای منطق بلوکبندی فعلی لازم نیست.
|
||||
- اما برای جریان قدیمی یا مراحل بعدی میتواند دوباره استفاده شود.
|
||||
|
||||
## فایل `remote_sensing.py`
|
||||
|
||||
این فایل مربوط به منطق سنجشازدور و دادههای ماهوارهای است.
|
||||
|
||||
در وضعیت فعلی:
|
||||
|
||||
- برای block layout فعلاً استفاده فعال ندارد.
|
||||
- بعداً میتواند برای تحلیل هر بلوک یا زیربلوک استفاده شود.
|
||||
|
||||
## فایل `ndvi.py`
|
||||
|
||||
این فایل سرویس/منطق NDVI را نگه میدارد و برای endpoint NDVI استفاده میشود.
|
||||
|
||||
## migrationها
|
||||
|
||||
مهمترین migrationهای فعلی:
|
||||
|
||||
| migration | توضیح |
|
||||
|---|---|
|
||||
| `0001_initial.py` | ساختار اولیه `SoilLocation` |
|
||||
| `0002_soildepthdata_refactor.py` | جداسازی دادههای عمقی در `SoilDepthData` |
|
||||
| `0004_soillocation_farm_boundary.py` | اضافه شدن `farm_boundary` |
|
||||
| `0007_ndviobservation.py` | اضافه شدن `NdviObservation` |
|
||||
| `0008_soillocation_block_layout.py` | اضافه شدن `input_block_count` و `block_layout` |
|
||||
|
||||
## تستها
|
||||
|
||||
فایلهای تست اصلی:
|
||||
|
||||
- `location_data/test_soil_api.py`
|
||||
- تست ساختار محلی بلوکها
|
||||
- تست پیشفرض یک بلوک
|
||||
- تست تغییر `block_count`
|
||||
|
||||
- `location_data/test_soil_adapters.py`
|
||||
- تست adapterهای خاک
|
||||
- تست ذخیره depth data
|
||||
|
||||
- `location_data/test_ndvi_health_api.py`
|
||||
- تست endpoint NDVI
|
||||
|
||||
## ارتباط با `farm_data`
|
||||
|
||||
`location_data` مستقیماً توسط `farm_data` استفاده میشود.
|
||||
|
||||
نمونه وابستگیها:
|
||||
|
||||
- `farm_data` از `SoilLocation` به عنوان `center_location` استفاده میکند.
|
||||
- `farm_boundary` از سمت `farm_data` میآید.
|
||||
- `block_count` هم از ورودی `farm_data` قابل ثبت است.
|
||||
- `farm_data` فعلاً فقط location و block layout را ذخیره میکند و برای این بخش sync خارجی انجام نمیدهد.
|
||||
|
||||
## جمعبندی ساختار فعلی
|
||||
|
||||
الان `location_data` دو لایه دارد:
|
||||
|
||||
1. لایه فعلی فعال برای بلوکبندی زمین
|
||||
- محلی
|
||||
- ساده
|
||||
- بدون API خارجی
|
||||
- با `input_block_count` و `block_layout`
|
||||
|
||||
2. لایه قدیمی/جانبی برای خاک و NDVI
|
||||
- `SoilDepthData`
|
||||
- `tasks.py`
|
||||
- `soil_adapters.py`
|
||||
- `NdviObservation`
|
||||
- `remote_sensing.py`
|
||||
|
||||
یعنی از نظر معماری، اپ الان هم داده مکانی زمین را نگه میدارد و هم زیرساختی برای تحلیل خاک/NDVI دارد، ولی منطق جدید بلوکها فعلاً مستقل و محلی پیاده شده است.
|
||||
Reference in New Issue
Block a user