پرش به مطلب اصلی

Map

کامپوننت x-map برای نمایش نقشه با امکانات مختلف مانند تنظیم موقعیت، زوم، مارکرها، ابزار نقشه، قابلیت جست‌وجو، و رسم اشکال تعاملی طراحی شده است. این کامپوننت بر پایه Maplibre توسعه یافته و انواع حالات نمایشی (ماهواره‌ای یا جاده‌ای) و ابزارهای کمکی را پوشش می‌دهد.


ویژگی‌ها

  • تنظیم موقعیت نقشه (مرکز و زوم اولیه)
  • قابلیت افزودن و نمایش مارکرها
  • تنظیم و سفارشی‌سازی کلاس و استایل
  • نمایش جست‌وجوگر محل روی نقشه (searchable)
  • امکان انتخاب حالت نمایش: «جاده‌ای» (base) یا «ماهواره‌ای» (satellite)
  • قابلیت کنترل ابزارهای نقشه
  • پشتیبانی از Zone های UTM قابل تنظیم (zones)
  • ابزارهای رسم (drawable)، شامل درج نقطه و انتخاب فایل‌های KML/KMZ
  • پشتیبانی از پارامترهای دلخواه اضافی (mapOptions, parameters)
  • ادغام با مودال‌های نقطه‌گذاری پیشرفته هنگام drawable بودن

ورودی‌های کامپوننت

نام پراپنوع دادهمقدار پیش‌فرضتوضیحات
idstring'x-component-map-RANDOM'شناسه یکتا برای هر نقشه؛ اگر مقداردهی نشود به صورت تصادفی تولید می‌گردد.
classstringnullکلاس CSS اختصاصی برای div نقشه
stylestring'base'نوع نمایش نقشه؛ فقط 'base' (جاده‌ای) و 'satellite' (ماهواره‌ای) معتبر است.
containerClassstringnullکلاس CSS برای کانتینر اصلی کامپوننت
heightstring'400px'ارتفاع نقشه
configClassstringnullکلاس پیکربندی پیشرفته؛ در صورتی که drawable فعال باشد اجباری است.
zoomint4سطح زوم اولیه
minZoomint3کمترین سطح زوم مجاز
maxZoomint19بیشترین سطح زوم مجاز
centerLatitudeint|float|null32.2943779مرکز اولیه نقشه (عرض جغرافیایی)
centerLongitudeint|float|null53.6833878مرکز اولیه نقشه (طول جغرافیایی)
interactivebooltrueفعال‌سازی تعامل کاربر با نقشه
controlsarray[navigation, fullscreen, geolocation]ابزارهای قابل نمایش روی نقشه؛ فقط این سه مقدار مجاز: navigation، fullscreen، geolocation
markersarray[]آرایه مارکرها برای نمایش روی نقشه
zonesarray[38, 39, 40, 41]آرایه Zone های UTM قابل استفاده
searchablebooltrueفعال‌سازی یا غیرفعال‌سازی جستجو روی نقشه
drawableboolfalseفعال‌سازی ابزارهای رسم و نقطه‌گذاری پیشرفته
selectableboolfalseفعال‌سازی امکان انتخاب نقطه از روی نقشه
radiusBoundaryarray|nullnullامکان تعیین محدوده مجاز برای انتخاب نقطه در شعاع خاص در حالت selectable
mapOptionsarray[]پارامتر اختیاری برای ارسال تنظیمات دلخواه به نقشه
parametersarraynullپارامترهای اضافی اختیاری برای ارسال به بک‌اند
boundaryarraynullمحدوده مجاز برای نمایش و انتخاب نقاط نقشه
minLatitudeint|float|null-180حداقل عرض جغرافیایی مجاز
maxLatitudeint|float|null180حداکثر عرض جغرافیایی مجاز
minLongitudeint|float|null-90حداقل طول جغرافیایی مجاز
maxLongitudeint|float|null90حداکثر طول جغرافیایی مجاز
minXUtmint|float|null100000حداقل X سیستم UTM
maxXUtmint|float|null999999حداکثر X سیستم UTM
minYUtmint|float|null0حداقل Y سیستم UTM
maxYUtmint|float|null10000000حداکثر Y سیستم UTM
maxKmlKmzFileSizeint|nullnullحداکثر حجم مجاز فایل‌های KML/KMZ برای بارگذاری
maxTxtFileSizeint|nullnullحداکثر حجم مجاز فایل‌های TXT برای بارگذاری
نکته

