I want to draw a line chart on the Android google map. I have gps coordinates of the path and I want to show the speed of the car on the map with the height of the line.
我想在Android谷歌地图上绘制折线图。我有路径的gps坐标,我想用线的高度显示汽车在地图上的速度。
See this image Something like this,
看到这个图像像这样的东西,
For each gps (lat,lng) point I want to add some height and calculate the corresponding gps(lat,lng) point. I want to show this in a 3D view so I will have to change the points when the camera position is changed but first step is to calculate the gps points with the added height.
对于每个gps(lat,lng)点,我想添加一些高度并计算相应的gps(lat,lng)点。我想在3D视图中显示这一点,因此我必须在更改摄像机位置时更改点,但第一步是计算增加高度的gps点。
For example
ArrayList<LatLng> basePoints = new ArrayList<LatLng>();
basePoints.add(new LatLng(53.262688, -2.500792));
basePoints.add(new LatLng(53.262758, -2.500897));
basePoints.add(new LatLng(53.262789, -2.501087));
basePoints.add(new LatLng(53.262798, -2.501229));
basePoints.add(new LatLng(53.262785, -2.501414));
basePoints.add(new LatLng(53.262760, -2.501594));
basePoints.add(new LatLng(53.262707, -2.501811));
basePoints.add(new LatLng(53.262655, -2.501943));
ArrayList<LatLng> topPoints = new ArrayList<LatLng>();
topPoints.add(new LatLng(53.262939, -2.500779));
topPoints.add(new LatLng(53.262975, -2.500916));
topPoints.add(new LatLng(53.262914, -2.501098));
topPoints.add(new LatLng(53.263055, -2.501248));
topPoints.add(new LatLng(53.262925, -2.501439));
topPoints.add(new LatLng(53.263045, -2.501581));
topPoints.add(new LatLng(53.262907, -2.501844));
topPoints.add(new LatLng(53.263002, -2.502015));
Any idea how can I do it? Thanks
不知道怎么办呢?谢谢
2 个解决方案
#1
From the link you provided I have implemented this for you.
从您提供的链接我已经为您实现了这一点。
final ArrayList<LatLng> basePoints = new ArrayList<LatLng>();
basePoints.add(new LatLng(53.262688, -2.500792));
basePoints.add(new LatLng(53.262758, -2.500897));
basePoints.add(new LatLng(53.262789, -2.501087));
basePoints.add(new LatLng(53.262798, -2.501229));
basePoints.add(new LatLng(53.262785, -2.501414));
basePoints.add(new LatLng(53.262760, -2.501594));
basePoints.add(new LatLng(53.262707, -2.501811));
basePoints.add(new LatLng(53.262655, -2.501943));
final ArrayList<Double> speedPoints = new ArrayList<Double>();
speedPoints.add(7.955734692);
speedPoints.add(8.761378798);
speedPoints.add(11.07760474);
speedPoints.add(13.69594751);
speedPoints.add(15.50864695);
speedPoints.add(16.01217576);
speedPoints.add(15.60935179);
speedPoints.add(15.71005663);
LatLngBounds.Builder bounds = new LatLngBounds.Builder();
for(int i=0;i<basePoints.size();i++)
{
bounds.include(basePoints.get(i));
}
map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), 300,300,0));
map.setOnCameraChangeListener(new OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition arg0)
{
map.clear();
ArrayList<LatLng> topPoints = new ArrayList<LatLng>();
for(int i=0;i<basePoints.size();i++)
{
topPoints.add(moveByDistance(basePoints.get(i), speedPoints.get(i)*3,map.getCameraPosition().bearing));
}
PolylineOptions topPO = new PolylineOptions();
topPO.addAll(topPoints).width(5).color(Color.BLUE).geodesic(true);
map.addPolyline(topPO);
for(int i=0;i<basePoints.size()-1;i++)
{
map.addPolygon(new PolygonOptions().add(basePoints.get(i),topPoints.get(i),topPoints.get(i+1),basePoints.get(i+1),basePoints.get(i)).fillColor(Color.YELLOW).strokeColor(Color.YELLOW));
}
}
});
/**
* Move a LatLng-Point into a given distance and a given angle (0-360,
* 0=North).
*/
public static LatLng moveByDistance(LatLng startGp, double distance,double angle) {
/*
* Calculate the part going to north and the part going to east.
*/
double arc = Math.toRadians(angle);
double toNorth = distance * Math.cos(arc);
double toEast = distance * Math.sin(arc);
double lonDiff = meterToLongitude(toEast, startGp.latitude);
double latDiff = meterToLatitude(toNorth);
return new LatLng(startGp.latitude + latDiff, startGp.longitude + lonDiff);
}
private static double meterToLongitude(double meterToEast, double latitude) {
double latArc = Math.toRadians(latitude);
double radius = Math.cos(latArc) * EARTHRADIUS;
double rad = meterToEast / radius;
double degrees = Math.toDegrees(rad);
return degrees;
}
private static double meterToLatitude(double meterToNorth) {
double rad = meterToNorth / EARTHRADIUS;
double degrees = Math.toDegrees(rad);
return degrees;
}
I hope it will help you implement this.
我希望它能帮助你实现这一目标。
#2
Calcualte how many degrees one meter is:
计算一米多少度:
At equator:
360 degrees, have 40.000 000 meters circumfene.
360度,有40 000 000米的环绕。
So one meter is about
所以一米就到了
double static final METERS_PER_DEGREE = 360.0 / 40 000 000;
Now offset the latitude e.g by 3 meters:
现在抵消纬度,例如3米:
lat = lat + 3 * METERS_PER_DEGREE.
When offseting longitude, one has to multiply with cos(Math.toRadians(latitude);
当偏离经度时,必须乘以cos(Math.toRadians(纬度);
double oneMeterLongitudeInDegrees = METERS_PER_DEGREE * cos(Math.toRadians(latitude);
lonNew = lonOld + 3 * oneMeterLongitudeInDegrees
#1
From the link you provided I have implemented this for you.
从您提供的链接我已经为您实现了这一点。
final ArrayList<LatLng> basePoints = new ArrayList<LatLng>();
basePoints.add(new LatLng(53.262688, -2.500792));
basePoints.add(new LatLng(53.262758, -2.500897));
basePoints.add(new LatLng(53.262789, -2.501087));
basePoints.add(new LatLng(53.262798, -2.501229));
basePoints.add(new LatLng(53.262785, -2.501414));
basePoints.add(new LatLng(53.262760, -2.501594));
basePoints.add(new LatLng(53.262707, -2.501811));
basePoints.add(new LatLng(53.262655, -2.501943));
final ArrayList<Double> speedPoints = new ArrayList<Double>();
speedPoints.add(7.955734692);
speedPoints.add(8.761378798);
speedPoints.add(11.07760474);
speedPoints.add(13.69594751);
speedPoints.add(15.50864695);
speedPoints.add(16.01217576);
speedPoints.add(15.60935179);
speedPoints.add(15.71005663);
LatLngBounds.Builder bounds = new LatLngBounds.Builder();
for(int i=0;i<basePoints.size();i++)
{
bounds.include(basePoints.get(i));
}
map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), 300,300,0));
map.setOnCameraChangeListener(new OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition arg0)
{
map.clear();
ArrayList<LatLng> topPoints = new ArrayList<LatLng>();
for(int i=0;i<basePoints.size();i++)
{
topPoints.add(moveByDistance(basePoints.get(i), speedPoints.get(i)*3,map.getCameraPosition().bearing));
}
PolylineOptions topPO = new PolylineOptions();
topPO.addAll(topPoints).width(5).color(Color.BLUE).geodesic(true);
map.addPolyline(topPO);
for(int i=0;i<basePoints.size()-1;i++)
{
map.addPolygon(new PolygonOptions().add(basePoints.get(i),topPoints.get(i),topPoints.get(i+1),basePoints.get(i+1),basePoints.get(i)).fillColor(Color.YELLOW).strokeColor(Color.YELLOW));
}
}
});
/**
* Move a LatLng-Point into a given distance and a given angle (0-360,
* 0=North).
*/
public static LatLng moveByDistance(LatLng startGp, double distance,double angle) {
/*
* Calculate the part going to north and the part going to east.
*/
double arc = Math.toRadians(angle);
double toNorth = distance * Math.cos(arc);
double toEast = distance * Math.sin(arc);
double lonDiff = meterToLongitude(toEast, startGp.latitude);
double latDiff = meterToLatitude(toNorth);
return new LatLng(startGp.latitude + latDiff, startGp.longitude + lonDiff);
}
private static double meterToLongitude(double meterToEast, double latitude) {
double latArc = Math.toRadians(latitude);
double radius = Math.cos(latArc) * EARTHRADIUS;
double rad = meterToEast / radius;
double degrees = Math.toDegrees(rad);
return degrees;
}
private static double meterToLatitude(double meterToNorth) {
double rad = meterToNorth / EARTHRADIUS;
double degrees = Math.toDegrees(rad);
return degrees;
}
I hope it will help you implement this.
我希望它能帮助你实现这一目标。
#2
Calcualte how many degrees one meter is:
计算一米多少度:
At equator:
360 degrees, have 40.000 000 meters circumfene.
360度,有40 000 000米的环绕。
So one meter is about
所以一米就到了
double static final METERS_PER_DEGREE = 360.0 / 40 000 000;
Now offset the latitude e.g by 3 meters:
现在抵消纬度,例如3米:
lat = lat + 3 * METERS_PER_DEGREE.
When offseting longitude, one has to multiply with cos(Math.toRadians(latitude);
当偏离经度时,必须乘以cos(Math.toRadians(纬度);
double oneMeterLongitudeInDegrees = METERS_PER_DEGREE * cos(Math.toRadians(latitude);
lonNew = lonOld + 3 * oneMeterLongitudeInDegrees