结合使用自定义地图图块和适用于Android的Google Map API V2。


10

我正在寻找一种将自定义地图图块与Android版Google Map API V2结合使用的方法。

我正在编写一个应用程序,它将使用来自机器人的数据实时创建自己的地图。

应用程序需要向操作员显示此地图。操作员需要与此地图进行交互,让路点等。

我想使用GoogleMap引擎来执行与此页面相同的操作:

http://cdn.mikecouturier.com/blog.mikecouturier.com/tilesgenerator/index.html

问题是,当我想使用Android API时,他使用了Javascript API

有什么方法可以在Android上通过Google Maps Engine使用自定义图块地图吗?

我已经在研究如何使用ArcGIS,但是我更喜欢使用API​​而无需支付许可证费用。

Answers:


8

是的,您可以在Android Maps API v2中使用自定义图块-您可以在Github上的适用于AndroidOpenTripPlanner应用程序中看到一个完整的示例。(您也可以直接从Google Play下载该应用程序

我们支持以下图块提供程序:

  • LyrkOpenStreetMap
  • MapQuestOpenStreetMap
  • 马普尼克
  • 周期图
  • Google(普通,卫星,混合,地形)

我们的CustomUrlTileProvider类可以在Github上看到,我也将其粘贴在下面:

public class CustomUrlTileProvider extends UrlTileProvider {

    private String baseUrl;

    public CustomUrlTileProvider(int width, int height, String url) {
        super(width, height);
        this.baseUrl = url;
    }

    @Override
    public URL getTileUrl(int x, int y, int zoom) {
        try {
            return new URL(baseUrl.replace("{z}", "" + zoom).replace("{x}", "" + x)
                    .replace("{y}", "" + y));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

这里的代码是地图图块提供商之间切换,根据用户的喜好:

/**
 * Changes the tiles used to display the map and sets max zoom level.
 *
 * @param overlayString tiles URL for custom tiles or description for
 *                      Google ones
 */
public void updateOverlay(String overlayString) {
    int tile_width = OTPApp.CUSTOM_MAP_TILE_SMALL_WIDTH;
    int tile_height = OTPApp.CUSTOM_MAP_TILE_SMALL_HEIGHT;

    if (overlayString == null) {
        overlayString = mPrefs.getString(OTPApp.PREFERENCE_KEY_MAP_TILE_SOURCE,
                mApplicationContext.getResources()
                        .getString(R.string.map_tiles_default_server));
    }
    if (mSelectedTileOverlay != null) {
        mSelectedTileOverlay.remove();
    }
    if (overlayString.startsWith(OTPApp.MAP_TILE_GOOGLE)) {
        int mapType = GoogleMap.MAP_TYPE_NORMAL;

        if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_HYBRID)) {
            mapType = GoogleMap.MAP_TYPE_HYBRID;
        } else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_NORMAL)) {
            mapType = GoogleMap.MAP_TYPE_NORMAL;
        } else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_TERRAIN)) {
            mapType = GoogleMap.MAP_TYPE_TERRAIN;
        } else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_SATELLITE)) {
            mapType = GoogleMap.MAP_TYPE_SATELLITE;
        }
        mMap.setMapType(mapType);
        mMaxZoomLevel = mMap.getMaxZoomLevel();
    } else {
        if (overlayString.equals(getResources().getString(R.string.tiles_mapnik))) {
            mMaxZoomLevel = getResources().getInteger(R.integer.tiles_mapnik_max_zoom);
        } else if (overlayString.equals(getResources().getString(R.string.tiles_lyrk))) {
            mMaxZoomLevel = getResources().getInteger(R.integer.tiles_lyrk_max_zoom);
            tile_width = OTPApp.CUSTOM_MAP_TILE_BIG_WIDTH;
            tile_height = OTPApp.CUSTOM_MAP_TILE_BIG_HEIGHT;
        } else {
            mMaxZoomLevel = getResources().getInteger(R.integer.tiles_maquest_max_zoom);
        }

        mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
        CustomUrlTileProvider mTileProvider = new CustomUrlTileProvider(
                tile_width,
                tile_height, overlayString);
        mSelectedTileOverlay = mMap.addTileOverlay(
                new TileOverlayOptions().tileProvider(mTileProvider)
                        .zIndex(OTPApp.CUSTOM_MAP_TILE_Z_INDEX));

        if (mMap.getCameraPosition().zoom > mMaxZoomLevel) {
            mMap.moveCamera(CameraUpdateFactory.zoomTo(mMaxZoomLevel));
        }
    }
}

这是MapQuest OpenStreetMap磁贴的屏幕截图: 在此处输入图片说明

有关制作自己的图块的更多信息,请参见Google文档TileOverlay以及有关“创建自己的图块”OpenStreetMap Wiki

具体来说,Google文档说:

请注意,世界是使用Mercator投影(请参阅Wikipedia)进行投影的,地图的左(西)侧对应于-180度经度,地图的右(东)侧对应于180度经度。要使地图方形化,地图的顶部(北侧)对应于85.0511纬度,地图的底部(南侧)对应于-85.0511纬度。此纬度范围以外的区域不会渲染。

在每个缩放级别,地图都会分为多个图块,并且仅下载和渲染与屏幕重叠的图块。每个图块都是正方形,并且地图按以下方式分为图块:

  • 缩放级别为0时,一个图块代表整个世界。该图块的坐标为(x,y)=(0,0)。

  • 缩放级别为1时,世界分为2个2 x 2网格的4个图块。...

  • 在缩放级别N下,世界被划分为以2N x 2N网格排列的4N个图块。

请注意,相机支持的最小缩放级别(可能取决于各种因素)为GoogleMap.getMinZoomLevel,最大缩放级别为GoogleMap.getMaxZoomLevel。

瓷砖的坐标是从地图的左上角(西北)开始测量的。在缩放级别N时,图块坐标的x值在0到2N-1的范围内,并从西向东增加; y值在0到2N-1的范围内,并从北向南增加。

在OTP Android中用于引用每个图块提供程序的格式化URL如下所示:

因此,对于上述提供者,图块图像是按照Google文档指示的目录结构排列的PNG文件。您将采用类似的格式来创建托管在您自己的服务器上的自己的地图图块。请注意,这些URL /图像必须是移动设备可以公开访问的(即,不能用密码保护)。


谢谢你的时间 可以在个人存储库中使用由我完全创建的图像吗?该图块的格式是什么?和树状?
MonkeyJLuffy 2014年

@MonkeyJLuffy我刚刚在答案的底部添加了一些信息。阅读此书后,如果您还有任何疑问,请告诉我。
肖恩·巴博

1

我发现的最广泛的解决方案是此StackOverflow 答案

基本上,您需要实现自己的TileProvider并将其用作TileOverlay

在几个应用程序中,我们使用了这种图层来在地图上显示图块,但是我们发现图块占用了大量空间。因此,我们转而使用mbtiles和此库在地图上显示mbtiles的数据。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.