{-------------------------------------------------------------------------------
ZoomToLayer
Adjusts the map camera so that the entire extent of the given layer becomes
visible within the current viewport (the drawing area on screen).
@param ALayer The layer to zoom to. Its bounds are used to compute the
required scale and center position.
The method:
1. Retrieves the layer's bounding box (TEnvelope) in world coordinates.
2. Gets the current camera (IMapCamera) and viewport (TViewport) from the map engine.
3. Computes the scale needed so that the layer's width and height fit into
the viewport with a 20% padding margin.
4. Applies limits to the scale (clamping to avoid extreme values).
5. Sets the camera's scale and centers it on the middle of the layer's bounds.
6. Notifies the view (via prMapCameraChanged) that the camera has changed,
triggering a redraw.
Note: The viewport is the size of the drawing area in pixels (e.g., a TPaintBox
on the form). The envelope is in world coordinates (e.g., meters for
Web Mercator). The camera translates between these coordinate systems.
-------------------------------------------------------------------------------}
procedure TPresenterMain.ZoomToLayer(ALayer: IMapLayer);
var
lEnv: TEnvelope; // Bounding box of the layer (minX, minY, maxX, maxY) in world coordinates
lCam: IMapCamera; // Camera object that defines where and how we look at the world
lVp: TViewport; // Size of the drawing area (the paintbox) in pixels
lScaleX, lScaleY, lNewScale: Double; // Scale factors to fit layer into viewport
begin
if ALayer = nil then Exit;
// Get the layer's world extent (the minimal rectangle that encloses all its geometries)
ALayer.GetBounds(lEnv);
if (lEnv.Width <= 0) or (lEnv.Height <= 0) then
Exit;
// Fetch current camera and viewport from the map engine
lCam:= fModel.GetMapEngine.GetCamera;
lVp:= fModel.GetMapEngine.GetViewport;
// Calculate the scale needed to fit the layer horizontally and vertically
// We divide by 1.2 to add 20% padding so the layer is not cut off at the edges
lScaleX:= (lVp.Width / lEnv.Width) / 1.2;
lScaleY:= (lVp.Height / lEnv.Height) / 1.2;
// Choose the smaller scale so both dimensions fit (aspect ratio is preserved)
// Dus passend maken...(4)
lNewScale:= lScaleX;
if lScaleY < lNewScale then
lNewScale:= lScaleY;
// Clamp scale to sensible limits to avoid zooming too far in or out
if lNewScale < 0.0001 then lNewScale:= 0.0001;
if lNewScale > 5000 then lNewScale:= 5000;
// Apply new scale and center the camera on the middle of the layer
lCam.SetScale(lNewScale);
lCam.SetCenterX((lEnv.minX + lEnv.maxX) / 2);
lCam.SetCenterY((lEnv.minY + lEnv.maxY) / 2);
// Notify the view that the camera has changed; the view will redraw the map
fProvider.NotifyConsumers(prMapCameraChanged, nil, nil);
end;