مقدار radiusBoundary آرایه ای به شکل زیر است:

[
"center_latitude"=>float,
"center_longitude"=>float,
"radius"=>int
]
توجه
  • در صورتی که drawable فعال باشد، مقداردهی به configClass الزامی است.
  • اگر drawable غیرفعال باشد و configClass مقداردهی شود، نقاط پیش‌فرض فقط به‌صورت نمایشی روی نقشه نمایش داده خواهند شد.
  • با استفاده از parameters می‌توانید سایر پارامترهای مورد نیاز راه به همراه اطلاعات نقاط و configClass به بک‌اند ارسال کنید.
  • همچنین می‌توانید بازه مجاز انتخاب مختصات و حداکثر حجم فایل‌های بارگذاری را به صورت config تعیین کنید.
'map' => [
'min_latitude' => null,
'max_latitude' => null,
'min_longitude' => null,
'max_longitude' => null,
'min_x_utm' => null,
'max_x_utm' => null,
'min_y_utm' => null,
'max_y_utm' => null
]

راهنمای دریافت مختصات نقطه انتخاب شده

برای دریافت مختصات نقطه انتخاب شده روی نقشه می‌توانید رویداد سفارشی map:select را گوش دهید. هرگاه کاربر نقطه‌ای را انتخاب کند، این رویداد روی المنت نقشه ارسال می‌شود.

$("#selectable-map").on("map:select", (e, data) => {
console.log(data); // data شامل اطلاعات lat و lng نقطه انتخابی است
});

راهنمای دریافت نقطه مرکزی

برای دریافت مختصات موقعیت مرکزی نقشه (Center Point) می‌توانید رویداد سفارشی map:change را گوش دهید. هرگاه کاربر نقاط انتخابی را تغییر دهد، این رویداد روی المنت نقشه ارسال می‌شود.

مثال جی‌کوئری

می‌توانید با سلکتور نقشه (مثلاً #drawable-map) رویداد مربوطه را کنترل کنید:

$("#drawable-map").on("map:change", (e, data) => {
console.log(data); // data شامل اطلاعات مرکز و مساحت است
});

آرگومان دوم تابع، یک آبجکت با ساختار زیر است:

{
center: {
latlng: { lat: ..., lng: ... }, // مختصات جغرافیایی (Latitude, Longitude)
utm: {
x: ..., // مختصات شرقی UTM (Easting)
y: ..., // مختصات شمالی UTM (Northing)
z: ... // شماره Zone UTM (ZoneNumber)
}
},
area: ... // مساحت نقاط انتخابی
}

🖥️ مثال استفاده

<x-map
id="drawable-map"
:zoom="14"
:center-latitude="36.5559807"
:center-longitude="53.0512492"
style="satellite"
:drawable="true"
:config-class="\App\Components\ProjectMap::class"
:zones="[38, 39, 40]"
/>

<x-map
:zoom="14"
:center-latitude="36.5559807"
:center-longitude="53.0512492"
:markers="[
[
'latitude' => 36.5559807,
'longitude' => 53.0512492,
'title' => 'ساری',
'color' => 'var(--bs-success)',
],
[
'latitude' => 36.5406547,
'longitude' => 52.6743405,
'title' => 'بابل',
'color' => '#563d2d',
],
[
'latitude' => 36.459708,
'longitude' => 52.848358,
],
]"
/>

⚠️ نکات مهم

  • تنها مقادیر 'satellite' و 'base' برای پراپ style قابل قبول هستند.
  • مقادیر پراپ controls باید فقط شامل موارد زیر باشد: navigation, fullscreen, geolocation. استفاده از مقدار دیگر منجر به خطا می‌شود.
  • در صورت فعال بودن drawable، مقداردهی به پراپ configClass اجباری است.
  • پراپ markers باید آرایه‌ای از آبجکت‌ها (یا معادل PHP array) شامل مختصات و مقادیر دلخواه باشد.

مستندات بک‌اند (Backend)

برای استفاده از قابلیت BaseMap در کامپوننت نقشه، باید یک configClass ایجاد کنید که از ارث‌بری می‌کند. این کلاس باید دو متد اجباری را پیاده‌سازی کند.

ایجاد configClass

configClass باید از Dornica\BladeComponents\Forms\Map ارث‌بری کند:

