您的位置:首页 > 其它

中国地图SVG绘制

2017-11-09 13:47 405 查看
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<ProvinceltemS> 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);}}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: