在Android应用程序中使用GeoServer中的getTileURL

时间:2013-03-21 17:03:21

标签: android overlay google-maps-android-api-2 geoserver wms

我们刚刚开始在Android上使用Google地图,并设置了GeoServer来提供我们想要在地图上添加为叠加层的切片。到目前为止,我已经按照一些教程和参考资料开始使用。

问题:当我设置断点并复制并粘贴时,我在getTileUrl的{​​{1}}函数中生成的网址确实会返回png图像将该网址添加到浏览器中,它不会作为Android设备上的叠加层加载到地图上。从我所看到的内容和阅读后this中没有任何错误被抛出。我不确定是否会有任何错误,因为他们已经指出错误被忽略了。

我想知道的是,如果您可以在我的代码中看到任何直接问题或者有任何调试建议我将能够判断应用程序是否实际与我的GeoServer通信以检索图像与否。我查看了GeoServer上的日志,似乎只有我的浏览器请求正在通过,而且它没有收到来自Android的任何请求(这有点难以分辨,因为我们还有其他应用程序使用服务器)。 Android手机通过wifi和手机连接,并启用了GPS。作为最后的手段,我尝试更改图块叠加zIndex并将其设置为可见,但这似乎没有任何区别。

编辑:此时Android设备肯定不与GeoServer通信。

编辑2:能够从网站加载静态图像 (比如this)作为叠加层,发现我在测试出形成的URL的HTTP请求时遇到以下异常:

TileProviderFactory

感谢。

MapTestActivity

W/System.err(10601): java.net.SocketException: The operation timed out
W/System.err(10601): at org.apache.harmony.luni.platform.OSNetworkSystem
     .connectStreamWithTimeoutSocketImpl(Native Method)
W/System.err(10601): at org.apache.harmony.luni.net.PlainSocketImpl
     .connect(PlainSocketImpl.java:244)
W/System.err(10601): at org.apache.harmony.luni.net.PlainSocketImpl
     .connect(PlainSocketImpl.java:533)
W/System.err(10601): at java.net.Socket
     .connect(Socket.java:1074)
W/System.err(10601): at org.apache.http.conn.scheme.PlainSocketFactory
     .connectSocket(PlainSocketFactory.java:119)

TileProviderFactory

public class MapTestActivity extends FragmentActivity
    implements LocationListener, LocationSource{

    private GoogleMap mMap;
    private OnLocationChangedListener mListener;
    private LocationManager locationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map_test);     
        setupLocationManager();     
        setupMapIfNeeded();
    }

    private void setupLocationManager() {
        this.locationManager = 
            (LocationManager) getSystemService(LOCATION_SERVICE);

        if (locationManager != null) {
            boolean gpsIsEnabled = locationManager.isProviderEnabled(
                    LocationManager.GPS_PROVIDER);
            boolean networkIsEnabled = locationManager.isProviderEnabled(
                    LocationManager.NETWORK_PROVIDER);

            if(gpsIsEnabled) {
                this.locationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER, 5000L, 10F, this);
            }
            else if(networkIsEnabled) {
                this.locationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER, 5000L, 10F, this);
            }
            else {
                //Show an error dialog that GPS is disabled...
            }
        }
        else {
            // Show some generic error dialog because 
            // something must have gone wrong with location manager.
        }
    }

    private void setupMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the
        // map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map)).getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
            mMap.setLocationSource(this);
        }
    }

    private void setUpMap() {
        // TODO Auto-generated method stub
        mMap.setMyLocationEnabled(true);
        TileProvider geoServerTileProvider = TileProviderFactory
            .getGeoServerTileProvider();
        TileOverlay geoServerTileOverlay = mMap.addTileOverlay(
            new TileOverlayOptions()
                .tileProvider(geoServerTileProvider)
                .zIndex(10000)
                .visible(true));
    }
    // Non-relevant listener methods removed
}

GeoServerTileProvider

public class TileProviderFactory {

    public static GeoServerTileProvider getGeoServerTileProvider() {

        String baseURL = "mytileserver.com";
        String version = "1.3.0";
        String request = "GetMap";
        String format = "image/png";
        String srs = "EPSG:900913";
        String service = "WMS";
        String width = "256";
        String height = "256";
        String styles = "";
        String layers = "wtx:road_hazards";

        final String URL_STRING = baseURL + 
                "&LAYERS=" + layers + 
                "&VERSION=" + version + 
                "&SERVICE=" + service + 
                "&REQUEST=" + request + 
                "&TRANSPARENT=TRUE&STYLES=" + styles + 
                "&FORMAT=" + format + 
                "&SRS=" + srs + 
                "&BBOX=%f,%f,%f,%f" + 
                "&WIDTH=" + width + 
                "&HEIGHT=" + height;


        GeoServerTileProvider tileProvider = 
            new GeoServerTileProvider(256,256) {

            @Override
            public synchronized URL getTileUrl(int x, int y, int zoom) {
                try {       

                    double[] bbox = getBoundingBox(x, y, zoom);

                    String s = String.format(Locale.US, URL_STRING, bbox[MINX], 
                            bbox[MINY], bbox[MAXX], bbox[MAXY]);

                    Log.d("GeoServerTileURL", s);

                    URL url = null;

                    try {
                        url = new URL(s);
                    } 
                    catch (MalformedURLException e) {
                        throw new AssertionError(e);
                    }

                    return url;
                }
                catch (RuntimeException e) {
                    Log.d("GeoServerTileException", 
                        "getTile x=" + x + ", y=" + y + 
                        ", zoomLevel=" + zoom + 
                        " raised an exception", e);
                    throw e;
                }

            }
        };
        return tileProvider;
    }
}

1 个答案:

答案 0 :(得分:8)

这结果是一个网络问题,与我的实施完全无关,这是“正确的”。我想这个问题可以作为开始使用Android + GeoServer的其他人的一个例子,所以我会把它留下来。