diff --git a/src/GUI/mapitem.cpp b/src/GUI/mapitem.cpp
index 47f56a61..a7a46d2c 100644
--- a/src/GUI/mapitem.cpp
+++ b/src/GUI/mapitem.cpp
@@ -89,8 +89,6 @@ MapItem::MapItem(MapAction *action, Map *map, GraphicsItem *parent)
 
 	_name = src->name();
 	_fileName = src->path();
-	// Zoom to the maximal zoom level to get the most accurate bounds
-	src->zoomFit(QSize(), RectC());
 	_bounds = src->llBounds();
 
 	connect(this, SIGNAL(triggered()), action, SLOT(trigger()));
diff --git a/src/map/IMG/rastertile.cpp b/src/map/IMG/rastertile.cpp
index da4dcb5f..a4c54221 100644
--- a/src/map/IMG/rastertile.cpp
+++ b/src/map/IMG/rastertile.cpp
@@ -454,4 +454,3 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
 			delete item;
 	}
 }
-
diff --git a/src/map/imgmap.cpp b/src/map/imgmap.cpp
index b7173929..dc854a0e 100644
--- a/src/map/imgmap.cpp
+++ b/src/map/imgmap.cpp
@@ -171,7 +171,7 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
 					polyRect &= bounds();
 					RectD polyRectD(_transform.img2proj(polyRect.topLeft()),
 					  _transform.img2proj(polyRect.bottomRight()));
-					_data.at(n)->polys(polyRectD.toRectC(_projection, 4), _zoom,
+					_data.at(n)->polys(polyRectD.toRectC(_projection, 20), _zoom,
 					  &polygons, &lines);
 
 					QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT,
@@ -180,7 +180,7 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
 					pointRect &= bounds();
 					RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
 					  _transform.img2proj(pointRect.bottomRight()));
