2015-06-20 52 views
-1

我想在屏幕的各个方向上显示方向图像。例如。如果目标的位置是用户位置的右侧并且位于可见地图区域之外,那么我想添加一个方向图像,如下图所示(绿色注释是用户的位置,红色是目标的方向,这是在屏幕的界限): Android中可见区域外的目标注释的方向

我发现这里的IOS的解决方案: Direction of target annotation when outside of visible area 但无法找到在Android解决方案呢。

回答

2

最后我找到了解决办法:

//Add at class level 
    private static final int NORTH = 1; 
    private static final int SOUTH = 2; 
    private static final int EAST = 3; 
    private static final int WEST = 4; 
    private ImageView imgEast; 
    private ImageView imgWest; 
    private ImageView imgNorth; 
    private ImageView imgSouth; 

    private LatLng source; 
    private LatLng target; 

//In onCreate or somewhere else 
    imgEast = (ImageView) findViewById(R.id.east); 
    imgWest = (ImageView) findViewById(R.id.west); 
    imgNorth = (ImageView) findViewById(R.id.north); 
    imgSouth = (ImageView) findViewById(R.id.south); 

    source = new LatLng(31.499851, 74.317489); 
    target = new LatLng(33.736189, 73.096848); 

//Add after populating map 
      googleMap.setOnCameraChangeListener(new OnCameraChangeListener() { 
       @Override 
       public void onCameraChange(CameraPosition position) { 
        if(isLocationVisible(source) && !isLocationVisible(target)){ 

         double bearing = calculateBearing(source, target); 
         showCardinalPointDirection(bearing); 
        }else{ 
         hideCardinalPointers(); 
        } 
       } 
      }); 

    public boolean isLocationVisible(LatLng latLng){ 
     LatLngBounds curScreen = googleMap.getProjection() 
       .getVisibleRegion().latLngBounds; 
     if(curScreen.contains(latLng)){ 
      return true; 
     }else{ 
      return false; 
     } 
    } 

    private double calculateBearing(LatLng source, LatLng target){ 
     double lat1 = DegreesToRadians(source.latitude); 
     double lon1 = DegreesToRadians(source.longitude); 

     double lat2 = DegreesToRadians(target.latitude); 
     double lon2 = DegreesToRadians(target.longitude); 

     double dLon = lon2 - lon1; 

     double y = Math.sin(dLon) * Math.cos(lat2); 
     double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon); 
     double radiansBearing = Math.atan2(y, x); 

     if(radiansBearing < 0.0) 
      radiansBearing += 2*Math.PI; 

     return RadiansToDegrees(radiansBearing); 
    } 

    private void showCardinalPointDirection(double bearing){ 
     int direction = cardinalPointWithBearing(bearing); 
     View activeDirection = null; 
     switch(direction){ 
     case EAST: 
      activeDirection = this.imgEast; 
      break; 
     case WEST: 
      activeDirection = this.imgWest; 
      break; 
     case SOUTH: 
      activeDirection = this.imgSouth; 
      break; 
     case NORTH: 
      activeDirection = this.imgNorth; 
      break; 
     } 

     //Hide all pointers 
     hideCardinalPointers(); 

     //Visible only active direction pointer 
     activeDirection.setVisibility(View.VISIBLE); 

     //Set rotation to show direction 
     activeDirection.setRotation((float)bearing); 
    } 

    private int cardinalPointWithBearing(double bearing){ 
     if (bearing > 45.0 && bearing <= 135.0) { 
      return EAST; 
     } else if (bearing > 135.0 && bearing <= 225.0) { 
      return SOUTH; 
     } else if (bearing > 225.0 && bearing <= 315.0) { 
      return WEST; 
     } else { 
      return NORTH; 
     } 
    } 

    double DegreesToRadians(double degrees) { 
     return degrees * Math.PI/180.0; 
    }; 

    double RadiansToDegrees(double radians) { 
     return radians * 180.0/Math.PI; 
    }; 

    private void hideCardinalPointers(){ 
     imgEast.setVisibility(View.INVISIBLE); 
     imgWest.setVisibility(View.INVISIBLE); 
     imgSouth.setVisibility(View.INVISIBLE); 
     imgNorth.setVisibility(View.INVISIBLE); 
    } 
+0

你做到了潇洒哥.... – junaidsidhu