<?php

namespace App\Components;

use Dornica\BladeComponents\Forms\Map\BaseMap;
use Dornica\Foundation\Regionalization\DTOs\UtmPoint;

class ProjectMap extends BaseMap
{
// پیاده‌سازی متدهای مورد نیاز
}

🔨 متدهای مورد نیاز

getCurrentValues

این متد باید آرایه‌ای از اشیاء UtmPoint را برگرداند که نشان‌دهنده نقاط فعلی روی نقشه است.

نوع بازگشتی: UtmPoint[]

محدودیت‌ها:

  • هر آیتم باید یک نمونه از کلاس UtmPoint باشد
  • هر UtmPoint باید دارای فیلدهای زیر باشد (همه غیر null):
    • identifier: شناسه یکتا برای نقطه
    • x: مختصات X (Easting) به صورت float
    • y: مختصات Y (Northing) به صورت float
    • z: شماره Zone به صورت int
  • فیلد sort: مقدار ترتیب نقطه در آرایه (اختیاری، به صورت خودکار تنظیم می‌شود)

مثال:

/**
* @return UtmPoint[]
*/
protected function getCurrentValues(): array
{
return [
new UtmPoint(
x: 681964.6172,
y: 4046655.000,
z: 39,
identifier: 123
),
new UtmPoint(
x: 682668.9766,
y: 4047225.2433,
z: 39,
identifier: 456
),
new UtmPoint(
x: 683467.4791,
y: 4047575.2166,
z: 39,
identifier: 789
)
];
}

نکات مهم:

  • در صورت عدم رعایت ساختار مورد نیاز، InvalidArgumentException throw می‌شود
  • می‌توانید از متد UtmPoint::fromArray() برای تبدیل آرایه به UtmPoint استفاده کنید
  • فیلدهای x و y اجباری هستند و نمی‌توانند null باشند
  • فیلدهای identifier و z نیز باید مقدار داشته باشند (غیر null)
  • فیلد sort به صورت خودکار بر اساس موقعیت نقطه در آرایه درخواست از فرانت‌اند تنظیم می‌شود (از 0 شروع می‌شود)

handleChanges

این متد زمانی فراخوانی می‌شود که تغییراتی در نقاط نقشه رخ دهد. می‌توانید از این متد برای پردازش تغییرات استفاده کنید.

نوع بازگشتی: void

متدهای کمکی در دسترس:

در این متد می‌توانید از متدهای زیر برای دسترسی به نقاط و پارامترها استفاده کنید:

  • getParameters(): دریافت پارامترهای ارسال شده از فرانت‌اند

    • این متد آرایه‌ای از پارامترهای دلخواه را برمی‌گرداند که از طریق پراپ parameters در کامپوننت نقشه ارسال شده‌اند
    • می‌توانید از این پارامترها برای دسترسی به اطلاعات اضافی مانند project_id، user_id و غیره استفاده کنید
  • getCurrentPoints(): دریافت تمام نقاط فعلی به صورت UtmPoint[]

    • هر نقطه دارای فیلد sort است که بر اساس موقعیت آن در آرایه درخواست از فرانت‌اند تنظیم شده است
  • getPreviousPoints(): دریافت تمام نقاط قبلی به صورت UtmPoint[]

    • هر نقطه دارای فیلد sort است که بر اساس موقعیت آن در آرایه قبلی تنظیم شده است
  • getAddedPoints(): دریافت نقاط اضافه شده (نقاطی که در قبلی نبودند اما در فعلی هستند)

    • هر نقطه دارای فیلد sort است که بر اساس موقعیت آن در آرایه فعلی تنظیم شده است (نه از 0 شروع می‌شود، بلکه موقعیت واقعی در آرایه فعلی)
  • getUpdatedPoints(): دریافت نقاط به‌روز شده (نقاطی با شناسه یکسان اما مختصات متفاوت)

    • هر نقطه دارای فیلد sort است که بر اساس موقعیت آن در آرایه فعلی تنظیم شده است
  • getDeletedPoints(): دریافت نقاط حذف شده (نقاطی که در قبلی بودند اما در فعلی نیستند)

    • هر نقطه دارای فیلد sort است که بر اساس موقعیت آن در آرایه قبلی تنظیم شده است

مثال:

