This commit is contained in:
2026-05-13 16:45:54 +03:30
parent 948c062b93
commit 46fe62fa04
96 changed files with 3834 additions and 155 deletions
+80
View File
@@ -37,8 +37,15 @@ from farm_data.models import SensorData
from .data_driven_subdivision import DEFAULT_CLUSTER_FEATURES
from .data_driven_subdivision import activate_subdivision_option
from .cluster_recommendation import (
ClusterRecommendationNotFound,
ClusterRecommendationValidationError,
build_cluster_crop_recommendations,
)
from .serializers import (
BlockSubdivisionSerializer,
ClusterCropRecommendationRequestSerializer,
ClusterCropRecommendationResponseSerializer,
NdviHealthRequestSerializer,
NdviHealthResponseSerializer,
RemoteSensingCellObservationSerializer,
@@ -140,6 +147,10 @@ RemoteSensingClusterBlockLiveEnvelopeSerializer = build_envelope_serializer(
"RemoteSensingClusterBlockLiveEnvelopeSerializer",
RemoteSensingClusterBlockLiveResponseSerializer,
)
ClusterCropRecommendationEnvelopeSerializer = build_envelope_serializer(
"ClusterCropRecommendationEnvelopeSerializer",
ClusterCropRecommendationResponseSerializer,
)
RemoteSensingSubdivisionOptionListEnvelopeSerializer = build_envelope_serializer(
"RemoteSensingSubdivisionOptionListEnvelopeSerializer",
RemoteSensingSubdivisionOptionListResponseSerializer,
@@ -843,6 +854,75 @@ class RemoteSensingClusterBlockLiveView(APIView):
)
class RemoteSensingClusterRecommendationView(APIView):
@extend_schema(
tags=["Location Data"],
summary="پیشنهاد گیاه برای هر کلاستر KMeans",
description=(
"با دریافت farm_uuid، داده هر کلاستر KMeans location_data به‌همراه "
"ndvi، ndwi، soil_vv، soil_vv_db و مقایسه گیاه‌های ثبت‌شده در farm_data "
"با crop_simulation برگردانده می‌شود و برای هر زیر‌بلاک یک گیاه پیشنهادی ارائه می‌شود."
),
parameters=[
OpenApiParameter(
name="farm_uuid",
type=str,
location=OpenApiParameter.QUERY,
required=True,
description="شناسه یکتای مزرعه",
),
],
responses={
200: build_response(
ClusterCropRecommendationEnvelopeSerializer,
"داده کلاسترها و پیشنهاد گیاه برای هر زیر‌بلاک بازگردانده شد.",
),
400: build_response(
SoilErrorResponseSerializer,
"پیش‌نیازهای مقایسه نامعتبر یا ناقص است.",
),
404: build_response(
SoilErrorResponseSerializer,
"مزرعه یا خروجی KMeans یافت نشد.",
),
},
examples=[
OpenApiExample(
"نمونه درخواست پیشنهاد گیاه برای کلاسترها",
value={"farm_uuid": "11111111-1111-1111-1111-111111111111"},
parameter_only=("farm_uuid", "query"),
)
],
)
def get(self, request):
serializer = ClusterCropRecommendationRequestSerializer(data=request.query_params)
if not serializer.is_valid():
return Response(
{"code": 400, "msg": "داده نامعتبر.", "data": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
try:
payload = build_cluster_crop_recommendations(
str(serializer.validated_data["farm_uuid"])
)
except ClusterRecommendationNotFound as exc:
return Response(
{"code": 404, "msg": str(exc), "data": None},
status=status.HTTP_404_NOT_FOUND,
)
except ClusterRecommendationValidationError as exc:
return Response(
{"code": 400, "msg": str(exc), "data": None},
status=status.HTTP_400_BAD_REQUEST,
)
return Response(
{"code": 200, "msg": "success", "data": payload},
status=status.HTTP_200_OK,
)
class RemoteSensingSubdivisionOptionListView(APIView):
@extend_schema(
tags=["Location Data"],