Страница 3 из 5

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

СообщениеДобавлено: 04 май 2012, 12:59
RGF
подскажите, как можно декодировать lonlatarr, каков формат кодирования?

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

СообщениеДобавлено: 04 май 2012, 13:00
garl
бывают online-декодеры

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

СообщениеДобавлено: 13 сен 2012, 20:39
Recar
В общем навоевавшись с дельфийским блобом =) Сделал так:
Если поле lonlatarr пустое то координаты точки берутся из lonL, latT
Также сделал перечитку меток по кнопке и убрал блокировку файла меток.
Коммитить такой хак не буду =)

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

СообщениеДобавлено: 13 сен 2012, 21:02
garl
а что в итоге делал то?

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

СообщениеДобавлено: 13 сен 2012, 21:09
Recar
Внешняя програмка парсит сайт оттуда берет номер уровня и координаты и генерит для саса метки.

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

СообщениеДобавлено: 06 дек 2012, 19:04
RGF
гуру, приведите пожалуйста если не алгоритм, то хотя бы кусок кода, в котором происходит кодирование из широты/долготы в lonlatarr

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

СообщениеДобавлено: 13 фев 2013, 09:23
zed
Вот вам кусок кода (из u_MarksDB.pas):
Код: Выделить всё
type
  TExtendedPoint = record
    X, Y: Extended;
  end;

procedure Blob2ExtArr(
  ABlobField: TField;
  const AAggregator: IDoublePointsAggregator
);
const
  CMaxDegres: Extended = 360;
  CMinDegres: Extended = -360;
var
  VSize: Integer;
  VPointsCount: Integer;
  VField: TBlobfield;
  VStream: TStream;
  i: Integer;
  VPoint: TExtendedPoint;
  VDoublePoint: TDoublePoint;
begin
  VField := TBlobfield(ABlobField);
  VStream := VField.DataSet.CreateBlobStream(VField, bmRead);
  try
    VSize := VStream.Size;
    VPointsCount := VSize div SizeOf(TExtendedPoint);
    for i := 0 to VPointsCount - 1 do begin
      VStream.ReadBuffer(VPoint, SizeOf(TExtendedPoint));
      try
        if IsNan(VPoint.X) or IsNan(VPoint.Y) then begin
          VDoublePoint := CEmptyDoublePoint;
        end else if (VPoint.X >= CMaxDegres) or (VPoint.X <= CMinDegres) or (VPoint.Y >= CMaxDegres) or (VPoint.Y <= CMinDegres) then begin
          VDoublePoint := CEmptyDoublePoint;
        end else begin
          VDoublePoint := DoublePoint(VPoint.X, VPoint.Y);
        end;
      except
        VDoublePoint := CEmptyDoublePoint;
      end;
      AAggregator.Add(VDoublePoint);
    end;
  finally
    VStream.Free;
  end;
end;

procedure BlobFromPoint(
  const APoint: TDoublePoint;
  ABlobField: TField
);
var
  VField: TBlobfield;
  VStream: TStream;
  VPoint: TExtendedPoint;
begin
  VField := TBlobfield(ABlobField);
  VStream := VField.DataSet.CreateBlobStream(VField, bmWrite);
  try
    VPoint.X := APoint.X;
    VPoint.Y := APoint.Y;
    VStream.Write(VPoint, SizeOf(VPoint));
  finally
    VStream.Free;
  end;
end;

procedure BlobFromPath(
  const APath: ILonLatPath;
  ABlobField: TField
);
var
  VField: TBlobfield;
  VStream: TStream;
  i: Integer;
  VPoint: TExtendedPoint;
  VEnum: IEnumDoublePoint;
  VFirstPoint: TDoublePoint;
  VCurrPoint: TDoublePoint;
  VPrevPoint: TDoublePoint;
