Find which tiles are currently visible in the viewport of a Google Maps v3 map

前端 未结 2 1931
长情又很酷
长情又很酷 2021-02-04 22:59

I am trying to build support for tiled vector data into some of our Google Maps v3 web maps, and I\'m having a hard time figuring out how to find out which 256 x 256 tiles are v

2条回答
  •  借酒劲吻你
    2021-02-04 23:01

    Here's what I came up with, with help from the documentation (http://code.google.com/apis/maps/documentation/javascript/maptypes.html, especially the "Map Coordinates" section) and a number of different sources:

    function loadData() {
        var bounds = map.getBounds(),
            boundingBoxes = [],
            boundsNeLatLng = bounds.getNorthEast(),
            boundsSwLatLng = bounds.getSouthWest(),
            boundsNwLatLng = new google.maps.LatLng(boundsNeLatLng.lat(), boundsSwLatLng.lng()),
            boundsSeLatLng = new google.maps.LatLng(boundsSwLatLng.lat(), boundsNeLatLng.lng()),
            zoom = map.getZoom(),
            tiles = [],
            tileCoordinateNw = pointToTile(boundsNwLatLng, zoom),
            tileCoordinateSe = pointToTile(boundsSeLatLng, zoom),
            tileColumns = tileCoordinateSe.x - tileCoordinateNw.x + 1;
            tileRows = tileCoordinateSe.y - tileCoordinateNw.y + 1;
            zfactor = Math.pow(2, zoom),
            minX = tileCoordinateNw.x,
            minY = tileCoordinateNw.y;
    
        while (tileRows--) {
            while (tileColumns--) {
                tiles.push({
                    x: minX + tileColumns,
                    y: minY
                });
            }
    
            minY++;
            tileColumns = tileCoordinateSe.x - tileCoordinateNw.x + 1;
        }
    
        $.each(tiles, function(i, v) {
            boundingBoxes.push({
                ne: projection.fromPointToLatLng(new google.maps.Point(v.x * 256 / zfactor, v.y * 256 / zfactor)),
                sw: projection.fromPointToLatLng(new google.maps.Point((v.x + 1) * 256 / zfactor, (v.y + 1) * 256 / zfactor))
            });
        });
        $.each(boundingBoxes, function(i, v) {
            var poly = new google.maps.Polygon({
                map: map,
                paths: [
                    v.ne,
                    new google.maps.LatLng(v.sw.lat(), v.ne.lng()),
                    v.sw,
                    new google.maps.LatLng(v.ne.lat(), v.sw.lng())
                ]
            });
    
            polygons.push(poly);
        });
    }
    function pointToTile(latLng, z) {
        var projection = new MercatorProjection();
        var worldCoordinate = projection.fromLatLngToPoint(latLng);
        var pixelCoordinate = new google.maps.Point(worldCoordinate.x * Math.pow(2, z), worldCoordinate.y * Math.pow(2, z));
        var tileCoordinate = new google.maps.Point(Math.floor(pixelCoordinate.x / MERCATOR_RANGE), Math.floor(pixelCoordinate.y / MERCATOR_RANGE));
        return tileCoordinate;
    };
    

    An explanation: Basically, everytime the map is panned or zoomed, I call the loadData function. This function calculates which tiles are in the map view, then iterates through the tiles that are already loaded and deletes the ones that are no longer in the view (I took this portion of code out, so you won't see it above). I then use the LatLngBounds stored in the boundingBoxes array to request data from the server.

    Hope this helps someone else...

提交回复
热议问题