![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
![]() Доброго времени суток!
Суть проблемы в переводе координат из одной системы в другую, а именно WGS84 в СК42. Есть код, в котором 4 функции, используя их возможно выполнить 2 направления перевода координат, т.е. Широта и долгота из WGS84 в СК42, и наоборот. Написал небольшой проект, в котором исходные данные из файла обрабатываются и выгружаются в STRINGGRID1. Проблема в том, что я не знаю как использовать функции для обработки массивов (я так понимаю данные загруженные данные в STRINGGRID1 это и есть массив). Из этих четырех функций меня интересуют только две: Код:
Function WGS84_SK42_Lat(Bd, Ld, H: Double): Double; Begin WGS84_SK42_Lat := Bd - dB(Bd, Ld, H) / 3600; End; Function WGS84_SK42_Long(Bd, Ld, H: Double): Double; Begin WGS84_SK42_Long := Ld - dL(Bd, Ld, H) / 3600; End; Вот код, который у меня получился: Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Math, xmldom, XMLIntf, msxmldom, XMLDoc, StdCtrls, Grids; type TForm1 = class(TForm) GroupBox1: TGroupBox; GroupBox2: TGroupBox; Button1: TButton; Edit1: TEdit; XMLDocument1: TXMLDocument; OpenDialog1: TOpenDialog; Button2: TButton; Button3: TButton; Button5: TButton; SaveDialog1: TSaveDialog; StringGrid1: TStringGrid; StringGrid2: TStringGrid; Button4: TButton; Memo1: TMemo; Широта: TLabel; Долгота: TLabel; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; const Pi: Double = 3.14159265358979; // Число Пи ro: Double = 206264.8062; // Число угловых секунд в радиане // Эллипсоид Красовского aP: Double = 6378245; // Большая полуось alP: Double = 1 / 298.3; // Сжатие {$J+} e2P: Double = 0; // Квадрат эксцентриситета 2 * alP - alP ^ 2 {$J-} // Эллипсоид WGS84 (GRS80, эти два эллипсоида сходны по большинству параметров) aW: Double = 6378137; // Большая полуось alW: Double = 1 / 298.257223563; // Сжатие {$J+} e2W: Double = 0; // Квадрат эксцентриситета 2 * alW - alW ^ 2 {$J-} // Вспомогательные значения для преобразования эллипсоидов {$J+} a: Double = 0; // (aP + aW) / 2 e2: Double = 0; // (e2P + e2W) / 2 da: Double = 0; // aW - aP de2: Double = 0; // e2W - e2P {$J-} // Линейные элементы трансформирования, в метрах dx: Double = 23.92; dy: Double = -141.27; dz: Double = -80.9; // Угловые элементы трансформирования, в секундах wx: Double = 0; wy: Double = 0; wz: Double = 0; // Дифференциальное различие масштабов ms: Double = 0; var Form1: TForm1; implementation {$R *.dfm} Function dB(Bd, Ld, H: Double): Double; Var B, L, M, N: Double; Begin B := Bd * Pi / 180; L := Ld * Pi / 180; M := a * (1 - e2) / Power((1 - e2 * Power(Sin(B), 2)), 1.5); N := a * Power((1 - e2 * Power(Sin(B), 2)), -0.5); dB := ro / (M + H) * (N / a * e2 * Sin(B) * Cos(B) * da + (Power(N, 2) / Power(a, 2) + 1) * N * Sin(B) * Cos(B) * de2 / 2 - (dx * Cos(L) + dy * Sin(L)) * Sin(B) + dz * Cos(B)) - wx * Sin(L) * (1 + e2 * Cos(2 * B)) + wy * Cos(L) * (1 + e2 * Cos(2 * B)) - ro * ms * e2 * Sin(B) * Cos(B); End; Function dL(Bd, Ld, H: Double): Double; Var B, L, N: Double; Begin B := Bd * Pi / 180; L := Ld * Pi / 180; N := a * Power((1 - e2 * Power(Sin(B), 2)), -0.5); dL := ro / ((N + H) * Cos(B)) * (-dx * Sin(L) + dy * Cos(L)) + Tan(B) * (1 - e2) * (wx * Cos(L) + wy * Sin(L)) - wz; End; Function WGS84Alt(Bd, Ld, H: Double): Double; Var B, L, N, dH: Double; Begin B := Bd * Pi / 180; L := Ld * Pi / 180; N := a * Power((1 - e2 * Power(Sin(B), 2)), -0.5); dH := -a / N * da + N * Power(Sin(B), 2) * de2 / 2 + (dx * Cos(L) + dy * Sin(L)) * Cos(B) + dz * Sin(B) - N * e2 * Sin(B) * Cos(B) * (wx / ro * Sin(L) - wy / ro * Cos(L)) + (Power(a, 2) / N + H) * ms; WGS84Alt := H + dH; End; Function WGS84_SK42_Lat(Bd, Ld, H: Double): Double; Begin WGS84_SK42_Lat := Bd - dB(Bd, Ld, H) / 3600; End; Function SK42_WGS84_Lat(Bd, Ld, H: Double): Double; Begin SK42_WGS84_Lat := Bd + dB(Bd, Ld, H) / 3600; End; Function WGS84_SK42_Long(Bd, Ld, H: Double): Double; Begin WGS84_SK42_Long := Ld - dL(Bd, Ld, H) / 3600; End; Function SK42_WGS84_Long(Bd, Ld, H: Double): Double; Begin SK42_WGS84_Long := Ld + dL(Bd, Ld, H) / 3600; End; procedure TForm1.FormCreate(Sender: TObject); begin e2P := 2 * alP - Power(alP, 2); // Квадрат эксцентриситета e2W := 2 * alW - Power(alW, 2); // Квадрат эксцентриситета a := (aP + aW) / 2; e2 := (e2P + e2W) / 2; da := aW - aP; de2 := e2W - e2P; end; procedure TForm1.Button1Click(Sender: TObject); begin openDialog1.InitialDir := GetCurrentDir; if OpenDialog1.Execute then Memo1.Lines.LoadFromFile(OpenDialog1.FileName); Edit1.Text:=extractfilename(opendialog1.filename); end; procedure TForm1.Button2Click(Sender: TObject); var i: integer; begin XMLDocument1.LoadFromFile(OpenDialog1.FileName); XMLDocument1.Active:= true; with XMLDocument1.DocumentElement.ChildNodes['trk'].ChildNodes['trkseg'] do for i:= 0 to ChildNodes.Count-1 do begin StringGrid1.RowCount:= StringGrid1.RowCount+1; StringGrid1.Cells[0,StringGrid1.RowCount-2]:= VarToStr(ChildNodes.Nodes[i].Attributes['lat']); StringGrid1.Cells[1,StringGrid1.RowCount-2]:= VarToStr(ChildNodes.Nodes[i].Attributes['lon']); end; XMLDocument1.Active:= false; end; procedure TForm1.Button5Click(Sender: TObject); begin close end; end. Как прочитать данные из строк в Stringgrid1 через функции соответственно в Stringgrid2, т.е. например так: Ячейка "(1,1) Srtinggrid1" -> Функция "Function WGS84_SK42_Lat(Bd, Ld, H: Double): Double;" -> Ячейка "(1,1) Srtinggrid2". Помогите кто знает, как возможно реализовать такое, ибо своих знаний на данное творение не хватает. Спасибо большое заранее! |
#2
|
||||
|
||||
![]() Цитата:
Цитата:
А по делу Код:
procedure TForm1.Button3Click(Sender: TObject); var Bd, Ld, H: Double; begin Bd := 0; // Ваше значение Ld := 0; // Ваше значение H := 0; // Ваше значение SG2.Cells[0,0] := FloatToStr(WGS84_SK42_Lat(Bd, Ld, H)); end; Всегда пишите код так, будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете. |
Этот пользователь сказал Спасибо Kailon за это полезное сообщение: | ||
LIONSMILE (04.04.2018)
|
#3
|
||||
|
||||
![]() Цитата:
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
LIONSMILE (04.04.2018)
|
#4
|
||||
|
||||
![]() Цитата:
Многоуважаемый Alegun! Цитата:
Вместе с проектом находится файл с данными, как пример TEST называется, его нужно открыть, потом нажать кнопку загрузить и необходимые данные выгрузятся в StringGrid1. А как их преобразовать с помощью функций и перенести потом в StringGrid2 я не знаю. Функций соответственно всего 2 мне необходимо, только из WGS-84 в СК-42. Kailon Я честно скажу, я с Delphi общаюсь всего месяца 2-3 и занялся этим не потому, что делать нечего, а потому, что нужда по работе заставила. За код выше огромное спасибо! Но я мало пока еще в этом что понимаю. Спасибо всем за помощь! |
#5
|
||||
|
||||
![]() Оффтоп: Ну зачем же так о своём проекте уничижительно отзываться, НЕДОпроект, так любая сборка начинается с каркаса и лишь со временем обрастает нормальным "мясом", важнее "нагул", в нём весь цимус
![]() Вопрос возник: функция WGS84_SK42_Lat() принимает 3 параметра, а в таблице лежат данные из тегов lat и lon, напр. <trkpt lat="44.039243" lon="43.070844">, значение высоты H брать откуда, в xml даже намёка на это нету, подскажите пжлст алгоритмику преобразования на примере одной пары, на "поискать в тырнетке" нету времени, к сожалению Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
LIONSMILE (12.04.2018)
|
#6
|
||||
|
||||
![]() Почитав форумы и еще статьи все что связано с тем, чтобы определить высоту в заданной точке по координатам выяснил три момента:
1. Если проекция плоская, то есть не предусматривает расчетов, связанных с определением точки в пространстве, а именно высота не важна, то значение H можно брать равным 0. 2. В документации яндекса вообще написано, что определение высоты в указанной точке по средствам API не производится и такая функция отсутствует. 3. Яндекс вообщем врет. Такая функция ЕСТЬ, но не у них да и в принципе какая разница. Она реализована на сайте http://api.geonames.org/srtm1. Отправил запрос в таком формате - http://api.geonames.org/srtm1XML?lat...o &style=full координаты взял в Google.maps (район г.Машук в городе Пятигорск), на карте в Google показывает высоту 820 м - в ответе пришло 826 Код:
<geonames> <srtm1> 826 </srtm1> <lat> 44.051674 </lat> <lng> 43.082298 </lng> </geonames> Вот теперь думаю, если действительно высота нужна для расчетов, и если она влияет каким-то образом на смещение по осям "X" и "Y", это получается, что в SG добавится еще одна колонка, нужно сначала прогнать файл один раз, прочитав из него координаты, затем вторым кругом прогонять их через другой API и получать координату "Z"? Есть файл в MS Excel, через функции которого сообственно можно сделать данную операцию, но там нужно было вводить только значение координат, без высот, при этом он все высчитывал правильно, и по полученным координатам точка ложилась ровно туда куда нужно. Файл пригалаю 84 to 42.rar (взят с http://gis-lab.info/qa/wgs84-sk42-wgs84-formula.html) Открыв его я так понял значение "ALT" там как раз и равно 0, собственно это наверное и есть высота, хотя работает четко, то что нужно. Спасибо за помощь! |
#7
|
||||
|
||||
![]() Оффтоп: Не знаю цели данной заморочки, но по роду своей деятельности могу следующим высказаться, много ездить приходится на своих четырёх и по нашей необъятной и за её пределами - высота н.у.м. нужна, есть такие места, ближе к западным границам, да и на Кавказе есть такой грешок, где вроде как две дороги на карте навигатора по протяжённости совершенно одинаковые, а одомер по прибытии за счёт высотных перепадов выдаёт разницу от нескольких сот метров до километров, для тех, кто ползает по земле не отрываясь высота необходима
Вложение 5125 в формате *.rar не хочет распаковываться, а на сайте ссыль на табличку для расчётов удалена, может выложите её текстом, если она у вас есть Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
LIONSMILE (12.04.2018)
|
#8
|
||||
|
||||
![]() Странно, может архиватор косячит. Сюда нельзя MS Excel прикрепить, но думаю не проблема. Вот сам файл 84 to 42.txt, расширение TXT на XLS просто смените. Так загрузил, что делать.
|
#9
|
||||
|
||||
![]() По поводу перепадов высот. Они несомненно нужны для проведения определенного рода расчетов или вычислений, меня в данном случае интересует только графическое отображение точек на плоскости, и высота соответственно не нужна. Может когда-нибудь (в 20NN году), когда поднаберусь немного опыта и добавлю эту функцию, но пока в этом нет необходимости, прочем как и нет ее в обратном переводе координат.
Еще знаю точно и видел примеры, что высоту в точке можно получить по средствам API Google maps, пока читаю документацию по его API, т.е. пока не нашел. |
#10
|
||||
|
||||
![]() Вот что получилось, вроде работает, проверьте пжлст, совпадает-ли результат
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
LIONSMILE (04.04.2018)
|
#11
|
||||
|
||||
![]() Многоуважаемый Alegun!
Огромное спасибо в очередной раз!!! Это самое то. Взял за основу точку на обычной карте яндекса. Отображена на рисунке Исходная.png . Потом загрузил ее и обработал. Для наглядности оба варианта загрузил в программу и получилось вот что: Обработанная.png. Первой загрузил точку просто как есть без преобразования, получилось "мы утонули", потом загрузил уже преобразованные координаты. Собственно легла там где она и должна была быть. |
Эти 2 пользователя(ей) сказали Спасибо LIONSMILE за это полезное сообщение: | ||
Alegun (05.04.2018),
dr. F.I.N. (05.04.2018)
|
#12
|
||||
|
||||
![]() Оффтоп:
Да я то здесь каким боком :-) всё ведь это ваши старания поиска способа решить задачу, вот подпись нашего постоянного кодотворца dr. F.I.N. содержит следующее - "Грамотно поставленный вопрос содержит не менее 50% ответа", так вот в вашем случае, этот показатель доходит до 90%, честно, первый раз сталкиваюсь с такой глубиной постановки вопроса, обычно ведь как, приходит такой задорный неофит с вопросом "сделайте мне то, сам не знаю чейго, иначе сюды и не обратился бы", а тут уже на протяжении нескольких тем душа просто радуется, это вам, многоуважаемый товарисч LIONSMILE, огромное спасибо, все бы так относились к поставленной задаче, было бы здорово! ;-) Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Эти 2 пользователя(ей) сказали Спасибо Alegun за это полезное сообщение: | ||
dr. F.I.N. (05.04.2018),
LIONSMILE (12.04.2018)
|
#13
|
||||
|
||||
![]() Спустя вторые сутки поиска уже чтобы убить спортивный интерес как найти высоты, все-таки нашел один сайт который при загрузке трека с навигатора делает две полезные вещи:
1. Показывает расстояние от исходной точки до каждой последующей. 2. Показывает высоту относительно уровня мирового океана в заданной точке. Регистрации нет, трек загружается в стандартном для навигатора формате GPX, ниже карты есть вариант отображения данных (самый удобный и из которого можно получить данные - это csv). Вот ссылка http://www.geocontext.org/publ/2010/...ru/?import=xml Может кому пригодится! |