简体   繁体   English

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

[英]Draw grid over polygon in osmdroid bonus pack

I have searched all internet but I don't find answer to my problem .I'm using osmdroid and I want to add grid over polygon as shown in image. 我已经搜索了所有互联网,但是找不到我的问题的答案。我使用的是osmdroid ,我想在多边形上添加网格,如图所示。 I found one similar question in stackoverflow but this question doesn't have answer. 我在stackoverflow中发现了一个类似的问题 ,但是这个问题没有答案。 So please tell me is that possible? 所以请告诉我这可能吗?

在此处输入图片说明

@Mker gave a good point to start: BitmapShader . @Mker提供了一个很好的起点: BitmapShader

Here is a sample code: 这是一个示例代码:

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

Usage: 用法:

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

But you might be confused if you tried to move the polygon - the bitmap doesn't want to move: 但是如果您尝试移动多边形,可能会感到困惑-位图不想移动:

描述

To avoid this you should calculate the offset for your shader: 为了避免这种情况,您应该计算着色器的偏移量:

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

Result: 结果:

在此处输入图片说明

Full source code . 完整的源代码

Yes it's possible. 是的,有可能。

There's a few potential solutions. 有一些潜在的解决方案。 1) Assuming someone was nice enough to make a kml file that meets your needs, the kml file can be directly imported using osmbonuspack. 1)假设某人足够友好,可以制作满足您需求的kml文件,则可以使用osmbonuspack直接导入kml文件。

2) Make it yourself programatically. 2)以编程方式自行制作。 So you have a few tasks. 因此,您有一些任务。

a) Make the polygon as an overlay b) Make the grid as an overlay c) Add them to the map view in that order. a)将多边形作为叠加层b)将网格作为叠加层c)按该顺序将其添加到地图视图中。 This should make the grid be on top of the polygon. 这应该使网格位于多边形的顶部。

Now on to the details. 现在到细节。 Making the polygon is trivial so won't cover this here. 制作多边形是微不足道的,因此这里不做介绍。

Making the grid isn't too hard either. 建立网格也不太困难。 You need to know the bounds of the grid, then place lines from the east, west bounds at some interval from the north bounds to the south bounds. 您需要知道网格的边界,然后从北边界到南边界以一定的间隔放置东西边界的线。 Then do the opposite for north south lines. 然后对南北线执行相反的操作。 There's special cases at the date line, equator, and poles so keep that in mind. 在日期线,赤道和极点处有特殊情况,因此请记住这一点。

Calculating the line interval in this case is somewhat simple and you can tackle it two ways. 在这种情况下,计算行距比较简单,您可以通过两种方法解决。 Use a fixed interval in degrees decimal or calculate based on zoom level. 使用以十进制度度为单位的固定间隔或根据缩放级别进行计算。 The later part is harder but generally gives a better visualization (when you zoom in, the grid redraws and looks more appropriate at that zoom level). 后面的部分比较难,但是通常会提供更好的可视化效果(放大时,网格会重新绘制,并且在该缩放级别看起来更合适)。

Important note, with osmbonuspack and osmdroid, you may run into out of memory errors if you give the overlay lines that are way outside of the bounds of the view (if hardware acceleration is off). 重要说明,使用osmbonuspack和osmdroid,如果提供的叠加线超出视图范围(如果关闭了硬件加速),则可能会遇到内存不足错误。 If hardware acceleration is on, then lines may not show at all if both the start and end points are off screen by a certain margin. 如果启用了硬件加速,则如果起点和终点都在屏幕外一定距离,则线条可能根本不会显示。 Long story short, for relatively small distances, you should be fine, otherwise, you have to clip at the view bounds on map panning and zooming. 长话短说,对于相对较小的距离,您应该没事,否则,您必须在地图平移和缩放时限制视图范围。

I've done similar things with osmbonuspack for displaying lat/lon grid lines that adjust as you zoom in and pan (meaning the interval adjusts based on on zoom level). 我用osmbonuspack做过类似的事情,以显示经纬度调整的纬度/经度网格线(这意味着间隔会根据缩放级别进行调整)。 If that's a requirement, then you might be able to just reuse the code, which essentially calculates about how far away and where to draw each line of the grid. 如果这是必需的,那么您也许可以只重用代码,该代码实际上计算了网格的多远和绘制每行的位置。

Now, if you just want to draw the grid as a pattern (no constraint about grid lines positions), there should be a simple alternative by using a "shader": 现在,如果您只想将网格绘制为图案(对网格线位置没有限制),则应该使用“着色器”进行简单的选择:

fillPaint.setShader(patternBMPshader);

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

Bad news, there is no getter of the Polygon fill paint. 坏消息是,多边形填充漆没有吸气剂。 Good news, the attribute is protected, not private. 好消息是,该属性是受保护的,而不是私有的。 So you can subclass Polygon, and add the getter: 因此,您可以继承Polygon的子类,并添加getter:

Paint getFillPaint(){
  return mFillPaint;
}

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

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