16. Проекція даних¶
Земля не є пласкою, і немає простого способу зобразити її на плоскому паперовому мапі (або на екрані комп’ютера), тому люди придумали різноманітні винахідливі рішення, кожне з яких має свої переваги і недоліки. Деякі проекції зберігають площу, тож усі об’єкти мають відносний розмір один до одного; інші проекції зберігають кути (конформні), як, наприклад, проекція Меркатора; деякі проекції намагаються знайти хороший проміжний варіант із мінімальними спотвореннями по кількох параметрах. Спільним для всіх проекцій є те, що вони трансформують (сферичний) світ у плоску декартову систему координат, а вибір проекції залежить від того, як ви плануєте використовувати ці дані.
Ми вже зустрічали проекції, коли завантажували наші дані Нью-Йорка — пам’ятаєте той нав’язливий SRID 26918? Іноді, однак, потрібно трансформувати та повторно проектувати між системами просторових координат. PostGIS має вбудовану підтримку зміни проекції даних за допомогою функції ST_Transform(geometry, srid). Для керування ідентифікаторами просторових систем координат (SRID) у геометріях, PostGIS надає функції ST_SRID(geometry) та ST_SetSRID(geometry, srid).
Ми можемо підтвердити SRID наших даних за допомогою функції ST_SRID:
SELECT ST_SRID(geom) FROM nyc_streets LIMIT 1;
26918
А що таке визначення «26918»? Як ми бачили у розділі «:ref: завантаження даних <loading_data>», це визначення міститься у таблиці spatial_ref_sys
. Насправді, там є дві версії визначення. Визначення у форматі «well-known text» (WKT) знаходиться у стовпці srtext
, а друга версія у форматі «proj.4» — у стовпці proj4text
.
SELECT * FROM spatial_ref_sys WHERE srid = 26918;
Механізм перепроектування PostGIS спробує знайти найкращу проекцію з таблиці spatial_ref_sys
:
auth_name / auth_srid Якщо proj може знайти дійсне «authority name» та «authority srid» у своєму внутрішньому каталозі, він використає їх для створення визначення проекції.
srtext Якщо proj може проаналізувати та сформувати об’єкт визначення з
srtext
, він буде використовувати його.proj4text Зрештою, proj спробує обробити
proj4text
.
Вся ця надмірність означає, що для створення нової проекції в PostGIS вам потрібно лише дійсний рядок srtext
або proj4text
. Усі поширені пари назв/кодів органів влади вже завантажені в таблицю за замовчуванням.
Якщо у вас є вибір під час створення власного проектування, заповніть стовпець «srtext», оскільки цей стовпець також використовується зовнішніми програмами, такими як «GeoServer <http://geoserver.org>», «QGIS <https://qgis.org>» та «FME <http://www.safe.com/>» та іншими.
16.1. Порівняння даних¶
Разом координати та SRID визначають місце на земній кулі. Без SRID координати є лише абстрактним поняттям. «Декартова» координатна площина визначається як «плоска» система координат, розміщена на поверхні Землі. Оскільки функції PostGIS працюють на такій площині, операції порівняння вимагають, щоб обидві геометрії були представлені в одному SRID.
Якщо ви введете геометрії з різними SRID, ви отримаєте помилку:
SELECT ST_Equals(
ST_GeomFromText('POINT(0 0)', 4326),
ST_GeomFromText('POINT(0 0)', 26918)
);
ERROR: ST_Equals: Operation on mixed SRID geometries (Point, 4326) != (Point, 26918)
Примітка
Будьте обережні, не захоплюйтеся використанням команди ST_Transform для перетворення на льоту. Просторові індекси будуються з використанням SRID збережених геометрій. Якщо порівняння виконується в іншому SRID, просторові індекси (часто) не використовуються. Найкраще вибрати один SRID для всіх таблиць у вашій базі даних. Використовуйте функцію перетворення тільки під час читання або запису даних у зовнішні додатки.
16.2. Перетворення даних¶
Якщо повернутися до нашого визначення proj4 для SRID 26918, ми побачимо, що наша робоча проекція — це UTM (універсальна поперечна проекція Меркатора) зони 18, з метрами як одиницею вимірювання.
SELECT srtext FROM spatial_ref_sys WHERE srid = 26918;
PROJCS["NAD83 / UTM zone 18N",
GEOGCS["NAD83",
DATUM["North_American_Datum_1983",
SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],
TOWGS84[0,0,0,0,0,0,0],
AUTHORITY["EPSG","6269"]],
PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4269"]],
PROJECTION["Transverse_Mercator"],
PARAMETER["latitude_of_origin",0],
PARAMETER["central_meridian",-75],
PARAMETER["scale_factor",0.9996],
PARAMETER["false_easting",500000],
PARAMETER["false_northing",0],
UNIT["metre",1,AUTHORITY["EPSG","9001"]],
AXIS["Easting",EAST],AXIS["Northing",NORTH],
AUTHORITY["EPSG","26918"]]
Давайте перетворимо деякі дані з нашої робочої проекції в географічні координати, також відомі як «довгота/широта».
Щоб перетворити дані з одного SRID в інший, спочатку потрібно перевірити, чи має ваша геометрія дійсний SRID. Оскільки ми вже підтвердили дійсність SRID, нам потрібно SRID проекції, в яку ми хочемо перетворити дані. Іншими словами, який SRID мають географічні координати?
Найпоширенішим SRID для географічних координат є 4326, що відповідає «довготі/широті на сфероїді WGS84». Ви можете ознайомитися з визначенням тут:
Ви також можете витягти визначення з таблиці spatial_ref_sys
:
SELECT srtext FROM spatial_ref_sys WHERE srid = 4326;
GEOGCS["WGS 84",
DATUM["WGS_1984",
SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],
AUTHORITY["EPSG","6326"]],
PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4326"]]
Перетворимо координати станції метро «Broad St» у географічні:
SELECT ST_AsText(ST_Transform(geom,4326))
FROM nyc_subway_stations
WHERE name = 'Broad St';
POINT(-74.01067146887341 40.70710481558761)
Якщо ви завантажуєте дані або створюєте нову геометрію без вказання SRID, значення SRID буде 0. Згадайте в Geometries, що коли ми створювали нашу таблицю geometries
, ми не вказали SRID. Якщо ми зробимо запит до нашої бази даних, ми повинні очікувати, що всі таблиці nyc_
матимуть SRID 26918, тоді як таблиця geometries
за замовчуванням матиме SRID 0.
Щоб переглянути призначення SRID таблиці, виконайте запит до таблиці geometry_columns
бази даних.
SELECT f_table_name AS name, srid
FROM geometry_columns;
name | srid
---------------------+-------
nyc_census_blocks | 26918
nyc_homicides | 26918
nyc_neighborhoods | 26918
nyc_streets | 26918
nyc_subway_stations | 26918
geometries | 0
Однак, якщо ви знаєте, яким має бути SRID координат, ви можете встановити його постфактум, використовуючи ST_SetSRID на геометрії. Після цього ви зможете перетворити геометрію в інші системи.
SELECT ST_AsText(
ST_Transform(
ST_SetSRID(geom,26918),
4326)
)
FROM geometries;
16.3. Список функцій¶
ST_AsText: Повертає представлення геометрії/географії у вигляді добре відомого тексту (WKT) без метаданих SRID.
ST_SetSRID(geometry, srid): Встановлює SRID для геометрії на певне ціле значення.
ST_SRID(geometry): Повертає ідентифікатор просторового посилання для ST_Geometry, як визначено в таблиці spatial_ref_sys.
ST_Transform(geometry, srid): Повертає нову геометрію з координатами, перетвореними у SRID, на який посилається цілочисельний параметр.