中国地图SVG绘制

package com.hwann.pathmeasurexu.maps;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;

import com.hwann.pathmeasurexu.R;
import com.hwann.pathmeasurexu.map.PathParser;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

/**
 * @author :yellow
 * @date: 2017/11/8  19:20
 * @update: 2017/11/8
 * @describe:
 */
public class Chians extends View {
    private Context context;
    private List itemList;
    private ProvinceltemS provin;
    private float scales = 0.8f;
    private int minWidth;
    private int minHeigth;
    private int[] colorArray = new int[]{0xFF239BD7, 0xFFFBB3E5, 0xFFBB2BD7};
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (itemList != null) {
                scales = viewWidth / rectMIN.width();
                float scales1 = viewHeight / rectMIN.height();
                scales = Math.min(scales, scales1);
                Log.i("1111","scales>>"+scales);
                int colorNunber = itemList.size();
                for (int i = 0; i < colorNunber; i++) {
                    int color = colorArray[0];
                    int flag = i % 4;
                    switch (flag) {
                        case 1:
                            color = colorArray[1];
                            break;
                        case 2:
                            color = colorArray[2];
                            break;
                        case 3:
                            color = colorArray[0];
                            break;
                    }
                    itemList.get(i).setColor(color);
                }
                postInvalidate();
            }
        }
    };
    private Paint paintW;
    private Paint paintm;
    private Path pathm;
    private float aniMoto;
    private int viewWidth;
    private int viewHeight;

    public Chians(Context context) {
        super(context);
    }

    public Chians(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init(context);
    }

    private void init(Context context) {
        itemList = new ArrayList<>();
        paintW = new Paint();
        paintm = new Paint();
        paintm.setAntiAlias(true);
        minHeigth = context.getResources().getDimensionPixelSize(R.dimen.map_max_height);
        minWidth = context.getResources().getDimensionPixelSize(R.dimen.map_min_width);
        paintm.setColor(Color.RED);
        paintm.setStrokeWidth(4);
        paintm.setStyle(Paint.Style.STROKE);
        pathm = new Path();
        thread.start();
        startVAnimation();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int heigthMode = MeasureSpec.getMode(heightMeasureSpec);
        int heigth = MeasureSpec.getSize(heightMeasureSpec);
        viewWidth = width;
        viewHeight = heigth;
        switch (widthMode) {
            case MeasureSpec.EXACTLY:
                viewWidth = width > minWidth ? width : minWidth;
                break;
            case MeasureSpec.AT_MOST:
            case MeasureSpec.UNSPECIFIED:
                viewWidth = minWidth;
                break;
        }
        //得到参考高度
        int computHeight = (minHeigth * viewHeight / minWidth);
        switch (heigthMode) {
            case MeasureSpec.EXACTLY:
                viewHeight = heigth;
                break;
            case MeasureSpec.AT_MOST:
            case MeasureSpec.UNSPECIFIED:
                //取最大的那个值
                viewHeight = minHeigth > computHeight ? minHeigth : computHeight;
                break;
        }
        setMeasuredDimension(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY));

    }

    GestureDetector gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onDown(MotionEvent e) {
            handerOnDown(e.getX(), e.getY());
            return true;
        }
    });

    private void handerOnDown(float x, float y) {
        if (itemList != null) {
            ProvinceltemS provinceltem = null;
            for (ProvinceltemS provinceltemS : itemList) {
                if (provinceltemS.isonTouth(x / scales, y / scales)) {
                    provinceltem = provinceltemS;
                    break;
                }
            }
            if (provinceltem != null) {
                provin = provinceltem;
                postInvalidate();
            }


        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();
        canvas.scale(scales, scales);
        for (int i = 0; i < itemList.size(); i++) {
            //没有被选中
            if (itemList.get(i) != provin) {
                itemList.get(i).onDrow(canvas, paintW, false);
            }
        }
        if (provin != null) {
            pathm.reset();
            pathm.lineTo(0, 0);
            provin.onDrow(canvas, paintW, true);
            PathMeasure pathMeasure = new PathMeasure(provin.getPath(), false);
            float pathLength = pathMeasure.getLength();
            pathMeasure.getSegment(pathLength * aniMoto - 100, pathLength * aniMoto, pathm, true);
            canvas.drawPath(pathm, paintm);
            postInvalidate();
        }


    }

    public void startVAnimation() {
        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
        animator.setDuration(1000);
        animator.setInterpolator(new LinearInterpolator());
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                aniMoto = (float) animation.getAnimatedValue();
            }
        });
        animator.start();
    }


    private RectF rectMIN;
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            InputStream inputStream = context.getResources().openRawResource(R.raw.chinas);
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builders = null;
            try {
                builders = builderFactory.newDocumentBuilder();
                Document doc = builders.parse(inputStream);
                Element element = doc.getDocumentElement();
                NodeList pathList = element.getElementsByTagName("path");
                float left = -1;
                float right = -1;
                float top = -1;
                float bottom = -1;
                for (int i = 0; i < pathList.getLength(); i++) {
                    Element elements = (Element) pathList.item(i);
                    String pathData = elements.getAttribute("android:pathData");
                    Path svgPath = PathParser.createPathFromPathData(pathData);
                    RectF rectF = new RectF();
                    svgPath.computeBounds(rectF, true);
                    left = left == -1 ? rectF.left : Math.min(rectF.left, left);
                    right = right == -1 ? rectF.right : Math.max(rectF.right, right);
                    top = top == -1 ? rectF.top : Math.min(rectF.top, top);
                    bottom = bottom == -1 ? rectF.bottom : Math.max(rectF.bottom, bottom);
                    ProvinceltemS provinceItem = new ProvinceltemS(svgPath);
                    itemList.add(provinceItem);
                }
                rectMIN = new RectF(left, top, right, bottom);
                handler.sendEmptyMessage(1);

            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            } catch (SAXException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }


        }
    });


}


绘制实体,这思路很不错
package com.hwann.pathmeasurexu.maps;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;

/**
 * @author :yellow
 * @date: 2017/11/8  19:21
 * @update: 2017/11/8
 * @describe:
 */
public class ProvinceltemS {

    private int color;


    private Path path;

    public ProvinceltemS(Path path) {
        this.path = path;
    }

    public Path getPath() {
        return path;
    }

    public void setColor(int color) {
        this.color = color;
    }

    public void onDrow(Canvas canvas, Paint paint, boolean isTouch) {
        //被选中
        if (isTouch) {
            //画阴影部分
            paint.setStrokeWidth(2);
            paint.setColor(Color.BLACK);
            paint.setStyle(Paint.Style.STROKE);
            paint.setShadowLayer(8, 0, 0, Color.BLUE);
            canvas.drawPath(path, paint);
            //画省份
            paint.clearShadowLayer();
            paint.setColor(color);
            paint.setStyle(Paint.Style.FILL);
            paint.setStrokeWidth(1);
            canvas.drawPath(path,paint);

        } else {
            //填充背景
            paint.clearShadowLayer();
            paint.setColor(color);
            paint.setStyle(Paint.Style.FILL);
            canvas.drawPath(path, paint);
            //绘制边界线
            paint.setStrokeWidth(1);
            paint.setColor(Color.BLUE);
            paint.setStyle(Paint.Style.STROKE);
            canvas.drawPath(path, paint);

        }

    }

    public boolean isonTouth(float x, float y) {
        RectF rectF = new RectF();
        getPath().computeBounds(rectF,true);
        Region region = new Region();
        region.setPath(path, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));

        return region.contains((int)x,(int)y);
    }


}

你可能感兴趣的:(中国地图SVG绘制)