/**
* @return void
*/
protected function handleChanges(): void
{
// دریافت پارامترهای ارسال شده از فرانت‌اند
$parameters = $this->getParameters();
$projectId = $parameters['project_id'] ?? null;

$addedPoints = $this->getAddedPoints();
$deletedPoints = $this->getDeletedPoints();
$updatedPoints = $this->getUpdatedPoints();

// پردازش نقاط اضافه شده
foreach ($addedPoints as $point) {
// ذخیره نقطه جدید در دیتابیس
// $point->getSort() مقدار ترتیب نقطه در آرایه فعلی را برمی‌گرداند
// مثال: اگر نقطه در موقعیت 3 آرایه فعلی باشد، sort = 3 خواهد بود
logger([
'project_id' => $projectId,
'identifier' => $point->getIdentifier(),
'sort' => $point->getSort(), // موقعیت در آرایه فعلی
'x' => $point->getX(),
'y' => $point->getY(),
]);
}

// پردازش نقاط حذف شده
foreach ($deletedPoints as $point) {
// حذف نقطه از دیتابیس
// $point->getSort() مقدار ترتیب نقطه در آرایه قبلی را برمی‌گرداند
logger([
'identifier' => $point->getIdentifier(),
'sort' => $point->getSort(), // موقعیت در آرایه قبلی
]);
}

// پردازش نقاط به‌روز شده
foreach ($updatedPoints as $point) {
// به‌روزرسانی مختصات نقطه در دیتابیس
// $point->getSort() مقدار ترتیب نقطه در آرایه فعلی را برمی‌گرداند
logger([
'identifier' => $point->getIdentifier(),
'sort' => $point->getSort(), // موقعیت در آرایه فعلی
]);
}
}

📋 مثال کامل

<?php

namespace App\Components;

use Dornica\BladeComponents\Forms\Map\BaseMap;
use Dornica\Foundation\Regionalization\DTOs\UtmPoint;

class ProjectMap extends BaseMap
{
/**
* دریافت نقاط فعلی نقشه
*
* @return UtmPoint[]
*/
protected function getCurrentValues(): array
{
// می‌توانید نقاط را از دیتابیس، API، یا هر منبع دیگری دریافت کنید
return [
new UtmPoint(
x: 681964.6172,
y: 4046655.000,
z: 39,
identifier: 123
),
new UtmPoint(
x: 682668.9766,
y: 4047225.2433,
z: 39,
identifier: 456
),
];
}

/**
* پردازش تغییرات نقاط نقشه
*
* @return void
*/
protected function handleChanges(): void
{
// دریافت پارامترهای ارسال شده از فرانت‌اند
$parameters = $this->getParameters();
$projectId = $parameters['project_id'] ?? null;

$addedPoints = $this->getAddedPoints();
$deletedPoints = $this->getDeletedPoints();
$updatedPoints = $this->getUpdatedPoints();

// مثال: ذخیره تغییرات در دیتابیس
// Project::saveChanges($projectId, $addedPoints, $deletedPoints, $updatedPoints);
}
}

📦 پارامترها (Parameters)

شما می‌توانید پارامترهای دلخواه را از طریق پراپ parameters در کامپوننت نقشه به configClass ارسال کنید. این پارامترها در متد handleChanges() از طریق متد getParameters() قابل دسترسی هستند.

نحوه دریافت پارامترها در بک‌اند

protected function handleChanges(): void
{
// دریافت تمام پارامترها
$parameters = $this->getParameters();

// دسترسی به پارامترهای خاص
$projectId = $parameters['project_id'] ?? null;
$category = $parameters['category'] ?? 'default';

// استفاده از پارامترها در منطق برنامه
if ($projectId) {
$project = Project::find($projectId);
// ...
}

$currentPoints = $this->getCurrentPoints();
// پردازش نقاط با استفاده از پارامترها
}

نمونه استفاده عملی

protected function handleChanges(): void
{
$parameters = $this->getParameters();
$projectId = $parameters['project_id'] ?? null;

if (!$projectId) {
logger()->warning('Project ID is missing in parameters');
return;
}

$addedPoints = $this->getAddedPoints();

foreach ($addedPoints as $point) {
ProjectPoint::create([
'project_id' => $projectId,
'identifier' => $point->getIdentifier(),
'sort_order' => $point->getSort(),
'x' => $point->getX(),
'y' => $point->getY(),
'z' => $point->getZ(),
]);
}
}

