【问题标题】:Fixed (zoom independent) Rectangle Google Map固定(独立缩放)矩形谷歌地图
【发布时间】:2017-11-08 10:30:17
【问题描述】:

如何在地图上添加一个代表屏幕 80% 宽度和 80% 高度的矩形,例如地图离线区域选择屏幕。我需要得到这个矩形的 LatLngBound,LinearLayout 可能不是这里的解决方案。

【问题讨论】:

    标签: android google-maps shape offline


    【解决方案1】:

    你可以通过getProjection()方法得到LatLon的像素坐标,并在custom viewonDraw()方法中画出你想要的一切。

    因此,就像在NSimonthis 答案中一样,只需在您的地图活动布局xml 中添加具有MapFragment 所需透明度的自定义视图(例如FrameView):

    <fragment
        android:id="@+id/map_fragment"
        android:name="com.google.android.gms.maps.MapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
    <[your_package].FrameView
        android:id="@+id/frame_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    

    [your_package].FrameView 在哪里

    public class FrameView extends View {
    
        private Paint mTransparentPaint;
        private Paint mBorderPaint;
        private Paint mSemiBlackPaint;
        private Path mPath = new Path();
        private GoogleMap mGoogleMap = null;
        private float x1, y1, x2, y2;
    
        public FrameView(Context context) {
            super(context);
            init();
        }
    
        public FrameView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public FrameView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
            mTransparentPaint = new Paint();
            mTransparentPaint.setColor(Color.TRANSPARENT);
            mTransparentPaint.setStyle(Paint.Style.FILL);
    
            mBorderPaint = new Paint();
            mBorderPaint.setColor(Color.BLUE);
            mBorderPaint.setStyle(Paint.Style.STROKE);
            mBorderPaint.setStrokeWidth(10);
    
            mSemiBlackPaint = new Paint();
            mSemiBlackPaint.setColor(Color.TRANSPARENT);
            mSemiBlackPaint.setStyle(Paint.Style.FILL);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            x1 = 0.1f * canvas.getWidth();
            y1 = 0.1f * canvas.getHeight();
            x2 = 0.9f * canvas.getWidth();
            y2 = 0.8f * canvas.getHeight();
    
            mPath.reset();
    
            mPath.addRect(x1, y1, x2, y2, Path.Direction.CW);
            mPath.setFillType(Path.FillType.INVERSE_EVEN_ODD);
    
            canvas.drawRect(x1, y1, x2, y2, mTransparentPaint);
            canvas.drawRect(x1, y1, x2, y2, mBorderPaint);
            canvas.drawPath(mPath, mSemiBlackPaint);
    
            canvas.clipPath(mPath);
            canvas.drawColor(Color.parseColor("#83000000"));
        }
    
        public void setMap(GoogleMap googleMap) {
            mGoogleMap = googleMap;
        }
    
        public LatLng getTopLeft() {
            return point2LatLng(new Point((int)x1, (int)y1));
        }
    
        public LatLng getTopRight() {
            return point2LatLng(new Point((int)x2, (int)y1));
        }
    
        public LatLng getBottomLeft() {
            return point2LatLng(new Point((int)x1, (int)y2));
        }
    
        public LatLng getBottomRight() {
            return point2LatLng(new Point((int)x2, (int)y2));
        }
    
        public LatLng point2LatLng(Point point) {
            if (mGoogleMap != null) {
                Projection projection = mGoogleMap.getProjection();
                return projection.fromScreenLocation(point);
            } else {
                return null;
            }
        }
    
    }
    

    其中 x1, x2, y1, y2 - “框架”矩形的坐标(以像素为单位)。

    你需要在onCreate() 中获取FrameView 对象:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mFrameView = (FrameView) findViewById(R.id.frame_view);
        mapFragment = (MapFragment) getFragmentManager()
                .findFragmentById(R.id.map_fragment);
        mapFragment.getMapAsync(this);
    
        ...
    }
    

    并在onMapReady() 中为mFrameView 设置GoogleMap 对象:

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
        mFrameView.setMap(mGoogleMap);
        ...
    }
    

    现在您可以在需要时通过mFrameView.getTopLeft()mFrameView.getTopRight() 等来电获取LatLon 坐标:

    注意!这只是自定义组件的快速而肮脏的示例。

    【讨论】:

    • getProjection() 是我错过的部分...听起来很完美!为什么说“又快又脏”?
    • @Daminox 因为以正确的方式FrameViewGoogleMap 应该是一个复合自定义视图:setMap() 正在工作,但不是很好的方法。并且没有必要在每个 point2LatLng() 调用和 "#83000000" 上创建新的 Point 对象 - 错误的常量,以及蓝色矩形周围的暗框等等 :)
    • 好的,所以在这种情况下,我不应该使用 MapFragment,而是使用自定义片段。对吗?
    • @Daminox 是的,自定义地图片段。
    猜你喜欢
    • 2018-09-08
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    • 2012-09-08
    • 2012-11-06
    • 1970-01-01
    相关资源
    最近更新 更多