Android加载SVG实现交互式地图绘制

来源:互联网 发布:嵌入式软件有哪些 编辑:程序博客网 时间:2024/04/29 04:33

Android加载SVG实现交互式地图绘制

    • Android加载SVG实现交互式地图绘制
        • 效果图
        • 实现思路
        • 准备工作
        • 具体实现

效果图

enter image description here

实现思路

  • 下载SVG文件
  • 将svg资源转换成相应的java代码
  • 解析svg/xml文件
  • 自定义MapView
  • 重写OnTouchEvent通过接回调实现交互

准备工作

1.下载SVG文件
下载地址: https://www.amcharts.com/dl/javascript-maps/

2.svg转换为xml文件(可选,也可以直接解析svg文件)
svg转换为xml文件地址:http://inloop.github.io/svg2android/
AndroidStudio可以安装一个SVG2VectorDrawable 直接进行转换

具体实现

首先先把下载好的svg文件放到raw目录下面 ps:下载下来的文件有大小写,放到raw目录下面只能全部小写,不然编译报错
接下来通过java代码将svg文件解析成为List 集合

    public void getCityItemList() {    new Thread() {        @Override        public void run() {            try {                List<CityItem> result = new ArrayList<>();                long startTime = System.currentTimeMillis();                InputStream inputStream = mContext.getResources().openRawResource(R.raw.china);                XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();                parser.setInput(inputStream, "utf-8");                int eventType;                while ((eventType = parser.getEventType()) != XmlPullParser.END_DOCUMENT) {                    if (eventType == XmlPullParser.START_TAG) {                        String name = parser.getName();                        if ("path".equals(name)) {                            String id = parser.getAttributeValue(null, "id");                            String title = parser.getAttributeValue(null, "title");                            String pathData = parser.getAttributeValue(null, "d");                            Path path = PathParser.createPathFromPathData(pathData);                            Region region = new Region();                            if (path != null) {                                RectF r = new RectF();                                //得到Path的矩形边界                                path.computeBounds(r, true);                                // 设置区域路径和剪辑描述的区域                                region.setPath(path, new Region((int) (r.left), (int) (r.top), (int) (r.right), (int) (r.bottom)));                            }                            CityItem cityItem = new CityItem();                            cityItem.setCityId(id);                            cityItem.setCityName(title);                            cityItem.setmPath(path);                            cityItem.setmRegion(region);                            result.add(cityItem);                        }                    }                    parser.next();                }                Message msg = Message.obtain();                msg.what = LOAD_FINISH;                msg.obj = result;                mHander.sendMessage(msg);                Log.d("TAG", "加载SVG数据结束耗时->" + (System.currentTimeMillis() - startTime));            } catch (Exception e) {                e.printStackTrace();            }        }    }.start();}

svg文件里面的一个path节点对应解析成一个CityItem ,这样就可以遍历解析得到的List 数据去绘制出每一个Path

        for (CityItem cityItem : list) {        if (!cityItem.equals(selectCity))            cityItem.onDraw(canvas, mPaint, false);    }

完成当前操作效果如下

enter image description here

接下来就是加上交互效果,当点击某一个省份的时候,需要给当前选中的省份加上一个描边和不同的颜色。此时实现View的OnTouch方法,去判读用户点击的点是否包含于地图中的某一个省份,如果包含则将当前省份绘制为选中状态

 /** * 处理点击事件 * * @param x 点击的X坐标 * @param y 点击的Y坐标 */private boolean handlerTouch(int x, int y) {    final List<CityItem> list = cityItemList;    CityItem cityItem = null;    if (list == null) return false;    for (CityItem temp : list) {        if (temp.isOnTouch((int) (x / scale), (int) (y / scale))) {//除以放大倍数            cityItem = temp;            break;        }    }    if (cityItem != null && !cityItem.equals(selectCity)) {        selectCity = cityItem;        onMapClickListener.onClick(selectCity);        postInvalidate();    }    return selectCity != null;}

这样就去别出了选中和未选中的省份,同时通过onMapClickListener接口将选中的数据回调,接下来就是绘制出不同状态的地图

public void onDraw(Canvas canvas, Paint paint, boolean isSelected) {    if (isSelected) {        paint.setStrokeWidth(2);        paint.setColor(Color.BLUE);        paint.setStyle(Paint.Style.FILL);        paint.setShadowLayer(8, 0, 0, 0xFFFFFFFF);        canvas.drawPath(mPath, paint);        paint.clearShadowLayer();        paint.setColor(Color.BLUE);        paint.setStyle(Paint.Style.FILL);        paint.setStrokeWidth(2);        canvas.drawPath(mPath, paint);    } else {        paint.clearShadowLayer();        paint.setStrokeWidth(1);        paint.setStyle(Paint.Style.FILL);        paint.setColor(drawColor);        canvas.drawPath(mPath, paint);        paint.setStyle(Paint.Style.STROKE);        int strokeColor = 0xFFD0E8F4;        paint.setColor(strokeColor);        canvas.drawPath(mPath, paint);    }}

这样就基本实现一个简单地图的绘制与交互
项目源码 github ps:model->pathmap

原创粉丝点击