-					_data.at(n)->points(pointRectD.toRectC(_projection, 4),
+					_data.at(n)->points(pointRectD.toRectC(_projection, 20),
 					  _zoom, &points);
 
 					tiles.append(RasterTile(this, _data.at(n)->style(), _zoom,
@@ -212,10 +212,18 @@ void IMGMap::setProjection(const Projection &projection)
 		return;
 
 	_projection = projection;
-	// Limit the bounds for some well known Mercator projections
+	// Limit the bounds for some well known projections
 	// (world maps have N/S bounds up to 90/-90!)
-	_dataBounds = (_projection == PCS::pcs(3857) || _projection == PCS::pcs(3395))
-	  ? _data.first()->bounds() & OSM::BOUNDS : _data.first()->bounds();
+	if (_projection == PCS::pcs(3857) || _projection == PCS::pcs(3395))
+		_dataBounds = _data.first()->bounds() & OSM::BOUNDS;
+	else if (_projection == PCS::pcs(3031) || _projection == PCS::pcs(3976))
+		_dataBounds = _data.first()->bounds() & RectC(Coordinates(-180, -60),
+		  Coordinates(180, -90));
+	else if (_projection == PCS::pcs(3995) || _projection == PCS::pcs(3413))
+		_dataBounds = _data.first()->bounds() & RectC(Coordinates(-180, 90),
+		  Coordinates(180, 60));
+	else
+		_dataBounds = _data.first()->bounds();
 
 	updateTransform();
 	QPixmapCache::clear();
diff --git a/src/map/rectd.cpp b/src/map/rectd.cpp
index b0b4f995..fba279b2 100644
--- a/src/map/rectd.cpp
+++ b/src/map/rectd.cpp
@@ -4,66 +4,30 @@
 #include "rectd.h"
 
 
-static void growLeft(const Projection &proj, const Coordinates &c, RectD &rect)
+static void growRect(const Projection &proj, const Coordinates &c, RectD &rect)
 {
 	PointD p(proj.ll2xy(c));
 
 	if (p.x() < rect.left())
 		rect.setLeft(p.x());
-}
-
-static void growRight(const Projection &proj, const Coordinates &c, RectD &rect)
-{
-	PointD p(proj.ll2xy(c));
-
 	if (p.x() > rect.right())
 		rect.setRight(p.x());
-}
-
-static void growTop(const Projection &proj, const Coordinates &c, RectD &rect)
-{
-	PointD p(proj.ll2xy(c));
-
 	if (p.y() > rect.top())
 		rect.setTop(p.y());
-}
-
-static void growBottom(const Projection &proj, const Coordinates &c, RectD &rect)
-{
-	PointD p(proj.ll2xy(c));
-
 	if (p.y() < rect.bottom())
 		rect.setBottom(p.y());
 }
 
-static void growLeft(const Projection &proj, const PointD &p, RectC &rect)
+static void growRect(const Projection &proj, const PointD &p, RectC &rect)
 {
 	Coordinates c(proj.xy2ll(p));
 
 	if (c.lon() < rect.left())
 		rect.setLeft(c.lon());
-}
-
-static void growRight(const Projection &proj, const PointD &p, RectC &rect)
-{
-	Coordinates c(proj.xy2ll(p));
-
 	if (c.lon() > rect.right())
 		rect.setRight(c.lon());
-}
-
-static void growTop(const Projection &proj, const PointD &p, RectC &rect)
-{
-	Coordinates c(proj.xy2ll(p));
-
 	if (c.lat() > rect.top())
 		rect.setTop(c.lat());
-}
-
-static void growBottom(const Projection &proj, const PointD &p, RectC &rect)
-{
-	Coordinates c(proj.xy2ll(p));
-
 	if (c.lat() < rect.bottom())
 		rect.setBottom(c.lat());
 }
@@ -82,14 +46,14 @@ RectD::RectD(const RectC &rect, const Projection &proj, int samples)
 
 	for (int i = 0; i <= samples; i++) {
 		double x = remainder(rect.left() + i * dx, 360.0);
-		growBottom(proj, Coordinates(x, rect.bottom()), prect);
-		growTop(proj, Coordinates(x, rect.top()), prect);
+		growRect(proj, Coordinates(x, rect.bottom()), prect);
+		growRect(proj, Coordinates(x, rect.top()), prect);
 	}
 
 	for (int i = 0; i <= samples; i++) {
 		double y = rect.bottom() + i * dy;
-		growLeft(proj, Coordinates(rect.left(), y), prect);
-		growRight(proj, Coordinates(rect.right(), y), prect);
+		growRect(proj, Coordinates(rect.left(), y), prect);
+		growRect(proj, Coordinates(rect.right(), y), prect);
 	}
 
 	*this = prect;
@@ -103,20 +67,19 @@ RectC RectD::toRectC(const Projection &proj, int samples) const
 	double dx = width() / samples;
 	double dy = height() / samples;
 
-	Coordinates tl(proj.xy2ll(topLeft()));
-	Coordinates br(proj.xy2ll(bottomRight()));
-	RectC rect(tl, br);
+	Coordinates c(proj.xy2ll(center()));
+	RectC rect(c, c);
 
 	for (int i = 0; i <= samples; i++) {
 		double x = left() + i * dx;
-		growBottom(proj, PointD(x, bottom()), rect);
-		growTop(proj, PointD(x, top()), rect);
+		growRect(proj, PointD(x, bottom()), rect);
+		growRect(proj, PointD(x, top()), rect);
 	}
 
 	for (int i = 0; i <= samples; i++) {
 		double y = bottom() + i * dy;
-		growLeft(proj, PointD(left(), y), rect);
-		growRight(proj, PointD(right(), y), rect);
+		growRect(proj, PointD(left(), y), rect);
+		growRect(proj, PointD(right(), y), rect);
 	}
 
 	return rect;
diff --git a/src/map/rectd.h b/src/map/rectd.h
index e41140c3..c8355b40 100644
--- a/src/map/rectd.h
+++ b/src/map/rectd.h
@@ -16,6 +16,9 @@ public:
 
 	PointD topLeft() const {return _tl;}
 	PointD bottomRight() const {return _br;}
+	PointD center() const
+	  {return PointD((_tl.x() + _br.x()) / 2.0,
+		(_tl.y() + _br.y()) / 2.0);}
 
 	double left() const {return _tl.x();}
 	double right() const {return _br.x();}
diff --git a/src/map/wmtsmap.cpp b/src/map/wmtsmap.cpp
index c6bb2b8e..92ce6f71 100644
--- a/src/map/wmtsmap.cpp
+++ b/src/map/wmtsmap.cpp
@@ -55,9 +55,9 @@ double WMTSMap::sd2res(double scaleDenominator) const
 	  * _wmts->projection().units().fromMeters(1.0);
 }
 
-void WMTSMap::updateTransform()
+Transform WMTSMap::transform(int zoom) const
 {
-	const WMTS::Zoom &z = _wmts->zooms().at(_zoom);
+	const WMTS::Zoom &z = _wmts->zooms().at(zoom);
 
 	PointD topLeft = (_wmts->cs().axisOrder() == CoordinateSystem::YX)
 	  ? PointD(z.topLeft().y(), z.topLeft().x()) : z.topLeft();
@@ -65,28 +65,50 @@ void WMTSMap::updateTransform()
 	double pixelSpan = sd2res(z.scaleDenominator());
 	if (_wmts->projection().isGeographic())
 		pixelSpan /= deg2rad(WGS84_RADIUS);
-	_transform = Transform(ReferencePoint(PointD(0, 0), topLeft),
+	return Transform(ReferencePoint(PointD(0, 0), topLeft),
 	  PointD(pixelSpan, pixelSpan));
 }
 
-QRectF WMTSMap::bounds()
+QRectF WMTSMap::tileBounds(int zoom) const
 {
-	const WMTS::Zoom &z = _wmts->zooms().at(_zoom);
-	QRectF tileBounds, bounds;
+	const WMTS::Zoom &z = _wmts->zooms().at(zoom);
 
-	tileBounds = (z.limits().isNull()) ?
-	  QRectF(QPointF(0, 0), QSize(z.tile().width() * z.matrix().width(),
+	return (z.limits().isNull())
+	  ? QRectF(QPointF(0, 0), QSize(z.tile().width() * z.matrix().width(),
 	  z.tile().height() * z.matrix().height()))
 	  : QRectF(QPointF(z.limits().left() * z.tile().width(), z.limits().top()
 	  * z.tile().height()), QSize(z.tile().width() * z.limits().width(),
 	  z.tile().height() * z.limits().height()));
+}
 
-	if (_bounds.isValid())
-		bounds = QRectF(_transform.proj2img(_bounds.topLeft())
-		  / coordinatesRatio(), _transform.proj2img(
-		  _bounds.bottomRight()) / coordinatesRatio());
+void WMTSMap::updateTransform()
+{
+	_transform = transform(_zoom);
+}
 
-	return bounds.isValid() ? tileBounds.intersected(bounds) : tileBounds;
+QRectF WMTSMap::bounds()
+{
+	QRectF tb(tileBounds(_zoom));
+	QRectF lb = _bounds.isValid()
+	  ? QRectF(_transform.proj2img(_bounds.topLeft()) / coordinatesRatio(),
+	  _transform.proj2img(_bounds.bottomRight()) / coordinatesRatio())
+	  : QRectF();
+
+	return lb.isValid() ? lb & tb : tb;
+}
+
+RectC WMTSMap::llBounds()
+{
+	if (_wmts->bbox().isValid())
+		return _wmts->bbox();
+	else {
+		int maxZoom = _wmts->zooms().size() - 1;
+		QRectF tb(tileBounds(maxZoom));
+		Transform t(transform(maxZoom));
+		RectD rect(t.img2proj(tb.topLeft() * coordinatesRatio()),
+		  t.img2proj(tb.bottomRight() * coordinatesRatio()));
+		return rect.toRectC(_wmts->projection());
+	}
 }
 
 int WMTSMap::zoomFit(const QSize &size, const RectC &rect)
diff --git a/src/map/wmtsmap.h b/src/map/wmtsmap.h
index ad67b28a..4b23c7e2 100644
--- a/src/map/wmtsmap.h
+++ b/src/map/wmtsmap.h
@@ -20,6 +20,7 @@ public:
 	QString name() const {return _name;}
 
 	QRectF bounds();
+	RectC llBounds();
 
 	int zoom() const {return _zoom;}
 	void setZoom(int zoom);
@@ -45,6 +46,8 @@ private slots:
 
 private:
 	double sd2res(double scaleDenominator) const;
+	Transform transform(int zoom) const;
+	QRectF tileBounds(int zoom) const;
 	void updateTransform();
 	QSizeF tileSize(const WMTS::Zoom &zoom) const;
 	qreal coordinatesRatio() const;