372 lines
12 KiB
Markdown
372 lines
12 KiB
Markdown
|
|
# ساختار فعلی `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 دارد، ولی منطق جدید بلوکها فعلاً مستقل و محلی پیاده شده است.
|