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); }
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); } }
/** 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); } }