Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
谷歌地图Android API:基于GroundOverlay已知像素绘制多边形';s巴布亚新几内亚_Android_Google Maps_Google Maps Android Api 2 - Fatal编程技术网

谷歌地图Android API:基于GroundOverlay已知像素绘制多边形';s巴布亚新几内亚

谷歌地图Android API:基于GroundOverlay已知像素绘制多边形';s巴布亚新几内亚,android,google-maps,google-maps-android-api-2,Android,Google Maps,Google Maps Android Api 2,我正在使用Google Maps Android API在Google Maps上添加一个PNG文件作为自己的平面图,代码如下: GroundOverlayOptions groundOverlayOptions = new GroundOverlayOptions(); BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromAsset("building-d.png"); groundOverlayOptions.ima

我正在使用Google Maps Android API在Google Maps上添加一个PNG文件作为自己的平面图,代码如下:

GroundOverlayOptions groundOverlayOptions = new GroundOverlayOptions();
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromAsset("building-d.png");
groundOverlayOptions.image(bitmapDescriptor);
groundOverlayOptions.anchor(0, 1);

LatLng buildingSW = new LatLng(47.014815, 8.305098);
LatLng buildingNE = new LatLng(47.015148, 8.305440);
LatLng buildingNW = new LatLng(47.015168, 8.305144);
LatLng buildingSE = new LatLng(47.014792, 8.305385);

Location swLoc = locationFromLatLng(buildingSW);
Location seLoc = locationFromLatLng(buildingSE);
Location nwLoc = locationFromLatLng(buildingNW);
Location neLoc = locationFromLatLng(buildingNE);

float angle = swLoc.bearingTo(nwLoc);
groundOverlayOptions.bearing(angle);

float width = swLoc.distanceTo(seLoc);
groundOverlayOptions.position(buildingSW, width);

mMap.addGroundOverlay(groundOverlayOptions);
现在我知道在PNG中有一个房间在像素坐标422/301、708/301、422/10和708/10(这些是角)。我想在覆盖那个房间的
GroundOverlay
上画一个多边形。我该怎么做?我是否需要将像素坐标转换为
LatLng
,如果需要,如何转换


顺便问一句:我真的必须为
GroundOverlay
s使用PNG吗?是否没有其他支持的矢量格式,如eps、pdf等

你应该这样做: 你的室内地图位置应该是相对于一个特定的点(左下角是0,0),然后所有其他位置都是相对于该点的,以米为单位,因此你通常会得到100米以下的值

有了这个,你必须“移动,旋转和缩放”室内地图相对于世界。 只需在不是LAT/LNG的桌面上绘制一张地图,然后找到与您相同的室内点的坐标(通常我们会得到左下角和右上角的真实和室内位置),这样您就可以找到它在世界上的位置。 还可以查看比例因子(根据纬度,地图必须缩放)

我们通过1/cos(纬度半径)来计算这个值


如果您能找到一种方法,请告诉我,否则我将搜索并尝试剥离我们的代码

您应该以这种方式工作: 你的室内地图位置应该是相对于一个特定的点(左下角是0,0),然后所有其他位置都是相对于该点的,以米为单位,因此你通常会得到100米以下的值

有了这个,你必须“移动,旋转和缩放”室内地图相对于世界。 只需在不是LAT/LNG的桌面上绘制一张地图,然后找到与您相同的室内点的坐标(通常我们会得到左下角和右上角的真实和室内位置),这样您就可以找到它在世界上的位置。 还可以查看比例因子(根据纬度,地图必须缩放)

我们通过1/cos(纬度半径)来计算这个值


如果您能找到方法,请告诉我,否则我将搜索并尝试删除我们的代码

看到您对另一个答案的评论后,让我用一些代码完成:

在latlng 47.014816、8.305098中设置“原点”后,您必须将这些坐标转换为墨卡托坐标,您可以执行类似于以下操作:

