IOS Android 地图 取点 支持地图的缩放,平移,旋转

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);

    }


}

代码至此结束

发布了18 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/INTKILOW/article/details/79773831
今日推荐