Ця відповідь розділена на кілька розділів:
Аналіз та скорочення проблеми , показуючи, як знайти потрібну точку за допомогою «консервованих» процедур.
Ілюстрація: робочий прототип , що дає робочий код.
Приклад , показуючи приклади рішень.
Підводні камені , обговорюючи потенційні проблеми та як з ними впоратися.
Впровадження ArcGIS , коментарі щодо створення користувальницького інструменту ArcGIS та де отримати необхідні процедури.
Аналіз та зменшення проблеми
Почнемо з того, що в (ідеально круглої) сферичній моделі завжди знайдеться рішення - фактично, саме два рішення. З огляду на базові точки A, B і C, кожна пара визначає свій "перпендикулярний бісектриса", який є набором точок, рівновіддалених від двох заданих точок. Цей бісектриса є геодезичним (велике коло). Сферична геометрія еліптична : будь-які дві геодезики перетинаються (у двох унікальних точках). Таким чином, точки перетину бісектриси AB та бісектриси BC - за визначенням - рівновіддалені від A, B і C, тим самим вирішуючи задачу. (Дивіться першу цифру нижче.)
Речі виглядають складніше на еліпсоїді, але оскільки це невелике збурення сфери, ми можемо очікувати подібної поведінки. (Аналіз цього може зайняти нас занадто далеко.) Складні формули, які використовуються (всередині ГІС) для обчислення точних відстаней на еліпсоїді, не є концептуальною складністю, однак: проблема в основному однакова. Щоб побачити, як насправді проста проблема, давайте викладемо її дещо абстрактно. У цьому твердженні "d (U, V)" посилається на справжню, повністю точну відстань між точками U і V.
Давши три точки A, B, C (як пари lat-lon) на еліпсоїді, знайдіть точку X, для якої (1) d (X, A) = d (X, B) = d (X, C) і ( 2) ця спільна відстань є якомога меншою.
Ці три відстані все залежить від невідомого X . Таким чином, різниці відстаней u (X) = d (X, A) - d (X, B) і v (X) = d (X, B) - d (X, C) є реально оціненими функціями X. Знову ж таки, дещо абстрактно, ми можемо зібрати ці відмінності в упорядковану пару. Ми також будемо використовувати (lat, lon) в якості координат для X, що дозволяє нам також вважати його впорядкованою парою, скажімо, X = (phi, лямбда). У цій установці функція
F (phi, лямбда) = (u (X), v (X))
це функція від частини двовимірного простору, що приймає значення у двовимірному просторі, і наша проблема зводиться до
Знайдіть усе можливе (phi, лямбда), для якого F (phi, лямбда) = (0,0).
Ось де абстракція окупається: існує багато чудового програмного забезпечення для вирішення цієї (чисто числової багатовимірної кореневої проблеми). Як це працює, ви пишете рутину для обчислення F , потім передаєте її до програмного забезпечення разом з будь-якою інформацією про обмеження на його введення ( phi повинен лежати між -90 і 90 градусів, а лямбда повинна лежати між -180 і 180 градусів). Це відкручує частину секунди і повертає (як правило) лише одне значення ( phi , лямбда ), якщо воно може знайти одне.
Є деталі, з якими можна обробитись, оскільки для цього є мистецтво: є різні способи вирішення, на вибір, залежно від того, як F "поводиться"; це допомагає "спрямовувати" програмне забезпечення, надаючи йому розумну вихідну точку для його пошуку (це один із способів отримати найближче рішення, а не будь-яке інше); і вам зазвичай потрібно вказати, наскільки точним ви хотіли б, щоб рішення було (тому воно знає, коли зупинити пошук). (Докладніше про те, що GIS-аналітики повинні знати про такі подробиці, які виникають у багатьох проблемах з ГІС, будь ласка, відвідайте рекомендації щодо тематики, яку слід включити до курсу «Комп’ютерна наука для геопросторових технологій» та подивіться у розділі «Різне» наприкінці. )
Ілюстрація: робочий прототип
Аналіз показує нам потрібно запрограмувати дві речі: неочищену первісну оцінку рішення та обчислення F сам.
Початкову оцінку можна зробити «сферичним середнім» з трьох базових точок. Це отримують, представляючи їх у геоцентричних декартових координатах (x, y, z), усереднюючи ці координати і проектуючи це середнє повернення до сфери та повторно виражаючи його у широті та довготі. Розмір сфери несуттєвий, і обчислення тим самим проводяться прямо: оскільки це лише вихідна точка, нам не потрібні еліпсоїдальні обчислення.
Для цього працюючого прототипу я використав Mathematica 8.
sphericalMean[points_] := Module[{sToC, cToS, cMean},
sToC[{f_, l_}] := {Cos[f] Cos[l], Cos[f] Sin[l], Sin[f]};
cToS[{x_, y_, z_}] := {ArcTan[x, y], ArcTan[Norm[{x, y}], z]};
cMean = Mean[sToC /@ (points Degree)];
If[Norm[Most@cMean] < 10^(-8), Mean[points], cToS[cMean]] / Degree
]
(Кінцева If
умова перевіряє, чи не може середній показник чітко вказати довготу; якщо так, то він повертається до прямого середнього арифметичного широт і довгот його введення - можливо, не великий вибір, але принаймні допустимий. Для тих, хто використовує цей код для керівництва реалізацією, зауважте, що аргументи Mathematica ArcTan
є зворотними порівняно з більшістю інших реалізацій: перший аргумент - координата x, другий - координата y, і він повертає кут, зроблений вектором ( х, у).)
Що стосується другої частини, тому що Mathematica - подібний ArcGIS і майже всі інші GIS - містить код для обчислення точних відстаней на еліпсоїді, писати майже нічого. Ми просто називаємо рутинний пошук кореневих програм:
tri[a_, b_, c_] := Block[{d = sphericalMean[{a, b, c}], sol, f, q},
sol = FindRoot[{GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, a] ==
GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, b] ==
GeoDistance[{Mod[f, 180, -90], Mod[q, 360, -180]}, c]},
{{f, d[[1]]}, {q, d[[2]]}},
MaxIterations -> 1000, AccuracyGoal -> Infinity, PrecisionGoal -> 8];
{Mod[f, 180, -90], Mod[q, 360, -180]} /. sol
];
Найбільш примітним аспектом цієї реалізації є те, як вона ухиляється від необхідності обмежувати широту ( f
) і довготу ( q
), завжди обчислюючи їх по модулю 180 і 360 градусів відповідно. Це дозволяє уникнути необхідності стримувати проблему (що часто створює ускладнення). Параметри керування MaxIterations
тощо налаштовуються, щоб цей код забезпечив максимально можливу точність.
Щоб побачити його в дії, давайте застосуємо його до трьох базових точок, наведених у відповідному питанні :
sol = tri @@ (bases = {{-6.28530175, 106.9004975375}, {-6.28955287, 106.89573839}, {-6.28388865789474, 106.908087643421}})
{-6.29692, 106.907}
Обчислені відстані між цим рішенням і трьома точками
{1450.23206979, 1450.23206979, 1450.23206978}
(це метри). Вони погоджуються через одинадцяту значущу цифру (що насправді занадто точне, оскільки відстані рідко точні до кращого на міліметр або близько того). Ось малюнок цих трьох точок (чорний), їх трьох взаємних бісектрис та рішення (червоний):
Приклад
Щоб перевірити цю реалізацію та отримати краще розуміння того, як поводиться проблема, ось контурний графік кореневої середньої квадратної невідповідності у відстанях для трьох широко розташованих базових точок. (Розбіжність RMS виходить шляхом обчислення всіх трьох відмінностей d (X, A) -d (X, B), d (X, B) -d (X, C) і d (X, C) -d (X , A), усереднюючи їх квадрати та беручи квадратний корінь. Він дорівнює нулю, коли X вирішує задачу і в іншому випадку збільшується, коли X відходить від рішення, і таким чином вимірює, наскільки "ми близькі" до рішення в будь-якій точці. )
Базові точки (60, -120), (10, -40) і (45,10) показані червоною в цій проекції Плат Керрі; розчин (49.2644488, -49.9052992), який вимагав 0,03 секунди для обчислення, - жовтий. Його невідповідність RMS становить менше трьох нанометрів , незважаючи на те, що всі відповідні відстані становлять тисячі кілометрів. Темні області показують невеликі значення RMS, а світлі - високі.
На цій карті чітко видно, що інше рішення лежить поруч (-49.2018206, 130.0297177) (обчислюється в RMS двох нанометрів, встановлюючи початкове значення пошуку діаметрально протилежне першому рішенню.)
Підводні камені
Числова нестабільність
Коли базові точки будуть майже колінеарними і зближуються, усі рішення будуть майже на півсвіту і надзвичайно важко точно визначити. Причина полягає в тому, що невеликі зміни місця розташування по всьому світу - переміщення його до базових точок або віддалення від нього - спричинить лише неймовірно крихітні зміни різниць відстаней. Просто не вистачає точності та точності, вбудованих у звичайні обчислення геодезичних відстаней, щоб закріпити результат.
Наприклад, починаючи з базових точок (45,001, 0), (45, 0) та (44,999,0), які розділені вздовж основного меридіана лише на 111 метрів між кожною парою, tri
отримують рішення (11.8213, 77.745 ). Відстань від неї до базових точок - 8,127,964,998 77; 8,127,964,998 41; та 8,127,964,998 65 метрів відповідно. Вони згодні на найближчий міліметр! Я не впевнений, наскільки точним може бути цей результат, але я не був би принаймні здивований, якби інші реалізації повернули місця далекі від цього, показуючи майже як хорошу рівність трьох відстаней.
Час обчислення
Ці обчислення, оскільки вони передбачають значний пошук, використовуючи складні обчислення відстані, не швидкі, зазвичай вимагають помітної частки секунди. Про це потрібно знати в режимі реального часу.
Впровадження ArcGIS
Python є кращим сценарієм для ArcGIS (починаючи з версії 9). Пакет scipy.optimize має багатоваріантний rootfinder, root
який повинен робити те, що FindRoot
робиться в коді Mathematica . Звичайно, ArcGIS сам пропонує точні еліпсоїдальні обчислення відстані. Потім решта - це всі деталі реалізації: визначте, як будуть отримані координати базової точки (від шару? Набраного користувачем? З текстового файлу? Від миші?) Та як буде представлений вихід (як координати відображається на екрані «як графічна точка» як новий об’єкт точки в шарі?), запишіть цей інтерфейс, перенесіть код Mathematica, показаний тут (прямо), і вам все буде налаштовано.