public boolean initializeByTwoCouplesOfCooordsAndScale(double[] coordAreal, double[] coordBreal, double[] coordAvirtual, double[] coordBvirtual, double scalingFactor) {
    if (coordAreal[0] == coordBreal[0] && coordAvirtual[1] == coordBvirtual[1] && coordAreal[1] == coordBreal[1] && coordAvirtual[0] == coordBvirtual[0]) {
        System.err.println("Coordinates must not be the same!");
        return false;
    }
    // aPoint is considered the "origin" point (0,0)
    aPoint = coordAreal;
    bPoint = coordAvirtual;
    // now calculate the angle of the Real world coordinate for the points
    double deltaRy = coordBreal[1] - coordAreal[1];
    double deltaRx = coordBreal[0] - coordAreal[0];
    double aR = Math.atan2(deltaRy, deltaRx);
    // Now calculate the angle of the virtual world coordinates
    double deltaVy = coordBvirtual[1] - coordAvirtual[1];
    double deltaVx = coordBvirtual[0] - coordAvirtual[0];
    double aV = Math.atan2(deltaVy, deltaVx);
    // Set the transformation angle as the difference between the real and the virtual angles.
    mPhi= (aR - aV);
    // Set the scaling factor as the provided one
    mScale = (scalingFactor);//scaling factor is in function below
    // Calculate the scaling factor error correction using the distances of the two systems.
    return true;
}
公共静态双getScalingFactor(双纬度){ 返回1/(数学余弦(数学环面(纬度)); }

因此,您可以调用该方法:

initializeByTwoCouplesOfCooordsAndScale(new double[]{MERCATOR_LNG,MERCATOR_LAT},//real coordinates for point A REMEMBER: LNG,LAT = x,y!
new double[]{0d,0d}, //Virual coordinates for point A
new double[]{MERCATOR_POINT_B_LNG, MERCATOR_POINT_B_LAT},//real point B
new double[]{X_METERS,Y_METERS},//coordinates in meters of point B in virtual map
getScalingFactor(47.014816));
然后可以使用此函数进行变换:

public double[] transform(double[] coord) {
        double[] transCoord = new double[2];
    double xscaled = (coord[0] - bPoint[0]) * mScale; // XXX bPoint is the position of origin point in the "VIRTUAL" world. [0] is the x coordinate
    double yscaled =  (coord[1] - bPoint[1]) * mScale;

    transCoord[0] = (xscaled * Math.cos(mPhi)) - (yscaled * Math.sin(mPhi)) + aPoint[0]; //aPoint is the point with real coordinates of origin!
    transCoord[1] = (xscaled * Math.sin(mPhi)) + (yscaled * Math.cos(mPhi)) + aPoint[1];
    return transCoord;
}

你可以在网上找到一种将latlng转换为mercator的方法,这只是一堆数学知识;)

看到您对另一个答案的评论后,让我用一些代码来完成:

在latlng 47.014816、8.305098中设置“原点”后,您必须将这些坐标转换为墨卡托坐标,您可以执行类似于以下操作:

