2026-05-13 22:29:18 +03:30
# مستند کامل response های Location Data
این فایل، response همه endpointهای اصلی `Location Data` را به زبان ساده و دقیق توضیح میدهد.
مسیرهای این مستند:
- `GET /api/location-data/`
- `POST /api/location-data/`
- `POST /api/location-data/ndvi-health/`
- `GET /api/location-data/remote-sensing/`
- `POST /api/location-data/remote-sensing/`
- `GET /api/location-data/remote-sensing/cluster-blocks/{cluster_uuid}/live/`
- `GET /api/location-data/remote-sensing/cluster-recommendations/`
- `GET /api/location-data/remote-sensing/results/{result_id}/k-options/`
- `POST /api/location-data/remote-sensing/results/{result_id}/k-options/activate/`
- `GET /api/location-data/remote-sensing/runs/{run_id}/status/`
## 1) ساختار عمومی همه response ها
تقریبا همه endpointها این envelope را دارند:
``` json
{
"code" : 200 ,
"msg" : "success" ,
"data" : { }
}
```
توضیح فیلدها:
- `code` : کد منطقی response در body
- `msg` : پیام کوتاه
- `data` : payload اصلی
در خطاها معمولا یکی از این دو حالت برمیگردد:
``` json
{
"code" : 400 ,
"msg" : "داده نامعتبر." ,
"data" : {
"field_name" : [ "error message" ]
}
}
```
یا:
``` json
{
"code" : 404 ,
"msg" : "location پیدا نشد." ,
"data" : null
}
```
## 2) `GET /api/location-data/`
کاربرد:
- خواندن ساختار ذخیرهشده مزرعه
- خواندن بلوکها
- خواندن subdivisionها
- خواندن snapshotهای ماهوارهای ذخیره/تجمیعشده
### response موفق `200`
``` json
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"source" : "database" ,
"id" : 12 ,
"lon" : "51.389000" ,
"lat" : "35.689200" ,
"input_block_count" : 2 ,
"farm_boundary" : { } ,
"block_layout" : { } ,
"block_subdivisions" : [ ] ,
"satellite_snapshots" : [ ]
}
}
```
### توضیح فیلدهای `data`
- `source` : در این endpoint همیشه از دیتابیس است و معمولا مقدار آن `database` است
- `id` : شناسه داخلی `SoilLocation`
- `lon` : طول جغرافیایی location
- `lat` : عرض جغرافیایی location
- `input_block_count` : تعداد بلوکهای تعریفشده برای این مزرعه
- `farm_boundary` : مرز کل مزرعه به صورت GeoJSON
- `block_layout` : ساختار کلی بلوکها، وضعیت الگوریتم، sub-blockها و metadata سطح مزرعه
- `block_subdivisions` : لیست subdivisionهای سطح بلوک
- `satellite_snapshots` : خلاصههای سنجشازدور هر بلوک و هر sub-block
### ساختار هر آیتم `block_subdivisions`
``` json
{
"block_code" : "block-1" ,
"chunk_size_sqm" : 900 ,
"grid_points" : [ ] ,
"centroid_points" : [ ] ,
"grid_point_count" : 0 ,
"centroid_count" : 0 ,
"elbow_plot" : null ,
"status" : "defined" ,
"metadata" : { } ,
"created_at" : "2026-05-13T14:00:00Z" ,
"updated_at" : "2026-05-13T14:00:00Z"
}
```
توضیح:
- `block_code` : کد بلوک
- `chunk_size_sqm` : اندازه هر سلول تحلیل
- `grid_points` : نقاط grid تولیدشده
- `centroid_points` : centroidهای grid
- `grid_point_count` : تعداد نقاط grid
- `centroid_count` : تعداد centroidها
- `elbow_plot` : تصویر elbow plot اگر ساخته شده باشد
- `status` : وضعیت subdivision مثل `defined` ، `created` ، `subdivided`
- `metadata` : دادههای تکمیلی
### `400`
وقتی `lat` یا `lon` نامعتبر باشد:
``` json
{
"code" : 400 ,
"msg" : "داده نامعتبر." ,
"data" : {
"lat" : [ "..." ] ,
"lon" : [ "..." ]
}
}
```
### `404`
وقتی location پیدا نشود:
``` json
{
"code" : 404 ,
"msg" : "location پیدا نشد." ,
"data" : null
}
```
## 3) `POST /api/location-data/`
کاربرد:
- ثبت یا بهروزرسانی مزرعه
- ثبت مرز مزرعه
- ثبت بلوکهای کشاورز
### response موفق `200`
``` json
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"source" : "created" ,
"id" : 12 ,
"lon" : "51.389000" ,
"lat" : "35.689200" ,
"input_block_count" : 2 ,
"farm_boundary" : { } ,
"block_layout" : { } ,
"block_subdivisions" : [ ] ,
"satellite_snapshots" : [ ]
}
}
```
### توضیح `source`
- `created` : این location تازه ساخته شده
- `database` : location از قبل وجود داشته و فقط update شده یا همان داده قبلی برگشته
### `400`
حالت اول: body نامعتبر باشد:
``` json
{
"code" : 400 ,
"msg" : "داده نامعتبر." ,
"data" : {
"farm_boundary" : [ "مختصات گوشههای کل زمین باید ارسال شود." ]
}
}
```
حالت دوم: مرز کل مزرعه نه در request آمده و نه قبلا ذخیره شده:
``` json
{
"code" : 400 ,
"msg" : "داده نامعتبر." ,
"data" : {
"farm_boundary" : [
"برای ثبت location باید گوشههای کل زمین ارسال یا قبلاً ذخیره شده باشد."
]
}
}
```
## 4) `POST /api/location-data/ndvi-health/`
کاربرد:
- برگرداندن وضعیت سلامت پوشش گیاهی مزرعه بر اساس NDVI
### response موفق `200`
``` json
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"ndviIndex" : 0.63 ,
"mean_ndvi" : 0.63 ,
"ndvi_map" : { } ,
"vegetation_health_class" : "healthy" ,
"observation_date" : "2026-05-12" ,
"satellite_source" : "sentinel-2" ,
"healthData" : [
{
"title" : "میانگین NDVI" ,
"value" : 0.63 ,
"color" : "green" ,
"icon" : "leaf"
}
]
}
}
```
### توضیح فیلدها
- `ndviIndex` : شاخص اصلی NDVI برای UI
- `mean_ndvi` : میانگین NDVI محاسبهشده
- `ndvi_map` : داده نقشه یا لایه NDVI
- `vegetation_health_class` : کلاس سلامت پوشش گیاهی
- `observation_date` : تاریخ مشاهده
- `satellite_source` : منبع داده ماهوارهای
- `healthData` : کارتهای خلاصه برای نمایش در فرانت
### ساختار هر آیتم `healthData`
- `title` : عنوان آیتم
- `value` : مقدار عددی یا ساختار JSON
- `color` : رنگ پیشنهادی UI
- `icon` : آیکون پیشنهادی UI
### `400`
``` json
{
"code" : 400 ,
"msg" : "داده نامعتبر." ,
"data" : {
"farm_uuid" : [ "..." ]
}
}
```
### `404`
``` json
{
"code" : 404 ,
"msg" : "مزرعه پیدا نشد." ,
"data" : null
}
```
## 5) `GET /api/location-data/remote-sensing/`
کاربرد:
- فقط نتایج cache شده remote sensing و subdivision را میخواند
- هیچ پردازش جدیدی اجرا نمیکند
### response موفق `200`
``` json
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"status" : "success" ,
"source" : "database" ,
"location" : { } ,
"block_code" : "" ,
"chunk_size_sqm" : 900 ,
"temporal_extent" : {
"start_date" : "2026-04-12" ,
"end_date" : "2026-05-12"
} ,
"summary" : {
"cell_count" : 12 ,
"ndvi_mean" : 0.54 ,
"ndwi_mean" : 0.21 ,
"soil_vv_db_mean" : -8.92
} ,
"cells" : [ ] ,
"run" : { } ,
"subdivision_result" : { } ,
"pagination" : { } ,
"metadata" : {
"farm_uuid" : "11111111-1111-1111-1111-111111111111" ,
"cache_hit" : true
}
}
}
```
### حالتهای مهم `status`
- `success` : داده کامل در DB موجود است
- `processing` : run در حال انجام است و هنوز observation نهایی کامل نشده
- `not_found` : runی وجود داشته ولی observation قابل استفاده برنگشته
### توضیح فیلدها
- `status` : وضعیت نتیجه
- `source` : معمولا `database` یا `processing`
- `location` : همان ساختار `SoilLocationResponse`
- `block_code` : برای full farm معمولا رشته خالی `""`
- `chunk_size_sqm` : اندازه سلول تحلیل
- `temporal_extent.start_date` : شروع بازه تحلیل
- `temporal_extent.end_date` : پایان بازه تحلیل
- `summary` : خلاصه آماری observationها
- `cells` : observationهای صفحه فعلی
- `run` : اطلاعات run مرتبط
- `subdivision_result` : نتیجه clustering و KMeans
- `pagination` : اطلاعات صفحهبندی `cells` و گاهی `assignments`
- `metadata.cache_hit` : نشان میدهد پاسخ از cache/DB آمده
### ساختار `summary`
- `cell_count` : تعداد سلولها
- `ndvi_mean` : میانگین NDVI
- `ndwi_mean` : میانگین NDWI
- `soil_vv_db_mean` : میانگین `soil_vv_db`
### ساختار هر آیتم `cells`
``` json
{
"cell_code" : "cell-1" ,
"block_code" : "" ,
"chunk_size_sqm" : 900 ,
"centroid_lat" : "35.689500" ,
"centroid_lon" : "51.389500" ,
"geometry" : { } ,
"temporal_start" : "2026-04-12" ,
"temporal_end" : "2026-05-12" ,
"ndvi" : 0.61 ,
"ndwi" : 0.22 ,
"soil_vv" : 0.13 ,
"soil_vv_db" : -8.860566 ,
"metadata" : { }
}
```
### ساختار `run`
``` json
{
"id" : 10 ,
"block_code" : "" ,
"chunk_size_sqm" : 900 ,
"temporal_start" : "2026-04-12" ,
"temporal_end" : "2026-05-12" ,
"status" : "success" ,
"status_label" : "completed" ,
"pipeline_status" : "completed" ,
"stage" : "completed" ,
"selected_features" : [ "ndvi" , "ndwi" , "soil_vv_db" ] ,
"requested_cluster_count" : null ,
"metadata" : { } ,
"error_message" : "" ,
"started_at" : null ,
"finished_at" : null ,
"created_at" : "2026-05-13T14:00:00Z" ,
"updated_at" : "2026-05-13T14:00:00Z"
}
```
### ساختار `subdivision_result`
``` json
{
"id" : 5 ,
"block_code" : "" ,
"chunk_size_sqm" : 900 ,
"temporal_start" : "2026-04-12" ,
"temporal_end" : "2026-05-12" ,
"cluster_count" : 3 ,
"selected_features" : [ "ndvi" , "ndwi" , "soil_vv_db" ] ,
"skipped_cell_codes" : [ ] ,
"metadata" : { } ,
"available_k_options" : [ ] ,
"cluster_blocks" : [ ] ,
"assignments" : [ ] ,
"created_at" : "2026-05-13T14:00:00Z" ,
"updated_at" : "2026-05-13T14:00:00Z"
}
```
### ساختار هر `assignment`
``` json
{
"cell_code" : "cell-1" ,
"cluster_label" : 0 ,
"centroid_lat" : "35.689500" ,
"centroid_lon" : "51.389500" ,
"raw_feature_values" : {
"ndvi" : 0.61
} ,
"scaled_feature_values" : {
"ndvi" : 0.21
}
}
```
### ساختار هر `cluster_block`
``` json
{
"uuid" : "11111111-1111-1111-1111-111111111111" ,
"sub_block_code" : "cluster-0" ,
"cluster_label" : 0 ,
"chunk_size_sqm" : 900 ,
"centroid_lat" : "35.689500" ,
"centroid_lon" : "51.389500" ,
"center_cell_code" : "cell-1" ,
"center_cell_lat" : "35.689500" ,
"center_cell_lon" : "51.389500" ,
"cell_count" : 4 ,
"cell_codes" : [ "cell-1" , "cell-2" ] ,
"geometry" : { } ,
"metadata" : { } ,
"created_at" : "2026-05-13T14:00:00Z" ,
"updated_at" : "2026-05-13T14:00:00Z"
}
```
### `400`
``` json
{
"code" : 400 ,
"msg" : "داده نامعتبر." ,
"data" : {
"farm_uuid" : [ "..." ]
}
}
```
### `404`
``` json
{
"code" : 404 ,
"msg" : "location پیدا نشد." ,
"data" : null
}
```
## 6) `POST /api/location-data/remote-sensing/`
کاربرد:
- اجرای async تحلیل سنجشازدور
- ساخت run و task قابل polling
- اگر داده قبلا در DB موجود باشد هم یک `task_id` tracking برمیگرداند تا status بلافاصله نتیجه را بدهد
### response موفق `202`
``` json
{
"code" : 202 ,
"msg" : "تحلیل سنجشازدور در صف قرار گرفت." ,
"data" : {
"status" : "processing" ,
"source" : "processing" ,
"location" : { } ,
"block_code" : "" ,
"chunk_size_sqm" : 900 ,
"temporal_extent" : {
"start_date" : "2026-04-12" ,
"end_date" : "2026-05-12"
} ,
"summary" : {
"cell_count" : 0 ,
"ndvi_mean" : null ,
"ndwi_mean" : null ,
"soil_vv_db_mean" : null
} ,
"cells" : [ ] ,
"run" : { } ,
"task_id" : "11111111-1111-1111-1111-111111111111"
}
}
```
### دو حالت مهم
#### حالت اول: واقعا task جدید ساخته شده
- `status = processing`
- `source = processing`
- `task_id` مربوط به Celery run جدید است
#### حالت دوم: data از قبل در DB وجود دارد
- باز هم `202` برمیگردد
- `status` ممکن است `success` باشد
- `source` معمولا `database` است
- `task_id` برای polling ساخته میشود
- `GET /runs/{run_id}/status/` بلافاصله نتیجه کامل را میدهد
### `400`
``` json
{
"code" : 400 ,
"msg" : "داده نامعتبر." ,
"data" : {
"farm_uuid" : [ "..." ]
}
}
```
### `404`
``` json
{
"code" : 404 ,
"msg" : "location پیدا نشد." ,
"data" : null
}
```
## 7) `GET /api/location-data/remote-sensing/cluster-blocks/{cluster_uuid}/live/`
کاربرد:
- دریافت metricهای زنده یا cache شده برای یک cluster block
### response موفق `200`
``` json
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"status" : "success" ,
"source" : "database" ,
"cluster_block" : { } ,
"temporal_extent" : {
"start_date" : "2026-04-12" ,
"end_date" : "2026-05-12"
} ,
"selected_features" : [ "ndvi" , "ndwi" , "soil_vv_db" ] ,
"summary" : {
"cell_count" : 2 ,
"ndvi_mean" : 0.54 ,
"ndwi_mean" : 0.17 ,
"soil_vv_db_mean" : -9.0
} ,
"metrics" : {
"ndvi" : 0.54 ,
"ndwi" : 0.17 ,
"soil_vv" : 0.14 ,
"soil_vv_db" : -9.0
} ,
"metadata" : {
"requested_cluster_uuid" : "11111111-1111-1111-1111-111111111111" ,
"cache_hit" : true
}
}
}
```
### توضیح فیلدها
- `source` : اگر از observationهای DB آمده باشد `database` و اگر مستقیم از openEO آمده باشد `openeo`
- `cluster_block` : ساختار کامل sub-block
- `selected_features` : metricهایی که برای تحلیل استفاده میشوند
- `summary` : خلاصه آماری cluster
- `metrics` : metric تجمیعشده همان cluster
- `metadata` : اطلاعات تکمیلی مثل backend، source_result_id، source_run_id
### `400`
- پارامترهای تاریخ نامعتبر باشند
- یا هندسه cluster معتبر نباشد
نمونه:
``` json
{
"code" : 400 ,
"msg" : "هندسه زیربلاک KMeans نامعتبر است." ,
"data" : {
"cluster_uuid" : [ "11111111-1111-1111-1111-111111111111" ]
}
}
```
### `404`
``` json
{
"code" : 404 ,
"msg" : "زیربلاک KMeans پیدا نشد." ,
"data" : null
}
```
### `502`
وقتی openEO پاسخ ندهد:
``` json
{
"code" : 502 ,
"msg" : "خواندن داده از openEO ناموفق بود." ,
"data" : {
"detail" : "..."
}
}
```
## 8) `GET /api/location-data/remote-sensing/cluster-recommendations/`
کاربرد:
- مقایسه گیاههای ثبتشده در `farm_data`
- استفاده از داده کلاسترها
- استفاده از `crop_simulation`
- پیشنهاد بهترین گیاه برای هر cluster
2026-05-14 22:58:32 +03:30
### query params
- `farm_uuid` اجباری است و باید UUID مزرعه باشد.
نمونه:
``` http
G E T / a p i / l o c a t i o n - d a t a / r e m o t e - s e n s i n g / c l u s t e r - r e c o m m e n d a t i o n s / ? f a r m _ u u i d = 1 1 1 1 1 1 1 1 - 1 1 1 1 - 1 1 1 1 - 1 1 1 1 - 1 1 1 1 1 1 1 1 1 1 1 1
```
### پیشنیازها
- مزرعه باید در `farm_data` وجود داشته باشد.
- برای مزرعه باید حداقل یک گیاه ثبت شده باشد.
- برای `location` همان مزرعه باید خروجی KMeans در `location_data` موجود باشد.
- دادههای لازم برای ساخت payload شبیهسازی باید قابل تولید باشند.
2026-05-13 22:29:18 +03:30
### response موفق `200`
``` json
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"farm_uuid" : "11111111-1111-1111-1111-111111111111" ,
2026-05-14 22:58:32 +03:30
"location_id" : 1 ,
"evaluated_plant_count" : 4 ,
2026-05-13 22:29:18 +03:30
"cluster_count" : 2 ,
2026-05-14 22:58:32 +03:30
"registered_plants" : [
{
"plant_id" : 201 ,
"plant_name" : "maize" ,
"position" : 0 ,
"stage" : ""
}
] ,
"clusters" : [
{
"block_code" : "" ,
"cluster_uuid" : "daa278cb-cf75-4f17-bc94-bb3a780dd4d4" ,
"sub_block_code" : "cluster-0" ,
"cluster_label" : 0 ,
"temporal_extent" : {
"start_date" : "2026-04-11" ,
"end_date" : "2026-05-11"
} ,
"cluster_block" : {
"uuid" : "daa278cb-cf75-4f17-bc94-bb3a780dd4d4" ,
"sub_block_code" : "cluster-0" ,
"cluster_label" : 0 ,
"chunk_size_sqm" : 900 ,
"centroid_lat" : "49.999770" ,
"centroid_lon" : "49.999920" ,
"center_cell_code" : "loc-1__block-farm__chunk-900__r0000c0000" ,
"center_cell_lat" : "49.999635" ,
"center_cell_lon" : "49.999710" ,
"cell_count" : 4 ,
"cell_codes" : [
"loc-1__block-farm__chunk-900__r0000c0000"
] ,
"geometry" : {
"type" : "Polygon" ,
"coordinates" : [ ]
} ,
"metadata" : { }
} ,
"satellite_metrics" : {
"ndvi" : 0.659927 ,
"ndwi" : -0.571487 ,
"soil_vv_db" : -13.73536 ,
"soil_vv" : -13.127913
} ,
"sensor_metrics" : { } ,
"resolved_metrics" : {
"ndvi" : 0.659927 ,
"ndwi" : -0.571487 ,
"soil_vv_db" : -13.73536 ,
"soil_vv" : -13.127913
} ,
"candidate_plants" : [
{
"plant_id" : 401 ,
"plant_name" : "wheat" ,
"position" : 3 ,
"stage" : "" ,
"score" : 123.4 ,
"predicted_yield" : 123.4 ,
"predicted_yield_tons" : 0.1234 ,
"biomass" : 456.7 ,
"max_lai" : 4.2 ,
"simulation_engine" : "pcse" ,
"simulation_model_name" : "Wofost81_NWLP_CWB_CNB" ,
"simulation_warning" : null ,
"supporting_metrics" : {
"yield_estimate" : 123.4 ,
"biomass" : 456.7 ,
"max_lai" : 4.2
}
}
] ,
"suggested_plant" : {
"plant_id" : 401 ,
"plant_name" : "wheat" ,
"position" : 3 ,
"stage" : "" ,
"score" : 123.4 ,
"predicted_yield" : 123.4 ,
"predicted_yield_tons" : 0.1234 ,
"biomass" : 456.7 ,
"max_lai" : 4.2 ,
"simulation_engine" : "pcse" ,
"simulation_model_name" : "Wofost81_NWLP_CWB_CNB" ,
"simulation_warning" : null ,
"supporting_metrics" : {
"yield_estimate" : 123.4 ,
"biomass" : 456.7 ,
"max_lai" : 4.2
}
} ,
"source_metadata" : {
"block_status" : "completed" ,
"aggregation_strategy" : "sub_block_mean" ,
"has_satellite_metrics" : true ,
"has_sensor_metrics" : false
}
}
] ,
"source_metadata" : {
"source" : "location_data+kmeans+farm_data+crop_simulation" ,
"location_id" : 1 ,
"snapshot_block_count" : 2
}
2026-05-13 22:29:18 +03:30
}
}
```
### توضیح فیلدهای سطح بالا
- `farm_uuid` : شناسه مزرعه
- `location_id` : شناسه داخلی location
- `evaluated_plant_count` : تعداد گیاههایی که وارد simulation شدهاند
- `cluster_count` : تعداد clusterهای بررسیشده
- `registered_plants` : گیاههای ثبتشده روی مزرعه
- `clusters` : خروجی نهایی هر cluster
- `source_metadata` : metadata کلی پاسخ
### ساختار هر آیتم `registered_plants`
``` json
{
"plant_id" : 101 ,
"plant_name" : "Tomato" ,
"position" : 0 ,
"stage" : "vegetative"
}
```
### ساختار هر آیتم `clusters`
``` json
{
2026-05-14 22:58:32 +03:30
"block_code" : "" ,
2026-05-13 22:29:18 +03:30
"cluster_uuid" : "11111111-1111-1111-1111-111111111111" ,
"sub_block_code" : "cluster-0" ,
"cluster_label" : 0 ,
"temporal_extent" : {
2026-05-14 22:58:32 +03:30
"start_date" : "2026-04-11" ,
"end_date" : "2026-05-11"
2026-05-13 22:29:18 +03:30
} ,
"cluster_block" : { } ,
"satellite_metrics" : {
2026-05-14 22:58:32 +03:30
"ndvi" : 0.659927 ,
"ndwi" : -0.571487 ,
"soil_vv_db" : -13.73536 ,
"soil_vv" : -13.127913
2026-05-13 22:29:18 +03:30
} ,
"sensor_metrics" : { } ,
"resolved_metrics" : {
2026-05-14 22:58:32 +03:30
"ndvi" : 0.659927 ,
"ndwi" : -0.571487 ,
"soil_vv_db" : -13.73536 ,
"soil_vv" : -13.127913
2026-05-13 22:29:18 +03:30
} ,
"candidate_plants" : [ ] ,
2026-05-14 22:58:32 +03:30
"suggested_plant" : null ,
2026-05-13 22:29:18 +03:30
"source_metadata" : { }
}
```
2026-05-14 22:58:32 +03:30
فیلدهای مهم داخل هر cluster:
- `block_code` : کد بلوک والد؛ در حالت تحلیل کل مزرعه ممکن است خالی باشد.
- `cluster_uuid` : شناسه یکتای cluster.
- `sub_block_code` : کد خوانا مثل `cluster-0` .
- `cluster_label` : لیبل عددی KMeans.
- `temporal_extent` : بازه زمانی داده remote sensing.
- `cluster_block` : اطلاعات هندسی، centroid، سلول مرکزی و geometry.
- `satellite_metrics` : میانگین متریکهای ماهوارهای cluster.
- `sensor_metrics` : داده سنسوری تجمیعشده، اگر وجود داشته باشد.
- `resolved_metrics` : متریک نهایی که برای simulation استفاده شده است.
- `candidate_plants` : همه گیاههای ارزیابیشده با رتبهبندی.
- `suggested_plant` : بهترین گزینه نهایی برای همان cluster.
- `source_metadata` : وضعیت پردازش و strategy تجمیع.
2026-05-13 22:29:18 +03:30
### ساختار هر آیتم `candidate_plants`
``` json
{
2026-05-14 22:58:32 +03:30
"plant_id" : 401 ,
"plant_name" : "wheat" ,
"position" : 3 ,
"stage" : "" ,
"score" : 123.4 ,
"predicted_yield" : 123.4 ,
"predicted_yield_tons" : 0.1234 ,
"biomass" : 456.7 ,
2026-05-13 22:29:18 +03:30
"max_lai" : 4.2 ,
"simulation_engine" : "pcse" ,
"simulation_model_name" : "Wofost81_NWLP_CWB_CNB" ,
"simulation_warning" : null ,
2026-05-14 22:58:32 +03:30
"supporting_metrics" : {
"yield_estimate" : 123.4 ,
"biomass" : 456.7 ,
"max_lai" : 4.2
}
2026-05-13 22:29:18 +03:30
}
```
### `400`
2026-05-14 22:58:32 +03:30
وقتی `farm_uuid` ارسال نشده باشد یا معتبر نباشد:
``` json
{
"code" : 400 ,
"msg" : "داده نامعتبر." ,
"data" : {
"farm_uuid" : [
"This field is required."
]
}
}
```
وقتی مزرعه گیاه ثبتشده نداشته باشد:
2026-05-13 22:29:18 +03:30
``` json
{
"code" : 400 ,
"msg" : "برای این مزرعه هنوز هیچ گیاهی در farm_data ثبت نشده است." ,
"data" : null
}
```
2026-05-14 22:58:32 +03:30
وقتی ساخت simulation یا مقایسه گیاهها fail شود:
``` json
{
"code" : 400 ,
"msg" : "مقایسه گیاهها با crop_simulation انجام نشد: ..." ,
"data" : null
}
```
2026-05-13 22:29:18 +03:30
### `404`
وقتی مزرعه یا خروجی KMeans پیدا نشود:
``` json
{
"code" : 404 ,
"msg" : "برای این مزرعه هنوز خروجی KMeans در location_data ثبت نشده است." ,
"data" : null
}
```
## 9) `GET /api/location-data/remote-sensing/results/{result_id}/k-options/`
کاربرد:
- لیست همه Kهای ذخیرهشده برای یک subdivision result
### response موفق `200`
``` json
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"result_id" : 5 ,
"active_requested_k" : 3 ,
"recommended_requested_k" : 4 ,
"options" : [ ]
}
}
```
### توضیح فیلدها
- `result_id` : شناسه subdivision result
- `active_requested_k` : K فعال فعلی
- `recommended_requested_k` : K پیشنهادی سیستم
- `options` : لیست کامل گزینهها
### ساختار هر آیتم `options`
``` json
{
"id" : 11 ,
"requested_k" : 3 ,
"effective_cluster_count" : 3 ,
"is_active" : true ,
"is_recommended" : false ,
"selection_source" : "user" ,
"metadata" : { } ,
"cluster_blocks" : [ ] ,
"created_at" : "2026-05-13T14:00:00Z" ,
"updated_at" : "2026-05-13T14:00:00Z"
}
```
### ساختار هر `cluster_blocks` داخل option
``` json
{
"cluster_label" : 0 ,
"sub_block_code" : "cluster-0" ,
"chunk_size_sqm" : 900 ,
"centroid_lat" : "35.689500" ,
"centroid_lon" : "51.389500" ,
"center_cell_code" : "cell-1" ,
"center_cell_lat" : "35.689500" ,
"center_cell_lon" : "51.389500" ,
"cell_count" : 4 ,
"cell_codes" : [ "cell-1" , "cell-2" ] ,
"geometry" : { } ,
"metadata" : { }
}
```
### `404`
``` json
{
"code" : 404 ,
"msg" : "subdivision result پیدا نشد." ,
"data" : null
}
```
## 10) `POST /api/location-data/remote-sensing/results/{result_id}/k-options/activate/`
کاربرد:
- فعالسازی یکی از Kهای ذخیرهشده
### response موفق `200`
``` json
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"result_id" : 5 ,
"activated_requested_k" : 4 ,
"subdivision_result" : { }
}
}
```
### توضیح فیلدها
- `result_id` : شناسه result
- `activated_requested_k` : K که الان active شده
- `subdivision_result` : خروجی کامل subdivision بعد از sync شدن روی K جدید
### `400`
حالت اول: body نامعتبر
``` json
{
"code" : 400 ,
"msg" : "داده نامعتبر." ,
"data" : {
"requested_k" : [ "..." ]
}
}
```
حالت دوم: K داخل optionها وجود ندارد
``` json
{
"code" : 400 ,
"msg" : "K انتخابی برای این subdivision result موجود نیست." ,
"data" : {
"requested_k" : [ 7 ]
}
}
```
### `404`
``` json
{
"code" : 404 ,
"msg" : "subdivision result پیدا نشد." ,
"data" : null
}
```
## 11) `GET /api/location-data/remote-sensing/runs/{run_id}/status/`
کاربرد:
- polling وضعیت run
- دیدن stageهای pipeline
- اگر run کامل شده باشد، دیدن نتیجه نهایی
- اگر run از نوع cache-hit باشد، دیدن نتیجه کامل DB بلافاصله
### response موفق `200` در حالت pending/running
``` json
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"status" : "running" ,
"source" : "database" ,
"run" : { } ,
"task_id" : "11111111-1111-1111-1111-111111111111" ,
"task" : {
"current_stage" : "fetching_remote_metrics" ,
"current_stage_details" : { } ,
"timestamps" : { } ,
"stages" : [ ] ,
"metric_progress" : { } ,
"celery" : {
"state" : "STARTED" ,
"ready" : false ,
"successful" : false ,
"failed" : false ,
"info" : { }
}
}
}
}
```
### response موفق `200` در حالت completed
``` json
{
"code" : 200 ,
"msg" : "success" ,
"data" : {
"status" : "completed" ,
"source" : "database" ,
"run" : { } ,
"task_id" : "11111111-1111-1111-1111-111111111111" ,
"task" : {
"current_stage" : "completed" ,
"current_stage_details" : { } ,
"timestamps" : { } ,
"stages" : [ ]
} ,
"location" : { } ,
"block_code" : "" ,
"chunk_size_sqm" : 900 ,
"temporal_extent" : {
"start_date" : "2026-04-12" ,
"end_date" : "2026-05-12"
} ,
"summary" : {
"cell_count" : 12 ,
"ndvi_mean" : 0.54 ,
"ndwi_mean" : 0.21 ,
"soil_vv_db_mean" : -8.92
} ,
"cells" : [ ] ,
"subdivision_result" : { } ,
"pagination" : { }
}
}
```
### توضیح فیلدهای `task`
- `current_stage` : stage فعلی pipeline
- `current_stage_details` : جزئیات همان stage
- `timestamps` : زمان ورود به stageها
- `stages` : تاریخچه stageها
- `metric_progress` : پیشرفت metricها هنگام fetch داده
- `retry` : اطلاعات retry اگر task در حال retry باشد
- `last_error` : آخرین خطا
- `failure_reason` : علت fail شدن task
- `celery.state` : وضعیت Celery مثل `PENDING` ، `STARTED` ، `RETRY`
- `celery.ready` : آیا task تمام شده
- `celery.successful` : آیا task موفق بوده
- `celery.failed` : آیا task fail شده
- `celery.info` : اطلاعات خام Celery
### مقادیر متداول `status`
- `pending`
- `running`
- `retrying`
- `completed`
- `failed`
### `404`
``` json
{
"code" : 404 ,
"msg" : "run با این task_id پیدا نشد." ,
"data" : null
}
```
## 12) نکات مهم برای فرانت
- در همه endpointها اول `code` و بعد `data` را چک کنید.
- در `POST /remote-sensing/` همیشه انتظار `task_id` داشته باشید.
- در `POST /remote-sensing/` اگر داده قبلا موجود باشد هم ممکن است `202` بگیرید، چون سیستم برای polling یک run قابل پیگیری میسازد.
- در `GET /remote-sensing/runs/{run_id}/status/` اگر `status = completed` شد، همان response نهایی را استفاده کنید و دیگر لازم نیست `GET /remote-sensing/` را دوباره صدا بزنید.
- در `GET /remote-sensing/cluster-blocks/{cluster_uuid}/live/` مقدار `source` مهم است:
- `database` : از cache
- `openeo` : از backend زنده
- در responseهای subdivision، pagination ممکن است هم برای `cells` باشد و هم برای `assignments` .
## 13) محل فایل
این مستند در این مسیر ذخیره شده است:
- `docs/location_data_api_responses_fa.md`