تا حالا شده دیتایی رو بخواین در پایگاه داده ذخیره کنید که شامل مختصات جغرافیایی باشه؟
از بین data type های معتبر که برای ذخیره کردن دیتای جغرافیایی در پایگاه داده ها ایجاد شدن، شاید دونستن فرق بین geography و geometry بتونه کار شما رو کمی راحت تر بکنه.
تفاوت این دو به طور خلاصه، دستگاه مختصاتی هست که برای محاسبات استفاده میکنن. وقتی نوع داده رو geometry تعریف میکنیم محاسبات روی دستگاه مختصات کروی (Spherical coordinate system) و برحسب زاویه انجام میشه. اما وقتی از نوع داده ی geography استفاده میکنیم، محاسبات روی دستگاه دکارتی و بر حسب متره! مواقعی که میخوایم مقایسه ایی انجام بدیم مثل مقایسه مساحت چند ضلعی ها یا فاصله ی چندین نقطه از هم، اگه خروجی مون زاویه باشه کارمون به مراتب سخت تر از وقتی هست که خروجی مون متر باشه.
برای روشن تر شدن موضوع، من میخوام با استفاده از تابع ST_Distance فاصله ی دو نقطه ی مترو شهید بهشتی و شرکت سان که با دایره قرمز مشخص شدن، رو محاسبه کنم.
SELECT ST_Distance( ST_GeometryFromText('POINT(51.427141 35.730271)', 4326), -- مترو شهید بهشتی ST_GeometryFromText('POINT(51.422646 35.732535)', 4326) --شرکت سان ); -- output : 0.00503296344115198
SELECT ST_Distance (ST_GeographyFromText('POINT(51.427141 35.730271)'), -- مترو شهید بهشتی ST_GeographyFromText('POINT(51.422646 35.732535)') --شرکت سان ); -- output: 477.98556905
پیداست که فاصله ی این دو نقطه ۴۷۷ متره! درحالی که در حالت اول از عدد 0.0050329 که خروجی کوئری مون بود این رو متوجه نمی شدیم.
برای اینکار اول باید مقدار EPSG رو با استفاده از تابع ST_Transform برابر ۴۳۲۶ کنیم.
SELECT Geography(ST_Transform(geom,4326)) AS geog FROM table_name;
SELECT geography_field:: geometry AS geometry FROM table_name;
CREATE INDEX test_geography_geog_gix ON table_name USING GIST (geog);
اگه از نوع داده geometry استفاده کنیم،به دلیل کروی بودن دستگاه مختصات، ممکنه محاسبات و تحلیل ها پیچیده تر و کندتر انجام بشن. اما وقتی پراکندگی دیتا به وسعت کره ی زمین هست و شامل کشورها و قاره های مختلف میشه مجبوریم حتما از geometry استفاده کنیم.اما اگه دیتامون مختص فقط یک کشور هست استفاده از geography مشکلی رو ایجاد نمیکنه.
اگه فاصله ی دو شهر Tokyo و Los Angeles رو در دستگاه دکارتی یعنی بر اساس geography حساب کنیم(خط صورتی رنگ) ، به نتیجه ی اشتباهی منجر میشه.نتیجه ی درست و واقعی وقتی حاصل میشه در دستگاه مختصات کروی(خط قرمز رنگ) باشیم.
SELECT ST_Distance( ST_GeometryFromText('Point(-118.4079 33.9434)'), -- LAX ST_GeometryFromText('Point(139.733 35.567)')) -- NRT (Tokyo/Narita) AS geometry_distance, ST_Distance( ST_GeographyFromText('Point(-118.4079 33.9434)'), -- LAX ST_GeographyFromText('Point(139.733 35.567)')) -- NRT (Tokyo/Narita) AS geography_distance; --output: geometry_distance : 258.146005837336 (correct answer) geography_distance : 8833954.76996256 (wrong answer)
تصور کنید یه هواپیما بخواد از شهر Tokyo به Los Angeles بره، قطعا مسیر صورتی که در دستگاه دکارتی هست رو انتخاب نمیکنه :)
یکی از محدودیت هایی که استفاده از نوع داده ی geography داره، فانکشن های محدودی هست که این نوع داده رو پشتیبانی میکنن.
text
geography
bytea
geography
text
text
text
text
double
boolean
double
double
boolean
boolean
boolean
geography
1geography
1اگه این مطلب براتون جالب بود و دوست دارین در موردش بیشتر بدونین، پیشنهاد می کنم این لینک رو حتما مطالعه کنید.