public boolean initializeByTwoCouplesOfCooordsAndScale(double[] coordAreal, double[] coordBreal, double[] coordAvirtual, double[] coordBvirtual, double scalingFactor) {
    if (coordAreal[0] == coordBreal[0] && coordAvirtual[1] == coordBvirtual[1] && coordAreal[1] == coordBreal[1] && coordAvirtual[0] == coordBvirtual[0]) {
        System.err.println("Coordinates must not be the same!");
        return false;
    }
    // aPoint is considered the "origin" point (0,0)
    aPoint = coordAreal;
    bPoint = coordAvirtual;
    // now calculate the angle of the Real world coordinate for the points
    double deltaRy = coordBreal[1] - coordAreal[1];
    double deltaRx = coordBreal[0] - coordAreal[0];
    double aR = Math.atan2(deltaRy, deltaRx);
    // Now calculate the angle of the virtual world coordinates
    double deltaVy = coordBvirtual[1] - coordAvirtual[1];
    double deltaVx = coordBvirtual[0] - coordAvirtual[0];
    double aV = Math.atan2(deltaVy, deltaVx);
    // Set the transformation angle as the difference between the real and the virtual angles.
    mPhi= (aR - aV);
    // Set the scaling factor as the provided one
    mScale = (scalingFactor);//scaling factor is in function below
    // Calculate the scaling factor error correction using the distances of the two systems.
    return true;
}
公共静态双getScalingFactor(双纬度){ 返回1/(数学余弦(数学环面(纬度)); }

因此,您可以调用该方法:

initializeByTwoCouplesOfCooordsAndScale(new double[]{MERCATOR_LNG,MERCATOR_LAT},//real coordinates for point A REMEMBER: LNG,LAT = x,y!
new double[]{0d,0d}, //Virual coordinates for point A
new double[]{MERCATOR_POINT_B_LNG, MERCATOR_POINT_B_LAT},//real point B
new double[]{X_METERS,Y_METERS},//coordinates in meters of point B in virtual map
getScalingFactor(47.014816));
然后可以使用此函数进行变换:

public double[] transform(double[] coord) {
        double[] transCoord = new double[2];
    double xscaled = (coord[0] - bPoint[0]) * mScale; // XXX bPoint is the position of origin point in the "VIRTUAL" world. [0] is the x coordinate
    double yscaled =  (coord[1] - bPoint[1]) * mScale;

    transCoord[0] = (xscaled * Math.cos(mPhi)) - (yscaled * Math.sin(mPhi)) + aPoint[0]; //aPoint is the point with real coordinates of origin!
    transCoord[1] = (xscaled * Math.sin(mPhi)) + (yscaled * Math.cos(mPhi)) + aPoint[1];
    return transCoord;
}

你可以在网上找到一种将latlng转换为mercator的方法,这只是一堆数学知识;)

在进行深入而复杂的讨论之前,只需问一个简单的问题:您是否需要以友好方式添加房间,或者房间只设置一次并始终存在?我认为房间将始终存在,但需要从图像中提取x/y位置。不幸的是,我无法为角点提供LatLng值。事实是,如果您在一生中绘制一次房间(或一年绘制一次),则更方便的方法是临时添加地图单击侦听器,单击房间的角点,并在logcat中输入您单击的坐标。然后写代码画出房间,你就没事了。如果您需要更实时或更动态的东西,您必须知道从原点到米的距离(为了方便起见,我们可以使用左下角的点),然后您可以计算坐标。使用像素是不可能的,因为你不知道GMAP是如何计算位置的。谢谢,我明白你的意思。关于像素,我同意你的观点,那根本不可行。这就是为什么我问是否有可能添加一个基于PDF的平面布置图,并使用“点”而不是像素(就像这个熟悉的问题:)。使用像素(或点)代替LatLng的优点是对GPS的依赖性较小,并且与实际平面图的耦合更紧密。嗯,我认为你不能使用PDF,我也不会使用它。我过去做过几件这样的事情,我总是用米作为度量单位。地图基本上是平面图,每样东西都有一个尺寸(以米为单位)。使用像墨卡托(Mercator)这样以米为单位的坐标系统,而不是GPS,你可以对任何东西进行地理参考。然后,你只需要将坐标从米转换为GPS,但这是一项常见的在线任务。在进行深入复杂的讨论之前,只需问一个简单的问题:你需要手动添加房间,还是房间只设置了一次就始终存在?我认为房间将始终存在,但需要从图像中提取x/y位置。不幸的是,我无法为角点提供LatLng值。事实是,如果您在一生中绘制一次房间(或一年绘制一次),则更方便的方法是临时添加地图单击侦听器,单击房间的角点,并在logcat中输入您单击的坐标。然后写代码画出房间,你就没事了。如果您需要更实时或更动态的内容,您必须知道距离原点的米数(为了方便起见,我们可以使用左下角的点),然后您可以计算