Files
Backend/CROP_ZONING_APIS.md
T

19 KiB
Raw Blame 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)

{
  "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)

{
  "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 (محدودهٔ همهٔ مربع‌ها):

{
  "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.

{
  "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)

{
  "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)

{
  "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).

خروجی نمونه:

{
  "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)

{
  "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)

interface ZoneInitialData {
  zoneId: string
  geometry: Polygon
  crop: string
  matchPercent: number
  waterNeed: string
  estimatedProfit: string
}

دیتای تکمیلی زون (برای پنل جزئیات — پس از کلیک)

interface ZoneDetailData {
  zoneId: string
  crop: string
  matchPercent: number
  waterNeed: string
  estimatedProfit: string
  reason: string
  criteria: { name: string; value: number }[]
  area_hectares?: number
}

محصولات و رنگ‌ها (پیش‌فرض فرانت)

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 نمایش داده شود.