繁体   English   中英

在osmdroid奖励包中的多边形上绘制网格

[英]Draw grid over polygon in osmdroid bonus pack

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

在此处输入图片说明

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

结果:

在此处输入图片说明

完整的源代码

是的,有可能。

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

2)以编程方式自行制作。 因此,您有一些任务。

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

现在到细节。 制作多边形是微不足道的,因此这里不做介绍。

建立网格也不太困难。 您需要知道网格的边界,然后从北边界到南边界以一定的间隔放置东西边界的线。 然后对南北线执行相反的操作。 在日期线,赤道和极点处有特殊情况,因此请记住这一点。

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

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

我用osmbonuspack做过类似的事情,以显示经纬度调整的纬度/经度网格线(这意味着间隔会根据缩放级别进行调整)。 如果这是必需的,那么您也许可以只重用代码,该代码实际上计算了网格的多远和绘制每行的位置。

现在,如果您只想将网格绘制为图案(对网格线位置没有限制),则应该使用“着色器”进行简单的选择:

fillPaint.setShader(patternBMPshader);

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

坏消息是,多边形填充漆没有吸气剂。 好消息是,该属性是受保护的,而不是私有的。 因此,您可以继承Polygon的子类,并添加getter:

Paint getFillPaint(){
  return mFillPaint;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM