Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 03.04.2018, 18:36
Аватар для LIONSMILE
LIONSMILE LIONSMILE вне форума
Новичок
 
Регистрация: 19.03.2018
Сообщения: 51
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Как записать данные через функции

Доброго времени суток!

Суть проблемы в переводе координат из одной системы в другую, а именно 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;
Как прописать обработчик на кнопке, чтобы данные из Srtinggrid1 обрабатывались функциями выше и заносились в Stringgrid 2?
Вот код, который у меня получился:
Код:
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.
Проект прилагаю - Проект_D7.ZIP

Как прочитать данные из строк в Stringgrid1 через функции соответственно в Stringgrid2, т.е. например так:
Ячейка "(1,1) Srtinggrid1" -> Функция "Function WGS84_SK42_Lat(Bd, Ld, H: Double): Double;" -> Ячейка "(1,1) Srtinggrid2".

Помогите кто знает, как возможно реализовать такое, ибо своих знаний на данное творение не хватает.

Спасибо большое заранее!
Ответить с цитированием
  #2  
Старый 03.04.2018, 20:00
Аватар для Kailon
Kailon Kailon вне форума
Активный
 
Регистрация: 06.06.2010
Сообщения: 340
Версия Delphi: 11.3
Репутация: 429
По умолчанию

Цитата:
Сообщение от LIONSMILE
Вот код, который у меня получился:
...
У Вас получился!? Не, это у кого-то получился, ибо не знать:
Цитата:
Сообщение от LIONSMILE
...
Как прочитать данные из строк в Stringgrid1 через функции соответственно в Stringgrid2, т.е. например так:
Ячейка "(1,1) Srtinggrid1" -> Функция "Function WGS84_SK42_Lat(Bd, Ld, H: Double): Double;" -> Ячейка "(1,1) Srtinggrid2".
...
выше указанный код написать самому - нельзя :-)
А по делу
Код:
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  
Старый 04.04.2018, 04:38
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от LIONSMILE
...Как прочитать данные из строк в Stringgrid1 через функции соответственно в Stringgrid2, т.е. например так:
Ячейка "(1,1) Srtinggrid1" -> Функция "Function WGS84_SK42_Lat(Bd, Ld, H: Double): Double;" -> Ячейка "(1,1) Srtinggrid2"...
Нужно циклом, раз у вас данные в ячейках первой сетки уже лежат, необходимо поочерёдно по ним проходить, считывать и переносить результат обработки посредством функций в другой грид, если покажете, в каких ячеях нужные цифирки лежат и куда класть изврат их преобразования, можно и пример привести
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
LIONSMILE (04.04.2018)
  #4  
Старый 04.04.2018, 16:27
Аватар для LIONSMILE
LIONSMILE LIONSMILE вне форума
Новичок
 
Регистрация: 19.03.2018
Сообщения: 51
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Kailon, У Вас получился!? Не, это у кого-то получился
Нет конечно, я до пенсии видимо бы такого не написал, я имелл ввиду то, что я слепил так скажем. Часть кода, касаемая самих функций, была переведена одним уважаемым человеком из макроса VBA в Delphi соответственно. Еще одна его часть, была реализована многоуважаемым Alegun, я просто слепил все вместе. Я ни разу не претендую на авторство, и согласен, не правильно выразился. Да и дай Бог здоровья всем тем людям, которые помогают!

Многоуважаемый Alegun!
Цитата:
если покажете, в каких ячеях нужные цифирки лежат и куда класть изврат их преобразования, можно и пример привести
В первом посте, вместе с кодом, ниже, я прикрепил НЕДОпроект в седьмой версии Delphi, хотя сам ей не пользуюсь, но все равно стоит на всякий случай. Исправил в нем все ошибки, которые вылетали при его компиляции.
Вместе с проектом находится файл с данными, как пример TEST называется, его нужно открыть, потом нажать кнопку загрузить и необходимые данные выгрузятся в StringGrid1. А как их преобразовать с помощью функций и перенести потом в StringGrid2 я не знаю. Функций соответственно всего 2 мне необходимо, только из WGS-84 в СК-42.

Kailon Я честно скажу, я с Delphi общаюсь всего месяца 2-3 и занялся этим не потому, что делать нечего, а потому, что нужда по работе заставила. За код выше огромное спасибо! Но я мало пока еще в этом что понимаю.

Спасибо всем за помощь!
Ответить с цитированием
  #5  
Старый 04.04.2018, 17:04
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Оффтоп: Ну зачем же так о своём проекте уничижительно отзываться, НЕДОпроект, так любая сборка начинается с каркаса и лишь со временем обрастает нормальным "мясом", важнее "нагул", в нём весь цимус

Вопрос возник: функция WGS84_SK42_Lat() принимает 3 параметра, а в таблице лежат данные из тегов lat и lon, напр. <trkpt lat="44.039243" lon="43.070844">, значение высоты H брать откуда, в xml даже намёка на это нету, подскажите пжлст алгоритмику преобразования на примере одной пары, на "поискать в тырнетке" нету времени, к сожалению
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
LIONSMILE (12.04.2018)
  #6  
Старый 04.04.2018, 18:35
Аватар для LIONSMILE
LIONSMILE LIONSMILE вне форума
Новичок
 
Регистрация: 19.03.2018
Сообщения: 51
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Почитав форумы и еще статьи все что связано с тем, чтобы определить высоту в заданной точке по координатам выяснил три момента:

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>
В принципе с учетом того, что мне для работы высота вообще не нужна 6 метров это вообще маленький разлет.

