lonlatarr="ADDdJAaB...b8EQAAwX" ...
Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...
подскажите, как можно декодировать lonlatarr, каков формат кодирования?
Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...
В общем навоевавшись с дельфийским блобом =) Сделал так:
Если поле lonlatarr пустое то координаты точки берутся из lonL, latT
Также сделал перечитку меток по кнопке и убрал блокировку файла меток.
Коммитить такой хак не буду =)
Если поле lonlatarr пустое то координаты точки берутся из lonL, latT
Также сделал перечитку меток по кнопке и убрал блокировку файла меток.
Коммитить такой хак не буду =)
Последний раз редактировалось Recar 13 сен 2012, 21:08, всего редактировалось 2 раза.
Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...
Внешняя програмка парсит сайт оттуда берет номер уровня и координаты и генерит для саса метки.
Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...
гуру, приведите пожалуйста если не алгоритм, то хотя бы кусок кода, в котором происходит кодирование из широты/долготы в lonlatarr
-
zed
- Гуру
- Сообщения: 2888
- Зарегистрирован: 16 авг 2008, 20:21
- Благодарил (а): 89 раз
- Поблагодарили: 568 раз
Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...
Вот вам кусок кода (из u_MarksDB.pas):
...откуда видно, что кодированием SAS напрямую не занимается.
Код: Выделить всё
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;
Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...
Похоже я недостаточно написал - у людей появляются вопросы - вот пример применения моей версии в 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 не нашел... вот и пришлось их доделать...
Это для точки - две координаты
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 не нашел... вот и пришлось их доделать...
-
Fed
- Новичок
- Сообщения: 19
- Зарегистрирован: 25 дек 2012, 13:28
- Откуда: Сосновый Бор
- Благодарил (а): 4 раза
Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...
А можно немного по подробнее (поконкретнее), чем именно пользуется SAS для кодирования и декодирования координат.zed писал(а):Вот вам кусок кода
...откуда видно, что кодированием SAS напрямую не занимается.
Нужен "конвектор", который может перекодировать файл с координатами (x, y) в файл с данными lonlatarr (и желательно обратно).
-
zed
- Гуру
- Сообщения: 2888
- Зарегистрирован: 16 авг 2008, 20:21
- Благодарил (а): 89 раз
- Поблагодарили: 568 раз
Re: lonlatarr="ADDdJAaB...b8EQAAwX" ...
Используется датасет, который "под капотом" производит все необходимые конвертации. Но тут уже писали, что оно производит всего лишь Base64 кодирование сырых данных. А в качестве сырых данных у нас используется последовательность X,Y координат, Extended типа. Только это очень хитрый тип, этот extended. Чуть выше, человек приводил пример кода на php, где успешно удалось побороть этот специфический тип данных и получить координаты из blob поля. На Delphi так оно вообще без проблем всё делается.
А вообще, конечно, очень неудачно сделано. Нужно было использовать стандартный тип Double (он же float) и обязательно packed record, чтобы не появлялось лишних выравнивающих байт. Но так уж сложилось исторически, и чтобы не ломать совместимость, так оно будет жить и впредь...
А вообще, конечно, очень неудачно сделано. Нужно было использовать стандартный тип Double (он же float) и обязательно packed record, чтобы не появлялось лишних выравнивающих байт. Но так уж сложилось исторически, и чтобы не ломать совместимость, так оно будет жить и впредь...