我搜索了所有网络,但我找不到问题的答案。我正在使用osmdroid
,我想在图像中显示多边形网格。我在stackoverflow中发现了一个类似的question,但这个问题没有答案。那么请告诉我可能吗?
答案 0 :(得分: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);
}
}
结果:
答案 1 :(得分:0)
是的,这是可能的。
有一些潜在的解决方案。 1)假设有人做得足以制作满足您需求的kml文件,可以使用osmbonuspack直接导入kml文件。
2)以编程方式自己创建。所以你有一些任务。
a)将多边形作为叠加层 b)将网格作为叠加层 c)按顺序将它们添加到地图视图中。这应该使网格位于多边形的顶部。
现在谈谈细节。制作多边形是微不足道的,所以不要在这里覆盖它。
使网格也不太难。您需要知道网格的边界,然后从北边界到南边界以一定间隔放置东,西边界线。然后在南北线做相反的事情。在日期线,赤道和两极都有特殊情况,所以请记住这一点。
在这种情况下计算行间隔有点简单,您可以通过两种方式解决它。使用十进制度的固定间隔或根据缩放级别计算。后面的部分更难,但通常会提供更好的可视化效果(当您放大时,网格重绘并在该缩放级别看起来更合适)。
重要提示,使用osmbonuspack和osmdroid,如果给出超出视图边界的覆盖线(如果硬件加速关闭),则可能会遇到内存不足错误。如果启用了硬件加速,则如果起点和终点都在屏幕外一定的余量,则可能根本不显示线条。长话短说,对于相对较小的距离,你应该没问题,否则,你必须在地图平移和缩放的视图边界处剪辑。
我用osmbonuspack做了类似的事情来显示lat / lon网格线,当你放大和平移时调整它们(意味着间隔根据缩放级别调整)。如果这是一项要求,那么您可能只需重复使用代码,该代码主要计算绘制网格每一行的距离和位置。
答案 2 :(得分:0)
现在,如果你只想将网格绘制为一个模式(没有关于网格线位置的约束),那么使用“着色器”应该有一个简单的替代方法:
fillPaint.setShader(patternBMPshader);
完整示例:http://code.tutsplus.com/tutorials/android-sdk-drawing-with-pattern-fills--mobile-19527
坏消息,没有Polygon填充漆的吸气剂。好消息是,属性受到保护,而不是私有。 所以你可以继承Polygon,并添加getter:
Paint getFillPaint(){
return mFillPaint;
}