【问题标题】:Draw grid over polygon in osmdroid bonus pack在 osmdroid 奖励包中在多边形上绘制网格
【发布时间】:2016-01-20 18:16:44
【问题描述】:

我搜索了所有互联网,但没有找到问题的答案。我正在使用osmdroid,我想在多边形上添加网格,如图所示。我在 stackoverflow 中找到了一个类似的question,但这个问题没有答案。那么请告诉我这可能吗?

【问题讨论】:

    标签: android osmdroid offlineapps mapping


    【解决方案1】:

    @Mker 给出了一个很好的起点:BitmapShader

    这是一个示例代码:

    public class GridPolygon extends Polygon {
    
        private BitmapShader bitmapShader;
    
        public GridPolygon(Context ctx) {
            super(ctx);
        }
    
        public void setPatternBMP(@NonNull final Bitmap patternBMP) {
            bitmapShader = new BitmapShader(patternBMP, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
            mFillPaint.setShader(bitmapShader);
        }
    }
    

    用法:

    final GridPolygon polygon = new GridPolygon(context);
    polygon.setPoints(geoData);
    polygon.setFillColor(fillColor);
    polygon.setStrokeColor(strokeColor);
    polygon.setStrokeWidth(strokeWidth);
    polygon.setPatternBMP(BitmapFactory.decodeResource(getResources(), R.drawable.pattern));
    map.getOverlays().add(polygon);
    map.invalidate();
    

    但如果您尝试移动多边形,您可能会感到困惑 - 位图不想移动:

    为避免这种情况,您应该计算着色器的偏移量:

    public class GridPolygon extends Polygon {
    
        private BitmapShader bitmapShader;
        private IGeoPoint lastCenterGeoPoint;
        private int xOffset = 0;
        private int yOffset = 0;
    
        public GridPolygon(Context ctx) {
            super(ctx);
        }
    
        public void setPatternBMP(@NonNull final Bitmap patternBMP) {
            bitmapShader = new BitmapShader(patternBMP, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
            mFillPaint.setShader(bitmapShader);
        }
    
        protected void recalculateMatrix(@NonNull final MapView mapView) {
            //final int mapSize = TileSystem.MapSize(mapView.getZoomLevel());
    
            final Projection projection = mapView.getProjection();
            final IGeoPoint geoPoint = mapView.getMapCenter();
            if (lastCenterGeoPoint == null) lastCenterGeoPoint = geoPoint;
    
            final Point point = projection.toPixels(geoPoint, null);
            final Point lastCenterPoint = projection.toPixels(lastCenterGeoPoint, null);
    
            xOffset += lastCenterPoint.x - point.x;
            yOffset += lastCenterPoint.y - point.y;
    
            xOffset %= 100; // 100 is pixel size of shader image
            yOffset %= 100;
    
            final Matrix matrix = new Matrix();
            matrix.reset();
            matrix.setScale(1,1);
            matrix.preTranslate(xOffset, yOffset);
            //matrix.setTranslate(xOffset, yOffset);
            bitmapShader.setLocalMatrix(matrix);
    
            mFillPaint.setShader(bitmapShader);
    
            lastCenterGeoPoint = geoPoint;
        }
    
        @Override
        protected void draw(Canvas canvas, MapView mapView, boolean shadow) {
            recalculateMatrix(mapView);
            super.draw(canvas, mapView, shadow);
        }
    }
    

    结果:

    Full source code.

    【讨论】:

      【解决方案2】:

      是的,这是可能的。

      有一些潜在的解决方案。 1)假设有人很好地制作了满足您需求的kml文件,则可以使用osmbonuspack直接导入kml文件。

      2) 以编程方式自己制作。所以你有一些任务。

      a) 将多边形设为叠加层 b) 将网格作为叠加层 c) 按该顺序将它们添加到地图视图中。这应该使网格位于多边形的顶部。

      现在进入细节。制作多边形是微不足道的,所以不会在这里介绍。

      制作网格也不是太难。您需要知道网格的边界,然后从东、西边界以从北边界到南边界的一定间隔放置线。然后对南北线做相反的事情。日期变更线、赤道和两极有特殊情况,请记住这一点。

      在这种情况下计算行间隔有点简单,您可以通过两种方式解决它。使用十进制的固定间隔或根据缩放级别计算。后面的部分更难,但通常会提供更好的可视化效果(当您放大时,网格会重新绘制并且在该缩放级别看起来更合适)。

      重要提示,对于 osmbonuspack 和 osmdroid,如果您提供的覆盖线超出视图边界(如果硬件加速已关闭),您可能会遇到内存不足错误。如果启用了硬件加速,那么如果起点和终点都在屏幕外一定的距离,则线条可能根本不显示。长话短说,对于相对较小的距离,您应该没问题,否则,您必须在地图平移和缩放时剪辑视图边界。

      我用 osmbonuspack 做了类似的事情来显示纬度/经度网格线,这些网格线会随着您的放大和平移而调整(意味着间隔会根据缩放级别进行调整)。如果这是一个要求,那么您也许可以重用代码,该代码基本上计算了绘制网格的每条线的距离和位置。

      【讨论】:

        【解决方案3】:

        现在,如果您只想将网格绘制为图案(对网格线位置没有限制),则应该有一个简单的替代方案,即使用“着色器”:

        fillPaint.setShader(patternBMPshader);
        

        完整示例:http://code.tutsplus.com/tutorials/android-sdk-drawing-with-pattern-fills--mobile-19527

        坏消息,多边形填充涂料没有吸气剂。好消息,该属性是受保护的,而不是私有的。 所以你可以继承 Polygon,并添加 getter:

        Paint getFillPaint(){
          return mFillPaint;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多