如何在 android google map v2 实现上为 geoserver 瓦片重新加载 TileOverlay
Posted
技术标签:
【中文标题】如何在 android google map v2 实现上为 geoserver 瓦片重新加载 TileOverlay【英文标题】:How to reload TileOverlay for geoserver tiles on android google map v2 implementation 【发布时间】:2015-05-28 10:02:12 【问题描述】:我正在使用 geoserve 实现来检索我的地图图块。 我请求切片的方式是,当相机更改地图上的视图时,它会触发我的 api 调用,然后发送地图中心视图的纬度和经度,然后 api 响应 TileOverlay 的 getTileUrl 所需的地理服务器层列表。
但不幸的是,当我的 Api 返回图层列表时,getTileUrl 已经被触发并且我的图块没有呈现。
简而言之,我的地理服务器请求的图层参数是动态变化的。所以我的问题是如何触发再次加载地图叠加层,以便当我的 Api 返回列表时,它会重新加载带有适当图层的叠加层。
这是我对 OnCameraChangeListener 的实现:
private GoogleMap.OnCameraChangeListener cameraChange = new GoogleMap.OnCameraChangeListener()
@Override
public void onCameraChange(CameraPosition cameraPosition)
LatLng latLng = map.getCameraPosition().target;
getLayerLists(latLng);
;
这里是getLayerList方法:
private void getLayerList(LatLng latLng)
nigsApi.getLayerForArea(TAG_FLOOD_MAP_REQUEST,
String.valueOf(latLng.latitude), String.valueOf(latLng.longitude),
onApiResponse);
这是返回层列表的 onApiResponse 回调:
private OnApiResponse<NigsApi.ResponsePair<List<String>>> onApiResponse = new OnApiResponse<NigsApi.ResponsePair<List<String>>>()
@Override
public void onRequestSuccessful(NigsApi.ResponsePair<List<String>> result)
tileProviderFactory.setLayerArea(result.getResult());
@Override
public void onRequestFailed(String errorMessage, Object tag)
Log.e("Maps", errorMessage);
@Override
public void onRequestError(RetrofitError error, Object tag)
Log.e("Maps", error.getMessage());
;
响应后它转到 My TileProviderFactory 类并设置 getTileUrl 所需的层列表。
这里是 getTileUrl 的块:
public void setLayerArea(List<String> listLayer)
this.listLayer = listLayer;
public WmsTileProvider getOsgeoWmsTileProvider()
//This is configured for:
// http://beta.sedac.ciesin.columbia.edu/maps/services
// (TODO check that this WMS service still exists at the time you try to run this demo,
// if it doesn't, find another one that supports EPSG:900913
final String WMS_FORMAT_STRING =
"http://202.90.153.87:8080/geoserver/flood_100/wms?" +
"service=WMS" +
"&version=1.1.0" +
"&request=GetMap" +
"&bbox=%f,%f,%f,%f" +
"&width=256" +
"&height=256" +
"&srs=EPSG:900913" +
"&format=image/png" +
"&transparent=true" +
"&tiled=true";
WmsTileProvider tileProvider = new WmsTileProvider(256,256)
@Override
public synchronized URL getTileUrl(int x, int y, int zoom)
double[] bbox = getBoundingBox(x, y, zoom);
String layerTitles = getLayerTitles();
String s = String.format(Locale.US, WMS_FORMAT_STRING, bbox[MINX],
bbox[MINY], bbox[MAXX], bbox[MAXY]);
s = s + layerTitles;
Log.e("MapLayers", s);
URL url = null;
try
url = new URL(s);
catch (MalformedURLException e)
throw new AssertionError(e);
return url;
;
return tileProvider;
getLayerTitles() 方法将所有图层连接成一个字符串并将其附加到 WMS_FORMAT_STRING url..
private String getLayerTitles()
if (listLayer.size() == 0)
return layers;
else
layers = "&layers=";
for (String location : listLayer)
if (layers.equals("&layers="))
layers = layers + location;
else
layers = layers + "," + location;
return layers;
【问题讨论】:
【参考方案1】:你需要渲染多少层?您是否需要一次渲染所有这些?
如果可以的话,最好每层创建一个WmsTileProvider;这将使您能够精细地启用或禁用图层。
如果您需要(或想要)一次渲染所有这些,您可以以更智能的方式使用您的 getTileUrl:
在您的 WmsTileProvider 中创建一个允许您设置图层的方法(您可以在类中创建一个 mLayers String 变量并更改 getLayersTitles 方法以更改此变量而不是返回它),然后在需要时调用此方法更改图层列表并调用 clearTileCache:
https://developers.google.com/android/reference/com/google/android/gms/maps/model/TileOverlay#clearTileCache%28%29
您的图块将重新加载新图层...
代码(抱歉格式错误):
public void setLayerArea(List<String> listLayer)
this.mLayers = getLayerTitles(listLayer);
private String getLayerTitles(List<String> listLayer)
if (listLayer.size() == 0)
return "DEFAULT LAYERS";
else
layers = "&layers=";
for (String location : listLayer)
if (layers.equals("&layers="))
layers = layers + location;
else
layers = layers + "," + location;
return layers;
public WmsTileProvider getOsgeoWmsTileProvider()
//This is configured for:
// http://beta.sedac.ciesin.columbia.edu/maps/services
// (TODO check that this WMS service still exists at the time you try to run this demo,
// if it doesn't, find another one that supports EPSG:900913
final String WMS_FORMAT_STRING =
"http://202.90.153.87:8080/geoserver/flood_100/wms?" +
"service=WMS" +
"&version=1.1.0" +
"&request=GetMap" +
"&bbox=%f,%f,%f,%f" +
"&width=256" +
"&height=256" +
"&srs=EPSG:900913" +
"&format=image/png" +
"&transparent=true" +
"&tiled=true";
WmsTileProvider tileProvider = new WmsTileProvider(256,256)
@Override
public synchronized URL getTileUrl(int x, int y, int zoom)
double[] bbox = getBoundingBox(x, y, zoom);
String s = String.format(Locale.US, WMS_FORMAT_STRING, bbox[MINX],
bbox[MINY], bbox[MAXX], bbox[MAXY]);
s = s + this.mLayers;
Log.e("MapLayers", s);
URL url = null;
try
url = new URL(s);
catch (MalformedURLException e)
throw new AssertionError(e);
return url;
;
return tileProvider;
【讨论】:
以上是关于如何在 android google map v2 实现上为 geoserver 瓦片重新加载 TileOverlay的主要内容,如果未能解决你的问题,请参考以下文章
如何设置 Android Google Maps API v2 地图以显示全球地图?
Android,如何从 Google Map V2 中删除所有标记?
如何在 Android Google Maps API v2 中将 LatLng 和半径转换为 LatLngBounds?
如何在 android 上使用 google maps api v2 很好地管理标记