Это код C #, который я использую в Maperitive :
public void ZoomToArea (Bounds2 mapArea, float paddingFactor)
{
double ry1 = Math.Log((Math.Sin(GeometryUtils.Deg2Rad(mapArea.MinY)) + 1)
/ Math.Cos(GeometryUtils.Deg2Rad(mapArea.MinY)));
double ry2 = Math.Log((Math.Sin(GeometryUtils.Deg2Rad(mapArea.MaxY)) + 1)
/ Math.Cos(GeometryUtils.Deg2Rad(mapArea.MaxY)));
double ryc = (ry1 + ry2) / 2;
double centerY = GeometryUtils.Rad2Deg(Math.Atan(Math.Sinh(ryc)));
double resolutionHorizontal = mapArea.DeltaX / Viewport.Width;
double vy0 = Math.Log(Math.Tan(Math.PI*(0.25 + centerY/360)));
double vy1 = Math.Log(Math.Tan(Math.PI*(0.25 + mapArea.MaxY/360)));
double viewHeightHalf = Viewport.Height/2.0f;
double zoomFactorPowered = viewHeightHalf
/ (40.7436654315252*(vy1 - vy0));
double resolutionVertical = 360.0 / (zoomFactorPowered * 256);
double resolution = Math.Max(resolutionHorizontal, resolutionVertical)
* paddingFactor;
double zoom = Math.Log(360 / (resolution * 256), 2);
double lon = mapArea.Center.X;
double lat = centerY;
CenterMapOnPoint(new PointD2(lon, lat), zoom);
}
mapArea
: ограничивающий прямоугольник в координатах long / lat (x = long, y = lat)
paddingFactor
: это может быть использовано для получения эффекта "120%", на который ссылается ThomM. Значение 1,2 даст вам 120%.
Обратите внимание, что в моем случае zoom
может быть действительным числом. В случае веб-карт вам нужно целочисленное значение масштабирования, поэтому вы должны использовать что-то вроде (int)Math.Floor(zoom)
этого.
Конечно, этот код относится только к проекции Web Mercator.