2011-12-04 70 views

回答

1

这里是我的解决办法:顶

import android.content.Context; 
import android.graphics.*; 
import android.graphics.drawable.BitmapDrawable; 
import android.util.Log; 
import com.google.android.maps.GeoPoint; 
import com.google.android.maps.MapView; 
import com.google.android.maps.Overlay; 
import com.google.android.maps.Projection; 
import com.jettaxi.R; 

import java.util.ArrayList; 

public class ArrowDirectionsOverlay extends Overlay { 
    private Context context; 

    private ArrayList<GeoPoint> directions; 
    private Bitmap arrowBitmap; 
    private int maximalPositionX; 
    private int maximalPositionY; 

    public ArrowDirectionsOverlay(Context context) { 
     this.context = context; 

     directions = new ArrayList<GeoPoint>(); 

     arrowBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.direction); 
    } 

    public void addDirectionPoint(GeoPoint destination) { 
     directions.add(destination); 
    } 

    public void clear() { 
     directions.clear(); 
    } 

    private double getAngle(GeoPoint center, GeoPoint destination) { 
     double lat1 = center.getLatitudeE6()/1000000.; 
     double lon1 = center.getLongitudeE6()/1000000.; 
     double lat2 = destination.getLatitudeE6()/1000000.; 
     double lon2 = destination.getLongitudeE6()/1000000.; 

     int MAXITERS = 20; 
     // Convert lat/long to radians 
     lat1 *= Math.PI/180.0; 
     lat2 *= Math.PI/180.0; 
     lon1 *= Math.PI/180.0; 
     lon2 *= Math.PI/180.0; 

     double a = 6378137.0; // WGS84 major axis 
     double b = 6356752.3142; // WGS84 semi-major axis 
     double f = (a - b)/a; 
     double aSqMinusBSqOverBSq = (a * a - b * b)/(b * b); 

     double L = lon2 - lon1; 
     double A = 0.0; 
     double U1 = Math.atan((1.0 - f) * Math.tan(lat1)); 
     double U2 = Math.atan((1.0 - f) * Math.tan(lat2)); 

     double cosU1 = Math.cos(U1); 
     double cosU2 = Math.cos(U2); 
     double sinU1 = Math.sin(U1); 
     double sinU2 = Math.sin(U2); 
     double cosU1cosU2 = cosU1 * cosU2; 
     double sinU1sinU2 = sinU1 * sinU2; 

     double sigma = 0.0; 
     double deltaSigma = 0.0; 
     double cosSqAlpha = 0.0; 
     double cos2SM = 0.0; 
     double cosSigma = 0.0; 
     double sinSigma = 0.0; 
     double cosLambda = 0.0; 
     double sinLambda = 0.0; 

     double lambda = L; // initial guess 
     for (int iter = 0; iter < MAXITERS; iter++) { 
      double lambdaOrig = lambda; 
      cosLambda = Math.cos(lambda); 
      sinLambda = Math.sin(lambda); 
      double t1 = cosU2 * sinLambda; 
      double t2 = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda; 
      double sinSqSigma = t1 * t1 + t2 * t2; // (14) 
      sinSigma = Math.sqrt(sinSqSigma); 
      cosSigma = sinU1sinU2 + cosU1cosU2 * cosLambda; // (15) 
      sigma = Math.atan2(sinSigma, cosSigma); // (16) 
      double sinAlpha = (sinSigma == 0) ? 0.0 : 
        cosU1cosU2 * sinLambda/sinSigma; // (17) 
      cosSqAlpha = 1.0 - sinAlpha * sinAlpha; 
      cos2SM = (cosSqAlpha == 0) ? 0.0 : 
        cosSigma - 2.0 * sinU1sinU2/cosSqAlpha; // (18) 

      double uSquared = cosSqAlpha * aSqMinusBSqOverBSq; // defn 
      A = 1 + (uSquared/16384.0) * // (3) 
        (4096.0 + uSquared * 
          (-768 + uSquared * (320.0 - 175.0 * uSquared))); 
      double B = (uSquared/1024.0) * // (4) 
        (256.0 + uSquared * 
          (-128.0 + uSquared * (74.0 - 47.0 * uSquared))); 
      double C = (f/16.0) * 
        cosSqAlpha * 
        (4.0 + f * (4.0 - 3.0 * cosSqAlpha)); // (10) 
      double cos2SMSq = cos2SM * cos2SM; 
      deltaSigma = B * sinSigma * // (6) 
        (cos2SM + (B/4.0) * 
          (cosSigma * (-1.0 + 2.0 * cos2SMSq) - 
            (B/6.0) * cos2SM * 
              (-3.0 + 4.0 * sinSigma * sinSigma) * 
              (-3.0 + 4.0 * cos2SMSq))); 

      lambda = L + 
        (1.0 - C) * f * sinAlpha * 
          (sigma + C * sinSigma * 
            (cos2SM + C * cosSigma * 
              (-1.0 + 2.0 * cos2SM * cos2SM))); // (11) 

      double delta = (lambda - lambdaOrig)/lambda; 
      if (Math.abs(delta) < 1.0e-12) { 
       break; 
      } 
     } 

     float distance = (float) (b * A * (sigma - deltaSigma)); 
     float initialBearing = (float) Math.atan2(cosU2 * sinLambda, 
       cosU1 * sinU2 - sinU1 * cosU2 * cosLambda); 
     initialBearing *= 180.0/Math.PI; 
     float finalBearing = (float) Math.atan2(cosU1 * sinLambda, 
       -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda); 
     finalBearing *= 180.0/Math.PI; 

     return finalBearing; 
    } 

    private void drawArrow(Canvas canvas, MapView mapView, GeoPoint destination) { 
     Point screenPts = mapView.getProjection().toPixels(destination, null); 

     int deltaX = mapView.getMapCenter().getLatitudeE6() - destination.getLatitudeE6(); 
     int deltaY = mapView.getMapCenter().getLongitudeE6() - destination.getLongitudeE6(); 

     double angle = getAngle(mapView.getMapCenter(), destination); 
     double tan = Math.tan(Math.toRadians(angle)); 

     Matrix matrix = new Matrix(); 
     matrix.postRotate((float) angle); 
     Bitmap rotatedBmp = Bitmap.createBitmap(
       arrowBitmap, 
       0, 0, 
       arrowBitmap.getWidth(), 
       arrowBitmap.getHeight(), 
       matrix, 
       true 
     ); 

     int currentPositionX = screenPts.x - (rotatedBmp.getWidth()/2); 
     int currentPositionY = screenPts.y - (rotatedBmp.getHeight()/2); 

     if ((currentPositionX < 0) || (currentPositionY < 0) || 
       (currentPositionX > maximalPositionX) || (currentPositionY > maximalPositionY)) { 

      int arrowPositionX = (int) (mapView.getWidth()/2 - Math.signum(deltaX) * mapView.getHeight()/2 * tan); 
      arrowPositionX = Math.min(Math.max(arrowPositionX, 0), maximalPositionX); 
      int arrowSpanX = (int) (mapView.getWidth()/2.); 

      int arrowPositionY = (int) (mapView.getHeight()/2 + Math.signum(deltaY) * arrowSpanX/tan); 
      arrowPositionY = Math.min(Math.max(arrowPositionY, 0), maximalPositionY); 

      canvas.drawBitmap(
        rotatedBmp, 
        arrowPositionX, 
        arrowPositionY, 
        null 
      ); 
     } 
    } 

    public void draw(Canvas canvas, MapView mapView, boolean shadow) { 
     super.draw(canvas, mapView, shadow); 

     maximalPositionX = mapView.getWidth() - arrowBitmap.getWidth(); 
     maximalPositionY = mapView.getHeight() - arrowBitmap.getHeight(); 

     for (GeoPoint geoPoint : directions) { 
      drawArrow(canvas, mapView, geoPoint); 
     } 
    } 
} 

位图箭头指向我的情况

0

我的解决方案是搜索距离用户当前位置一定距离内的感兴趣的地方(在本例中为咖啡店)。这个距离可能是您当前位置的北部,南部,东部或西部的“屏幕” - 屏幕距离取决于您的缩放级别。不在当前屏幕上的商店将通过放置在屏幕边缘上的箭头来表示,其中方向设置在当前位置和商店之间。

+0

我有兴趣与屏幕边缘的箭头。你能提供你的覆盖范例吗? – skayred

+0

我已经做了几件事情与地图,但不是这样,所以我没有一个例子。看起来箭头是从中点向左或向右放置的。 –

+0

你能描述伪代码中箭头定位算法吗? – skayred