نکات مهم درباره Parameters

  • پارامترها به صورت آرایه از فرانت‌اند به بک‌اند ارسال می‌شوند
  • می‌توانید هر نوع داده‌ای (string، int، array و غیره) را در پارامترها ارسال کنید
  • در صورت عدم ارسال پارامتر، getParameters() آرایه خالی برمی‌گرداند
  • از ?? یا isset() برای بررسی وجود پارامترها استفاده کنید
  • پارامترها در هر درخواست تغییرات نقشه در دسترس هستند

🔢 فیلد Sort در UtmPoint

هر نقطه (UtmPoint) دارای فیلد sort است که نشان‌دهنده ترتیب نقطه در آرایه درخواست از فرانت‌اند است. این فیلد به صورت خودکار تنظیم می‌شود و نیازی به تنظیم دستی ندارد.

نحوه کار فیلد Sort

  • نقاط فعلی (getCurrentPoints()): مقدار sort بر اساس موقعیت نقطه در آرایه فعلی تنظیم می‌شود (0, 1, 2, 3, ...)
  • نقاط اضافه شده (getAddedPoints()): مقدار sort بر اساس موقعیت نقطه در آرایه فعلی تنظیم می‌شود. به عنوان مثال، اگر نقطه در موقعیت 3 آرایه فعلی باشد، sort = 3 خواهد بود (نه 0)
  • نقاط به‌روز شده (getUpdatedPoints()): مقدار sort بر اساس موقعیت نقطه در آرایه فعلی تنظیم می‌شود
  • نقاط حذف شده (getDeletedPoints()): مقدار sort بر اساس موقعیت نقطه در آرایه قبلی تنظیم می‌شود

نمونه استفاده از Sort

protected function handleChanges(): void
{
$currentPoints = $this->getCurrentPoints();

foreach ($currentPoints as $point) {
// دریافت مقدار sort
$sort = $point->getSort(); // 0, 1, 2, 3, ...

// استفاده از sort برای ذخیره ترتیب در دیتابیس
// ProjectPoint::create([
// 'project_id' => $this->projectId,
// 'identifier' => $point->getIdentifier(),
// 'sort_order' => $point->getSort(),
// 'x' => $point->getX(),
// 'y' => $point->getY(),
// 'z' => $point->getZ(),
// ]);
}

// مثال: مرتب‌سازی نقاط بر اساس sort
$addedPoints = $this->getAddedPoints();
usort($addedPoints, function($a, $b) {
return $a->getSort() <=> $b->getSort();
});
}

نکات مهم درباره Sort

  • فیلد sort همیشه بر اساس موقعیت واقعی نقطه در آرایه درخواست تنظیم می‌شود
  • مقدار sort برای نقاط اضافه شده از 0 شروع نمی‌شود، بلکه موقعیت واقعی آن‌ها در آرایه فعلی است
  • می‌توانید از $point->getSort() برای دریافت مقدار sort استفاده کنید
  • در متد toArray() نقطه، فیلد sort نیز شامل می‌شود (در صورت وجود)

📐 DTOs و تبدیل مختصات

ماژول Regionalization شامل دو DTO (Data Transfer Object) برای کار با مختصات جغرافیایی است:

UtmPoint

کلاس UtmPoint برای نمایش نقاط با مختصات UTM استفاده می‌شود.

فیلدها:

  • x (float): مختصات شرقی (Easting) به متر
  • y (float): مختصات شمالی (Northing) به متر
  • z (int|null): شماره Zone UTM (1-60)
  • identifier (mixed|null): شناسه یکتا نقطه
  • attributes (array): ویژگی‌های اضافی
  • sort (int|null): ترتیب نقطه در آرایه

متدهای مهم:

  • getX(): دریافت مختصات X
  • getY(): دریافت مختصات Y
  • getZ(): دریافت شماره Zone
  • getIdentifier(): دریافت شناسه
  • getSort(): دریافت ترتیب
  • toArray(): تبدیل به آرایه
  • fromArray(array $data): ایجاد از آرایه
  • fromArrayList(array $points): ایجاد آرایه‌ای از نقاط
  • toLatLongPoint(): تبدیل به LatLongPoint (مختصات جغرافیایی)

مثال استفاده:

use Dornica\Foundation\Regionalization\DTOs\UtmPoint;

// ایجاد نقطه UTM
$utmPoint = new UtmPoint(
x: 681964.6172,
y: 4046655.000,
z: 39,
identifier: 123
);

