Android - 在自定义地图上绘制gps坐标

时间:2013-10-30 00:39:45

标签: android gps android-canvas

我的应用中有一个活动,其中有我用作地图的图像。如果图像与Google地图“网格对齐”,那么当我使用地图的左上角和右下角时,我会从googlemaps在线获取,然后我可以将用户gps转换为屏幕上的x和y。但是,如果地图不是“网格对齐”并且与我的数学返回值成一定角度,则会将用户位置偏离屏幕。显然我错过了关于如何处理地图角度的部分,所以如果有人能够阐明如何做到这一点,那将是非常有用的。

我知道我必须用弧度计算角度并做一些转换,但我不知道从哪里开始。这是我用来获得x和y到目前为止在画布上绘制的内容。

public double[] getPositionGPS(Location upperLeft, Location lowerRight, Location current){

    try{

        double hypotenuse = upperLeft.distanceTo(current);
        double bearing = upperLeft.bearingTo(current);
        double currentDistanceY = Math.cos(bearing * Math.PI / OneEightyDeg) * hypotenuse;
        //                           "percentage to mark the position"
        double totalHypotenuse = upperLeft.distanceTo(lowerRight);
        double totalDistanceY = totalHypotenuse * Math.cos(upperLeft.bearingTo(lowerRight) * Math.PI / OneEightyDeg);
        double currentPixelY = currentDistanceY / totalDistanceY * ImageSizeH;

        double hypotenuse2 = upperLeft.distanceTo(current);
        double bearing2 = upperLeft.bearingTo(current);
        double currentDistanceX = Math.sin(bearing2 * Math.PI / OneEightyDeg) * hypotenuse2;
        //                           "percentage to mark the position"
        double totalHypotenuse2 = upperLeft.distanceTo(lowerRight);
        double totalDistanceX = totalHypotenuse2 * Math.sin(upperLeft.bearingTo(lowerRight) * Math.PI / OneEightyDeg);
        double currentPixelX = currentDistanceX / totalDistanceX * ImageSizeW;

        return new double[]{currentPixelX, currentPixelY};

    }catch(Exception e){

        e.printStackTrace();
        return new double[]{0,0};

    }

5 个答案:

答案 0 :(得分:2)

首先,将您的谷歌地图坐标映射到您的自定义图像,就像图像不是一个角度一样。在这里,您基本上处理缩放和偏移。假设你得到的坐标为(x, y)

然后,根据此矩阵旋转您的坐标:Rotate a point around origin。由于您已经知道角度,因此您知道/可以计算自定义地图旋转的中心点坐标。假设它是(a, b)。具体做法是:

1)将您的地图坐标(x, y)转换为基于(0,0)的坐标,(x-a, y-b)

2)使用该矩阵旋转,你有一个新的坐标(x', y')

3)将其转回基于(a, b)的coord,(x'+a, y'+b)

答案 1 :(得分:1)

我可能完全错了,但我认为这是一种获得旋转角度(或者可能是4个角)的方法:

  1. 在lowerRight和upperLeft之间获取角度 alpha 。我想这是相等的180 - lowerRight.bearingTo(upperLeft) 编辑(这个等式应该取决于屏幕的象限)
  2. 使用X,Y(屏幕)坐标获得斜边和下边缘之间的角度 theta 。我想(再次)这个角度的正弦等于:(height) / ((height^2) + (width^2))^1/2
  3. 现在,旋转角度等于 theta - alpha
  4. 如果你想要想象一下:

    bla

答案 2 :(得分:0)

我不确定我是否理解了您的问题,但是您不能从这样的API中获取(X,Y)位置吗?

// myMap is a GoogleMap instance and location is a Location instance
Projection projection = myMap.getProjection();
LatLng latlng = new LatLng(location.getLatitude(), location.getLongitude());
Point pointInTheScreen = projection.toScreenLocation(latlng);

有关详细信息,请参阅GoogleMap API。

答案 3 :(得分:0)

是的,您可以绘制不在可见地图上的点。通过设置LatLngBounds来解决这个问题。然后显示LatLngBounds的地图。您还可以移动地图以显示LatLngBounds。没有什么棘手的东西没有切线或斜坡或地球的双曲曲率。所有这些都以度为单位来处理,所以不要过分考虑你的解决方案。如果你转动地图,点将随之转动。因此,将您的点添加到地图中找到边界并倾斜相机。向后倾斜相机,所有点仍然在屏幕上!这将使您开始使用屏幕上的所有点。

相同的示例获得对谷歌地图的引用。

private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the
    // map.

    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        // mMap = mMapFragment.getMap();
        // // Check if we were successful in obtaining the map.

        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map)).getMap();
        // use the settings maptype

        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap();
        }
    }
}

让我们开始寻找地图的边界。

import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;

LatLngBounds和LatLngBounds.Builder的字段

private LatLngBounds bounds;
private LatLngBounds.Builder myLatLngBuilder;

初始化LatLngBounds.Builder

myLatLngBuilder = new LatLngBounds.Builder();

为地图上的每个点。

LatLng myLatLng = new LatLng(latitude, longitude);
myLatLngBuilder.include(myLatLng);

然后,当您完成的添加点构建您的边界时。

bounds = myLatLngBuilder.build();

现在我有了地图上所有点的界限,我可以只显示地图的那个区域。这段代码我从地图样本中解脱出来。

final View mapView = getSupportFragmentManager().findFragmentById(
            R.id.map).getView();
    if (mapView.getViewTreeObserver().isAlive()) {
        mapView.getViewTreeObserver().addOnGlobalLayoutListener(
                new OnGlobalLayoutListener() {
                    @SuppressWarnings("deprecation")
                    // We use the new method when supported
                    @SuppressLint("NewApi")
                    // We check which build version we are using.
                    @Override
                    public void onGlobalLayout() {
                        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                            mapView.getViewTreeObserver()
                                    .removeGlobalOnLayoutListener(this);
                        } else {
                            mapView.getViewTreeObserver()
                                    .removeOnGlobalLayoutListener(this);
                        }
                        mMap.moveCamera(CameraUpdateFactory
                                .newLatLngBounds(bounds, 50));
                    }
                });
    }

这实际上是我的应用程序 Bestrides KML Reader 显示地图的方式,因此屏幕上没有任何点。

祝你好运 Danny117

答案 4 :(得分:-1)

您可以使用Magnetic Field sensor(又名指南针)获取设备的方向,然后将自定义视图“网格对齐”到地图。