> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> توثيق الإحداثيات

# دوال للتعامل مع الإحداثيات الجغرافية

<div id="greatcircledistance">
  ## greatCircleDistance
</div>

يحسب المسافة بين نقطتين على سطح الأرض باستخدام [معادلة الدائرة العظمى](https://en.wikipedia.org/wiki/Great-circle_distance).

```sql theme={null}
greatCircleDistance(lon1Deg, lat1Deg, lon2Deg, lat2Deg)
```

**معلمات الإدخال**

* `lon1Deg` — خط الطول النقطة الأولى بالدرجات. النطاق: `[-180°, 180°]`.
* `lat1Deg` — خط العرض النقطة الأولى بالدرجات. النطاق: `[-90°, 90°]`.
* `lon2Deg` — خط الطول النقطة الثانية بالدرجات. النطاق: `[-180°, 180°]`.
* `lat2Deg` — خط العرض النقطة الثانية بالدرجات. النطاق: `[-90°, 90°]`.

تشير القيم الموجبة إلى خط العرض شمالًا وخط الطول شرقًا، وتشير القيم السالبة إلى خط العرض جنوبًا وخط الطول غربًا.

**القيمة المُعادة**

المسافة بين نقطتين على سطح الأرض، بالمتر.

يُنشئ استثناءً عندما تقع قيم معلمات الإدخال خارج النطاق.

**مثال**

```sql theme={null}
SELECT greatCircleDistance(55.755831, 37.617673, -55.755831, -37.617673) AS greatCircleDistance
```

```text theme={null}
┌─greatCircleDistance─┐
│            14128352 │
└─────────────────────┘
```

<div id="geodistance">
  ## geoDistance
</div>

مشابهة لـ `greatCircleDistance`، لكنها تحسب المسافة على إهليلج WGS-84 بدلًا من الكرة. ويوفّر ذلك تقريبًا أدق لجيود الأرض.
الأداء مماثل لأداء `greatCircleDistance` (من دون أي تراجع في الأداء). ويُوصى باستخدام `geoDistance` لحساب المسافات على الأرض.

ملاحظة تقنية: بالنسبة للنقاط المتقاربة بما يكفي، نحسب المسافة باستخدام تقريب مستوٍ وفق المترية على المستوى المماس عند منتصف الإحداثيات.

```sql theme={null}
geoDistance(lon1Deg, lat1Deg, lon2Deg, lat2Deg)
```

**معلمات الإدخال**

* `lon1Deg` — خط الطول النقطة الأولى بالدرجات. النطاق: `[-180°, 180°]`.
* `lat1Deg` — خط العرض النقطة الأولى بالدرجات. النطاق: `[-90°, 90°]`.
* `lon2Deg` — خط الطول النقطة الثانية بالدرجات. النطاق: `[-180°, 180°]`.
* `lat2Deg` — خط العرض النقطة الثانية بالدرجات. النطاق: `[-90°, 90°]`.

تشير القيم الموجبة إلى خطوط العرض الشمالية وخطوط الطول الشرقية، وتشير القيم السالبة إلى خطوط العرض الجنوبية وخطوط الطول الغربية.

**القيمة المعادة**

المسافة بين نقطتين على سطح الأرض، بالمتر.

يتم إنشاء استثناء عندما تقع قيم معلمات الإدخال خارج هذا النطاق.

**مثال**

```sql theme={null}
SELECT geoDistance(38.8976, -77.0366, 39.9496, -75.1503) AS geoDistance
```

```text theme={null}
┌─geoDistance─┐
│   212458.73 │
└─────────────┘
```

<div id="greatcircleangle">
  ## greatCircleAngle
</div>

تحسب الزاوية المركزية بين نقطتين على سطح الأرض باستخدام [معادلة الدائرة العظمى](https://en.wikipedia.org/wiki/Great-circle_distance).

```sql theme={null}
greatCircleAngle(lon1Deg, lat1Deg, lon2Deg, lat2Deg)
```

**معلمات الإدخال**

* `lon1Deg` — خط الطول للنقطة الأولى، بالدرجات.
* `lat1Deg` — خط العرض للنقطة الأولى، بالدرجات.
* `lon2Deg` — خط الطول للنقطة الثانية، بالدرجات.
* `lat2Deg` — خط العرض للنقطة الثانية، بالدرجات.

**القيمة المعادة**

الزاوية المركزية بين نقطتين، بالدرجات.

**مثال**

```sql theme={null}
SELECT greatCircleAngle(0, 0, 45, 0) AS arc
```

```text theme={null}
┌─arc─┐
│  45 │
└─────┘
```

<div id="geotoutm">
  ## geoToUTM
</div>

يحوّل الإحداثيات الجغرافية وفق نظام WGS84 `(longitude, latitude)` إلى إحداثيات [Universal Transverse Mercator (UTM)](https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system).

UTM عبارة عن مجموعة من 60 إسقاط ميركاتور مستعرض، يغطي كلٌّ منها نطاقًا من خطوط الطول بعرض 6°، ويحوّل الإحداثيات الجغرافية إلى شبكة مستوية بوحدة المتر. يُحدَّد نطاق UTM تلقائيًا من خط الطول، مع تطبيق الاستثناءات القياسية الخاصة بـ Norway وSvalbard، ما لم تُحدَّد قيمة `zone` صراحةً. لا يُعرَّف UTM إلا لخطوط العرض ضمن النطاق `[-80°, 84°]`؛ أما المناطق القطبية فتستخدم نظام UPS المنفصل.

```sql theme={null}
geoToUTM(longitude, latitude[, zone])
```

**المعاملات**

* `longitude` — خط الطول بالدرجات. النطاق: `[-180°, 180°]`. [`Float32`](/docs/ar/reference/data-types/float)/[`Float64`](/docs/ar/reference/data-types/float).
* `latitude` — خط العرض بالدرجات. النطاق: `[-80°, 84°]`. [`Float32`](/docs/ar/reference/data-types/float)/[`Float64`](/docs/ar/reference/data-types/float).
* `zone` — اختياري. يفرض الإسقاط على نطاق UTM هذا بدلًا من اختيارها تلقائيًا. النطاق: `[1, 60]`. [`(U)Int*`](/docs/ar/reference/data-types/int-uint).

**القيمة المعادة**

Tuple مسمّاة بالشكل `(easting, northing, zone, band)`: تكون قيمتا `easting` و`northing` بالمتر ([`Float64`](/docs/ar/reference/data-types/float))، ورقم `zone` الخاص بـ UTM ([`UInt8`](/docs/ar/reference/data-types/int-uint))، وحرف `band` لخط العرض في MGRS ([`FixedString(1)`](/docs/ar/reference/data-types/fixedstring)). وتشير قيمة `band` التي تساوي `'N'` أو أي حرف يليه إلى نصف الكرة الشمالي.

يُنتج استثناءً عندما يكون خط العرض خارج `[-80°, 84°]` أو يكون خط الطول خارج `[-180°, 180°]`.

**مثال**

```sql theme={null}
SELECT geoToUTM(2.294497, 48.858222) AS utm; -- Eiffel Tower
```

```text theme={null}
(448251.5978370684,5411935.125629659,31,'U')
```

<div id="utmtogeo">
  ## UTMToGeo
</div>

يحوّل إحداثيات [UTM](https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system) إلى الإحداثيات الجغرافية وفق WGS84 `(خط الطول، خط العرض)`. وهذه هي الدالة العكسية لـ [`geoToUTM`](#geotoutm).

```sql theme={null}
UTMToGeo(easting, northing, zone, is_north)
```

**الوسيطات**

* `easting` — الإحداثي الشرقي بالأمتار (يتضمن الإزاحة الشرقية الكاذبة بمقدار 500000 م). [`(U)Int*`](/docs/ar/reference/data-types/int-uint)/[`Float*`](/docs/ar/reference/data-types/float).
* `northing` — الإحداثي الشمالي بالأمتار (يتضمن الإزاحة الشمالية الكاذبة بمقدار 10000000 م في نصف الكرة الجنوبي). [`(U)Int*`](/docs/ar/reference/data-types/int-uint)/[`Float*`](/docs/ar/reference/data-types/float).
* `zone` — رقم نطاق UTM. المدى: `[1, 60]`. [`(U)Int*`](/docs/ar/reference/data-types/int-uint).
* `is_north` — نصف الكرة الأرضية: `1` للنصف الشمالي و`0` للنصف الجنوبي. [`(U)Int*`](/docs/ar/reference/data-types/int-uint).

**القيمة المعادة**

Tuple مُسمّى بالشكل `(longitude, latitude)` بالدرجات. [`Tuple(Float64, Float64)`](/docs/ar/reference/data-types/tuple).

**مثال**

```sql theme={null}
SELECT UTMToGeo(448251.6, 5411935.13, 31, 1) AS coord;
```

```text theme={null}
(2.2944970289079203,48.85822204127082)
```

<div id="geotomgrs">
  ## geoToMGRS
</div>

يحوِّل الإحداثيات الجغرافية وفق WGS84 `(خط الطول، خط العرض)` إلى سلسلة [Military Grid Reference System (MGRS)](https://en.wikipedia.org/wiki/Military_Grid_Reference_System).

تكون السلسلة بالتنسيق `<zone><band><100km square><easting><northing>`، على سبيل المثال `31UDQ4825111935`. تتحكم الوسيطة `precision` في عدد الخانات المستخدمة لكلٍّ من `easting` و`northing`: تكون القيمة `5` (الافتراضية) لدقة 1 م، و`4` لدقة 10 م، و`3` لدقة 100 م، و`2` لدقة 1 كم، و`1` لدقة 10 كم، و`0` لمربع شبكة 100 كم فقط. لا يُعرَّف MGRS إلا لدوائر العرض ضمن النطاق `[-80°, 84°]`.

```sql theme={null}
geoToMGRS(longitude, latitude[, precision])
```

**الوسائط**

* `longitude` — خط الطول بالدرجات. النطاق: `[-180°, 180°]`. [`Float32`](/docs/ar/reference/data-types/float)/[`Float64`](/docs/ar/reference/data-types/float).
* `latitude` — خط العرض بالدرجات. النطاق: `[-80°, 84°]`. [`Float32`](/docs/ar/reference/data-types/float)/[`Float64`](/docs/ar/reference/data-types/float).
* `precision` — اختياري. عدد الخانات لكل من الإحداثي الشرقي والإحداثي الشمالي. القيمة الافتراضية: `5`. النطاق: `[0, 5]`. [`(U)Int*`](/docs/ar/reference/data-types/int-uint).

**القيمة المُعادة**

سلسلة مرجعية بتنسيق MGRS. [`String`](/docs/ar/reference/data-types/string).

**مثال**

```sql theme={null}
SELECT geoToMGRS(2.294497, 48.858222) AS mgrs, geoToMGRS(2.294497, 48.858222, 3) AS mgrs_100m;
```

```text theme={null}
┌─mgrs────────────┬─mgrs_100m───┐
│ 31UDQ4825111935 │ 31UDQ482119 │
└─────────────────┴─────────────┘
```

<div id="mgrstogeo">
  ## MGRSToGeo
</div>

يفكّ ترميز سلسلة [MGRS](https://en.wikipedia.org/wiki/Military_Grid_Reference_System) إلى إحداثيات جغرافية وفق WGS84 `(longitude, latitude)`. وهذه هي العملية العكسية لـ [`geoToMGRS`](#geotomgrs).

النقطة المُعادة هي مركز مربع الشبكة المشار إليه، لذلك تتوافق دقة النتيجة مع الدقة المرمّزة في السلسلة. ويُتجاهل الفراغ الأبيض في الإدخال، كما أن الأحرف لا تتأثر بحالة الأحرف.

```sql theme={null}
MGRSToGeo(mgrs)
```

**الوسائط**

* `mgrs` — سلسلة مرجعية بتنسيق MGRS المطلوب فك ترميزها. [`String`](/docs/ar/reference/data-types/string)/[`FixedString`](/docs/ar/reference/data-types/fixedstring).

**القيمة المُعادة**

Tuple مُسمّى `(longitude, latitude)` بالدرجات. [`Tuple(Float64, Float64)`](/docs/ar/reference/data-types/tuple).

**مثال**

```sql theme={null}
SELECT MGRSToGeo('31UDQ4825111935') AS coord;
```

```text theme={null}
(2.294495618908297,48.85822536113692)
```

<div id="pointinellipses">
  ## pointInEllipses
</div>

يتحقق مما إذا كانت النقطة تقع داخل شكل بيضاوي واحد على الأقل.
الإحداثيات هندسية ضمن نظام الإحداثيات الديكارتية.

```sql theme={null}
pointInEllipses(x, y, x₀, y₀, a₀, b₀,...,xₙ, yₙ, aₙ, bₙ)
```

**معلمات الإدخال**

* `x, y` — إحداثيات نقطة على المستوى.
* `xᵢ, yᵢ` — إحداثيات مركز القطع الناقص رقم `i`.
* `aᵢ, bᵢ` — محورا القطع الناقص رقم `i` بوحدات إحداثيي x وy.

يجب أن يكون عدد معلمات الإدخال `2+4⋅n`، حيث إن `n` هو عدد الأشكال البيضوية.

**القيم المعادة**

`1` إذا كانت النقطة داخل شكل بيضوي واحد على الأقل؛ `0` إذا لم تكن كذلك.

**مثال**

```sql theme={null}
SELECT pointInEllipses(10., 10., 10., 9.1, 1., 0.9999)
```

```text theme={null}
┌─pointInEllipses(10., 10., 10., 9.1, 1., 0.9999)─┐
│                                               1 │
└─────────────────────────────────────────────────┘
```

<div id="pointinpolygon">
  ## pointInPolygon
</div>

يتحقق مما إذا كانت النقطة تقع داخل المضلع على المستوى.

```sql theme={null}
pointInPolygon((x, y), [(a, b), (c, d) ...], ...)
```

**قيم الإدخال**

* `(x, y)` — إحداثيات نقطة على المستوى. نوع البيانات — [Tuple](/docs/ar/reference/data-types/tuple) — قيمة Tuple مكوّنة من رقمين، أو [Point](/docs/ar/reference/data-types/geo#point).
* `[(a, b), (c, d) ...]` — رؤوس المضلع. نوع البيانات — [Array](/docs/ar/reference/data-types/array) أو [Ring](/docs/ar/reference/data-types/geo#ring). تُمثَّل كل قمة بزوج من الإحداثيات `(a, b)`. يجب تحديد الرؤوس بترتيب مع عقارب الساعة أو عكس اتجاه عقارب الساعة. الحد الأدنى لعدد الرؤوس هو 3.
* تدعم الدالة أيضًا المضلع ذي الفتحات (الأجزاء المقتطعة). نوع البيانات — [Polygon](/docs/ar/reference/data-types/geo#polygon). مرِّر إما `Polygon` بالكامل باعتباره المُدخل الثاني، أو مرِّر الحلقة الخارجية أولًا ثم كل فتحة كمدخل إضافي منفصل.
* تدعم الدالة أيضًا MultiPolygon. نوع البيانات — [MultiPolygon](/docs/ar/reference/data-types/geo#multipolygon). مرِّر إما `MultiPolygon` بالكامل باعتباره المُدخل الثاني، أو أدرج كل مضلع مكوّن باعتباره مُدخلًا مستقلًا.
* يمكن أيضًا أن تكون وسيطة المضلع عمود [Geometry](/docs/ar/reference/data-types/geo#geometry) يحتوي على قيم ذات شكل مضلع (`Ring` أو `Polygon` أو `MultiPolygon`).

يمكن تمرير الأنواع ذات الشكل المضلع ([Ring](/docs/ar/reference/data-types/geo#ring) و[Polygon](/docs/ar/reference/data-types/geo#polygon) و[MultiPolygon](/docs/ar/reference/data-types/geo#multipolygon) و[Geometry](/docs/ar/reference/data-types/geo#geometry)) إما كثوابت أو كأعمدة جدول عادية (غير ثابتة). وعندما يُمرَّر المضلع عبر عدة وسائط منفصلة (حلقة خارجية تتبعها فتحات، أو عدة مضلعات ضمن multipolygon)، يجب أن تكون جميع تلك الوسائط ثابتة.

**القيم المعادة**

`1` إذا كانت النقطة داخل المضلع، و`0` إذا لم تكن كذلك.
إذا كانت النقطة على حدود المضلع، فقد تُرجع الدالة 0 أو 1.

**مثال**

```sql theme={null}
SELECT pointInPolygon((3., 3.), [(6, 0), (8, 4), (5, 8), (0, 2)]) AS res
```

```text theme={null}
┌─res─┐
│   1 │
└─────┘
```

يمكن أيضًا تمرير المضلع باستخدام أنواع البيانات الهندسية المسمّاة، بما في ذلك كعمود في جدول:

```sql theme={null}
CREATE TABLE poly (id UInt32, shape Polygon) ENGINE = Memory;
INSERT INTO poly VALUES (1, [[(0, 0), (10, 0), (10, 10), (0, 10)], [(4, 4), (6, 4), (6, 6), (4, 6)]]);
SELECT id, pointInPolygon((2., 2.), shape) AS res FROM poly;
```

```text theme={null}
┌─id─┬─res─┐
│  1 │   1 │
└────┴─────┘
```

> **ملاحظة**
> • يمكنك تعيين `validate_polygons = 0` لتجاوز التحقق من صحة الأشكال الهندسية.
> • تفترض الدالة `pointInPolygon` أن كل مضلع مُشكَّل بصورة صحيحة. إذا كان الإدخال متقاطعًا مع نفسه، أو كانت حلقاته مرتبة على نحو غير صحيح، أو كانت حوافه متداخلة، تصبح النتائج غير موثوقة—خصوصًا للنقاط الواقعة تمامًا على حافة أو رأس، أو داخل تقاطع ذاتي حيث يكون مفهوم "الداخل" مقابل "الخارج" غير معرّف.
> • عندما تكون وسيطة المضلع ثابتة وتُعبَّر النقطة باستخدام أعمدة المفتاح المفهرسة (على سبيل المثال، `pointInPolygon((x, y), constant_polygon)` على جدول تكون فيه `x, y` جزءًا من `PRIMARY KEY` أو مشمولة بفهرس `minmax`)، يمكن لـ ClickHouse استخدام كلٍّ من المفتاح الأساسي وفهارس تخطي البيانات `minmax` لاستبعاد الحبيبات غير ذات الصلة.
