![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | 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
|
||||
|
||||
|
По поводу перепадов высот. Они несомненно нужны для проведения определенного рода расчетов или вычислений, меня в данном случае интересует только графическое отображение точек на плоскости, и высота соответственно не нужна. Может когда-нибудь (в 20NN году), когда поднаберусь немного опыта и добавлю эту функцию, но пока в этом нет необходимости, прочем как и нет ее в обратном переводе координат.
Еще знаю точно и видел примеры, что высоту в точке можно получить по средствам API Google maps, пока читаю документацию по его API, т.е. пока не нашел. |
|
#9
|
||||
|
||||
|
Вот что получилось, вроде работает, проверьте пжлст, совпадает-ли результат
|
| Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
LIONSMILE (04.04.2018)
| ||
|
#10
|
||||
|
||||
|
Странно, может архиватор косячит. Сюда нельзя MS Excel прикрепить, но думаю не проблема. Вот сам файл 84 to 42.txt, расширение TXT на XLS просто смените. Так загрузил, что делать.
|
|
#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 Может кому пригодится! |