// تبدیل به مختصات جغرافیایی
$latLongPoint = $utmPoint->toLatLongPoint();
echo $latLongPoint->getLatitude(); // 36.5559807
echo $latLongPoint->getLongitude(); // 53.0512492

LatLongPoint

کلاس LatLongPoint برای نمایش نقاط با مختصات جغرافیایی (Latitude/Longitude) استفاده می‌شود.

فیلدها:

  • latitude (float): عرض جغرافیایی (درجه اعشاری)
  • longitude (float): طول جغرافیایی (درجه اعشاری)
  • identifier (mixed|null): شناسه یکتا نقطه
  • attributes (array): ویژگی‌های اضافی
  • sort (int|null): ترتیب نقطه در آرایه

متدهای مهم:

  • getLatitude(): دریافت عرض جغرافیایی
  • getLongitude(): دریافت طول جغرافیایی
  • getIdentifier(): دریافت شناسه
  • getSort(): دریافت ترتیب
  • toArray(): تبدیل به آرایه
  • fromArray(array $data): ایجاد از آرایه
  • fromArrayList(array $points): ایجاد آرایه‌ای از نقاط
  • toUtmPoint(): تبدیل به UtmPoint

مثال استفاده:

use Dornica\Foundation\Regionalization\DTOs\LatLongPoint;

// ایجاد نقطه جغرافیایی
$latLongPoint = new LatLongPoint(
latitude: 36.5559807,
longitude: 53.0512492,
identifier: 123
);

// دریافت مختصات
echo $latLongPoint->getLatitude(); // 36.5559807
echo $latLongPoint->getLongitude(); // 53.0512492

تبدیل مختصات

در Doravel دو متد تبدیل اصلی در سطح DTO در اختیار شماست:

  • UtmPoint::toLatLongPoint()
  • LatLongPoint::toUtmPoint()

تبدیل UTM به Lat/Long:

use Dornica\Foundation\Regionalization\DTOs\UtmPoint;

$utmPoint = new UtmPoint(
x: 681964.6172,
y: 4046655.000,
z: 39,
identifier: 123
);

// تبدیل به Lat/Long
$latLongPoint = $utmPoint->toLatLongPoint();

// استفاده از مختصات جغرافیایی
$latitude = $latLongPoint->getLatitude();
$longitude = $latLongPoint->getLongitude();

تبدیل Lat/Long به UTM:

use Dornica\Foundation\Regionalization\DTOs\LatLongPoint;

$latLongPoint = new LatLongPoint(
latitude: 36.5559807,
longitude: 53.0512492,
identifier: 123
);

$utmPoint = $latLongPoint->toUtmPoint();

نکات مهم:

  • برای تبدیل UTM به Lat/Long، فیلد z یا zone باید مقدار داشته باشد
  • در صورت نبودن zone، متد InvalidArgumentException throw می‌کند
  • اگر با facade کار می‌کنید، می‌توانید از Regionalizer::toLatLong() و Regionalizer::toUtm() هم استفاده کنید

مثال کامل:

protected function handleChanges(): void
{
$currentPoints = $this->getCurrentPoints();

foreach ($currentPoints as $utmPoint) {
// تبدیل UTM به Lat/Long
$latLongPoint = $utmPoint->toLatLongPoint();

// استفاده از مختصات جغرافیایی
logger([
'identifier' => $utmPoint->getIdentifier(),
'utm' => [
'x' => $utmPoint->getX(),
'y' => $utmPoint->getY(),
'z' => $utmPoint->getZ(),
],
'latlong' => [
'latitude' => $latLongPoint->getLatitude(),
'longitude' => $latLongPoint->getLongitude(),
],
]);
}
}

⚠️ خطاهای رایج

خطای ساختار داده

در صورت عدم رعایت ساختار مورد نیاز در getCurrentValues()، خطاهای زیر ممکن است رخ دهد:

  • Item at index X must be an instance of UtmPoint, got array: آیتم باید یک نمونه از UtmPoint باشد، نه آرایه
  • Item at index X is missing required field: 'identifier': فیلد identifier الزامی است
  • Item at index X is missing required field: 'z': فیلد z الزامی است

راه حل: اطمینان حاصل کنید که تمام آیتم‌های برگشتی نمونه‌های معتبر UtmPoint با تمام فیلدهای مورد نیاز هستند.