/* Do some calculations and drag attributes to local variables to save some performance. */
final int zoomLevel = this.mZoomLevel;
final int viewWidth = this.getWidth();
final int viewHeight = this.getHeight();
final int tileSizePx = this.mRendererInfo.MAPTILE_SIZEPX;
/* Get the center MapTile which is above this.mLatitudeE6 and this.mLongitudeE6 .*/
final int[] centerMapTileCoords = Util.getMapTileFromCoordinates(this.mLatitudeE6, this.mLongitudeE6, zoomLevel, null);
/* Calculate the Latitude/Longitude on the left-upper ScreenCoords of the center MapTile.
* So in the end we can determine which MapTiles we additionally need next to the centerMapTile. */
final Point upperLeftCornerOfCenterMapTile = getUpperLeftCornerOfCenterMapTileInScreen(centerMapTileCoords, tileSizePx, null);
final int centerMapTileScreenLeft = upperLeftCornerOfCenterMapTile.x;
final int centerMapTileScreenTop = upperLeftCornerOfCenterMapTile.y;
final int centerMapTileScreenRight = centerMapTileScreenLeft + tileSizePx;
final int centerMapTileScreenBottom = centerMapTileScreenTop + tileSizePx;
/* Calculate the amount of tiles needed for each side around the center one. */
final int additionalTilesNeededToLeftOfCenter = (int)Math.ceil((float)centerMapTileScreenLeft / tileSizePx); // i.e. "30 / 256" = 1;
final int additionalTilesNeededToRightOfCenter = (int)Math.ceil((float)(viewWidth - centerMapTileScreenRight) / tileSizePx);
final int additionalTilesNeededToTopOfCenter = (int)Math.ceil((float)centerMapTileScreenTop / tileSizePx); // i.e. "30 / 256" = 1;
final int additionalTilesNeededToBottomOfCenter = (int)Math.ceil((float)(viewHeight - centerMapTileScreenBottom) / tileSizePx);
final int mapTileUpperBound = (int)Math.pow(2, zoomLevel);
final int[] mapTileCoords = new int[]{centerMapTileCoords[MAPTILE_LATITUDE_INDEX], centerMapTileCoords[MAPTILE_LONGITUDE_INDEX]};
/* Draw all the MapTiles (from the upper left to the lower right). */
for(int y = -additionalTilesNeededToTopOfCenter; y <= additionalTilesNeededToBottomOfCenter; y++){
for(int x = -additionalTilesNeededToLeftOfCenter; x <= additionalTilesNeededToRightOfCenter; x++){
/* Add/substract the difference of the tile-position to the one of the center. */
mapTileCoords[MAPTILE_LATITUDE_INDEX] = MyMath.mod(centerMapTileCoords[MAPTILE_LATITUDE_INDEX] + y, mapTileUpperBound);
mapTileCoords[MAPTILE_LONGITUDE_INDEX] = MyMath.mod(centerMapTileCoords[MAPTILE_LONGITUDE_INDEX] + x, mapTileUpperBound);
/* Construct a URLString, which represents the MapTile. */
final String tileURLString = this.mRendererInfo.getTileURLString(mapTileCoords, zoomLevel);
/* Draw the MapTile 'i * tileSizePx' above of the centerMapTile */
final Bitmap currentMapTile = this.mTileProvider.getMapTile(tileURLString);
final int tileLeft = this.mTouchMapOffsetX + centerMapTileScreenLeft + (x * tileSizePx);
final int tileTop = this.mTouchMapOffsetY + centerMapTileScreenTop + (y * tileSizePx);
c.drawBitmap(currentMapTile, tileLeft, tileTop, this.mPaint);
if(DEBUGMODE){
// Draw frame around the tiles...
c.drawLine(tileLeft, tileTop, tileLeft + tileSizePx, tileTop, this.mPaint);
c.drawLine(tileLeft, tileTop, tileLeft, tileTop + tileSizePx, this.mPaint);
}
}
}
/* Draw all Overlays. */
for(OpenStreetMapViewOverlay osmvo : this.mOverlays)
osmvo.onManagedDraw(c, this);
this.mPaint.setStyle(Style.STROKE);
if (this.mMaxiMap != null) // If this is a MiniMap
c.drawRect(0, 0, viewWidth - 1, viewHeight - 1, this.mPaint);