如何绘制优步折线?
How to draw Uber polyline?
优步应用有一条弯曲的折线,甚至包括阴影。阴影可能只是黑色,带有连接两点的透明多段线。那很容易。但是第二条带曲线的折线,如何实现呢?这是贝塞尔曲线,还是像 setGeodesic(true) 这样的内置函数?
我查看了 google 地图示例并看到了有关圆形多段线的部分。这可以用来创建半圆吗?来自演示的代码片段。
PolylineOptions options = new PolylineOptions();
int radius = 5; //What is that?
int numPoints = 100;
double phase = 2 * Math.PI / numPoints;
for (int i = 0; i <= numPoints; i++) {
options.add(new LatLng(SYDNEY.latitude + radius * Math.sin(i * phase),
SYDNEY.longitude + radius * Math.cos(i * phase)));
}
int color = Color.RED;
mMap.addPolyline(options
.color(color)
.width(2));
我能够通过以下贝塞尔曲线计算实现这一点
double cLat = ((start.latitude + end.latitude) / 2);
double cLon = ((start.longitude + end.longitude) / 2);
//add skew and arcHeight to move the midPoint
if(Math.abs(start.longitude - end.longitude) < 0.0001){
cLon -= 0.0195;
} else {
cLat += 0.0195;
}
double tDelta = 1.0/50;
for (double t = 0; t <= 1.0; t+=tDelta) {
double oneMinusT = (1.0-t);
double t2 = Math.pow(t, 2);
double lon = oneMinusT * oneMinusT * start.longitude
+ 2 * oneMinusT * t * cLon
+ t2 * end.longitude;
double lat = oneMinusT * oneMinusT * start.latitude
+ 2 * oneMinusT * t * cLat
+ t2 * end.latitude;
alLatLng.add(new LatLng(lat, lon));
}
// draw polyline
PolylineOptions line = new PolylineOptions();
line.width(POLYGON_STROKE_WIDTH_PX);
line.color(Color.RED);
line.addAll(alLatLng);
map.addPolyline(line);
private fun plotPolyline(
startLat: Double?,
startLon: Double?,
markerLat: Double?,
markerLon: Double?
) {
if (startLat == null || startLon == null || markerLat == null || markerLon == null) {
return
}
var startPoint = LatLng(startLat, startLon)
var endPoint = LatLng(markerLat, markerLon)
val distance = SphericalUtil.computeDistanceBetween(startPoint, endPoint)
val midPoint = SphericalUtil.interpolate(startPoint, endPoint, 0.5)
val midToStartLocHeading = SphericalUtil.computeHeading(midPoint, startPoint)
val controlPointAngle = 360.0 - (90.0 - midToStartLocHeading)
val controlPoint = SphericalUtil.computeOffset(midPoint, distance / 2.0, controlPointAngle)
var t = 0.0
val polylineOptions = PolylineOptions()
while (t <= 1.00) {
val oneMinusT = 1.0 - t
val lon: Double =
oneMinusT * oneMinusT * startLon + 2 * oneMinusT * t * controlPoint.longitude + t * t * markerLon
val lat: Double =
oneMinusT * oneMinusT * startLat + 2 * oneMinusT * t * controlPoint.latitude + t * t * markerLat
polylineOptions.add(LatLng(lat, lon))
t += 0.05
}
polylineOptions.add(endPoint)
// Draw polyline
polyline?.remove()
var pattern = listOf<PatternItem>(Gap(10.0f), Dash(10.0f))
polyline = googleMap?.addPolyline(
polylineOptions.width(10f).pattern(pattern)
.geodesic(false)
)
}
优步应用有一条弯曲的折线,甚至包括阴影。阴影可能只是黑色,带有连接两点的透明多段线。那很容易。但是第二条带曲线的折线,如何实现呢?这是贝塞尔曲线,还是像 setGeodesic(true) 这样的内置函数?
我查看了 google 地图示例并看到了有关圆形多段线的部分。这可以用来创建半圆吗?来自演示的代码片段。
PolylineOptions options = new PolylineOptions();
int radius = 5; //What is that?
int numPoints = 100;
double phase = 2 * Math.PI / numPoints;
for (int i = 0; i <= numPoints; i++) {
options.add(new LatLng(SYDNEY.latitude + radius * Math.sin(i * phase),
SYDNEY.longitude + radius * Math.cos(i * phase)));
}
int color = Color.RED;
mMap.addPolyline(options
.color(color)
.width(2));
我能够通过以下贝塞尔曲线计算实现这一点
double cLat = ((start.latitude + end.latitude) / 2);
double cLon = ((start.longitude + end.longitude) / 2);
//add skew and arcHeight to move the midPoint
if(Math.abs(start.longitude - end.longitude) < 0.0001){
cLon -= 0.0195;
} else {
cLat += 0.0195;
}
double tDelta = 1.0/50;
for (double t = 0; t <= 1.0; t+=tDelta) {
double oneMinusT = (1.0-t);
double t2 = Math.pow(t, 2);
double lon = oneMinusT * oneMinusT * start.longitude
+ 2 * oneMinusT * t * cLon
+ t2 * end.longitude;
double lat = oneMinusT * oneMinusT * start.latitude
+ 2 * oneMinusT * t * cLat
+ t2 * end.latitude;
alLatLng.add(new LatLng(lat, lon));
}
// draw polyline
PolylineOptions line = new PolylineOptions();
line.width(POLYGON_STROKE_WIDTH_PX);
line.color(Color.RED);
line.addAll(alLatLng);
map.addPolyline(line);
private fun plotPolyline(
startLat: Double?,
startLon: Double?,
markerLat: Double?,
markerLon: Double?
) {
if (startLat == null || startLon == null || markerLat == null || markerLon == null) {
return
}
var startPoint = LatLng(startLat, startLon)
var endPoint = LatLng(markerLat, markerLon)
val distance = SphericalUtil.computeDistanceBetween(startPoint, endPoint)
val midPoint = SphericalUtil.interpolate(startPoint, endPoint, 0.5)
val midToStartLocHeading = SphericalUtil.computeHeading(midPoint, startPoint)
val controlPointAngle = 360.0 - (90.0 - midToStartLocHeading)
val controlPoint = SphericalUtil.computeOffset(midPoint, distance / 2.0, controlPointAngle)
var t = 0.0
val polylineOptions = PolylineOptions()
while (t <= 1.00) {
val oneMinusT = 1.0 - t
val lon: Double =
oneMinusT * oneMinusT * startLon + 2 * oneMinusT * t * controlPoint.longitude + t * t * markerLon
val lat: Double =
oneMinusT * oneMinusT * startLat + 2 * oneMinusT * t * controlPoint.latitude + t * t * markerLat
polylineOptions.add(LatLng(lat, lon))
t += 0.05
}
polylineOptions.add(endPoint)
// Draw polyline
polyline?.remove()
var pattern = listOf<PatternItem>(Gap(10.0f), Dash(10.0f))
polyline = googleMap?.addPolyline(
polylineOptions.width(10f).pattern(pattern)
.geodesic(false)
)
}