From c6d652e51debd78dd1dbb8591e056c13424287fb Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Wed, 12 Feb 2025 00:14:38 +0000 Subject: [PATCH] LazMapViewer: Make TDraggableMarkerPlugin act on TMapPoint and descendants as well. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9625 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../source/addons/plugins/mvplugins.pas | 54 +++++++++++++----- .../lazmapviewer/source/mvmapviewer.pas | 57 +++++++++++++++++++ 2 files changed, 97 insertions(+), 14 deletions(-) diff --git a/components/lazmapviewer/source/addons/plugins/mvplugins.pas b/components/lazmapviewer/source/addons/plugins/mvplugins.pas index 27619e18d..c5abe2a21 100644 --- a/components/lazmapviewer/source/addons/plugins/mvplugins.pas +++ b/components/lazmapviewer/source/addons/plugins/mvplugins.pas @@ -728,33 +728,59 @@ end; function TDraggableMarkerPlugin.GetFirstMarkerAtMousePos(const AMapView: TMapView; const AX, AY: Integer): TGPSPoint; + + function FindInList(AGpsList: TGpsObjList): TGpsPoint; + var + i: Integer; + begin + if Assigned(AGpsList) then + for i := AGpsList.Count-1 downto 0 do + begin + if (AGpsList[i] is TGpsPoint) then + begin + Result := TGpsPoint(AGpsList[i]); + if (not Assigned(FDraggableMarkerCanMoveEvent)) or + DraggableMarkerCanMoveEvent(Self, Result) + then + exit; + end; + end; + Result := nil; + end; + var aArea : TRealArea; - lGpsPt : TGpsPoint; gpsList: TGpsObjList; + layer: TMapLayer; i : Integer; begin Result := Nil; aArea.TopLeft := AMapView.ScreenToLatLon(Point(AX - FTolerance, AY - FTolerance)); aArea.BottomRight := AMapView.ScreenToLatLon(Point(AX + FTolerance, AY + FTolerance)); + + // Search in GPSItems for all gps-type-of-points gpsList := AMapView.GPSItems.GetObjectsInArea(aArea); try - for i := gpsList.Count-1 downto 0 do - begin - if (gpsList[i] is TGpsPoint) then - begin - lGpsPt := TGpsPoint(gpsList[i]); - if (not Assigned(FDraggableMarkerCanMoveEvent)) or - FDraggableMarkerCanMoveEvent(Self,lGpsPt) then - begin - Result := lGpsPt; - Exit; - end; - end; - end; + Result := FindInList(gpsList); + if Result <> nil then + exit; finally gpsList.Free; end; + + // Search in all layers for all map-type points + for i := AMapView.Layers.Count-1 downto 0 do + begin + layer := AMapView.Layers[i]; + gpsList := layer.GetObjectsInArea(aArea); + try + Result := FindInList(gpsList); + if Result <> nil then + exit; + finally + gpsList.Free; + end; + end; end; function TDraggableMarkerPlugin.GetDraggedMarker(AMapView: TMapView): TGPSPoint; diff --git a/components/lazmapviewer/source/mvmapviewer.pas b/components/lazmapviewer/source/mvmapviewer.pas index 271cf4b3d..591a1125f 100644 --- a/components/lazmapviewer/source/mvmapviewer.pas +++ b/components/lazmapviewer/source/mvmapviewer.pas @@ -118,6 +118,8 @@ type property Tag: PtrInt read FTag write FTag default 0; end; + TMapItemClass = class of TMapItem; + { TMapCollectionBase } TMapCollectionBase = class(TOwnedCollection) @@ -189,6 +191,7 @@ type public constructor Create(ACollection: TCollection); override; destructor Destroy; override; + function GetObjectsInArea(const Area: TRealArea; AClass: TMapItemClass = Nil): TGPSObjList; function HitTest(constref Area: TRealArea): TMapObjectList; override; function AddPointOfInterest(APoint: TRealPoint; ACaption: String = ''): TMapPointOfInterest; procedure AssignFromGPSList(AList: TGPSObjectList); @@ -2129,6 +2132,60 @@ begin inherited Destroy; end; +function TMapLayer.GetObjectsInArea(const Area: TRealArea; + AClass: TMapItemClass = nil): TGPSObjList; +var + i, j: integer; + P: TMapPoint; + mapArea: TMapArea; + track: TMapTrack; + objArea: TRealArea; + obj: TGpsObj; +begin + Result := TGPSObjList.Create(false); + + if (AClass = nil) or (AClass = TMapPointOfInterest) then + for i := 0 to Pred(PointsOfInterest.Count) do + begin + P := PointsOfInterest[i]; + obj := TMapPoint(P).GpsObj; + objArea := obj.BoundingBox; + if (not Assigned(AClass) or (P is AClass)) and HasIntersectArea(Area, objArea) then + Result.Add(obj); + end; + + if (AClass = nil) or (AClass = TMapAreaPoint) then + for j := 0 to Pred(Areas.Count) do + begin + mapArea := Areas[j]; + for i := 0 to Pred(mapArea.Points.Count) do + begin + P := mapArea.Points[i]; + obj := P.GpsObj; + objArea := obj.BoundingBox; + if (not Assigned(AClass) or (P is AClass)) and HasIntersectArea(Area, objArea) then + Result.Add(obj); + end; + end; + + if (AClass = nil) or (AClass = TMapTrackPoint) then + for j := 0 to Pred(Tracks.Count) do + begin + track := Tracks[j]; + for i := 0 to Pred(track.Points.Count) do + begin + P := track.Points[i]; + obj := P.GpsObj; + objArea := obj.BoundingBox; + if (not Assigned(AClass) or (P is AClass)) and HasIntersectArea(Area, objArea) then + Result.Add(obj); + end; + end; + + if Result.Count = 0 then + FreeAndNil(Result); +end; + function TMapLayer.HitTest(constref Area: TRealArea): TMapObjectList; begin Result := Nil;