Sử dụng lát bản đồ tùy chỉnh với Google Map API V2 cho Android.?


10

Tôi đang tìm cách sử dụng các lát bản đồ tùy chỉnh với Google Map API V2 cho Android.

Tôi đang viết một ứng dụng sẽ tạo ra bản đồ của riêng mình trong thời gian thực với dữ liệu đến từ robot.

Ứng dụng cần hiển thị cho người vận hành bản đồ này. Người vận hành cần tương tác với bản đồ này, cho phép các điểm, v.v.

Tôi muốn sử dụng công cụ GoogleMap để thực hiện tương tự trang này:

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

Vấn đề là anh ấy đã sử dụng API Javascript khi tôi muốn sử dụng API Android

Có cách nào để sử dụng bản đồ lát tùy chỉnh trên Android với Google Maps Engine không?

Tôi đã xem cách sử dụng ArcGIS nhưng, tôi thích sử dụng API hơn mà không phải trả tiền cho giấy phép.

Câu trả lời:


8

Có, bạn có thể sử dụng các ô tùy chỉnh với API Android Maps v2 - bạn có thể thấy một ví dụ hoạt động đầy đủ trong ứng dụng OpenTripPlanner cho Android của chúng tôi trên Github . (Bạn cũng có thể tải xuống ứng dụng trực tiếp từ Google Play )

Chúng tôi hỗ trợ các nhà cung cấp gạch sau:

  • LyrkOpenStreetMap
  • MapQuestOpenStreetMap
  • Mapnik
  • Chu kỳ
  • Google (bình thường, vệ tinh, lai, địa hình)

Lớp CustomUrlTileProvider của chúng tôi có thể được nhìn thấy ở đây trên Github và tôi cũng đã dán nó bên dưới:

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

đây là mã chuyển đổi giữa các nhà cung cấp ô bản đồ, dựa trên sở thích của người dùng:

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

Dưới đây là ảnh chụp màn hình của các ô MapStest OpenStreetMap: nhập mô tả hình ảnh ở đây

Để biết thêm thông tin về cách tạo các ô riêng của bạn, hãy xem tài liệu Google cho TileOverlay cũng như wiki OpenStreetMap để biết "Tạo các ô của riêng bạn" .

Cụ thể, tài liệu Google cho biết:

Lưu ý rằng thế giới được chiếu bằng phép chiếu Mercator (xem Wikipedia) với phía bên trái (phía tây) của bản đồ tương ứng với -180 độ kinh độ và phía bên phải (phía đông) của bản đồ tương ứng với 180 độ kinh độ. Để làm cho hình vuông bản đồ, phía trên cùng (phía bắc) của bản đồ tương ứng với 85,0511 độ vĩ độ và phía dưới (phía nam) của bản đồ tương ứng với -85,0511 độ vĩ độ. Các khu vực bên ngoài phạm vi vĩ độ này không được hiển thị.

Ở mỗi mức thu phóng, bản đồ được chia thành các ô và chỉ các ô chồng lên màn hình mới được tải xuống và hiển thị. Mỗi ô vuông là hình vuông và bản đồ được chia thành các ô như sau:

  • Ở mức thu phóng 0, một ô đại diện cho toàn bộ thế giới. Tọa độ của ô đó là (x, y) = (0, 0).

  • Ở mức thu phóng 1, thế giới được chia thành 4 ô xếp thành một lưới 2 x 2. ...

  • Ở mức thu phóng N, thế giới được chia thành các ô 4N được sắp xếp theo lưới 2N x 2N.

Lưu ý rằng mức thu phóng tối thiểu mà máy ảnh hỗ trợ (có thể phụ thuộc vào nhiều yếu tố khác nhau) là GoogleMap.getMinZoomLevel và mức thu phóng tối đa là GoogleMap.getMaxZoomLevel.

Các tọa độ của các ô được đo từ góc trên cùng bên trái (phía tây bắc) của bản đồ. Ở mức thu phóng N, các giá trị x của tọa độ ô dao động trong khoảng từ 0 đến 2N - 1 và tăng dần từ tây sang đông và các giá trị y nằm trong khoảng từ 0 đến 2N - 1 và tăng dần từ bắc xuống nam.

Các URL được định dạng được sử dụng trong OTP Android để tham chiếu mỗi nhà cung cấp ô xếp như sau:

Vì vậy, đối với các nhà cung cấp ở trên, hình ảnh xếp là các tệp PNG được sắp xếp trong cấu trúc thư mục được chỉ định bởi tài liệu Google. Bạn sẽ theo một định dạng tương tự để tạo các ô bản đồ của riêng bạn được lưu trữ trên máy chủ của riêng bạn. Lưu ý rằng các URL / hình ảnh này phải được truy cập công khai vào thiết bị di động (nghĩa là không thể bảo vệ bằng mật khẩu).


Cảm ơn bạn đã dành thời gian. Có thể sử dụng hình ảnh được tạo hoàn toàn bởi tôi trong một kho lưu trữ cá nhân? Định dạng của gạch đó là gì? Và sự phát triển?
MonkeyJLuffy

@MonkeyJLuffy Tôi chỉ cần thêm một số thông tin vào cuối câu trả lời của tôi cho điều này. Xin vui lòng cho tôi biết nếu bạn vẫn còn thắc mắc sau khi đọc này.
Sean Barbeau

1

Giải pháp rộng lớn nhất mà tôi đã tìm thấy là trong StackOverflow này Trả lời :

Về cơ bản, bạn cần triển khai TileProvider của riêng mình và sử dụng nó như là một TileOverlay

Trong một vài ứng dụng, chúng tôi đã sử dụng loại lớp này để hiển thị các ô trên bản đồ, nhưng chúng tôi thấy các ô chiếm rất nhiều không gian. Do đó, chúng tôi đã chuyển sang sử dụng mbtiles và thư viện này để hiển thị dữ liệu từ mbtiles trên bản đồ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.