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

android中目标注释在可见区域之外时的方向,android,google-maps,Android,Google Maps,我想在屏幕的各个侧面显示方向图像。例如,如果目标位置位于用户位置的右侧,并且位于可见地图区域之外,则我想添加一个方向图像,如下图所示(绿色注释为用户位置,红色注释为目标方向,超出屏幕范围): 我在这里找到了IOS的解决方案: 但在android中还无法找到解决方案。最终我找到了解决方案: //Add at class level private static final int NORTH = 1; private static final int SOUTH = 2;

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

我在这里找到了IOS的解决方案:
但在android中还无法找到解决方案。

最终我找到了解决方案:

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

//在类级别添加
专用静态最终int北=1;
私有静态最终int南=2;
私人静态最终int东=3;
私人静态最终int WEST=4;
私有图像视图imgEast;
私有图像视图imgWest;
私有ImageView imgNorth;
私有ImageView imgSouth;
私人来源;
私人目标;
//在onCreate或其他地方
imgEast=(ImageView)findViewById(R.id.east);
imgWest=(ImageView)findViewById(R.id.west);
imgNorth=(ImageView)findViewById(R.id.north);
imgSouth=(ImageView)findViewById(R.id.south);
来源=新车床(31.499851,74.317489);
目标=新车床(33.736189,73.096848);
//填充地图后添加
setonCamerachenglistener(新的onCamerachenglistener(){
@凌驾
摄影机更改上的公共空白(摄影机位置){
if(isLocationVisible(源)和&!isLocationVisible(目标)){
双方位=计算方位(源、目标);
显示方向(轴承);
}否则{
hideCardinalPointers();
}
}
});
公共布尔值isLocationVisible(LatLng LatLng){
LatLngBounds curScreen=googleMap.getProjection()
.getVisibleRegion().latLngBounds;
if(光标屏幕包含(板条)){
返回true;
}否则{
返回false;
}
}
私人双重计算(LatLng来源、LatLng目标){
双lat1=度弧度(源纬度);
双lon1=度弧度(源经度);
双lat2=度弧度(目标纬度);
双lon2=度弧度(目标经度);
双dLon=lon2-lon1;
双y=Math.sin(dLon)*Math.cos(lat2);
double x=Math.cos(lat1)*Math.sin(lat2)-Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
双弧度轴承=数学atan2(y,x);
if(弧度轴承<0.0)
弧度轴承+=2*Math.PI;
返回弧度0度(弧度轴承);
}
专用空心轴方向(双轴承){
int方向=带轴承的基数点(轴承);
View activeDirection=null;
开关(方向){
案例东:
activeDirection=this.imgEast;
打破
凯西:
activeDirection=this.imgWest;
打破
南方案例:
activeDirection=this.imgSouth;
打破
案例北:
activeDirection=this.imgNorth;
打破
}
//隐藏所有指针
hideCardinalPointers();
//仅可见活动方向指针
activeDirection.setVisibility(View.VISIBLE);
//设置旋转以显示方向
活动方向。设置旋转((浮动)轴承);
}
带轴承的专用内基点(双轴承){
如果(轴承>45.0和轴承135.0和轴承225.0和轴承