8

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

问题:虽然当我设置断点并将 url 复制并粘贴到浏览器中时,我在getTileUrl函数中生成的 urlTileProviderFactory确实返回了 png 图像,但它不会作为 Android 设备上的叠加层加载到地图上. 从我所看到的内容中没有抛出任何错误,在阅读完这篇文章后,我不确定是否会有任何错误,因为他们已经表明错误正在被忽略。

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

编辑:Android 设备此时绝对没有与 GeoServer 通信。

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

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)

谢谢。

地图测试活动

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
}

TileProviderFactory

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;
    }
}

GeoServerTileProvider

public abstract class GeoServerTileProvider extends UrlTileProvider{

    // 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;

    // array indexes for array to hold bounding boxes.
    protected static final int MINX = 0;
    protected static final int MINY = 1;
    protected static final int MAXX = 2;
    protected static final int MAXY = 3;

    public GeoServerTileProvider(int width, int height) {
        super(width, height);
    }

    // Return a web Mercator bounding box given tile x/y indexes and a zoom
    // level.
    protected double[] getBoundingBox(int x, int y, int zoom) {
        double tileSize = MAP_SIZE / Math.pow(2, zoom);
        double minx = TILE_ORIGIN[ORIG_X] + x * tileSize;
        double maxx = TILE_ORIGIN[ORIG_X] + (x+1) * tileSize;
        double miny = TILE_ORIGIN[ORIG_Y] - (y+1) * tileSize;
        double maxy = TILE_ORIGIN[ORIG_Y] - y * tileSize;

        double[] bbox = new double[4];
        bbox[MINX] = minx;
        bbox[MINY] = miny;
        bbox[MAXX] = maxx;
        bbox[MAXY] = maxy;
        return bbox;
    }
}
4

1 回答 1

8

结果证明这是一个网络问题,与我的“正确”实现完全无关。我想这个问题对于开始使用 Android + GeoServer 实现的其他人来说是一个很好的例子,所以我会留下它。

于 2013-03-22T14:53:27.830 回答