lonlatarr="ADDdJAaB...b8EQAAwX" ...

Форум для обсуждения деталей разработки программы SAS.Планета

Модераторы: vdemidov, Tolik

Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...

Сообщение Banzay » 03 апр 2015, 14:52

zed писал(а):Это было очень неудачное решение на заре развития программы. Писать её начинали студенты-программисты, поэтому вот такое наследие: и мусорные 4 байта и монструозный Extended.

Благодарю за пояснение! Понимаю, что всегда бывают недочеты, приятно, что при их наличии SAS.Планета разрослась в такой полезный и многофункциональный инструмент! Жалко, только, что для реализации различных ярлыков на карте нельзя использовать KMZ-файлы, в силу не полной поддержи их средствами SAS.Планета. Из-за этого пришлось изобретать велосипед, хотя можно было проще реализовывать задачу средствами стороннего ПО. :)
Banzay
Новичок
 
Сообщения: 2
ICQ: 238208421
Зарегистрирован: 02 апр 2015, 00:21
Откуда: РФ, Саратов
Благодарил (а): 1 раз.
Поблагодарили: 0 раз.

Не прошло и года... вроде как удалось победить lonlatarr

Сообщение Cheetos » 03 апр 2015, 19:53

1. В uses добавляем EDBase64
2. Объявляем следующие типы:
Код: Выделить всё
type
  TExtendedPoint = packed record
    X: Extended;
    Y: Extended;
    Reserved: LongWord;
  end;

type
  TDoublePoint = record
    X: Double;
    Y: Double;
  end;

3. Юзаем функцию LonLatArr, где в качестве параметра передаем координаты точки в градусах:
Код: Выделить всё
function LonLatArr(DP: TDoublePoint): String;
var
  AStream: TMemoryStream;
  S: AnsiString;
  ExtPoint: TExtendedPoint;
begin
  try
    AStream:=TMemoryStream.Create;
    ExtPoint.X := DP.X;
    ExtPoint.Y := DP.Y;
    ExtPoint.Reserved:=0;
    AStream.Write(ExtPoint, SizeOf(ExtPoint));
    AStream.Position:=0;
    SetString(S, PAnsiChar(AStream.Memory), AStream.Size);
    Result:=Base64Encode(S);
  finally
    AStream.Free;
  end;
end;
Последний раз редактировалось Cheetos 03 апр 2015, 20:21, всего редактировалось 1 раз.
Аватара пользователя
Cheetos
Новичок
 
Сообщения: 11
Зарегистрирован: 30 мар 2015, 20:03
Откуда: РФ, Тула
Благодарил (а): 2 раз.
Поблагодарили: 0 раз.

Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...

Сообщение Cheetos » 03 апр 2015, 20:03

to zed:
1. Выражаю огромную благодарность за оказанную помощь.
2. В отношении директивы {$A4} для решения конкретной задачи - она не обязательна - packed record ее игнорирует.
Аватара пользователя
Cheetos
Новичок
 
Сообщения: 11
Зарегистрирован: 30 мар 2015, 20:03
Откуда: РФ, Тула
Благодарил (а): 2 раз.
Поблагодарили: 0 раз.

Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...

Сообщение Cheetos » 03 апр 2015, 20:17

Banzay писал(а):
zed писал(а):Это было очень неудачное решение на заре развития программы. Писать её начинали студенты-программисты, поэтому вот такое наследие: и мусорные 4 байта и монструозный Extended.

Благодарю за пояснение! Понимаю, что всегда бывают недочеты, приятно, что при их наличии SAS.Планета разрослась в такой полезный и многофункциональный инструмент! Жалко, только, что для реализации различных ярлыков на карте нельзя использовать KMZ-файлы, в силу не полной поддержи их средствами SAS.Планета. Из-за этого пришлось изобретать велосипед, хотя можно было проще реализовывать задачу средствами стороннего ПО. :)

Можно :)
Аватара пользователя
Cheetos
Новичок
 
Сообщения: 11
Зарегистрирован: 30 мар 2015, 20:03
Откуда: РФ, Тула
Благодарил (а): 2 раз.
Поблагодарили: 0 раз.

Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...