begin
  VField := TBlobfield(ABlobField);
  VStream := VField.DataSet.CreateBlobStream(VField, bmWrite);
  try
    VEnum := APath.GetEnum;
    i := 0;
    if VEnum.Next(VFirstPoint) then begin
      VCurrPoint := VFirstPoint;
      VPrevPoint := VCurrPoint;
      VPoint.X := VCurrPoint.X;
      VPoint.Y := VCurrPoint.Y;
      VStream.Write(VPoint, SizeOf(VPoint));
      Inc(i);
      while VEnum.Next(VCurrPoint) do begin
        VPoint.X := VCurrPoint.X;
        VPoint.Y := VCurrPoint.Y;
        VStream.Write(VPoint, SizeOf(VPoint));
        VPrevPoint := VCurrPoint;
        Inc(i);
      end;
    end;
    if (i = 1) or ((i > 1) and DoublePointsEqual(VFirstPoint, VPrevPoint)) then begin
      VPoint.X := CEmptyDoublePoint.X;
      VPoint.Y := CEmptyDoublePoint.Y;
      VStream.Write(VPoint, SizeOf(VPoint));
    end;
  finally
    VStream.Free;
  end;
end;

procedure BlobFromPolygon(
  const APolygon: ILonLatPolygon;
  ABlobField: TField
);
var
  VField: TBlobfield;
  VStream: TStream;
  VPoint: TExtendedPoint;
  VEnum: IEnumDoublePoint;
  VCurrPoint: TDoublePoint;
  VLine: ILonLatPolygonLine;
begin
  VField := TBlobfield(ABlobField);
  VStream := VField.DataSet.CreateBlobStream(VField, bmWrite);
  try
    if APolygon.Count > 0 then begin
      VLine := APolygon.Item[0];
      if VLine.Count = 1 then begin
        VPoint.X := VLine.Points[0].X;
        VPoint.Y := VLine.Points[0].Y;
        VStream.Write(VPoint, SizeOf(VPoint));
        VStream.Write(VPoint, SizeOf(VPoint));
      end else begin
        VEnum := VLine.GetEnum;
        while VEnum.Next(VCurrPoint) do begin
          VPoint.X := VCurrPoint.X;
          VPoint.Y := VCurrPoint.Y;
          VStream.Write(VPoint, SizeOf(VPoint));
        end;
      end;
    end;
  finally
    VStream.Free;
  end;
end;

...откуда видно, что кодированием SAS напрямую не занимается.

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

СообщениеДобавлено: 13 фев 2013, 15:40
gorec
Похоже я недостаточно написал - у людей появляются вопросы - вот пример применения моей версии в php:

Это для точки - две координаты
function point80bit($fl1,$fl2) {
$z=chr(0);$z4=$z.$z.$z.$z;
$b1=float80bit($fl1).float80bit($fl2).$z4;
$b2=base64_encode($b1);
return $b2;
}

это для линии - четыре координаты

function line80bit($fl1,$fl2,$fl3,$fl4) {
$z=chr(0);$z4=$z.$z.$z.$z;
$b1=float80bit($fl1).float80bit($fl2).$z4.float80bit($fl3).float80bit($fl4).$z4;
$b2=base64_encode($b1);
return $b2;
}

вся сложноть в размерности - 80-ти битных чисел в php не нашел... вот и пришлось их доделать...

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

СообщениеДобавлено: 16 апр 2014, 09:53
Fed
zed писал(а):Вот вам кусок кода
...откуда видно, что кодированием SAS напрямую не занимается.

А можно немного по подробнее (поконкретнее), чем именно пользуется SAS для кодирования и декодирования координат.
Нужен "конвектор", который может перекодировать файл с координатами (x, y) в файл с данными lonlatarr (и желательно обратно).

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

СообщениеДобавлено: 16 апр 2014, 21:33
zed
Используется датасет, который "под капотом" производит все необходимые конвертации. Но тут уже писали, что оно производит всего лишь Base64 кодирование сырых данных. А в качестве сырых данных у нас используется последовательность X,Y координат, Extended типа. Только это очень хитрый тип, этот extended. Чуть выше, человек приводил пример кода на php, где успешно удалось побороть этот специфический тип данных и получить координаты из blob поля. На Delphi так оно вообще без проблем всё делается.

А вообще, конечно, очень неудачно сделано. Нужно было использовать стандартный тип Double (он же float) и обязательно packed record, чтобы не появлялось лишних выравнивающих байт. Но так уж сложилось исторически, и чтобы не ломать совместимость, так оно будет жить и впредь...