Вот теперь думаю, если действительно высота нужна для расчетов, и если она влияет каким-то образом на смещение по осям "X" и "Y", это получается, что в SG добавится еще одна колонка, нужно сначала прогнать файл один раз, прочитав из него координаты, затем вторым кругом прогонять их через другой API и получать координату "Z"?

Есть файл в MS Excel, через функции которого сообственно можно сделать данную операцию, но там нужно было вводить только значение координат, без высот, при этом он все высчитывал правильно, и по полученным координатам точка ложилась ровно туда куда нужно.

Файл пригалаю 84 to 42.rar (взят с http://gis-lab.info/qa/wgs84-sk42-wgs84-formula.html)

Открыв его я так понял значение "ALT" там как раз и равно 0, собственно это наверное и есть высота, хотя работает четко, то что нужно.

Спасибо за помощь!
Ответить с цитированием
  #7  
Старый 04.04.2018, 19:48
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Оффтоп: Не знаю цели данной заморочки, но по роду своей деятельности могу следующим высказаться, много ездить приходится на своих четырёх и по нашей необъятной и за её пределами - высота н.у.м. нужна, есть такие места, ближе к западным границам, да и на Кавказе есть такой грешок, где вроде как две дороги на карте навигатора по протяжённости совершенно одинаковые, а одомер по прибытии за счёт высотных перепадов выдаёт разницу от нескольких сот метров до километров, для тех, кто ползает по земле не отрываясь высота необходима

Вложение 5125 в формате *.rar не хочет распаковываться, а на сайте ссыль на табличку для расчётов удалена, может выложите её текстом, если она у вас есть
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
LIONSMILE (12.04.2018)
  #8  
Старый 04.04.2018, 20:54
Аватар для LIONSMILE
LIONSMILE LIONSMILE вне форума
Новичок
 
Регистрация: 19.03.2018
Сообщения: 51
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Странно, может архиватор косячит. Сюда нельзя MS Excel прикрепить, но думаю не проблема. Вот сам файл 84 to 42.txt, расширение TXT на XLS просто смените. Так загрузил, что делать.
Ответить с цитированием
  #9  
Старый 04.04.2018, 21:00
Аватар для LIONSMILE
LIONSMILE LIONSMILE вне форума
Новичок
 
Регистрация: 19.03.2018
Сообщения: 51
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

По поводу перепадов высот. Они несомненно нужны для проведения определенного рода расчетов или вычислений, меня в данном случае интересует только графическое отображение точек на плоскости, и высота соответственно не нужна. Может когда-нибудь (в 20NN году), когда поднаберусь немного опыта и добавлю эту функцию, но пока в этом нет необходимости, прочем как и нет ее в обратном переводе координат.
Еще знаю точно и видел примеры, что высоту в точке можно получить по средствам API Google maps, пока читаю документацию по его API, т.е. пока не нашел.
Ответить с цитированием
  #10  
Старый 04.04.2018, 21:23
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Вот что получилось, вроде работает, проверьте пжлст, совпадает-ли результат
Вложения
Тип файла: zip WGS84toSK42.zip (6.8 Кбайт, 4 просмотров)
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
LIONSMILE (04.04.2018)
  #11  
Старый 04.04.2018, 23:14
Аватар для LIONSMILE
LIONSMILE LIONSMILE вне форума
Новичок
 
Регистрация: 19.03.2018
Сообщения: 51
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Многоуважаемый Alegun!
Огромное спасибо в очередной раз!!!
Это самое то. Взял за основу точку на обычной карте яндекса. Отображена на рисунке Исходная.png . Потом загрузил ее и обработал.
Для наглядности оба варианта загрузил в программу и получилось вот что: Обработанная.png.
Первой загрузил точку просто как есть без преобразования, получилось "мы утонули", потом загрузил уже преобразованные координаты. Собственно легла там где она и должна была быть.
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо LIONSMILE за это полезное сообщение:
Alegun (05.04.2018), dr. F.I.N. (05.04.2018)
  #12  
Старый 05.04.2018, 08:19
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Оффтоп:
Да я то здесь каким боком :-) всё ведь это ваши старания поиска способа решить задачу, вот подпись нашего постоянного кодотворца dr. F.I.N. содержит следующее - "Грамотно поставленный вопрос содержит не менее 50% ответа", так вот в вашем случае, этот показатель доходит до 90%, честно, первый раз сталкиваюсь с такой глубиной постановки вопроса, обычно ведь как, приходит такой задорный неофит с вопросом "сделайте мне то, сам не знаю чейго, иначе сюды и не обратился бы", а тут уже на протяжении нескольких тем душа просто радуется, это вам, многоуважаемый товарисч LIONSMILE, огромное спасибо, все бы так относились к поставленной задаче, было бы здорово! ;-)
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо Alegun за это полезное сообщение:
dr. F.I.N. (05.04.2018), LIONSMILE (12.04.2018)
  #13  
Старый 06.04.2018, 00:20
Аватар для LIONSMILE
LIONSMILE LIONSMILE вне форума
Новичок
 
Регистрация: 19.03.2018
Сообщения: 51
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Спустя вторые сутки поиска уже чтобы убить спортивный интерес как найти высоты, все-таки нашел один сайт который при загрузке трека с навигатора делает две полезные вещи:
1. Показывает расстояние от исходной точки до каждой последующей.
2. Показывает высоту относительно уровня мирового океана в заданной точке.

Регистрации нет, трек загружается в стандартном для навигатора формате GPX, ниже карты есть вариант отображения данных (самый удобный и из которого можно получить данные - это csv).

Вот ссылка http://www.geocontext.org/publ/2010/...ru/?import=xml Может кому пригодится!
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 12:38.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025