谷歌地图Android API:基于GroundOverlay已知像素绘制多边形';s巴布亚新几内亚
我正在使用Google Maps Android API在Google Maps上添加一个PNG文件作为自己的平面图,代码如下:谷歌地图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
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中输入您单击的坐标。然后写代码画出房间,你就没事了。如果您需要更实时或更动态的内容,您必须知道距离原点的米数(为了方便起见,我们可以使用左下角的点),然后您可以计算