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