如何在特定边界框的 osmdroid 地图上加载 geoserver WMS 图层?
我正在使用 osmdroid 库在我的应用程序中显示地图视图。我必须在我的 osm 地图中加载 wms 图层以显示村庄边界。
我在谷歌和堆栈溢出上进行搜索,发现以下博客和帖子
- 如何将 OSMDroid 与私人提供商使用的网络地图服务 (WMS) 配合使用?
- 带有自定义 wms 图块提供程序的 Android Mapview
- 在带有 GeoServer 的 Android 应用程序中使用 getTileURL
- https://osmdroid.github.io/osmdroid/Map-Sources.html
- < a href="https://docs.geoserver.org/latest/en/user/services/wms/reference.html#getmap" rel="nofollow noreferrer">https://docs.geoserver.org/latest/en/user/services/wms/reference.html#getmap
我引用了这些并尝试实现相同的,我能够在 osm 上加载 wms 层映射成功。但它是在多个循环中加载的,您可以在下图中看到
我希望此 wms 图层仅加载到我在 wms Api url 中传递的提到的边界框中。
我调用 wms 层 api
public class TileProviderFactory {
private static final String TAG = "TileProviderFactory";
private String version = "1.1.0";
private String url = "http://49.206.244.230:8080/geoserver/cfr/wms";
private String layers = "cfr:bastar_villages";
public WMSTileProvider getWmsTileProvider() {
String[] baseUrl = {url};
final String WMS_FORMAT_STRING =
url +
"?service=WMS" +
"&version=" + version +
"&request=GetMap" +
"&layers=" + layers +
"&bbox=81.3445510864258,18.6015472412109,82.2461547851562,19.5618953704834" +
"&width=721" +
"&height=768" +
"&srs=EPSG:4326" + // NB This is important, other SRS's won't work.
"&format=image/png" +
"&transparent=true";
WMSTileProvider tileProvider = new WMSTileProvider(baseUrl, 256) {
@Override
public String getTileURLString(long pMapTileIndex) {
WebMercatorBoundingBox bb = new WebMercatorBoundingBox(MapTileIndex.getX(pMapTileIndex), MapTileIndex.getY(pMapTileIndex), MapTileIndex.getZoom(pMapTileIndex));
String s = String.format(
Locale.ENGLISH,
WMS_FORMAT_STRING,
bb.getWest(),
bb.getSouth(),
bb.getEast(),
bb.getNorth());
Log.d(TAG,"Fetching map tile: " + s);
return s;
}
};
return tileProvider;
}}
WebMercatorBoundingBox 类
public class WebMercatorBoundingBox {
double north;
double south;
double east;
double west;
// Web Mercator n/w corner of the map.
private static final double[] TILE_ORIGIN = {-20037508.34789244, 20037508.34789244};
//array indexes for that data
private static final int ORIG_X = 0;
private static final int ORIG_Y = 1; // "
// Size of square world map in meters, using WebMerc projection.
private static final double MAP_SIZE = 20037508.34789244 * 2;
protected WebMercatorBoundingBox(final int x, final int y, final int zoom) {
north = tile2lat(y, zoom);
south = tile2lat(y + 1, zoom);
west = tile2lon(x, zoom);
east = tile2lon(x + 1, zoom);
}
double tile2lon(int x, int z) {
double tileSize = MAP_SIZE / Math.pow(2.0, z);
return TILE_ORIGIN[ORIG_X] + x * tileSize;
}
double tile2lat(int y, int z) {
double tileSize = MAP_SIZE / Math.pow(2.0, z);
return TILE_ORIGIN[ORIG_Y] - y * tileSize;
}
public double getNorth(){
return this.north;
}
public double getSouth(){
return this.south;
}
public double getEast(){
return this.east;
}
public double getWest(){
return this.west;
}}
WMSTileProvider 抽象类
public abstract class WMSTileProvider extends OnlineTileSourceBase {
// cql filters
private String cqlString = "";
// Construct with tile size in pixels, normally 256, see parent class.
public WMSTileProvider(String[] baseurl, int tileSizeInPixels) {
super("WMS tile source", 1 ,19,tileSizeInPixels,"png",baseurl);
}
protected String getCql() {
return URLEncoder.encode(cqlString);
}
public void setCql(String c) {
cqlString = c;
}
}
WebMercatorBoundingBox 的代码返回以下边界框(s 的值):
D/TileProviderFactory: Fetching map tile: http://49.206.244.230:8080/geoserver/cfr/wms?service=WMS&version=1.1.0&request=GetMap&layers=cfr:bastar_villages&bbox=-626172.135872,-1878516.407615,0.000000,-1252344.271743&width=721&height=768&srs=EPSG:4326&format=image/png&transparent=true
D/TileProviderFactory: Fetching map tile: http://49.206.244.230:8080/geoserver/cfr/wms?service=WMS&version=1.1.0&request=GetMap&layers=cfr:bastar_villages&bbox=-626172.135872,626172.135872,0.000000,1252344.271743&width=721&height=768&srs=EPSG:4326&format=image/png&transparent=true
D/TileProviderFactory: Fetching map tile: http://49.206.244.230:8080/geoserver/cfr/wms?service=WMS&version=1.1.0&request=GetMap&layers=cfr:bastar_villages&bbox=-1252344.271743,0.000000,-626172.135872,626172.135872&width=721&height=768&srs=EPSG:4326&format=image/png&transparent=true
请帮助我找出我的错误或给我任何如何实现目标的建议。
I am using osmdroid library to show mapview in my application. I have to load wms layer in my osm map to show village boundaries.
I have search on google and stack overflow and I found following blogs and posts
- How to work OSMDroid with Web Map Service (WMS) used by the private provider?
- android mapview with custom wms tile provider
- Using getTileURL in Android Application with GeoServer
- https://osmdroid.github.io/osmdroid/Map-Sources.html
- https://docs.geoserver.org/latest/en/user/services/wms/reference.html#getmap
I referred these and tried to implement same and I am able to load wms layer on osm map successfully. But it is loaded in multiple loop you can see in below image
I want this wms layer only be loaded in mentioned bounding box which I am passing in wms Api url.
My code to calling wms layer api
public class TileProviderFactory {
private static final String TAG = "TileProviderFactory";
private String version = "1.1.0";
private String url = "http://49.206.244.230:8080/geoserver/cfr/wms";
private String layers = "cfr:bastar_villages";
public WMSTileProvider getWmsTileProvider() {
String[] baseUrl = {url};
final String WMS_FORMAT_STRING =
url +
"?service=WMS" +
"&version=" + version +
"&request=GetMap" +
"&layers=" + layers +
"&bbox=81.3445510864258,18.6015472412109,82.2461547851562,19.5618953704834" +
"&width=721" +
"&height=768" +
"&srs=EPSG:4326" + // NB This is important, other SRS's won't work.
"&format=image/png" +
"&transparent=true";
WMSTileProvider tileProvider = new WMSTileProvider(baseUrl, 256) {
@Override
public String getTileURLString(long pMapTileIndex) {
WebMercatorBoundingBox bb = new WebMercatorBoundingBox(MapTileIndex.getX(pMapTileIndex), MapTileIndex.getY(pMapTileIndex), MapTileIndex.getZoom(pMapTileIndex));
String s = String.format(
Locale.ENGLISH,
WMS_FORMAT_STRING,
bb.getWest(),
bb.getSouth(),
bb.getEast(),
bb.getNorth());
Log.d(TAG,"Fetching map tile: " + s);
return s;
}
};
return tileProvider;
}}
WebMercatorBoundingBox class
public class WebMercatorBoundingBox {
double north;
double south;
double east;
double west;
// Web Mercator n/w corner of the map.
private static final double[] TILE_ORIGIN = {-20037508.34789244, 20037508.34789244};
//array indexes for that data
private static final int ORIG_X = 0;
private static final int ORIG_Y = 1; // "
// Size of square world map in meters, using WebMerc projection.
private static final double MAP_SIZE = 20037508.34789244 * 2;
protected WebMercatorBoundingBox(final int x, final int y, final int zoom) {
north = tile2lat(y, zoom);
south = tile2lat(y + 1, zoom);
west = tile2lon(x, zoom);
east = tile2lon(x + 1, zoom);
}
double tile2lon(int x, int z) {
double tileSize = MAP_SIZE / Math.pow(2.0, z);
return TILE_ORIGIN[ORIG_X] + x * tileSize;
}
double tile2lat(int y, int z) {
double tileSize = MAP_SIZE / Math.pow(2.0, z);
return TILE_ORIGIN[ORIG_Y] - y * tileSize;
}
public double getNorth(){
return this.north;
}
public double getSouth(){
return this.south;
}
public double getEast(){
return this.east;
}
public double getWest(){
return this.west;
}}
WMSTileProvider abstract class
public abstract class WMSTileProvider extends OnlineTileSourceBase {
// cql filters
private String cqlString = "";
// Construct with tile size in pixels, normally 256, see parent class.
public WMSTileProvider(String[] baseurl, int tileSizeInPixels) {
super("WMS tile source", 1 ,19,tileSizeInPixels,"png",baseurl);
}
protected String getCql() {
return URLEncoder.encode(cqlString);
}
public void setCql(String c) {
cqlString = c;
}
}
WebMercatorBoundingBox return following bounding box(value of s):
D/TileProviderFactory: Fetching map tile: http://49.206.244.230:8080/geoserver/cfr/wms?service=WMS&version=1.1.0&request=GetMap&layers=cfr:bastar_villages&bbox=-626172.135872,-1878516.407615,0.000000,-1252344.271743&width=721&height=768&srs=EPSG:4326&format=image/png&transparent=true
D/TileProviderFactory: Fetching map tile: http://49.206.244.230:8080/geoserver/cfr/wms?service=WMS&version=1.1.0&request=GetMap&layers=cfr:bastar_villages&bbox=-626172.135872,626172.135872,0.000000,1252344.271743&width=721&height=768&srs=EPSG:4326&format=image/png&transparent=true
D/TileProviderFactory: Fetching map tile: http://49.206.244.230:8080/geoserver/cfr/wms?service=WMS&version=1.1.0&request=GetMap&layers=cfr:bastar_villages&bbox=-1252344.271743,0.000000,-626172.135872,626172.135872&width=721&height=768&srs=EPSG:4326&format=image/png&transparent=true
Please help me to figure out my mistake or give me any suggestions how I achieve my goal.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您似乎正在使用整个地图边界框来发出平铺请求 - 正如您所看到的
http://49.206.244.230:8080/geoserver/cfr/wms?service=WMS&version=1.1.0&request=GetMap&layers=cfr:bastar_villages&bbox=81.34455108 64258,18.6015472412109,82.2461547851562,19.5618953704834&宽度=721&高度=768&srs=EPSG:4326&格式=image/png&透明=true
但是您在每个图块中都要求它,因此您需要计算每个图块的边界(这也会将大小更改为 256x256)。此时,您可能应该在 WebMercator 坐标 (EPSG:3857) 中工作(否则地球的曲率会使数学变得困难)。
这就是我认为
WebMercatorBoundingBox
应该为您提供的内容,因此将这些坐标(它们将在数千到数百万范围内)与 EPSG:3857 的 SRS 相结合应该会返回您所需的图块。使用这些边界后,您需要确保已在width
和height
参数中将图块大小正确设置为 265x256,并且SRS< /code> 也设置正确。
更新
通过查看服务器,您可以使用WGS 图块设置并从以下位置开始计算:
然后您将得到纬度/经度并可以使用 EPSG:4326。
You seem to be using the whole maps bounding box to make your tile requests - as you can see with
http://49.206.244.230:8080/geoserver/cfr/wms?service=WMS&version=1.1.0&request=GetMap&layers=cfr:bastar_villages&bbox=81.3445510864258,18.6015472412109,82.2461547851562,19.5618953704834&width=721&height=768&srs=EPSG:4326&format=image/png&transparent=true
But you are asking for it in each tile, so you need to calculate the bounds for each tile (which changes the size to 256x256 as well). At this point you should probably be working in WebMercator coordinates (EPSG:3857) (otherwise the curvature of the Earth makes the maths hard).
This is what I think
WebMercatorBoundingBox
should give you so combining those coordinates (they will be in the thousands to millions range) with an SRS of EPSG:3857 should return you the required tiles. Once you are using those bounds you will need to make sure that you have correctly set the tile size to 265x256 in thewidth
andheight
parameters and that theSRS
is correctly set too.Update
From a look at the server you could get use the WGS tile set and start your calculations from:
and then you would get lat/lon out and could use EPSG:4326.