簡體   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