android中可见区域外目标注释的方向

Posted

技术标签:

【中文标题】android中可见区域外目标注释的方向【英文标题】:Direction of target annotation when outside of visible area in android 【发布时间】:2015-06-20 10:58:12 【问题描述】:

我想在屏幕的所有侧面显示方向图像。例如。如果目标的位置是用户位置的右侧并且在可见地图区域之外,那么我想添加一个方向图像,如下图所示(绿色注释是用户位置,红色是目标的方向,超出屏幕范围):

我在这里找到了 ios 的解决方案: Direction of target annotation when outside of visible area 但是在android中还没有找到解决方案。

【问题讨论】:

【参考方案1】:

终于找到了解决办法:

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

【讨论】:

以上是关于android中可见区域外目标注释的方向的主要内容,如果未能解决你的问题,请参考以下文章

处理菜单项点击事件 - Android

MKMapView 缩放以显示框架中的所有注释

横竖屏样式

Ionic 2: Beta 8 - 底部的可滚动内容区域切断按钮

Android 屏幕方向:横向回到纵向

Android中的相机方向问题