Android在带有方向路径的谷歌地图上绘制带有箭头的多段线 [英] Android Draw polylines with arrow on google map with direction path

查看:249
本文介绍了Android在带有方向路径的谷歌地图上绘制带有箭头的多段线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已添加多段线,但无法在Google地图上添加方向箭头应显示为



当它缩小时,应该显示更多箭头,如下所示:



我试过阅读各种博客和代码,但没有能够实现目标



我使用了下面的代码片段:

  private void DrawArrowHead(MarkerOptions MO,GoogleMap mMap,LatLng from,LatLng to){
//获取最后两点之间的方位
double bearing = GetBearing(from,to);

//将其舍入为3的倍数并抛出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);

//从Google
获取相应的三角形标记URL url;
位图图像=空;

尝试{
url =新网址(http://www.google.com/intl/zh-TW/mapfiles/dir_+ String.valueOf((int)adjBearing)+ .PNG);
try {
// image = BitmapFactory.decodeStream(url.openConnection()。getInputStream());
Log.d(HistoryDisplay,String.valueOf(adjBearing));
// image = BitmapFactory.decodeResource(getResources(),R.drawable.arrow);
image = BitmapFactory.decodeResource(getResources(),allArrow.get((int)adjBearing));
} catch(Exception e){
// TODO自动生成的catch块
e.printStackTrace();
}
} catch(MalformedURLException e){
// TODO自动生成的catch块
e.printStackTrace();


如果(image!= null){

// Anchor是范围[0..1]的比率,所以x和y的值为0.5将标记图像置于lat / long
float anchorX = 0.5f;
float anchorY = 0.5f;

int offsetX = 0;
int offsetY = 0;

//图片是24px x 24px
//所以转换后的图片将是48px x 48px

// 315范围 - 22.5任意一边315
if 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范围
else if(bearing> = 112.5&& bearing< 157.5){
offsetX = 0;
offsetY = 0;
}
// 90范围
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;
}

位图wideBmp;
Canvas wideBmpCanvas;
Rect src,dest;

//创建4倍于箭头头部图像大小的位图
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);
// MO.position(to);
MO.icon(BitmapDescriptorFactory.fromBitmap(wideBmp));
MO.anchor(anchorX,anchorY);

mMap.addMarker(MO);
// mMap.addMarker(new MarkerOptions()
// .position(to)
// .icon(BitmapDescriptorFactory.fromBitmap(wideBmp))
// .anchor( anchorX,anchorY));



$ b 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;

//计算角度。 Math.scos(Lat2),Math.cos(lat1)* Math.sin(lat2) - Math.sin(lat1)*数学公式.cos(lat2)* Math.cos(lon1 - lon2));

if(angle <0.0)
angle + = Math.PI * 2.0;

//将结果转换为度数。
angle = angle * degreesPerRadian;

返回角度;
}


解决方案

绘制箭头的最佳方式是使用'标记'到地图并且它的位置相同作为线的结尾或起点。



幸运的是,Google地图实用工具可以帮助您计算标题(旋转)。



只需在您的build.gradle文件中添加compile 'com.google.maps.android:android-maps-utils:0.3.4'作为依赖项

  public static void double computeHeading(LatLng from,LatLng to)

使用 Double HeadingRotation = SphericalUtil.computeHeading(LatLng from,LatLng to)



设置值(以度为单位)作为标记旋转。

箭头可以是一个简单的位图,或者甚至更好的可绘制 Shape



另请参阅: Google地图Android API实用工具


I have added polylines but not able to add arrow with direction on google map should be display as below

And when it zoom up, more arrow should be display like below

I have tried reading various blogs and codes but not able to get the goal

I have used following code snippet below:

private void DrawArrowHead(MarkerOptions MO, 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());
                Log.d("HistoryDisplay", String.valueOf(adjBearing));
//                image = BitmapFactory.decodeResource(getResources(), R.drawable.arrow);
                image = BitmapFactory.decodeResource(getResources(), allArrow.get((int) adjBearing));
            } catch (Exception 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);
//            MO.position(to);
            MO.icon(BitmapDescriptorFactory.fromBitmap(wideBmp));
            MO.anchor(anchorX, anchorY);

            mMap.addMarker(MO);
//            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;
    }

解决方案

The best way to draw arrowhead is to use 'Marker' to the map and position it the same as the line's end or starting point. You will need to make it flat and set its rotation manually.

Fortunately, Google Maps Utils can help out with computing the heading (rotation).

Just add compile 'com.google.maps.android:android-maps-utils:0.3.4' as a dependency in your build.gradle file

public static void double computeHeading(LatLng from, LatLng to)

Use Double HeadingRotation = SphericalUtil.computeHeading(LatLng from, LatLng to)

Set the value (which is in degrees) as the markers rotation.

The arrowhead could be a simple bitmap, or even better a drawable Shape.

See Also : Google Map Android API Utility

这篇关于Android在带有方向路径的谷歌地图上绘制带有箭头的多段线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