@Override public void draw(final Canvas c, final MapView mapView, final boolean shadow) { if (shadow) { return; } // If map views is animating, don't update, scale will be wrong. if (mapView.isAnimating()) { return; } final int zoomLevel = mapView.getZoomLevel(); if (zoomLevel >= minZoom) { final Projection projection = mapView.getProjection(); if (projection == null) { return; } final IGeoPoint center = projection.fromPixels((screenWidth / 2), screenHeight / 2); if (zoomLevel != lastZoomLevel || (int) (center.getLatitudeE6() / 1E6) != (int) (lastLatitude / 1E6)) { lastZoomLevel = zoomLevel; lastLatitude = center.getLatitudeE6(); createScaleBarPicture(mapView); } mBounds.set(projection.getScreenRect()); mBounds.offset((int) xOffset, (int) yOffset); mBounds.set( mBounds.left, mBounds.top, mBounds.left + scaleBarPicture.getWidth(), mBounds.top + scaleBarPicture.getHeight()); c.drawPicture(scaleBarPicture, mBounds); } }
@Override protected void draw(final Canvas pC, final MapView pOsmv, final boolean shadow) { if (shadow) { return; } // Don't draw if we are animating if (pOsmv.isAnimating()) { return; } // Calculate the half-world size final Projection projection = pOsmv.getProjection(); final int zoomLevel = projection.getZoomLevel(); mWorldSize_2 = TileSystem.MapSize(zoomLevel) / 2; // Save the Mercator coordinates of what is on the screen mViewportRect.set(projection.getScreenRect()); mViewportRect.offset(mWorldSize_2, mWorldSize_2); // Start calculating the tile area with the current viewport mTileArea.set(mViewportRect); // Get the target zoom level difference. int miniMapZoomLevelDifference = getZoomDifference(); // Make sure the zoom level difference isn't below the minimum zoom level if (zoomLevel - getZoomDifference() < mTileProvider.getMinimumZoomLevel()) { miniMapZoomLevelDifference += zoomLevel - getZoomDifference() - mTileProvider.getMinimumZoomLevel(); } // Shift the screen coordinates into the target zoom level mTileArea.set( mTileArea.left >> miniMapZoomLevelDifference, mTileArea.top >> miniMapZoomLevelDifference, mTileArea.right >> miniMapZoomLevelDifference, mTileArea.bottom >> miniMapZoomLevelDifference); // Limit the area we are interested in for tiles to be the MAP_WIDTH by MAP_HEIGHT and // centered on the center of the screen mTileArea.set( mTileArea.centerX() - (getWidth() / 2), mTileArea.centerY() - (getHeight() / 2), mTileArea.centerX() + (getWidth() / 2), mTileArea.centerY() + (getHeight() / 2)); // Get the area where we will draw the minimap in screen coordinates mMiniMapCanvasRect.set( mViewportRect.right - getPadding() - getWidth(), mViewportRect.bottom - getPadding() - getHeight(), mViewportRect.right - getPadding(), mViewportRect.bottom - getPadding()); mMiniMapCanvasRect.offset(-mWorldSize_2, -mWorldSize_2); // Draw a solid background where the minimap will be drawn with a 2 pixel inset pC.drawRect( mMiniMapCanvasRect.left - 2, mMiniMapCanvasRect.top - 2, mMiniMapCanvasRect.right + 2, mMiniMapCanvasRect.bottom + 2, mPaint); super.drawTiles( pC, projection.getZoomLevel() - miniMapZoomLevelDifference, TileSystem.getTileSize(), mTileArea); }
/** * This method draws the line. Note - highly optimized to handle long paths, proceed with care. * Should be fine up to 10K points. */ @Override protected void draw(final Canvas canvas, final MapView mapView, final boolean shadow) { if (shadow) { return; } if (this.mPoints.size() < 2) { // nothing to paint return; } final Projection pj = mapView.getProjection(); // precompute new points to the intermediate projection. final int size = this.mPoints.size(); while (this.mPointsPrecomputed < size) { final Point pt = this.mPoints.get(this.mPointsPrecomputed); pj.toMapPixelsProjected(pt.x, pt.y, pt); this.mPointsPrecomputed++; } Point screenPoint0 = null; // points on screen Point screenPoint1 = null; Point projectedPoint0; // points from the points list Point projectedPoint1; // clipping rectangle in the intermediate projection, to avoid performing projection. final Rect clipBounds = pj.fromPixelsToProjected(pj.getScreenRect()); mPath.rewind(); projectedPoint0 = this.mPoints.get(size - 1); mLineBounds.set(projectedPoint0.x, projectedPoint0.y, projectedPoint0.x, projectedPoint0.y); for (int i = size - 2; i >= 0; i--) { // compute next points projectedPoint1 = this.mPoints.get(i); mLineBounds.union(projectedPoint1.x, projectedPoint1.y); if (!Rect.intersects(clipBounds, mLineBounds)) { // skip this line, move to next point projectedPoint0 = projectedPoint1; screenPoint0 = null; continue; } // the starting point may be not calculated, because previous segment was out of clip // bounds if (screenPoint0 == null) { screenPoint0 = pj.toMapPixelsTranslated(projectedPoint0, this.mTempPoint1); mPath.moveTo(screenPoint0.x, screenPoint0.y); } screenPoint1 = pj.toMapPixelsTranslated(projectedPoint1, this.mTempPoint2); // skip this point, too close to previous point if (Math.abs(screenPoint1.x - screenPoint0.x) + Math.abs(screenPoint1.y - screenPoint0.y) <= 1) { continue; } mPath.lineTo(screenPoint1.x, screenPoint1.y); // update starting point to next position projectedPoint0 = projectedPoint1; screenPoint0.x = screenPoint1.x; screenPoint0.y = screenPoint1.y; mLineBounds.set(projectedPoint0.x, projectedPoint0.y, projectedPoint0.x, projectedPoint0.y); } canvas.drawPath(mPath, this.mPaint); }