Files
Backend/CROP_ZONING_APIS.md
T

545 lines
19 KiB
Markdown
Raw Normal View History

# مستندات APIهای زون‌بندی کشت (Crop Zoning)
این سند تمام APIهای مورد نیاز برای صفحه **Crop Zoning** را شرح می‌دهد: ورودی‌ها، خروجی‌ها، محصولات، رنگ‌ها، مساحت کلی و دیتای هر بخش زمین به صورت جداگانه.
**مسیر صفحه:** `(dashboard)/(private)/crop-zoning`
**کامپوننت اصلی:** `CropZoningWrapper`
---
## نمای کلی و جریان درخواست‌ها
```
۱. GET area → منطقهٔ ثابت (کاربر امکان رسم ندارد)
۲. GET products → لیست محصولات و رنگ‌ها
۳. POST zones/initial → ارسال محدودهٔ مربع‌ها → دیتای محصولات پیشنهادی (نقشه + tooltip)
۴. POST zones/water-need → ارسال محدودهٔ مربع‌ها → نیاز آبی هر منطقه
۵. POST zones/soil-quality → ارسال محدودهٔ مربع‌ها → کیفیت خاک هر منطقه
۶. POST zones/cultivation-risk → ارسال محدودهٔ مربع‌ها → ریسک کشت هر منطقه
۷. GET zone/:zoneId → کلیک روی مربع → دیتای تکمیلی (پنل جزئیات: reason, criteria, ...)
```
| ردیف | API | هدف |
|------|-----|------|
| ۱ | **منطقهٔ اولیه** | دریافت منطقهٔ زمین به صورت GeoJSON؛ کاربر نمی‌تواند چیزی رسم کند |
| ۲ | **لیست محصولات و رنگ‌ها** | دریافت محصولات قابل کشت به همراه رنگ نمایش و لیبل فارسی |
| ۳ | **دیتای اولیه زون‌ها (محصولات)** | ارسال محدودهٔ مربع‌ها، دریافت محصول پیشنهادی برای نقشه و tooltip |
| ۴ | **نیاز آبی** | ارسال محدودهٔ مربع‌ها، دریافت نیاز آبی هر منطقه برای لایهٔ نیاز آبی |
| ۵ | **کیفیت خاک** | ارسال محدودهٔ مربع‌ها، دریافت کیفیت خاک هر منطقه برای لایهٔ کیفیت خاک |
| ۶ | **ریسک کشت** | ارسال محدودهٔ مربع‌ها، دریافت ریسک کشت هر منطقه برای لایهٔ ریسک کشت |
| ۷ | **دیتای تکمیلی زون** | با کلیک روی هر مربع، دریافت دیتای جزئیات (دلیل، معیارها، نمودار) |
---
## ۰. API منطقهٔ اولیه (Area)
منطقهٔ ثابت زمین که از بک‌اند دریافت می‌شود. کاربر امکان رسم یا ویرایش منطقه را ندارد.
### ۰.۱ مشخصات
- **متد:** `GET`
- **آدرس پیشنهادی:** `GET /api/crop-zoning/area/`
- **هدف:** دریافت polygon منطقهٔ زمین برای نمایش روی نقشه.
### ۰.۲ ورودی (Request)
بدون پارامتر.
### ۰.۳ خروجی (Response Body)
```json
{
"status": "success",
"data": {
"area": {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[51.38, 35.68],
[51.40, 35.68],
[51.40, 35.70],
[51.38, 35.70],
[51.38, 35.68]
]
]
}
}
}
}
```
- **مختصات:** `[longitude, latitude]` طبق استاندارد GeoJSON
---
## ۱. API لیست محصولات و رنگ‌ها
برای نمایش راهنمای رنگ‌ها (Legend) و dropdown انتخاب محصول در پنل جزئیات هر زون.
### ۱.۱ مشخصات
- **متد:** `GET`
- **آدرس پیشنهادی:** `GET /api/crop-zoning/products/` یا `GET /api/crops/`
- **هدف:** دریافت لیست محصولات قابل کشت با رنگ و لیبل نمایشی.
### ۱.۲ ورودی (Request)
بدون پارامتر یا با پارامترهای اختیاری:
| پارامتر | نوع | اجباری | توضیح |
|---------|-----|--------|--------|
| `locale` | string | خیر | کد زبان برای لیبل‌ها (مثلاً `fa`, `en`) |
### ۱.۳ خروجی (Response)
```json
{
"status": "success",
"data": {
"products": [
{
"id": "wheat",
"label": "گندم",
"color": "#6bcb77"
},
{
"id": "canola",
"label": "کلزا",
"color": "#ffd93d"
},
{
"id": "saffron",
"label": "زعفران",
"color": "#9b59b6"
}
]
}
}
```
**ساختار هر محصول:**
| فیلد | نوع | اجباری | توضیح |
|------|-----|--------|--------|
| `id` | string | بله | شناسهٔ یکتا (مثلاً `wheat`, `canola`, `saffron`) |
| `label` | string | بله | نام نمایشی به زبان کاربر |
| `color` | string | بله | رنگ hex برای نمایش روی نقشه و Legend |
---
## ۲. API دیتای اولیه زون‌ها
با رسم منطقهٔ زمین، فرانت **محدودهٔ همهٔ مربع‌ها** (گرید داخل polygon) را ارسال می‌کند و **دیتای اولیه** هر مربع را دریافت می‌کند — برای نمایش نقشه، رنگ‌بندی، و **هاور/tooltip**. این دیتا شامل `reason` و `criteria` **نیست**.
### ۲.۱ مشخصات
- **متد:** `POST`
- **آدرس پیشنهادی:** `POST /api/crop-zoning/zones/initial/`
- **هدف:** ارسال محدودهٔ مربع‌ها، دریافت دیتای اولیه برای نقشه، هاور و tooltip.
### ۲.۲ ورودی (Request Body)
فرانت ابتدا با Turf.js از روی polygon منطقه گرید می‌سازد، سپس `FeatureCollection` همهٔ polygonهای مربع‌ها را ارسال می‌کند.
| فیلد | نوع | اجباری | توضیح |
|------|-----|--------|--------|
| `zones` | GeoJSON FeatureCollection | بله | محدودهٔ هر مربع به صورت Polygon؛ ترتیب index با پاسخ یکسان است |
| `products` | string[] | خیر | لیست محصولات مدنظر؛ در صورت عدم ارسال از همهٔ محصولات استفاده شود |
**ساختار `zones` (محدودهٔ همهٔ مربع‌ها):**
```json
{
"zones": {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[51.38, 35.68],
[51.3815, 35.68],
[51.3815, 35.6815],
[51.38, 35.6815],
[51.38, 35.68]
]
]
},
"properties": { "index": 0 }
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[51.3815, 35.68],
[51.383, 35.68],
[51.383, 35.6815],
[51.3815, 35.6815],
[51.3815, 35.68]
]
]
},
"properties": { "index": 1 }
}
]
},
"products": ["wheat", "canola", "saffron"]
}
```
- **مختصات:** `[longitude, latitude]` طبق استاندارد GeoJSON
- **index:** در `properties` هر feature برای تطابق با پاسخ (اختیاری؛ در صورت نبودن از ترتیب آرایه استفاده شود)
### ۲.۳ خروجی (Response Body) — دیتای اولیه
فقط فیلدهای لازم برای **نقشه**، **هاور** و **tooltip** (نمایش هنگام عبور ماوس روی هر مربع)؛ بدون `reason` و `criteria`.
```json
{
"status": "success",
"data": {
"total_area_hectares": 23.45,
"total_area_sqm": 234500,
"zone_count": 3,
"zones": [
{
"zoneId": "zone-0",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[51.38, 35.68],
[51.3815, 35.68],
[51.3815, 35.6815],
[51.38, 35.6815],
[51.38, 35.68]
]
]
},
"crop": "wheat",
"matchPercent": 85,
"waterNeed": "۴۵۰۰-۵۵۰۰ m³/ha",
"estimatedProfit": "۱۵-۲۵ میلیون/هکتار"
},
{
"zoneId": "zone-1",
"geometry": { "type": "Polygon", "coordinates": [...] },
"crop": "canola",
"matchPercent": 78,
"waterNeed": "۵۰۰۰-۶۰۰۰ m³/ha",
"estimatedProfit": "۲۰-۳۵ میلیون/هکتار"
}
]
}
}
```
**ساختار دیتای اولیه هر زون (هم برای نقشه هم برای هاور/tooltip):**
| فیلد | نوع | اجباری | توضیح |
|------|-----|--------|--------|
| `zoneId` | string | بله | شناسهٔ یکتا برای درخواست دیتای تکمیلی |
| `geometry` | Polygon | بله | هندسهٔ همان مربع ارسالی |
| `crop` | string \| null | خیر | محصول پیشنهادی؛ اگر `null`/خالی/`uncultivable` باشد → زون **غیرقابل کشت** و رنگ خاکستری |
| `matchPercent` | number | خیر | درصد تطابق (هاور/tooltip) |
| `waterNeed` | string | خیر | نیاز آبی (هاور/tooltip) |
| `estimatedProfit` | string | خیر | سود تخمینی (هاور/tooltip) |
**زون غیرقابل کشت:** اگر برای مربعی اطلاعاتی نیاید یا `crop` خالی/`null`/`uncultivable` باشد، آن مربع خاکستری نمایش داده شده و در tooltip «غیر قابل کشت» نشان داده می‌شود. کلیک روی آن پنل جزئیات باز نمی‌شود.
**نکته:** این فیلدها هنگام **هاور** روی مربع در tooltip نمایش داده می‌شوند؛ نیازی به درخواست جداگانه برای tooltip نیست.
---
## ۲.۱ API نیاز آبی (Water Need)
نیاز آبی هر منطقه را بر اساس محدودهٔ مربع‌ها برمی‌گرداند. با تغییر لایه به «نیاز آبی» در LayerControl، فرانت این API را صدا می‌زند و نقشه و Legend را به‌روزرسانی می‌کند.
### مشخصات
- **متد:** `POST`
- **آدرس پیشنهادی:** `POST /api/crop-zoning/zones/water-need/`
- **هدف:** دریافت نیاز آبی هر منطقه برای نمایش روی نقشه در لایهٔ نیاز آبی.
### ورودی (Request Body)
همان ساختار `POST zones/initial/`:
| فیلد | نوع | اجباری | توضیح |
|------|-----|--------|--------|
| `zones` | GeoJSON FeatureCollection | بله | محدودهٔ هر مربع به صورت Polygon |
### خروجی (Response Body)
```json
{
"status": "success",
"data": {
"zones": [
{
"zoneId": "zone-0",
"geometry": { "type": "Polygon", "coordinates": [...] },
"level": "low",
"value": "۳۰۰۰-۴۰۰۰ m³/ha",
"color": "#7dd3fc"
},
{
"zoneId": "zone-1",
"geometry": { "type": "Polygon", "coordinates": [...] },
"level": "medium",
"value": "۵۰۰۰-۶۰۰۰ m³/ha",
"color": "#0ea5e9"
}
]
}
}
```
| فیلد | نوع | توضیح |
|------|-----|--------|
| `zoneId` | string | شناسهٔ زون |
| `geometry` | Polygon | هندسهٔ مربع |
| `level` | string | سطح: `low`, `medium`, `high` |
| `value` | string | مقدار نیاز آبی (مثلاً m³/ha) |
| `color` | string | رنگ hex برای نمایش |
---
## ۲.۲ API کیفیت خاک (Soil Quality)
کیفیت خاک هر منطقه را برمی‌گرداند. با تغییر لایه به «کیفیت خاک»، فرانت این API را صدا می‌زند.
### مشخصات
- **متد:** `POST`
- **آدرس پیشنهادی:** `POST /api/crop-zoning/zones/soil-quality/`
### ورودی (Request Body)
همان `zones` (FeatureCollection).
### خروجی (Response Body)
```json
{
"status": "success",
"data": {
"zones": [
{
"zoneId": "zone-0",
"geometry": { "type": "Polygon", "coordinates": [...] },
"level": "low",
"score": 35,
"color": "#f87171"
},
{
"zoneId": "zone-1",
"geometry": { "type": "Polygon", "coordinates": [...] },
"level": "high",
"score": 85,
"color": "#22c55e"
}
]
}
}
```
| فیلد | نوع | توضیح |
|------|-----|--------|
| `level` | string | سطح: `low`, `medium`, `high` |
| `score` | number | امتیاز ۰–۱۰۰ |
| `color` | string | رنگ hex |
---
## ۲.۳ API ریسک کشت (Cultivation Risk)
ریسک کشت هر منطقه را برمی‌گرداند. با تغییر لایه به «ریسک کشت»، فرانت این API را صدا می‌زند.
### مشخصات
- **متد:** `POST`
- **آدرس پیشنهادی:** `POST /api/crop-zoning/zones/cultivation-risk/`
### ورودی و خروجی
ورودی: همان `zones` (FeatureCollection).
خروجی نمونه:
```json
{
"status": "success",
"data": {
"zones": [
{
"zoneId": "zone-0",
"geometry": { "type": "Polygon", "coordinates": [...] },
"level": "low",
"color": "#22c55e"
},
{
"zoneId": "zone-1",
"geometry": { "type": "Polygon", "coordinates": [...] },
"level": "high",
"color": "#ef4444"
}
]
}
}
```
| فیلد | نوع | توضیح |
|------|-----|--------|
| `level` | string | سطح: `low`, `medium`, `high` |
| `color` | string | رنگ hex |
**نکته:** برای هر لایه (نیاز آبی، کیفیت خاک، ریسک کشت) فرانت یک **درخواست جداگانه** ارسال می‌کند و نقشه و Legend متناسب با همان لایه به‌روزرسانی می‌شوند.
---
## ۳. API دیتای تکمیلی زون (با کلیک روی مربع)
وقتی کاربر روی یک مربع کلیک می‌کند، فرانت با `zoneId` دیتای **تکمیلی** را درخواست می‌کند — برای نمایش پنل جزئیات: دلیل پیشنهاد، معیارها، نمودار راداری.
### ۳.۱ مشخصات
- **متد:** `GET`
- **آدرس پیشنهادی:** `GET /api/crop-zoning/zones/:zoneId/details/`
- **هدف:** دریافت دیتای تکمیلی یک زون برای پنل جزئیات.
### ۳.۲ ورودی (Request)
| پارامتر | محل | نوع | اجباری | توضیح |
|---------|------|-----|--------|--------|
| `zoneId` | path | string | بله | شناسهٔ زون (مثلاً `zone-0`) |
**مثال:** `GET /api/crop-zoning/zones/zone-0/details/`
### ۳.۳ خروجی (Response Body)
```json
{
"status": "success",
"data": {
"zoneId": "zone-0",
"crop": "wheat",
"matchPercent": 85,
"waterNeed": "۴۵۰۰-۵۵۰۰ m³/ha",
"estimatedProfit": "۱۵-۲۵ میلیون/هکتار",
"reason": "دمای مناسب، خاک حاصلخیز، دسترسی به آب کافی",
"criteria": [
{ "name": "دما", "value": 82 },
{ "name": "بارش", "value": 75 },
{ "name": "خاک", "value": 88 },
{ "name": "آب", "value": 70 }
],
"area_hectares": 2.25
}
}
```
**فیلدهای دیتای تکمیلی:**
| فیلد | نوع | اجباری | توضیح |
|------|-----|--------|--------|
| `zoneId` | string | بله | همان zoneId درخواست |
| `crop` | string | بله | محصول پیشنهادی |
| `matchPercent` | number | بله | درصد تطابق |
| `waterNeed` | string | بله | نیاز آبی |
| `estimatedProfit` | string | بله | سود تخمینی |
| `reason` | string | بله | **فقط در دیتای تکمیلی** — دلیل پیشنهاد محصول |
| `criteria` | object[] | بله | **فقط در دیتای تکمیلی** — معیارها برای نمودار راداری |
| `area_hectares` | number | خیر | مساحت این زون بر حسب هکتار |
### ۳.۴ ساختار `criteria`
| فیلد | نوع | توضیح |
|------|-----|--------|
| `name` | string | نام معیار (دما، بارش، خاک، آب) |
| `value` | number | امتیاز ۰–۱۰۰ |
---
## ۴. مساحت کلی (Total Area)
در پاسخ **API دیتای اولیه زون‌ها** برمی‌گردد:
| فیلد | نوع | توضیح |
|------|-----|--------|
| `total_area_hectares` | number | مساحت کل منطقه بر حسب هکتار |
| `total_area_sqm` | number | مساحت کل بر حسب متر مربع |
---
## ۵. خلاصهٔ ساختار‌های مورد نیاز فرانت
### دیتای اولیه زون (برای نقشه و هاور/tooltip)
```ts
interface ZoneInitialData {
zoneId: string
geometry: Polygon
crop: string
matchPercent: number
waterNeed: string
estimatedProfit: string
}
```
### دیتای تکمیلی زون (برای پنل جزئیات — پس از کلیک)
```ts
interface ZoneDetailData {
zoneId: string
crop: string
matchPercent: number
waterNeed: string
estimatedProfit: string
reason: string
criteria: { name: string; value: number }[]
area_hectares?: number
}
```
### محصولات و رنگ‌ها (پیش‌فرض فرانت)
```ts
const CROP_COLORS: Record<CropType, string> = {
wheat: '#6bcb77',
canola: '#ffd93d',
saffron: '#9b59b6'
}
```
---
## ۶. جریان فرانت با APIها
1. **لود صفحه:** `GET /api/crop-zoning/products/` → لیست محصولات و رنگ‌ها.
2. **رسم منطقه / بهینه‌سازی:** فرانت با Turf از polygon منطقه گرید می‌سازد → `POST /api/crop-zoning/zones/initial/` با `zones` (FeatureCollection) → نقشه و tooltip با دیتای محصولات رسم می‌شود.
3. **تغییر لایه در LayerControl:** برای هر لایه یک درخواست جداگانه ارسال می‌شود:
- محصولات پیشنهادی: `POST zones/initial/` (در مرحلهٔ ۲)
- نیاز آبی: `POST zones/water-need/` → نقشه و Legend به‌روزرسانی می‌شوند
- کیفیت خاک: `POST zones/soil-quality/` → نقشه و Legend به‌روزرسانی می‌شوند
- ریسک کشت: `POST zones/cultivation-risk/` → نقشه و Legend به‌روزرسانی می‌شوند
4. **کلیک روی مربع:** `GET /api/crop-zoning/zones/{zoneId}/details/` → دیتای تکمیلی → پنل جزئیات باز می‌شود (reason, criteria, نمودار راداری).
---
## ۷. وضعیت فعلی و نیازمندی‌ها
- در حال حاضر زون‌بندی با **دیتای ماک** و الگوریتم محلی (`createZonedGrid` در `cropZoningUtils.ts`) کار می‌کند.
- برای اتصال به بک‌اند، لازم است:
1. سرویس `cropZoningService` با سه endpoint: `getProducts()`, `getZonesInitial(zones)`, `getZoneDetails(zoneId)` ایجاد شود.
2. در `CropZoningMap` به جای `createZonedGrid` ابتدا گرید با Turf ساخته شود، سپس `zones` به API ارسال و پاسخ برای رسم استفاده شود.
3. در `onZoneClick` قبل از باز کردن پنل، `getZoneDetails(zoneId)` صدا زده شود و دیتای تکمیلی به `ZoneDetailPanel` پاس داده شود.
4. مساحت کلی (`total_area_hectares`) در پاسخ initial در UI نمایش داده شود.