protected void drawPointingdirection( Canvas canvas, MapView mapView, Location lastFix, GeoPoint myLocation) { Projection p = mapView.getProjection(); Point loc = p.toPixels(myLocation, null); int orientation = getOrientation(); // Pythagore double cb = 42; // canvas.getWidth();// Math.hypot(canvas.getWidth(), canvas.getHeight()); // canvas.drawText("Orientation " + getOrientation(), loc.x, loc.y, paintDirection); double orientationRad = Math.toRadians(orientation); double ca = Math.cos(orientationRad) * cb; double ab = Math.sqrt(cb * cb - ca * ca) * (Math.signum(orientation) * -1); // Point float startX = loc.x; float startY = (float) (loc.y - ca); float stopY = loc.y; // float stopY = (float) (loc.y + ca); float stopX = loc.x; if (orientation > 180) { startX = (float) (loc.x + ab); // stopX = (float) (loc.x - ab); } else { startX = (float) (loc.x - ab); // stopX = (float) (loc.x + ab); } // paintDirection.setStrokeMiter(5); canvas.drawLine(startX, startY, stopX, stopY, paintDirection); }
protected void drawMyLocation( Canvas canvas, MapView mapView, Location lastFix, GeoPoint myLocation) { Projection p = mapView.getProjection(); Point loc = p.toPixels(myLocation, null); // Orientation v2 // Canvas g = new Canvas( compassArrow ); // Paint p = new Paint( Paint.ANTI_ALIAS_FLAG ); // Matrix matrix = new Matrix(); // matrix.postRotate(orientation, (compassArrow.getWidth() / 2), (compassArrow.getHeight() / // 2)); // Bitmap resizedBitmap = Bitmap.createBitmap(compassArrow, 0, 0, compassArrow.getWidth(), // compassArrow.getHeight(), matrix, true); // canvas.drawBitmap(resizedBitmap, loc.x - (compassArrow.getWidth() / 2), loc.y - // (compassArrow.getHeight() / 2), paint); // canvas.drawBitmap(compassArrow, loc.x - (compassArrow.getWidth() / 2), loc.y- // (compassArrow.getHeight() / 2), paint); // Original Method float accuracy = p.metersToEquatorPixels(lastFix.getAccuracy()); if (accuracy > 10.0f) { canvas.drawCircle(loc.x, loc.y, accuracy, paintPosAccuracy); } canvas.drawCircle(loc.x, loc.y, 10, paintPos); }
/** * Animated equivalent to {@link MapController#scrollBy(int, int)}. Scroll by a given amount using * the default animation, in pixels. * * <p><strong>Limitations</strong>: This method internally uses {@link * MapController#animateTo(com.google.android.maps.GeoPoint)} which doesn't animate anything if * the point is really far (in pixels) from the current point. In this case, nothing will be * animated at all. * * @param mapView The {@link MapView} to scroll * @param dx The horizontal scroll amount in pixels. * @param dy The vertical scroll amount in pixels. */ public static void smoothScrollBy(MapView mapView, int dx, int dy) { final Projection projection = mapView.getProjection(); final Point tmpPoint = TEMP_POINT; projection.toPixels(mapView.getMapCenter(), tmpPoint); tmpPoint.offset(dx, dy); IGeoPoint geoPoint = projection.fromPixels(tmpPoint.x, tmpPoint.y); // mapView.getController().animateTo(geoPoint); mapView.getController().setCenter(geoPoint); }
protected void drawMyLocation( final Canvas canvas, final MapView mapView, final Location lastFix, final GeoPoint myLocation) { final Projection pj = mapView.getProjection(); pj.toMapPixels(mMyLocation, mMapCoords); if (mDrawAccuracyEnabled) { final float radius = pj.metersToEquatorPixels(lastFix.getAccuracy()); mCirclePaint.setAlpha(50); mCirclePaint.setStyle(Style.FILL); canvas.drawCircle(mMapCoords.x, mMapCoords.y, radius, mCirclePaint); mCirclePaint.setAlpha(150); mCirclePaint.setStyle(Style.STROKE); canvas.drawCircle(mMapCoords.x, mMapCoords.y, radius, mCirclePaint); } canvas.getMatrix(mMatrix); mMatrix.getValues(mMatrixValues); if (DEBUGMODE) { final float tx = (-mMatrixValues[Matrix.MTRANS_X] + 20) / mMatrixValues[Matrix.MSCALE_X]; final float ty = (-mMatrixValues[Matrix.MTRANS_Y] + 90) / mMatrixValues[Matrix.MSCALE_Y]; canvas.drawText("Lat: " + lastFix.getLatitude(), tx, ty + 5, mPaint); canvas.drawText("Lon: " + lastFix.getLongitude(), tx, ty + 20, mPaint); canvas.drawText("Cog: " + lastFix.getBearing(), tx, ty + 35, mPaint); canvas.drawText("Acc: " + lastFix.getAccuracy(), tx, ty + 50, mPaint); canvas.drawText("Kts: " + lastFix.getSpeed() / 1.94384449, tx, ty + 65, mPaint); } // TODO: read from compass if available for bearing if (lastFix.hasBearing()) { /* * Rotate the direction-Arrow according to the bearing we are driving. And draw it * to the canvas. */ directionRotater.setRotate( lastFix.getBearing(), DIRECTION_ARROW_CENTER_X, DIRECTION_ARROW_CENTER_Y); directionRotater.postTranslate(-DIRECTION_ARROW_CENTER_X, -DIRECTION_ARROW_CENTER_Y); directionRotater.postScale( 1 / mMatrixValues[Matrix.MSCALE_X], 1 / mMatrixValues[Matrix.MSCALE_Y]); directionRotater.postTranslate(mMapCoords.x, mMapCoords.y); canvas.drawBitmap(DIRECTION_ARROW, directionRotater, mPaint); } else { directionRotater.setTranslate(-NULLDIRECTION_ICON_CENTER_X, -NULLDIRECTION_ICON_CENTER_Y); directionRotater.postScale( 1 / mMatrixValues[Matrix.MSCALE_X], 1 / mMatrixValues[Matrix.MSCALE_Y]); directionRotater.postTranslate(mMapCoords.x, mMapCoords.y); canvas.drawBitmap(NULLDIRECTION_ICON, directionRotater, mPaint); } }
public boolean onSnapToItem( final int x, final int y, final Point snapPoint, final MapView mapView) { if (this.mLocation != null) { final Projection pj = mapView.getProjection(); pj.toMapPixels(new GeoPoint(mLocation), mMapCoords); snapPoint.x = mMapCoords.x; snapPoint.y = mMapCoords.y; final double xDiff = x - mMapCoords.x; final double yDiff = y - mMapCoords.y; final boolean snap = xDiff * xDiff + yDiff * yDiff < 64; if (DEBUGMODE) { logger.debug("snap=" + snap); } return snap; } else { return false; } }
@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(Canvas canvas, MapView mapView, boolean shadow) { try { Projection projection = mapView.getProjection(); if (!shadow) { GeoPoint geoPoint = new GeoPoint(latituded, longituded); Point point = new Point(); projection.toPixels(geoPoint, point); RectF oval = new RectF(point.x - mRadius, point.y - mRadius, point.x + mRadius, point.y + mRadius); Paint paint = new Paint(); paint.setARGB(250, 255, 255, 255); paint.setAntiAlias(true); paint.setFakeBoldText(true); paint.setTextSize(30); paint.setColor(Color.RED); paint.setTypeface(Typeface.SERIF); Paint backPaint = new Paint(); backPaint.setARGB(250, 50, 50, 50); backPaint.setAntiAlias(true); backPaint.setColor(Color.BLACK); int countString = description.length() * 17; RectF backOval = new RectF( point.x + 5 + mRadius, point.y - mRadius - 15, point.x + countString, point.y + 25); canvas.drawOval(oval, paint); canvas.drawRoundRect(backOval, 5, 5, backPaint); canvas.drawText(" " + description, point.x + 2 * mRadius, point.y + 10, paint); } } catch (Exception e) { Log.i("Log : ", "Exception : " + e.getMessage()); } }
@Override public boolean onSingleTapUp(final MotionEvent event, final MapView mapView) { Projection pj = mapView.getProjection(); IGeoPoint p = pj.fromPixels(event.getX(), event.getY()); // Store whether prior popup was displayed so we can call invalidate() & // remove it if necessary. boolean onHandleEvent = false; boolean isRemovePriorPopup = selectedGeoTrack != null; long idPriorStation = -1; if (isRemovePriorPopup) { idPriorStation = selectedGeoTrack.getId(); } // Next test whether a new popup should be displayed selectedGeoTrack = getHitMapLocation(mapView, p); if (isRemovePriorPopup && selectedGeoTrack != null && idPriorStation == selectedGeoTrack.getId()) { selectedGeoTrack = null; hideBubble(mapView); onHandleEvent = true; } if (selectedGeoTrack != null) { openBubble(mapView, selectedGeoTrack); onHandleEvent = true; } else if (isRemovePriorPopup) { hideBubble(mapView); } // if (isRemovePriorPopup || selectedGeoTrack != null) { // // TODO hideBubble(); // mapView.invalidate(); // onHandleEvent = true; // } // ?? balloonView return onHandleEvent; }
private GeoTrack getHitMapLocation(MapView mapView, IGeoPoint tapPoint) { // Track which MapLocation was hit...if any GeoTrack result = null; RectF tapPointHitTestRect = new RectF(); Point tapPointTestScreenCoords = new Point(); int zoonLevel = mapView.getZoomLevel(); int selectRadius = zoonLevel + 6; Projection pj = mapView.getProjection(); for (GeoTrack testLocation : geoTracks) { if (!seletedRangeActivated || (testLocation.time >= seletedRangeBeginTimeInMs && testLocation.time <= seletedRangeEndTimeInMs)) { // Translate the MapLocation's lat/long coordinates to screen // coordinates pj.toPixels(testLocation.asGeoPoint(), tapPointTestScreenCoords); // Create a 'hit' testing Rectangle w/size and coordinates of // our // icon // Set the 'hit' testing Rectangle with the size and coordinates // of // our on screen icon tapPointHitTestRect.set(-selectRadius, -selectRadius, selectRadius, selectRadius); tapPointHitTestRect.offset(tapPointTestScreenCoords.x, tapPointTestScreenCoords.y); // Finally test for a match between our 'hit' Rectangle and the // location clicked by the user pj.toPixels(tapPoint, tapPointTestScreenCoords); if (tapPointHitTestRect.contains(tapPointTestScreenCoords.x, tapPointTestScreenCoords.y)) { result = testLocation; // break; } } } return result; }
/** This function does some fancy drawing, could be shortened a lot. */ @Override public void draw(final Canvas canvas, final MapView mapView, final boolean shadow) { try { /* DEBUG Output */ // final long startMs = System.currentTimeMillis(); // long routedrawStartMs = 0, routedrawEndMs = 0; /* END DEBUG Output */ /* Get the width/height of the underlying MapView.*/ final int mapViewWidth = this.myDDMapActivity.getMapViewWidth(); final int mapViewHeight = this.myDDMapActivity.getMapViewHeight(); // final GeoPoint curMapCenter = mapView.getMapCenter(); /* Will hold various screen-coordinates. */ final Point screenCoords = new Point(); final Navigator nav = this.myDDMapActivity.getNavigator(); /* Method in our custom map view * to return the DrivingDirection object. */ this.mRoute = this.myDDMapActivity.getRoute(); if (this.mRoute != null && this.mStaticNavCurrentTurnPointIndex != Constants.NOT_SET) { final int currentZoomLevel = this.myDDMapActivity.getZoomLevel(); final int nextRouteIndex; final int nextTurnPointIndex; final int nextTurnIndexInRoute; final int turnAngle; final GeoPoint myProjectedLocationGeoPoint; final List<RouteInstruction> turnPointsRaw = this.mRoute.getRouteInstructions(); if (!this.mRealtimeNav) { final RouteInstruction currentRouteInstruction = turnPointsRaw.get(this.mStaticNavCurrentTurnPointIndex); final GeoPoint liteVersionCurrentTurnPoint = currentRouteInstruction.getTurnPoint(); nextRouteIndex = currentRouteInstruction.getFirstMotherPolylineIndex(); nextTurnPointIndex = Math.min(this.mStaticNavCurrentTurnPointIndex + 1, turnPointsRaw.size() - 1); final RouteInstruction nextTurnPoint = turnPointsRaw.get(nextTurnPointIndex); nextTurnIndexInRoute = nextTurnPoint.getFirstMotherPolylineIndex(); myProjectedLocationGeoPoint = liteVersionCurrentTurnPoint; turnAngle = (int) nextTurnPoint.getAngle(); } else { nextRouteIndex = nav.getNextRoutePointIndex(); nextTurnPointIndex = nav.getNextTurnPointIndex(); nextTurnIndexInRoute = Math.max(0, nav.getNextTurnPointIndexInRoute()); turnAngle = (int) nav.getTurnAngle(); myProjectedLocationGeoPoint = nav.getLastKnownLocationProjectedGeoPoint(); } final GeoPoint myCurrentLocationGeoPoint = this.myDDMapActivity.getLastKnownLocationAsGeoPoint(true); /* First get Start end End Point of the route. */ final GeoPoint startPoint = this.mRoute.getStart(); final GeoPoint endPoint = this.mRoute.getDestination(); final Projection pj = mapView.getProjection(); final ManagedLinePath pathDone = new ManagedLinePath(); final ManagedLinePath pathCurrentSegment = new ManagedLinePath(); final ArrayList<Path> pathTurnSegments = new ArrayList<Path>(); final ArrayList<Path> pathTurnSegmentsPeaks = new ArrayList<Path>(); final ManagedLinePath pathUpcoming = new ManagedLinePath(); /* DEBUG Output */ { // routedrawStartMs = routedrawEndMs = System.currentTimeMillis(); } /* END DEBUG Output */ /* Check to see if the route is too long. */ if (nav.isReady()) { /* Retrieve all (Map)Points of the route Found. */ final List<GeoPoint> polyLine = this.mRoute.getPolyLine(); // final long startTransform = System.currentTimeMillis(); // canvas.drawText("nri: " + nextRouteIndex, 2, 40, this.pathDonePaint); // canvas.drawText("nti: " + nextTurnPointIndex, 2, 50, this.pathDonePaint); // canvas.drawText("ntiir: " + nextTurnIndexInRoute, 2, 60, this.pathDonePaint); if (nextRouteIndex != Constants.NOT_SET && polyLine != null) { /* Loop through all MapPoints returned. */ final int increment = (int) (Math.max(1, Math.pow(2, 14 - currentZoomLevel))); final int lastIndexPathDone = Math.max( 0, (myProjectedLocationGeoPoint != null) ? nextRouteIndex - 1 : nextRouteIndex); // -1 when there is the projection in between final int firstIndexPathDone = Math.max(0, lastIndexPathDone - 100 * increment); final int firstIndexPathCurrent = nextRouteIndex; final int lastIndexPathCurrent = nextTurnIndexInRoute; final int firstIndexPathUpcoming = lastIndexPathCurrent; final int lastIndexPathUPcoming = Math.min(firstIndexPathUpcoming + 100 * increment, polyLine.size() - 1); if (firstIndexPathDone != lastIndexPathDone) { for (int i = firstIndexPathDone; i <= lastIndexPathDone; i += increment) { pathDone.lineTo(pj.toMapPixels(polyLine.get(i), screenCoords)); } } pathDone.lineTo( pj.toMapPixels( polyLine.get(lastIndexPathDone), screenCoords)); // Ensures, that the this path and the next are connected. if (myProjectedLocationGeoPoint != null) { pj.toMapPixels(myProjectedLocationGeoPoint, screenCoords); pathDone.lineTo(screenCoords); pathCurrentSegment.lineTo(screenCoords); } if (firstIndexPathCurrent != lastIndexPathCurrent) { for (int i = firstIndexPathCurrent; i <= lastIndexPathCurrent; i += increment) { pathCurrentSegment.lineTo(pj.toMapPixels(polyLine.get(i), screenCoords)); } } pathCurrentSegment.lineTo( pj.toMapPixels( polyLine.get(lastIndexPathCurrent), screenCoords)); // Ensures, that the this path and the next are connected. if (firstIndexPathUpcoming != lastIndexPathUPcoming) { for (int i = firstIndexPathUpcoming; i <= lastIndexPathUPcoming; i += increment) { pathUpcoming.lineTo(pj.toMapPixels(polyLine.get(i), screenCoords)); } } // final long endTransform = System.currentTimeMillis(); // // Log.d(Constants.DEBUGTAG, "Transform: " + (endTransform - startTransform) + " // ms"); /* Used for transforming all paths. */ final float scaleFactor = (this.mapRotationDegree == Constants.NOT_SET) ? 1.0f : FloatMath.sqrt(mapViewHeight * mapViewHeight + mapViewWidth * mapViewWidth) / Math.min(mapViewHeight, mapViewWidth); /* Calculate the turn-segment-arrow. */ if (currentZoomLevel >= MIN_ZOOMLEVEL_FOR_ARROWS) { { /* next Arrow */ final Path arrowPath = new Path(); final Path arrowPeakPath = new Path(); try { ArrowPathCreator.createArrowOverIndex( pj, nextTurnIndexInRoute, polyLine, arrowPath, arrowPeakPath, scaleFactor, currentZoomLevel, turnAngle); pathTurnSegments.add(arrowPath); pathTurnSegmentsPeaks.add(arrowPeakPath); } catch (final IndexOutOfBoundsException ioobe) { // Log.e(DEBUGTAG, "Error drawing arrow. index=" + nextTurnIndexInRoute + " // polyline length = " + polyLine.size()); } { // TODO Remove on release // final int ARROW_RENDER_ZOOMLEVEL = 15; // // Projection pj2 = mapView.new Projection(ARROW_RENDER_ZOOMLEVEL, 0, 0); // // final Path arrowPathDummy = new Path(); // final Path arrowPeakPathDummy = new Path(); // ArrowPathCreator.createArrowOverIndex(pj2, nextTurnIndexInRoute, // polyLine, arrowPathDummy, arrowPeakPathDummy, 1, ARROW_RENDER_ZOOMLEVEL, // turnAngle); // // final Bitmap b = ArrowPathCreator.drawToBitmap(arrowPathDummy, // arrowPeakPathDummy); // canvas.drawBitmap(b, 250,250, new Paint()); } } final int between = nav.getDistanceBetweenNextAndUpperNextTurnPoint(); if (between < 1500 && nextTurnPointIndex != Constants.NOT_SET) { /* upperNext Arrow */ final int upperNextTurnPointIndex = nextTurnPointIndex + 1; if (upperNextTurnPointIndex > 0 && upperNextTurnPointIndex < this.mRoute.getRouteInstructions().size()) { final Path arrowPath = new Path(); final Path arrowPeakPath = new Path(); final RouteInstruction upperNextTurnPoint = turnPointsRaw.get(upperNextTurnPointIndex); final float upperNextTurnAngle = upperNextTurnPoint.getAngle(); final int upperNextTurnIndexInRoute = upperNextTurnPoint.getFirstMotherPolylineIndex(); try { ArrowPathCreator.createArrowOverIndex( pj, upperNextTurnIndexInRoute, polyLine, arrowPath, arrowPeakPath, scaleFactor, currentZoomLevel, upperNextTurnAngle); pathTurnSegments.add(arrowPath); pathTurnSegmentsPeaks.add(arrowPeakPath); } catch (final IndexOutOfBoundsException ioobe) { // Log.e(DEBUGTAG, "Error drawing arrow. index=" + // upperNextTurnIndexInRoute + " polyline length = " + polyLine.size()); } } } } } /* Draw the already driven route to the canvas. */ // if(!canvas.quickReject(pathDone, EdgeType.BW)) canvas.drawPath(pathDone, this.mPathDonePaint); /* Draw the rest Route to the canvas. */ // if(!canvas.quickReject(pathUpcoming, EdgeType.BW)) canvas.drawPath(pathUpcoming, this.mPathUpcomingPaint); /* Draw the current Route Segment to the canvas. */ // if(!canvas.quickReject(pathCurrentSegment, EdgeType.AA)) canvas.drawPath(pathCurrentSegment, this.mPathCurrentSegmentPaint); /* Draw the Turn Segment to the canvas. */ for (int j = pathTurnSegments.size() - 1; j >= 0; j--) { canvas.drawPath(pathTurnSegments.get(j), this.mPathTurnSegmentOutlinePaint); canvas.drawPath(pathTurnSegments.get(j), this.mPathTurnSegmentPaint); canvas.drawPath(pathTurnSegmentsPeaks.get(j), this.mPathTurnSegmentPeakOutlinePaint); canvas.drawPath(pathTurnSegmentsPeaks.get(j), this.mPathTurnSegmentPeakPaint); } // DEBUG Output { // int minLatitude = // this.mRoute.getLatitudeMinSpans()[nav.getNextRoutePointIndex()]; // int maxLatitude = // this.mRoute.getLatitudeMaxSpans()[nav.getNextRoutePointIndex()]; // int minLongitude = // this.mRoute.getLongitudeMinSpans()[nav.getNextRoutePointIndex()]; // int maxLongitude = // this.mRoute.getLongitudeMaxSpans()[nav.getNextRoutePointIndex()]; // //// Log.d(DEBUGTAG, "nextRoutePointIndex=" + nav.getNextRoutePointIndex()); // // int myLat = myCurrentLocationMapPoint.getLatitude(); // int myLon = myCurrentLocationMapPoint.getLongitude(); // // maxLatitude = Math.max(myLat, maxLatitude); // minLatitude = Math.min(myLat, minLatitude); // maxLongitude = Math.max(myLon, maxLongitude); // minLongitude = Math.min(myLon, minLongitude); // // int x1, x2, y1, y2; // pj.toMapPixels(new GeoPoint(minLatitude, minLongitude), screenCoords); // x1 = screenCoords.x; // y1 = screenCoords.y; // // pj.toMapPixels(new GeoPoint(maxLatitude, maxLongitude), screenCoords); // x2 = screenCoords.x; // y2 = screenCoords.y; //// Log.d(DEBUGTAG, "x1=" + x1 + ", y1=" + y1 + ", x2=" + x2 + ", y2="+ y2); // Paint p = new Paint(); // p.setStrokeWidth(3); // p.setARGB(255,255,0,0); // p.setStyle(Style.STROKE); // canvas.drawRect(new Rect(x1,y1,x2,y2), p); } // END DEBUG Output { /* Print Pin-MArkers. */ /* Finally draw a fancy PIN to mark the end... */ pj.toMapPixels(endPoint, screenCoords); canvas.drawBitmap( this.MARKER_END, screenCoords.x - MARKER_DESTINATION_HOTSPOT_X, screenCoords.y - MARKER_DESTINATION_HOTSPOT_Y, this.mMarkerPaint); /* ...for all via-points. */ final List<GeoPoint> vias = this.mRoute.getVias(); for (final GeoPoint mpVia : vias) { pj.toMapPixels(mpVia, screenCoords); canvas.drawBitmap( this.MARKER_VIA, screenCoords.x - MARKER_VIA_HOTSPOT_X, screenCoords.y - MARKER_VIA_HOTSPOT_Y, this.mMarkerPaint); } /* ...and the start of the route.*/ pj.toMapPixels(startPoint, screenCoords); canvas.drawBitmap( this.MARKER_START, screenCoords.x - MARKER_START_HOTSPOT_X, screenCoords.y - MARKER_START_HOTSPOT_Y, this.mMarkerPaint); } { /* DEBUG Output */ // routedrawEndMs = System.currentTimeMillis(); } /* END DEBUG Output */ } final AbstractAndNavLocationProvider andNavLocationProvider = this.myDDMapActivity.getAndNavLocationProvider(); if (myCurrentLocationGeoPoint != null) { /* Draw ourself to our real location. */ pj.toMapPixels(myCurrentLocationGeoPoint, screenCoords); /* Draw the HorizontalPositioningError if we have a location. */ if (this.mShowAccuracy) { final float accuracyRadius = (andNavLocationProvider.hasHorizontalPositioningError()) ? pj.metersToEquatorPixels( andNavLocationProvider.getHorizontalPositioningError()) : RADIUS_NO_ACCURACY; /* Only draw if the DirectionArrow doesn't cover it. */ if (accuracyRadius > 8) { /* Draw the inner shadow. */ this.mAccuracyPaint.setAntiAlias(false); this.mAccuracyPaint.setAlpha(30); this.mAccuracyPaint.setStyle(Style.FILL); canvas.drawCircle( screenCoords.x, screenCoords.y, accuracyRadius, this.mAccuracyPaint); /* Draw the edge. */ this.mAccuracyPaint.setAntiAlias(true); this.mAccuracyPaint.setAlpha(150); this.mAccuracyPaint.setStyle(Style.STROKE); canvas.drawCircle( screenCoords.x, screenCoords.y, accuracyRadius, this.mAccuracyPaint); } } /* Get the bearing if available. */ final boolean hasBearing = andNavLocationProvider.hasBearing(); final float directionBearing = (hasBearing) ? andNavLocationProvider.getBearing() : 0; /* Rotate the direction-Arrow according to the bearing we are driving. And draw it to the canvas. */ this.mDirectionRotater.setRotate( directionBearing, this.DIRECTION_ARROW_CENTER_X, this.DIRECTION_ARROW_CENTER_Y); final Bitmap rotatedDirection = Bitmap.createBitmap( this.DIRECTION_ARROW, 0, 0, this.DIRECTION_ARROW_WIDTH, this.DIRECTION_ARROW_HEIGHT, this.mDirectionRotater, true); /* Calculate the deltas needed after the rotation, to paint the hotspot of the directionarrow on the actual location. */ final float py = this.DIRECTION_ARROW_HOTSPOT_Y - this.DIRECTION_ARROW_CENTER_Y; final float dx; final float dy; if (py < 0.001 || py > 0.001) { final float alpha = MathConstants.DEG2RAD * (-directionBearing + 90f); dx = FloatMath.cos(alpha) * py; dy = FloatMath.sin(alpha) * py; } else { dx = 0; dy = 0; } canvas.drawBitmap( rotatedDirection, screenCoords.x - rotatedDirection.getWidth() / 2 + dx, screenCoords.y - rotatedDirection.getHeight() / 2 - dy, this.mDirectionRotatorPaint); } { /* DEBUG Output */ // long endMs = System.currentTimeMillis(); // // this.debugDrawSum += endMs - startMs; // this.debugDrawCount++; // Log.d(DEBUGTAG, "GUI: " + (endMs - startMs) + " ms [Avg: " + (this.debugDrawSum / // this.debugDrawCount) + " ms]" // + " [Route: " + (routedrawEndMs - routedrawStartMs) + " ms]"); } /* END DEBUG Output */ } } catch (final Exception e) { Log.e(Constants.DEBUGTAG, "Error in directionsOverlay", e); // Exceptor.e("Error in directionsOverlay", e, this.myDDMapActivity); } }
@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); }
private void createScaleBarPicture(final MapView mapView) { // We want the scale bar to be as long as the closest round-number miles/kilometers // to 1-inch at the latitude at the current center of the screen. projection = mapView.getProjection(); if (projection == null) { return; } // Two points, 1-inch apart in x/latitude, centered on screen IGeoPoint p1 = projection.fromPixels((screenWidth / 2) - (xdpi / 2), screenHeight / 2); IGeoPoint p2 = projection.fromPixels((screenWidth / 2) + (xdpi / 2), screenHeight / 2); final int xMetersPerInch = ((GeoPoint) p1).distanceTo(p2); p1 = projection.fromPixels(screenWidth / 2, (screenHeight / 2) - (ydpi / 2)); p2 = projection.fromPixels(screenWidth / 2, (screenHeight / 2) + (ydpi / 2)); final int yMetersPerInch = ((GeoPoint) p1).distanceTo(p2); final Canvas canvas = scaleBarPicture.beginRecording((int) xdpi, (int) ydpi); if (latitudeBar) { final String xMsg = scaleBarLengthText(xMetersPerInch, imperial, nautical); final Rect xTextRect = new Rect(); textPaint.getTextBounds(xMsg, 0, xMsg.length(), xTextRect); final int textSpacing = (int) (xTextRect.height() / 5.0); canvas.drawRect(0, 0, xdpi, lineWidth, barPaint); canvas.drawRect( xdpi, 0, xdpi + lineWidth, xTextRect.height() + lineWidth + textSpacing, barPaint); if (!longitudeBar) { canvas.drawRect(0, 0, lineWidth, xTextRect.height() + lineWidth + textSpacing, barPaint); } canvas.drawText( xMsg, xdpi / 2 - xTextRect.width() / 2, xTextRect.height() + lineWidth + textSpacing, textPaint); } if (longitudeBar) { final String yMsg = scaleBarLengthText(yMetersPerInch, imperial, nautical); final Rect yTextRect = new Rect(); textPaint.getTextBounds(yMsg, 0, yMsg.length(), yTextRect); final int textSpacing = (int) (yTextRect.height() / 5.0); canvas.drawRect(0, 0, lineWidth, ydpi, barPaint); canvas.drawRect( 0, ydpi, yTextRect.height() + lineWidth + textSpacing, ydpi + lineWidth, barPaint); if (!latitudeBar) { canvas.drawRect(0, 0, yTextRect.height() + lineWidth + textSpacing, lineWidth, barPaint); } final float x = yTextRect.height() + lineWidth + textSpacing; final float y = ydpi / 2 + yTextRect.width() / 2; canvas.rotate(-90, x, y); canvas.drawText(yMsg, x, y + textSpacing, textPaint); } scaleBarPicture.endRecording(); }
/** * 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); }