Сообщение zed » 03 апр 2015, 22:28

Banzay писал(а):нельзя использовать KMZ-файлы, в силу не полной поддержи их средствами SAS.Планета

Ну так присылайте пул-реквесты, глядишь и поддержка появится ;)
Cheetos писал(а):3. Юзаем функцию LonLatArr

По-моему, можно проще:
Код: Выделить всё
function LonLatArr(DP: TDoublePoint): String;
var
  ExtPoint: TExtendedPoint;
begin
  ExtPoint.X := DP.X;
  ExtPoint.Y := DP.Y;
  ExtPoint.Reserved := 0;
  Result := Base64Encode(PAnsiChar(@ExtPoint), SizeOf(ExtPoint));
end;

Но это если всего одна точка. А вообще, имейте в виду, что SAS умеет оперировать мультиполигонами и полилиниями (особенно это стоит учитывать при чтении lonlatarr, а то могут быть сюрпризы). Код сериализации геометрии живёт в юните Src/MarksDB/SML/u_GeometryToStreamSML.pas, десериализация: Src/MarksDB/SML/u_GeometryFromStreamSML.pas
Хитрости GoogleEarth - то, чего вы не знаете о гугле
Аватара пользователя
zed
Гуру
 
Сообщения: 2888
ICQ: 357167611
Зарегистрирован: 16 авг 2008, 20:21
Откуда: Беларусь, Могилёв
Благодарил (а): 89 раз.
Поблагодарили: 523 раз.

Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...

Сообщение Cheetos » 03 апр 2015, 23:42

zed писал(а):По-моему, можно проще:
Код: Выделить всё
function LonLatArr(DP: TDoublePoint): String;
var
  ExtPoint: TExtendedPoint;
begin
  ExtPoint.X := DP.X;
  ExtPoint.Y := DP.Y;
  ExtPoint.Reserved := 0;
  Result := Base64Encode(PAnsiChar(@ExtPoint), SizeOf(ExtPoint));
end;

Совершенству нет предела :)

zed писал(а):Но это если всего одна точка. А вообще, имейте в виду, что SAS умеет оперировать мультиполигонами и полилиниями (особенно это стоит учитывать при чтении lonlatarr, а то могут быть сюрпризы).

В рамках поставленной задачи (получение строки LonLatArr из координат точки) этого более чем достаточно
Аватара пользователя
Cheetos
Новичок
 
Сообщения: 11
Зарегистрирован: 30 мар 2015, 20:03
Откуда: РФ, Тула
Благодарил (а): 2 раз.
Поблагодарили: 0 раз.

Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...

Сообщение OverPaw » 11 окт 2019, 10:35

Cheetos, zed, спасибо за алгоритм, но непосредственно сам ваш код в FreePascal у меня не заработал.
Пришлось немного допилить - взять что-то от каждого и адаптировать к встроенной библиотеке Base64.
Привожу рабочий вариант для FreePascal 3.0.4 с примером конвертации координат.
Код: Выделить всё
uses Base64;

type
  TExtendedPoint = packed record
    X: Extended;
    Y: Extended;
    Reserved: LongWord;
  end;

type
  TDoublePoint = record
    X: Double;
    Y: Double;
  end;

function LonLatArr(DP: TDoublePoint): String;
var
  S: AnsiString;
  ExtPoint: TExtendedPoint;
begin
    ExtPoint.X := DP.X;
    ExtPoint.Y := DP.Y;
    ExtPoint.Reserved:=0;
    SetString(S, PAnsiChar(@ExtPoint), SizeOf(ExtPoint));
    LonLatArr := EncodeStringBase64(S);
end;

var
  lonlat: TDoublePoint;
begin
  lonlat.X := 47.817875;
  lonlat.Y := 52.022758;
  writeln(LonLatArr(lonlat));
  readln();
end.
Аватара пользователя
OverPaw
Новичок
 
Сообщения: 24
Зарегистрирован: 12 янв 2013, 13:14
Откуда: Киев
Благодарил (а): 14 раз.
Поблагодарили: 3 раз.

Пред.

Вернуться в Раздел для разработчиков программы SAS.Планета

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0