如何使用Android Maps V2 API绘制带有箭头头部的折线(它表示方向)。在Android地图文档中,此选项不可用。是否有可能在折线上添加箭头?
如何使用Android Maps V2 API绘制带有箭头头部的折线(它表示方向)。在Android地图文档中,此选项不可用。是否有可能在折线上添加箭头?
这里有一个可行的示例,我使用Doug建议的相同概念进行开发,通过将JavaScript示例(http://econym.org.uk/gmap/example_arrows.htm)转换为Java代码。方便起见,它使用了来自Google Maps服务器的图像,但这些图像可以是您设计的图像,也可以从Web上抓取并在应用程序中本地存储。为了演示方便,我正在主线程上下载这些内容,但如果在实时应用程序中使用,请勿这样做!
然而,与JavaScript示例的关键区别在于,您必须将箭头头部图像投影到四倍大小的较大图像上,根据从A到B的方位计算出图像要平移的位置,并通过添加另一个带有更大图像的定位标记来在现有B标记上居中该图像作为图标。
首先添加您的折线:
PolylineOptions polylines = new PolylineOptions();
LatLng from = new LatLng(f.getLatitude(), f.getLongitude());
LatLng to = new LatLng(t.getLatitude(), t.getLongitude());
polylines.add(from, to).color(polyColor).width(2);
mMap.addPolyline(polylines);
DrawArrowHead(mMap, from, to);
然后添加箭头:
private final double degreesPerRadian = 180.0 / Math.PI;
private void DrawArrowHead(GoogleMap mMap, LatLng from, LatLng to){
// obtain the bearing between the last two points
double bearing = GetBearing(from, to);
// round it to a multiple of 3 and cast out 120s
double adjBearing = Math.round(bearing / 3) * 3;
while (adjBearing >= 120) {
adjBearing -= 120;
}
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
// Get the corresponding triangle marker from Google
URL url;
Bitmap image = null;
try {
url = new URL("http://www.google.com/intl/en_ALL/mapfiles/dir_" + String.valueOf((int)adjBearing) + ".png");
try {
image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (image != null){
// Anchor is ratio in range [0..1] so value of 0.5 on x and y will center the marker image on the lat/long
float anchorX = 0.5f;
float anchorY = 0.5f;
int offsetX = 0;
int offsetY = 0;
// images are 24px x 24px
// so transformed image will be 48px x 48px
//315 range -- 22.5 either side of 315
if (bearing >= 292.5 && bearing < 335.5){
offsetX = 24;
offsetY = 24;
}
//270 range
else if (bearing >= 247.5 && bearing < 292.5){
offsetX = 24;
offsetY = 12;
}
//225 range
else if (bearing >= 202.5 && bearing < 247.5){
offsetX = 24;
offsetY = 0;
}
//180 range
else if (bearing >= 157.5 && bearing < 202.5){
offsetX = 12;
offsetY = 0;
}
//135 range
else if (bearing >= 112.5 && bearing < 157.5){
offsetX = 0;
offsetY = 0;
}
//90 range
else if (bearing >= 67.5 && bearing < 112.5){
offsetX = 0;
offsetY = 12;
}
//45 range
else if (bearing >= 22.5 && bearing < 67.5){
offsetX = 0;
offsetY = 24;
}
//0 range - 335.5 - 22.5
else {
offsetX = 12;
offsetY = 24;
}
Bitmap wideBmp;
Canvas wideBmpCanvas;
Rect src, dest;
// Create larger bitmap 4 times the size of arrow head image
wideBmp = Bitmap.createBitmap(image.getWidth() * 2, image.getHeight() * 2, image.getConfig());
wideBmpCanvas = new Canvas(wideBmp);
src = new Rect(0, 0, image.getWidth(), image.getHeight());
dest = new Rect(src);
dest.offset(offsetX, offsetY);
wideBmpCanvas.drawBitmap(image, src, dest, null);
mMap.addMarker(new MarkerOptions()
.position(to)
.icon(BitmapDescriptorFactory.fromBitmap(wideBmp))
.anchor(anchorX, anchorY));
}
}
private double GetBearing(LatLng from, LatLng to){
double lat1 = from.latitude * Math.PI / 180.0;
double lon1 = from.longitude * Math.PI / 180.0;
double lat2 = to.latitude * Math.PI / 180.0;
double lon2 = to.longitude * Math.PI / 180.0;
// Compute the angle.
double angle = - Math.atan2( Math.sin( lon1 - lon2 ) * Math.cos( lat2 ), Math.cos( lat1 ) * Math.sin( lat2 ) - Math.sin( lat1 ) * Math.cos( lat2 ) * Math.cos( lon1 - lon2 ) );
if (angle < 0.0)
angle += Math.PI * 2.0;
// And convert result to degrees.
angle = angle * degreesPerRadian;
return angle;
}
int identifier = getResources().getIdentifier("dir_" + String.valueOf((int)adjBearing), "drawable", getActivity().getPackageName());
Bitmap image = BitmapFactory.decodeResource(getResources(), identifier);
- Breenodrawable-nodpi
文件夹中,以便它们不会因屏幕密度而被缩放! - BreenoMap.getUiSettings().setRotateGesturesEnabled(false);
- Breeno谷歌的相关问题解决帖子在这里中说:The following snippet specifies a custom bitmap for the end cap:
mPolyline.setEndCap( new CustomCap(BitmapDescriptorFactory.fromResource(R.drawable.arrow), 16));
When you use a custom bitmap, you should specify a reference stroke width in pixels. The API scales the bitmap accordingly. The reference stroke width is the stroke width that you used when designing the bitmap image for the cap, at the original dimension of the image. The default reference stroke width is 10 pixels. Hint: To determine the reference stroke width, open your bitmap image at 100% zoom in an image editor, and plot the desired width of the line stroke relative to the image.
If you use
BitmapDescriptorFactory.fromResource()
to create the bitmap, make sure you use a density-independent resource (nodpi).