LazMapViewer: Track segment marks and GPX track loading. TryStrToGpxColor fix.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9290 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
6a13ae7fb3
commit
8eaa889f85
@ -39,29 +39,51 @@ type
|
||||
property Width: Double read FWidth write SetWidth; // Line width in mm
|
||||
end;
|
||||
|
||||
{ TTrackSegmentExtraData }
|
||||
{ TSegmentExtraData }
|
||||
|
||||
TTrackSegmentExtraData = class(TObject)
|
||||
TSegmentExtraData = class(TObject)
|
||||
public
|
||||
type TSegmentMark = (smNone, smStart, smMid, smEnd);
|
||||
private
|
||||
FMark: TSegmentMark;
|
||||
public
|
||||
constructor Create(AMark: TSegmentMark);
|
||||
class function MarkOf(const APoint: TObject): TSegmentMark;
|
||||
property Mark: TSegmentMark read FMark write FMark;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
{ TTrackSegmentExtraData }
|
||||
uses
|
||||
mvGpsObj;
|
||||
|
||||
constructor TTrackSegmentExtraData.Create(AMark: TSegmentMark);
|
||||
{ TSegmentExtraData }
|
||||
|
||||
constructor TSegmentExtraData.Create(AMark: TSegmentMark);
|
||||
begin
|
||||
inherited Create;
|
||||
FMark := AMark;
|
||||
end;
|
||||
|
||||
// Can be invoked with APoint.Extradata or with APoint itself
|
||||
class function TSegmentExtraData.MarkOf(const APoint: TObject): TSegmentMark;
|
||||
begin
|
||||
// Quick check for Nil (APoint.Extradata, APoint)
|
||||
if not Assigned(APoint) then
|
||||
Result := smNone
|
||||
// Check for non-nil TSegmentExtraData (APoint.Extradata)
|
||||
else if (APoint is Self) then
|
||||
Result := TSegmentExtraData(APoint).Mark
|
||||
// Check for non-nil object with a non-nil TSegmentExtraData (APoint)
|
||||
else if (APoint is TGPSObj) and Assigned(TGPSObj(APoint).ExtraData) and
|
||||
(TGPSObj(APoint).ExtraData is Self)
|
||||
then
|
||||
Result := TSegmentExtraData(TGPSObj(APoint).ExtraData).Mark
|
||||
else // None of the above
|
||||
Result := smNone;
|
||||
end;
|
||||
|
||||
{ TDrawingExtraData }
|
||||
|
||||
constructor TDrawingExtraData.Create(aId: integer);
|
||||
|
@ -55,7 +55,7 @@ implementation
|
||||
|
||||
uses
|
||||
Math,
|
||||
mvExtraData;
|
||||
mvExtraData, Graphics;
|
||||
|
||||
var
|
||||
PointSettings: TFormatSettings;
|
||||
@ -192,30 +192,34 @@ begin
|
||||
end;
|
||||
|
||||
function TryStrToGpxColor(AGpxText: String; out AColor: LongInt): Boolean;
|
||||
type
|
||||
PGpxColorRec = ^TGpxColorRec;
|
||||
TGpxColorRec = record
|
||||
r: array[0..1] of char;
|
||||
g: array[0..1] of char;
|
||||
b: array[0..1] of char;
|
||||
end;
|
||||
var
|
||||
rv, gv, bv: Integer;
|
||||
ch: Char;
|
||||
//type
|
||||
// PGpxColorRec = ^TGpxColorRec;
|
||||
// TGpxColorRec = record
|
||||
// r: array[0..1] of char;
|
||||
// g: array[0..1] of char;
|
||||
// b: array[0..1] of char;
|
||||
// end;
|
||||
//var
|
||||
// rv, gv, bv: Integer;
|
||||
// ch: Char;
|
||||
begin
|
||||
Result := false;
|
||||
if Length(AGpxText) <> 6 then
|
||||
exit;
|
||||
for ch in AGpxText do
|
||||
if not (ch in ['0'..'9', 'A'..'F', 'a'..'f']) then exit;
|
||||
//for ch in AGpxText do
|
||||
// if not (ch in ['0'..'9', 'A'..'F', 'a'..'f']) then exit;
|
||||
|
||||
with PGpxColorRec(@AGpxText[1])^ do begin
|
||||
rv := (ord(r[0]) - ord('0')) * 16 + ord(r[1]) - ord('0');
|
||||
gv := (ord(g[0]) - ord('0')) * 16 + ord(g[1]) - ord('0');
|
||||
bv := (ord(b[0]) - ord('0')) * 16 + ord(b[1]) - ord('0');
|
||||
end;
|
||||
AColor := rv + gv shl 8 + bv shl 16;
|
||||
Result := true;
|
||||
(* Doesn't work for letters! *)
|
||||
|
||||
//with PGpxColorRec(@AGpxText[1])^ do begin
|
||||
// rv := (ord(r[0]) - ord('0')) * 16 + ord(r[1]) - ord('0');
|
||||
// gv := (ord(g[0]) - ord('0')) * 16 + ord(g[1]) - ord('0');
|
||||
// bv := (ord(b[0]) - ord('0')) * 16 + ord(b[1]) - ord('0');
|
||||
//end;
|
||||
//AColor := rv + gv shl 8 + bv shl 16;
|
||||
Result := TryStrToInt('$' + AGpxText, AColor);
|
||||
if Result then
|
||||
AColor := ((AColor and $FF) shl 16) + (AColor and $FF00) + ((AColor and $FF0000) shr 16);
|
||||
end;
|
||||
|
||||
|
||||
@ -296,6 +300,50 @@ var
|
||||
CreateTextElement(Result, 'time', DateToISO8601(APOI.DateTime));
|
||||
end;
|
||||
|
||||
function CreateTrack(AName: String; ATrack: TGPSTrack): TDOMElement;
|
||||
var
|
||||
Seg, LineEx, Ex: TDOMElement;
|
||||
L: LongInt;
|
||||
|
||||
procedure CreateSegments;
|
||||
var
|
||||
P: TGPSObj;
|
||||
begin
|
||||
for P in ATrack.AllObjs do
|
||||
begin
|
||||
Seg.AppendChild(CreatePoint('trkpt', TGPSPoint(P)));
|
||||
if TSegmentExtraData.MarkOf(P) = smEnd then
|
||||
begin
|
||||
Seg := Doc.CreateElement('trkseg');
|
||||
Result.AppendChild(Seg);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result := Doc.CreateElement(AName);
|
||||
if ATrack.Name <> '' then
|
||||
CreateTextElement(Result, 'name', ATrack.Name);
|
||||
if Assigned(ATrack.ExtraData) and (ATrack.ExtraData is TTrackExtraData) then
|
||||
with TTrackExtraData(ATrack.ExtraData) do
|
||||
begin
|
||||
Ex := Doc.CreateElement('extensions');
|
||||
LineEx := Doc.CreateElement('line');
|
||||
Ex.AppendChild(LineEx);
|
||||
Result.AppendChild(Ex);
|
||||
L := ColorToRGB(Color);
|
||||
L := ((L and $FF) shl 16) + (L and $FF00) + ((L and $FF0000) shr 16);
|
||||
CreateTextElement(LineEx, 'color', L.ToHexString(6));
|
||||
CreateTextElement(LineEx, 'width', Width.ToString);
|
||||
end;
|
||||
if ATrack.Points.Count > 0 then
|
||||
begin
|
||||
Seg := Doc.CreateElement('trkseg');
|
||||
Result.AppendChild(Seg);
|
||||
CreateSegments;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
Doc := TXMLDocument.Create;
|
||||
try
|
||||
@ -314,6 +362,8 @@ begin
|
||||
else if O is TGPSPoint then
|
||||
RootNode.AppendChild(CreatePoint('wpt', TGPSPoint(O)))
|
||||
else if O is TGPSTrack then
|
||||
RootNode.AppendChild(CreateTrack('trk', TGPSTrack(O)))
|
||||
else
|
||||
{TODO};
|
||||
end;
|
||||
WriteXMLFile(doc, AStream);
|
||||
@ -531,7 +581,7 @@ begin
|
||||
ANode := ANode.NextSibling;
|
||||
end;
|
||||
if Assigned(gpsPt) then // Mark the last point of the segment
|
||||
gpsPt.ExtraData := TTrackSegmentExtraData.Create(smEnd);
|
||||
gpsPt.ExtraData := TSegmentExtraData.Create(smEnd);
|
||||
end;
|
||||
|
||||
procedure TGpxReader.ReadWayPoints(ANode: TDOMNode; AList: TGpsObjectList);
|
||||
|
@ -25,7 +25,7 @@ uses
|
||||
Classes, SysUtils, Controls, GraphType, Graphics, FPImage, IntfGraphics,
|
||||
Forms, ImgList, LCLVersion,
|
||||
MvTypes, MvGPSObj, MvEngine, MvMapProvider, MvDownloadEngine, MvDrawingEngine,
|
||||
mvCache;
|
||||
mvCache, mvExtraData;
|
||||
|
||||
Type
|
||||
|
||||
@ -224,10 +224,16 @@ type
|
||||
{ TMapTrackPoint }
|
||||
|
||||
TMapTrackPoint = class(TMapPoint)
|
||||
private
|
||||
FMark: TSegmentExtraData.TSegmentMark;
|
||||
function MarkIsStored: Boolean;
|
||||
procedure SetMark(AValue: TSegmentExtraData.TSegmentMark);
|
||||
protected
|
||||
function GPSTrack: TGPSTrack;
|
||||
function CreatePoint: TGPSPoint; override;
|
||||
procedure DestroyPoint; override;
|
||||
published
|
||||
property Mark: TSegmentExtraData.TSegmentMark read FMark write SetMark stored MarkIsStored;
|
||||
end;
|
||||
|
||||
{ TMapTrackPoints }
|
||||
@ -285,6 +291,9 @@ type
|
||||
FOnDrawTrack: TMapTrackDrawEvent;
|
||||
function GetGPSObj: TGPSObj; override;
|
||||
function GetPoints: TMapTrackPoints;
|
||||
procedure SetLineColor(AValue: TColor);
|
||||
procedure SetLineWidth(AValue: Double);
|
||||
procedure ExtraData;
|
||||
procedure SetOnDrawTrack(AValue: TMapTrackDrawEvent);
|
||||
procedure SetPoints(AValue: TMapTrackPoints);
|
||||
protected
|
||||
@ -295,8 +304,8 @@ type
|
||||
procedure ItemChanged; override;
|
||||
published
|
||||
//property DateTime: TDateTime read GetDateTime write FDateTime;
|
||||
property LineColor: TColor read FLineColor write FLineColor default clDefault;
|
||||
property LineWidth: Double read FLineWidth write FLineWidth;
|
||||
property LineColor: TColor read FLineColor write SetLineColor default clDefault;
|
||||
property LineWidth: Double read FLineWidth write SetLineWidth;
|
||||
property Points: TMapTrackPoints read GetPoints write SetPoints;
|
||||
property OnDrawTrack: TMapTrackDrawEvent read FOnDrawTrack write SetOnDrawTrack;
|
||||
end;
|
||||
@ -574,7 +583,7 @@ implementation
|
||||
|
||||
uses
|
||||
GraphMath, FileUtil, LazLoggerBase, Types, Math,
|
||||
mvJobQueue, mvExtraData, mvDLEFpc,
|
||||
mvJobQueue, mvDLEFpc,
|
||||
{$IFDEF MSWINDOWS}
|
||||
mvDLEWin,
|
||||
{$ENDIF}
|
||||
@ -636,6 +645,26 @@ begin
|
||||
//FPoint.Free;
|
||||
end;
|
||||
|
||||
function TMapTrackPoint.MarkIsStored: Boolean;
|
||||
begin
|
||||
Result := FMark <> smNone;
|
||||
end;
|
||||
|
||||
procedure TMapTrackPoint.SetMark(AValue: TSegmentExtraData.TSegmentMark);
|
||||
begin
|
||||
if FMark = AValue then
|
||||
Exit;
|
||||
FMark := AValue;
|
||||
if (AValue = smNone) then
|
||||
FPoint.ExtraData.Free
|
||||
else
|
||||
begin
|
||||
if not Assigned(FPoint.ExtraData)
|
||||
then FPoint.ExtraData := TSegmentExtraData.Create(AValue)
|
||||
else TSegmentExtraData(FPoint.ExtraData).Mark := AValue;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMapTrackPoint.GPSTrack: TGPSTrack;
|
||||
begin
|
||||
Result := Nil;
|
||||
@ -735,6 +764,36 @@ begin
|
||||
Result := FPoints;
|
||||
end;
|
||||
|
||||
procedure TMapTrack.SetLineColor(AValue: TColor);
|
||||
begin
|
||||
if FLineColor = AValue then Exit;
|
||||
FLineColor := AValue;
|
||||
ExtraData;
|
||||
end;
|
||||
|
||||
procedure TMapTrack.SetLineWidth(AValue: Double);
|
||||
begin
|
||||
if FLineWidth = AValue then Exit;
|
||||
FLineWidth := AValue;
|
||||
ExtraData;
|
||||
end;
|
||||
|
||||
procedure TMapTrack.ExtraData;
|
||||
begin
|
||||
if (FLineColor = clDefault) and (FLineWidth < 0.01) then
|
||||
begin
|
||||
FTrack.ExtraData.Free; // No need, aId?
|
||||
FTrack.ExtraData := Nil;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if not Assigned(FTrack.ExtraData) then
|
||||
FTrack.ExtraData := TTrackExtraData.Create(-1); // aId?
|
||||
TTrackExtraData(FTrack.ExtraData).Color := FLineColor;
|
||||
TTrackExtraData(FTrack.ExtraData).Width := FLineWidth;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMapTrack.SetPoints(AValue: TMapTrackPoints);
|
||||
begin
|
||||
FPoints.Assign(AValue);
|
||||
@ -768,6 +827,7 @@ end;
|
||||
|
||||
procedure TMapTrack.ItemChanged;
|
||||
begin
|
||||
FTrack.Name := Caption;
|
||||
FTrack.LineColor := LineColor;
|
||||
FTrack.LineWidth := LineWidth;
|
||||
FTrack.Visible := Visible;
|
||||
@ -1195,12 +1255,10 @@ begin
|
||||
FVisible := True;
|
||||
FTag := 0;
|
||||
|
||||
DebugLn('TMapLayer.Create 1');
|
||||
FPointsOfInterest := TPointsOfInterest.Create(Self);
|
||||
FTracks := TMapTracks.Create(Self);
|
||||
FComboLayer := TGPSComboLayer.Create;
|
||||
View.GPSItems.Add(FComboLayer, _TILELAYERS_ID_, Self.Index - LAYERS_ZOFFS);
|
||||
DebugLn('TMapLayer.Create X');
|
||||
end;
|
||||
|
||||
destructor TMapLayer.Destroy;
|
||||
@ -1232,6 +1290,8 @@ procedure TMapLayer.AssignFromGPSList(AList: TGPSObjectList);
|
||||
P: TGPSPoint;
|
||||
begin
|
||||
with Tracks.Add as TMapTrack do
|
||||
begin
|
||||
Caption := ATrack.Name;
|
||||
for I := 0 to Pred(ATrack.Points.Count) do
|
||||
with Points.Add as TMapTrackPoint do
|
||||
begin
|
||||
@ -1241,7 +1301,15 @@ procedure TMapLayer.AssignFromGPSList(AList: TGPSObjectList);
|
||||
Latitude := P.Lat;
|
||||
Elevation := P.Elevation;
|
||||
DateTime := P.DateTime;
|
||||
if ATrack.Points[I].ExtraData is TSegmentExtraData then
|
||||
Mark := TSegmentExtraData(ATrack.Points[I].ExtraData).Mark;
|
||||
end;
|
||||
if ATrack.ExtraData is TTrackExtraData then
|
||||
begin
|
||||
LineWidth := TTrackExtraData(ATrack.ExtraData).Width;
|
||||
LineColor := TTrackExtraData(ATrack.ExtraData).Color;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
@ -1250,6 +1318,7 @@ begin
|
||||
if not Assigned(AList) then
|
||||
Exit;
|
||||
PointsOfInterest.Clear;
|
||||
Tracks.Clear;
|
||||
for I := 0 to Pred(AList.Count) do
|
||||
if AList[I] is TGPSPoint then
|
||||
AddPoint(TGPSPoint(AList[I]))
|
||||
@ -1907,7 +1976,7 @@ var
|
||||
I, L, T, WS: Integer;
|
||||
ClipRect: TRect;
|
||||
iPt1, iPt2, iPt3, iPt4: TPoint;
|
||||
ToEast: Boolean;
|
||||
ToEast, EndSegm: Boolean;
|
||||
pt1, pt2: TRealPoint;
|
||||
trkColor: TColor;
|
||||
trkWidth: Integer;
|
||||
@ -1945,6 +2014,7 @@ begin
|
||||
|
||||
pt1 := trk.Points[0].RealPoint;
|
||||
iPt1 := Engine.LonLatToScreen(pt1);
|
||||
EndSegm := TSegmentExtraData.MarkOf(trk.Points[0].ExtraData) = smEnd;
|
||||
for I := 1 to Pred(trk.Points.Count) do
|
||||
begin
|
||||
pt2 := trk.Points[I].RealPoint;
|
||||
@ -1964,14 +2034,16 @@ begin
|
||||
iPt4 := (iPt1 - iPt2); // delta to the right point
|
||||
end;
|
||||
|
||||
// Draw all copies of the segment, right to left
|
||||
repeat
|
||||
ClipDrawLine(iPt3, iPt3 + iPt4);
|
||||
iPt3 := CyclicPointOf(iPt3, Pred(iPt3.X), False); // Next left cyclic iPt3
|
||||
until Max(iPt3.X, iPt3.X + iPt4.X) < ClipRect.Left;
|
||||
if TSegmentExtraData.MarkOf(trk.Points[Pred(I)].ExtraData) <> smEnd then
|
||||
// Draw all copies of the segment, right to left
|
||||
repeat
|
||||
ClipDrawLine(iPt3, iPt3 + iPt4);
|
||||
iPt3 := CyclicPointOf(iPt3, Pred(iPt3.X), False); // Next left cyclic iPt3
|
||||
until Max(iPt3.X, iPt3.X + iPt4.X) < ClipRect.Left;
|
||||
|
||||
pt1 := pt2;
|
||||
iPt1 := iPt2;
|
||||
EndSegm := TSegmentExtraData.MarkOf(trk.Points[I].ExtraData) = smEnd;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user