Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vector tiles with Google Maps V3

I have a bunch of very large polygons that I'd like to overlay on my Google map. I have a tile server that serves GeoJSON features, and which also takes care of the various geometric operations I need to make the app work (joining polygons, simplification to zoom level, tiling, etc).

At present, we're just displaying the large polygons on the map as data layers, but ideally we'd be able to display simplified versions of the polygons at lesser zoom levels and increase their complexity inline with zoom level.

My options seem to be:

1) Data Layers: hook into the various map change events and then add/remove from the map as appropriate (where adding would be fetching the appropriate tile). Difficulty here would be that there seem to be a lot of map change events and finding the smoothest way to achieve could take considerable effort. Plus, it feels as though I'm working against the data API here.

2) OverlayView: similar to the above, but as an absolute sized OverlayView (i.e. a full covering). The thinking would be that the overlay would listen to draw events, fetch the appropriate tile, and add/clean-up as required. This seems like it'd be a more predictable solution, but again there's a lot to it.

I don't know enough about how maps works under-the-hood to provide much more insight, but my eventual solution (in so much as it helps) would be something that takes a tile server URL and then fits as smoothly as possible into how maps works to load the right tile, for the right zoom level (and given they're vector tiles, I could possibly also progressively enhance/degrade as zoom levels or position changed).

Can anyone shed any insight? How would you approach it?

like image 406
Whestley P. Tavistock Avatar asked Dec 04 '14 00:12

Whestley P. Tavistock


People also ask

Does Google Maps use vector tiles?

Vector tiles have been used by the Google Maps Android client since December 2010 and on the desktop client since 2013.

Can you download Google Maps vector?

What does it do? If you want to overlay an interactive vector graphics on top of Google Map, you should download a calibrated SVG file with Google Maps screenshot, edit the SVG file in Inkscape and then upload the file back to MapSVG. Your vector graphics will be automatically overlayed on Google Map by MapSVG.

Does Google Maps use vector or raster?

The Maps JavaScript API offers two different implementations of the map: raster and vector. The raster map is loaded by default, and loads the map as a grid of pixel-based raster image tiles, which are generated by Google Maps Platform server-side, then served to your web app.


3 Answers

The way I've come to deal with the idea of fetching tiled data is by using overlayMapTypes. Here's a working example.

Just as any object implementing the MapType interface, it expects you to define a getTile method and, optionally, a releaseTile method.

Whenever a tile enters the viewport, this kind of object calls getTile passing it the coords and zoom. Whenever a tile exits the viewport, it calls releaseTile with the node element that it's being removed. So, using the linked example, you just need to add a Data Layer to each tile, and remove it when the tile is released:

Let's say your tile serving backend answers to an url like

'/mytiles/1048/1520/13';

Then (borrowing almost the complete code for the example) you would declare the overlayMapType as

function CoordMapType() {
    this.tileSize = new google.maps.Size(256, 256);
}

CoordMapType.prototype.getTile = function (coord, zoom, ownerDocument) {
    var div = ownerDocument.createElement('div'),
        tileUrl = '/mytiles/' + coord.x + '/' + coord.y + '/' + zoom;

    div.innerHTML = coord;
    div.style.width = this.tileSize.width + 'px';
    div.style.height = this.tileSize.height + 'px';
    div.style.fontSize = '10';
    div.style.borderStyle = 'solid';
    div.style.borderWidth = '1px';
    div.style.borderColor = '#AAAAAA';

    div.dataLayer = new google.maps.Data();


    div.dataLayer.loadGeoJson(tileUrl,null, function() {
        div.dataLayer.setMap(map);
    });

    return div;
};

CoordMapType.prototype.releaseTile = function (tile) {
    if (tile.dataLayer) {
        tile.dataLayer.setMap(null);
    }
};


map.overlayMapTypes.insertAt(0, new CoordMapType());
like image 195
ffflabs Avatar answered Oct 23 '22 23:10

ffflabs


I have just open-sourced a fork of mapbox-gl-js which lets you render vector tiles on the client in a controlled way, in particular this means you can use vector tiles on top of a google map.

A live demo is here, and the documention/code is here

Here is open streetmap tiles on top of a google satellite image...

screenshot

like image 42
dan-man Avatar answered Oct 24 '22 01:10

dan-man


Another option to the already mentioned ones is using deck.gl, in specific the following component, which works pretty well for vector tiles and is compatible with Gooogle Maps (you don't have to use Mapbox):

https://deck.gl/docs/api-reference/geo-layers/mvt-layer

like image 1
Javi Marzán Avatar answered Oct 24 '22 01:10

Javi Marzán