[marble] [Bug 461569] centerOn(GeoDataLatLonBox) behaviour does not match documentation

Torsten Rahn bugzilla_noreply at kde.org
Sat Apr 22 14:31:12 BST 2023


https://bugs.kde.org/show_bug.cgi?id=461569

Torsten Rahn <rahn at kde.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rahn at kde.org
             Status|REPORTED                    |CONFIRMED
     Ever confirmed|0                           |1

--- Comment #1 from Torsten Rahn <rahn at kde.org> ---
Yes, the current implementation of 

void MarbleAbstractPresenter::centerOn(const GeoDataLatLonBox &box, bool
animated)

is only a rough approximation. In order to center on a boundingbox internally
Marble needs to center on the center point and adjust the zoom level (which is
internally tied to the pixel-radius that a fully rendered earth would cover in
terms of vertical extent).
Since Marble allows for usage of different projections the actual calculation
of the zoom level would hard to calculate in a generic way. So the only
"better" option would be to iteratively approximate the optimal zoom level
(while either working on a copy of the view parameters or turning off rendering
during the iterative convergence towards the optimal zoom level).  

The current code looks like this:

void MarbleAbstractPresenter::centerOn(const GeoDataLatLonBox &box, bool
animated)
    {
        if (box.isEmpty())
        {
            return;
        }

        int newRadius = radius();
        ViewportParams* viewparams = map()->viewport();
        //prevent divide by zero
        if(box.height() && box.width())
        {
            //work out the needed zoom level
            int const horizontalRadius = ( 0.25 * M_PI ) *
(viewparams->height() / box.height());
            int const verticalRadius = ( 0.25 * M_PI ) * (viewparams->width() /
box.width());
            newRadius = qMin<int>(horizontalRadius, verticalRadius );
            newRadius = qMax<int>(radius(minimumZoom()), qMin<int>(newRadius,
radius(maximumZoom())));
        }

        //move the map
        GeoDataLookAt target;
        target.setCoordinates(box.center());
        target.setAltitude(box.center().altitude());
        target.setRange(KM2METER * distanceFromRadius(newRadius));
        flyTo(target, animated ? Automatic : Instant);
    }

Any suggestions for improvements welcome.

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the Marble-bugs mailing list