SUMMARY *** NOTE: If you are reporting a crash, please try to attach a backtrace with debug symbols. See https://community.kde.org/Guidelines_and_HOWTOs/Debugging/How_to_create_useful_crash_reports *** The documentation for centerOn(GeoDataLatLonBox) specifies: "Center the view on a bounding box so that it **completely fills the viewport**" However, the actual behaviour of this function is that the map is correctly centered, but zoomed *out* from the bounding box. STEPS TO REPRODUCE 1. Define a bounding box 2. call centerOn the bounding box OBSERVED RESULT Bounding box does _not_ completely fill the viewport as described in the documentation. EXPECTED RESULT Bounding box should completely fill the viewport. SOFTWARE/OS VERSIONS Linux/KDE Plasma: RHEL7 and RHEL8 Qt Version: 5.10
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.