IOS Android 地图 取点 支持地图的缩放,平移,旋转
废话不多说 先看效果
直接上代码
———IOS———
主要介绍2个方法
需要把屏幕横屏
平移,缩放 (旋转未做)
// 屏幕宽高
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGTH [UIScreen mainScreen].bounds.size.height
//状态栏大小
#define SCREEN_OFFSET 64
//先定义几个变量 一会要用到
float screenHight , screenWidth , gridHight , gridWidth ,X,Y;
float scale , centerX , centerY, oldDX , oldDY,angle;
float MAX_SCALE,MIN_SCALE;
初始化时调用
//初始化
[self startGridHW:image.size.height :image.size.width andScreenHW:SCREEN_WIDTH- SCREEN_OFFSET :SCREEN_HEIGTH];
imgv1 = [[UIImageView alloc]initWithFrame:CGRectMake(centerX, centerY,scale*image.size.width,scale*image.size.height)];
imgv1.userInteractionEnabled = YES;
[self.view addSubview:imgv1];
//平移
-(void)doMoveAction:(UIPanGestureRecognizer *)recognizer{
// Figure out where the user is trying to drag the view.
CGPoint translation = [recognizer translationInView:imgv1];//得到偏移量
float distanceX = translation.x;
float distanceY = translation.y;
//计算一下地图上的xy坐标进行限制
float tX = ((X-distanceX) / scale);
float tY = ((Y+distanceY) / scale);
if(tX >0 && tX < gridWidth){
X = X - distanceX;
centerX += distanceX;
oldDX += distanceX;//记录总的偏移量,缩放时使用
}else{
distanceX = 0;
}
if(tY >0 && tY < gridHight){
Y = Y + distanceY;
centerY += distanceY;
oldDY += distanceY;
}else{
distanceY = 0;
}
[imgv1 setCenter:(CGPoint){ imgv1.center.x+distanceX,imgv1.center.y +distanceY}];
[recognizer setTranslation:CGPointZero inView:imgv1.superview];
// self.label.text = [NSString stringWithFormat:@"(%.f,%.f)",X/scale,Y/scale];
}
缩放
-(void)onScale:(UIPinchGestureRecognizer*)gesture
{
//临时变量保存 缩放比例 如果符合把缩放比例赋值
float scaleFactor = gesture.scale;
float tempScale =scale * scaleFactor;
if(tempScale>=MIN_SCALE&&tempScale<=MAX_SCALE){
float currentX = ((gridWidth * tempScale / 2 - oldDX)/tempScale);
float currentY = ((gridHight * tempScale / 2 + oldDY)/tempScale);
if(currentX > 0 && currentX < gridWidth && currentY > 0 && currentY < gridHight){
scale = scale*scaleFactor;
centerX = (screenWidth - gridWidth * scale) / 2 + oldDX;
centerY = (screenHight - gridHight * scale) / 2 + oldDY;
//计算缩放后新的坐标点
X = gridWidth * scale / 2 - oldDX;
Y = gridHight * scale / 2 + oldDY;
//图像的平移
imgv1.transform = CGAffineTransformScale(imgv1.transform, scaleFactor, scaleFactor);
//画出坐标
// self.label.text = [NSString stringWithFormat:@"(%.f,%.f)",X/scale,Y/scale];
}
}
//及时处理手势缩放
gesture.scale = 1;
}
初始化
//初始化 在draw 调用
-(void)startGridHW:(int)gridH :(int)gridW andScreenHW:(int)screenH :(int)screenW
{
//设置最大 最小缩放比例
MAX_SCALE = 3;
MIN_SCALE = 0.2;
//设置屏幕 宽高 绘制区域
screenHight = screenH;
screenWidth = screenW;
//地图 的宽高
gridWidth = gridW;
gridHight = gridH;
//计算一下初始的缩放比例
scale = screenHight / gridHight;
//计算图片移动到屏幕中心坐标
centerY = (screenHight - gridHight * scale) / 2 + SCREEN_OFFSET;
centerX = (screenWidth - gridWidth * scale) / 2;
//计算在scale 缩放比例下 中心点的坐标
//X,Y 分别除当前的缩放比例即为地图上的缩放比例
X = gridWidth * scale / 2;
Y = gridHight * scale / 2;
}
———Android———
/**
* 自定义控件的基类
* Created by 咸鱼1号 on 2018/1/17.
*/
public abstract class GSBaseView extends View {
protected int screenHight = 0, screenWidth = 0, gridHight = 0, gridWidth = 0;
protected float scale = 0, centerX = 0, centerY = 0, oldDX = 0, oldDY = 0,angle=0;
protected boolean isFirst = true;
protected float MIN_SCALE = 0.7f,MAX_SCALE=0.7f;
protected Paint paint;
protected int refreshTime = 24;
/**
* 初始化方法
*/
protected abstract void init();
/**
* 旋转操作
*
* @param degree 旋转角度
*/
protected abstract void rotation(float degree);
/**
* 图像缩放操作
*
* @param scaleFactor 缩放比例因子
*/
protected abstract void scale(float scaleFactor);
/**
* 图像平移操作
*
* @param distanceX x方向的位移
* @param distanceY y方向的位移
*/
protected abstract void translation(float distanceX, float distanceY);
public GSBaseView(Context context) {
super(context);
init();
}
public GSBaseView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public GSBaseView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
}
//地图的缩放
public class GSBitMapView extends GSBaseView implements Runnable {
private Matrix matrix ;
private float defalut = -1f,X, Y;
private Bitmap bitmap = null;
private boolean isRunning = true;
public GSBitMapView(Context context) {
super(context);
}
public GSBitMapView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void init() {
paint = new Paint();
matrix = new Matrix();
MAX_SCALE = 5f;
MIN_SCALE = 0.5f;
scale = 1f;
}
@Override
protected void rotation(float degree) {
// angle +=degree;
angle += (float) (degree * 180 / Math.PI);
// Log.e("TAG","degree"+angle);
}
@Override
protected void scale(float scaleFactor) {
scale = scale * scaleFactor;
scale = scale >= MAX_SCALE ? MAX_SCALE : scale;
scale = scale <= MIN_SCALE ? MIN_SCALE : scale;
int currentX = (int) ((gridWidth * scale / 2 - oldDX)/scale);
int currentY = (int) ((gridHight * scale / 2 + oldDY)/scale);
if(currentX > 0 && currentX < gridWidth && currentY > 0 && currentY < gridHight){
centerX = (screenWidth - gridWidth * scale) / 2 + oldDX;
centerY = (screenHight - gridHight * scale) / 2 + oldDY ;
X = gridWidth * scale / 2 - oldDX;
Y = gridHight * scale / 2 + oldDY;
defalut = scale;
}else{
scale = defalut;
}
}
// 左移动限制- //右移动限制+
@Override
protected void translation(float distanceX, float distanceY) {
int tX = (int) ((X-distanceX) / scale);
int tY = (int) ((Y+distanceY) / scale);
if(tX >0 && tX < gridWidth){
X = X - distanceX;
centerX += distanceX;
oldDX += distanceX;
}
if(tY >0 && tY < gridHight){
Y = Y + distanceY;
centerY += distanceY;
oldDY += distanceY;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(isFirst){
isFirst = false;
new Thread(this).start();
}
drawBitMap(canvas,bitmap);
}
private void drawBitMap(Canvas canvas, Bitmap bitmap){
if(bitmap!=null){
matrix.setTranslate(centerX, centerY);
matrix.postScale(scale, scale, centerX, centerY);
matrix.postRotate(angle, centerX + gridWidth * scale / 2, centerY + gridHight * scale / 2);
// Log.e("TAG", "centerX" + centerX + "centerY" + centerY);
canvas.drawBitmap(bitmap, matrix, paint);
// Log.e("TAG", "scale scale" + scale);
}
}
public void setData(Bitmap bitmap){
screenHight = getHeight();
screenWidth = getWidth();
this.bitmap = bitmap;
gridWidth = bitmap.getWidth();
gridHight = bitmap.getHeight();
if(defalut<0){
scale =(float) screenHight / gridHight;
defalut = scale;
}
centerY = (screenHight - gridHight * scale) / 2;
centerX = (screenWidth - gridWidth * scale) / 2;
X = gridWidth * scale / 2;
Y = gridHight * scale / 2;
}
@Override
public void run() {
while(isRunning){
try {
Thread.sleep(refreshTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
postInvalidate();
}
}
public void onDestory(){
try {
isRunning = false;
if (bitmap != null && !bitmap.isRecycled()) {
bitmap.recycle();
bitmap = null;
}
} catch (Throwable t) {
}
}
}
取点的相关操作
public class GSMapEdit extends GSBaseView implements Runnable {
private LinkedList<GPoint> points = new LinkedList<>();
private boolean isRunning = true;
private Paint linePaint;
private float X, Y, currentX, currentY,dirctorAngle=0;
private float defalut = -1f;
private Point currentPoint = new Point();
private boolean isLine = false,isDrawCenter = true;
private Matrix dirctorsMatrix ;
private Bitmap dirctors = null;
public GSMapEdit(Context context) {
super(context);
}
public GSMapEdit(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void init() {
paint = new Paint();
paint.setStrokeWidth(15);
paint.setTextSize(16);
paint.setColor(Color.RED);
linePaint = new Paint();
linePaint.setTextSize(16);
linePaint.setStrokeWidth(10);
linePaint.setColor(Color.BLUE);
scale = 1f;
MAX_SCALE = 5f;
MIN_SCALE = 0.5f;
dirctorsMatrix = new Matrix();
}
@Override
protected void rotation(float degree) {
angle += (float) (degree * 180 / Math.PI);
}
@Override
protected void scale(float scaleFactor) {
//Log.e("TAG","scaleFactor:"+scaleFactor);
scale = scale * scaleFactor;
scale = scale >= MAX_SCALE ? MAX_SCALE : scale;
scale = scale <= MIN_SCALE ? MIN_SCALE : scale;
//1184 832
int tX = (int) ((gridWidth * scale / 2 - currentX)/scale);
int tY = (int) ((gridHight * scale / 2 + currentY)/scale);
if(tX >0 && tX < gridWidth && tY >0 && tY < gridHight){
centerX = (screenWidth - gridWidth * scale) / 2 + currentX;
centerY = (screenHight - gridHight * scale) / 2 + currentY;
X = gridWidth * scale / 2 - currentX;
Y = gridHight * scale / 2 + currentY;
currentPoint.x = (int) (X / scale);
currentPoint.y = (int) (Y / scale);
defalut = scale;
}else{
scale = defalut;
}
}
@Override
protected void translation(float distanceX, float distanceY) {
int tX = (int) ((X-distanceX) / scale);
int tY = (int) ((Y+distanceY) / scale);
if(tX > 0 && tX < gridWidth){
X = X - distanceX;
centerX += distanceX;
currentX += distanceX;
currentPoint.x = (int) (X / scale);
}
if(tY >0 && tY < gridHight){
Y = Y + distanceY;
centerY += distanceY;
currentY += distanceY;
currentPoint.y = (int) (Y / scale);
}
// Log.e("TAG","currentX"+currentX+"currentY"+currentY);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isFirst) {
isFirst = false;
dirctors = BitmapFactory.decodeResource(getResources(), R.drawable.dirctors);
new Thread(this).start();
}
if (gridHight != 0) {
if(isDrawCenter){
dirctorsMatrix.setTranslate(screenWidth / 2 , screenHight / 2 - dirctors.getHeight()/2);
dirctorsMatrix.postRotate(dirctorAngle, screenWidth / 2, screenHight / 2 );
// dirctorsMatrix.postScale(3/4f, 3/4f, screenWidth / 2, screenHight / 2);
canvas.drawBitmap(dirctors, dirctorsMatrix, paint);
canvas.drawText("("+currentPoint.x +","+currentPoint.y+")",screenWidth / 2,screenHight / 2 - 20,paint);
canvas.drawCircle(screenWidth / 2, screenHight / 2,8, paint);
}
canvas.translate(centerX, centerY);
canvas.rotate(angle, gridWidth * scale / 2, gridHight * scale / 2);
drawPoint(canvas,isLine);
}
}
public void setDirctorAngle(float angle){
// dirctorAngle = (float) Math.toRadians(angle);
dirctorAngle = angle;
}
private void drawPoint(Canvas canvas,boolean isLine) {
int size = points.size();
if (size > 0) {
if(isLine){
canvas.drawLine((points.get(size - 1).getX()) * scale, (gridHight - points.get(size - 1).getY()) * scale,
(currentPoint.x) * scale, (gridHight - currentPoint.y) * scale, linePaint);
for (int i = 0; i < size - 1; i++) {
GPoint start = points.get(i);
GPoint end = points.get(i + 1);
canvas.drawLine((start.getX()) * scale, (gridHight - start.getY()) * scale,
(end.getX()) * scale, (gridHight - end.getY()) * scale, linePaint);
}
}else{
for (int i = 0; i < size - 1; i++) {
GPoint start = points.get(i);
GPoint end = points.get(i + 1);
canvas.drawCircle((start.getX()) * scale, (gridHight - start.getY()) * scale , 8, linePaint);
canvas.drawText(start.getName(), (start.getX()) * scale+10, (gridHight - start.getY()) * scale, linePaint);
canvas.drawCircle((end.getX()) * scale, (gridHight - end.getY()) * scale, 8, linePaint);
canvas.drawText(end.getName(), (end.getX()) * scale+10, (gridHight - end.getY()) * scale , linePaint);
}
}
}
}
public boolean isDrawCenter() {
return isDrawCenter;
}
public void setDrawCenter(boolean drawCenter) {
isDrawCenter = drawCenter;
}
/**
* 获取当前画线点的状态
* @return
*/
public boolean isLine() {
return isLine;
}
/**
* 设置划线还是画点
* @param line
*/
public void setLine(boolean line) {
isLine = line;
}
@Override
public void run() {
while (isRunning) {
try {
Thread.sleep(refreshTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
postInvalidate();
}
}
public void onDestory() {
try {
isRunning = false;
if(dirctors != null && !dirctors.isRecycled()){
dirctors.recycle();
dirctors = null;
}
}catch (Throwable t){}
}
/**
* 添加点
*/
public void add() {
GPoint point = new GPoint();
point.set(currentPoint.x, currentPoint.y);
points.add(point);
}
/**
* 撤销点
*/
public void reduce(){
if(points!=null&&points.size()>0){
points.remove(points.size()-1);
}
}
/**
* 获取当前点
* @return
*/
public Point getCurrentPoint() {
return currentPoint;
}
/**
* 获取所有点
* @return
*/
public LinkedList<GPoint> getPoints() {
return points;
}
/**
* 设置地图点
* @param p
*/
public void setPoints(LinkedList<GPoint> p) {
if(p!=null&&p.size()>0){
points.clear();
points.addAll(p);
}
}
/**
* 初始化 网格
* @param girdW
* @param girdH
*/
public void setGirHWAndScale(int girdW, int girdH) {
screenHight = getHeight();
screenWidth = getWidth();
gridHight = girdH;
gridWidth = girdW;
if (defalut < 0) {
scale = (float) screenHight / gridHight;
defalut = scale;
}
centerY = (screenHight - gridHight * scale) / 2;
centerX = (screenWidth - gridWidth * scale) / 2;
X = gridWidth * scale / 2;
Y = gridHight * scale / 2;
currentPoint.x = (int) (X / scale);
currentPoint.y = (int) (Y / scale);
}
}