package com.demo.basic.customviews;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PathEffect;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import com.demo.basic.base.BaseSurfaceView;
import com.demo.basic.data.AppDatabase;
import com.demo.basic.data.beans.LocalMapBean;
import com.demo.basic.data.beans.MapBean;
import com.demo.basic.data.beans.MapPath;
import com.demo.basic.data.daos.LocalMapDao;
import com.demo.basic.net.ListenerAdapter;
import com.demo.basic.net.Requester;
import com.demo.basic.utils.PathUtil;
import com.demo.basic.utils.Pool;
import com.demo.basic.utils.ThreadPool;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Created by Wang.Wenhui
* Date: 2020/7/8
* Description: blablabla
*/
public class MapShowView extends BaseSurfaceView {
private LocalMapBean nowMapBean;
private List<MapPath> mapPaths;
private Map<LocalMapBean, List<MapPath>> insides;
private PathEffect dash;
private int selectCode = 0;
private float canvasScale;
private float baseX, baseY, scaleX, scaleY;
private RectF bounds;
private static final String base = "https://geo.datav.aliyun.com/areas_v2/bound/";
private boolean canTouch;
private String name = "";
private Matrix matrix, inverse;
private float[] pts;
private Pool<MapPath> pathPool;
private LocalMapDao mapDao;
public MapShowView(Context context) {
super(context);
}
public MapShowView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MapShowView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onInit() {
mapPaths = new CopyOnWriteArrayList<>();
mPaint.setTextAlign(Paint.Align.CENTER);
insides = new ConcurrentHashMap<>();
dash = new DashPathEffect(new float[]{5, 5}, 0);
bounds = new RectF();
if (canvasScale == 0) {
canvasScale = 1;
}
matrix = new Matrix();
inverse = new Matrix();
pts = new float[2];
mapDao = AppDatabase.getDatabase().localMapDao();
pathPool = new Pool<>(MapPath::new);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int size = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(size, size);
}
@Override
protected void onReady() {
callDraw("");
}
@Override
protected void onDataUpdate() {
}
@Override
protected void onRefresh(Canvas canvas) {
}
@Override
protected void draw(Canvas canvas, Object data) {
canvas.drawColor(0xFF20B2AA);
canvas.save();
transformCanvas(canvas);
drawMainArea(canvas);
drawChildAreas(canvas);
canvas.restore();
drawName(canvas);
}
private void transformCanvas(Canvas canvas) {
if (baseX != 0 || baseY != 0 || canvasScale != 1) {
matrix.reset();
matrix.preScale(canvasScale, canvasScale, scaleX, scaleY);
matrix.postTranslate(baseX, baseY);
canvas.concat(matrix);
}
}
private void drawMainArea(Canvas canvas) {
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(1.2f);
for (MapPath mapPath : mapPaths) {
canvas.drawPath(mapPath, mPaint);
}
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.FILL);
for (MapPath mapPath : mapPaths) {
canvas.drawPath(mapPath, mPaint);
}
mPaint.setStrokeWidth(0.5f);
}
private void drawChildAreas(Canvas canvas) {
for (Map.Entry<LocalMapBean, List<MapPath>> entry : insides.entrySet()) {
for (MapPath path : entry.getValue()) {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.BLACK);
mPaint.setPathEffect(dash);
canvas.drawPath(path, mPaint);
if (selectCode == entry.getKey().getAdCode()) {
mPaint.setPathEffect(null);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(0xFFFF8C00);
canvas.drawPath(path, mPaint);
}
}
}
}
private void drawName(Canvas canvas) {
mPaint.setPathEffect(null);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL);
float textSize = getMeasuredWidth() * 0.04f;
mPaint.setTextSize(textSize);
canvas.drawText(name, getMeasuredWidth() >> 1, textSize * 1.5f, mPaint);
}
@Override
protected void onDrawRect(Canvas canvas, Object data, Rect rect) {
}
@Override
protected boolean preventClear() {
return false;
}
private void setOnLineLocation(MapBean bean) {
canTouch = true;
selectCode = 0;
resetTransform();
resetPaths();
bounds.set(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
nowMapBean = getLocalMapBean(bean.getFeatures().get(0), true);
pos2Path(mapPaths, nowMapBean.getCoords(), true);
if (nowMapBean.getChildrenNum() > 0) {
List<LocalMapBean> list = new ArrayList<>();
list.add(nowMapBean);
Requester.getBean(base + nowMapBean.getAdCode() + "_full.json", new ListenerAdapter<MapBean>() {
@Override
public void onSucceed(MapBean mapBean) {
super.onSucceed(mapBean);
for (MapBean.FeaturesBean feature : mapBean.getFeatures()) {
if (feature.getProperties().getLevel() == null)
break;
MapPath path = new MapPath();
LocalMapBean localMapBean = getLocalMapBean(feature, false);
list.add(localMapBean);
List<MapPath> paths = new ArrayList<>();
pos2Path(paths, feature.getGeometry().getCoordinates(), false);
insides.put(localMapBean, paths);
}
callDraw("");
if (list.size() > 0) {
ThreadPool.fixed().execute(() -> mapDao.insertLocalMaps(list));
}
}
@Override
public void onFailed(Throwable throwable) {
super.onFailed(throwable);
Log.e("wwh", "MapShowView --> onFailed: " + throwable.getMessage());
}
});
} else {
ThreadPool.fixed().execute(() -> mapDao.insertLocalMap(nowMapBean));
}
name = nowMapBean.getName();
callDraw("");
}
private LocalMapBean getLocalMapBean(MapBean.FeaturesBean feature, boolean isFull) {
LocalMapBean localMapBean = new LocalMapBean();
localMapBean.setAdCode(feature.getProperties().getAdcode());
localMapBean.setName(feature.getProperties().getName());
localMapBean.setLevel(feature.getProperties().getLevel());
localMapBean.setChildrenNum(feature.getProperties().getChildrenNum());
localMapBean.setFull(isFull);
MapBean.FeaturesBean.PropertiesBean.ParentBean parent = feature.getProperties().getParent();
if (parent != null) {
localMapBean.setParent(parent.getAdcode());
}
localMapBean.setCoords(feature.getGeometry().getCoordinates