Android WMS地图库

时间:2015-06-17 12:04:26

标签: android android-maps

目前我正在使用Geoserver中的地图。我想在android中以WMS格式显示地图。我见过openscales,mapsforge,osm-droid。哪些android地图库最适合使用WMS,WFS图层?它们的优点和缺点是什么?

1 个答案:

答案 0 :(得分:3)

我没有为WMS使用特定的库,因为我不喜欢它们(对于特定情况而言非常复杂,在我的情况下非标准情况),所以我创建了我的课程来管理它。例如,在地图上显示WMS只是简单地覆盖URLTileProvider:

/*
 * Copyright [2015] Nicola Dorigatti
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package it.dorigatti.android.editing.wms;

import com.google.android.gms.maps.model.UrlTileProvider;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;

public abstract class WMSTileProvider 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 MAXX = 1;
    protected static final int MINY = 2;
    protected static final int MAXY = 3;

    // cql filters
    private String cqlString = "";

    // Construct with tile size in pixels, normally 256, see parent class.
    public WMSTileProvider(int x, int y) {
        super(x, y);
    }

    @SuppressWarnings("deprecation")
    protected String getCql() {
        try {
            return URLEncoder.encode(cqlString, Charset.defaultCharset().name());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return URLEncoder.encode(cqlString);
        }
    }

    public void setCql(String c) {
        cqlString = c;
    }

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

}

他们将图层管理为:

/*
 * Copyright [2015] Nicola Dorigatti
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package it.dorigatti.android.editing.wms;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;

import it.dorigatti.android.editing.dto.WMSLayerInfo;

public class TileProviderFactory {

    public static WMSTileProvider getWMSTileProviderByName(String layerName) {
        final String OSGEO_WMS = "YOURGEOSERVER/gwc/service/wms/?"
                + "LAYERS=" + layerName
                + "&FORMAT=image/png8&"
                + "PROJECTION=EPSG:3857&"
                + "TILEORIGIN=lon=-20037508.34,lat=-20037508.34&"
                + "TILESIZE=w=256,h=256"
                + "&MAXEXTENT=-20037508.34,-20037508.34,20037508.34,20037508.34&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG:3857"
                + "&BBOX=%f,%f,%f,%f&WIDTH=256&HEIGHT=256";

        return new WMSTileProvider(256, 256) {

            @Override
            public synchronized URL getTileUrl(int x, int y, int zoom) {
                final double[] bbox = getBoundingBox(x, y, zoom);
                String s = String.format(Locale.US, OSGEO_WMS, bbox[MINX], bbox[MINY], bbox[MAXX], bbox[MAXY]);
                try {
                    return new URL(s);
                } catch (MalformedURLException e) {
                    throw new AssertionError(e);
                }
            }
        };
    }

}

对于WFS服务,我开发了一个小型库,它使用GeoJSON进行数据下载/上传。 XML不适用于Android,WFS太宽,无法支持所有内容,所以我只是根据自己的需要实现了它。 请注意,在某些情况下,geoserver与WFS v2存在一些问题,我不得不切换到WFS 1.1。