diff --git a/demo/demo-labels.html b/demo/demo-labels.html new file mode 100644 index 0000000..b4cbac6 --- /dev/null +++ b/demo/demo-labels.html @@ -0,0 +1,79 @@ + + + + Leaflet Map Panes Example + + + + + + + + + +
+ + + + diff --git a/src/Leaflet.VectorGrid.js b/src/Leaflet.VectorGrid.js index c950c9b..208cfb1 100644 --- a/src/Leaflet.VectorGrid.js +++ b/src/Leaflet.VectorGrid.js @@ -5,6 +5,7 @@ L.VectorGrid = L.GridLayer.extend({ options: { rendererFactory: L.svg.tile, vectorTileLayerStyles: {}, + onEachFeature: null, interactive: false }, @@ -14,14 +15,16 @@ L.VectorGrid = L.GridLayer.extend({ if (this.options.getFeatureId) { this._vectorTiles = {}; this._overriddenStyles = {}; - this.on('tileunload', function(e) { - delete this._vectorTiles[this._tileCoordsToKey(e.coords)]; - }, this); } + this._userLayers = {}; + this.on('tileunload', function(e) { + this._tileUnload(e); + }, this); }, createTile: function(coords, done) { var storeFeatures = this.options.getFeatureId; + var onEachFeature = this.options.onEachFeature; var tileSize = this.getTileSize(); var renderer = this.options.rendererFactory(coords, tileSize, this.options); @@ -69,11 +72,18 @@ L.VectorGrid = L.GridLayer.extend({ } if (!styleOptions.length) { + if (onEachFeature) { + onEachFeature.call(this, feat, null, layer, coords); + } continue; } var featureLayer = this._createLayer(feat, pxPerExtent); + if (onEachFeature) { + onEachFeature.call(this, feat, null, layer, coords); + } + for (var j in styleOptions) { var style = L.extend({}, L.Path.prototype.options, styleOptions[j]); featureLayer.render(renderer, style); @@ -148,6 +158,48 @@ L.VectorGrid = L.GridLayer.extend({ } }, + vtGeometryToPoint: function(geometry, vtLayer, tileCoords) { + var pxPerExtent = this.getTileSize().x / vtLayer.extent; + var tileSize = this.getTileSize(); + var offset = tileCoords.scaleBy(tileSize); + var point; + if (typeof geometry[0] === 'object' && 'x' in geometry[0]) { + // Protobuf vector tiles return [{x: , y:}] + point = L.point(offset.x + (geometry[0].x * pxPerExtent), offset.y + (geometry[0].y * pxPerExtent)); + } else { + // Geojson-vt returns [,] + point = L.point(offset.x + (geometry[0] * pxPerExtent), offset.y + (geometry[1] * pxPerExtent)); + } + return point; + }, + + vtGeometryToLatLng: function(geometry, vtLayer, tileCoords) { + return this._map.unproject(this.vtGeometryToPoint(geometry, vtLayer, tileCoords)); + }, + + addUserLayer: function(userLayer, tileCoords) { + var tileKey = this._tileCoordsToKey(tileCoords); + this._userLayers[tileKey] = this._userLayers[tileKey] || []; + this._userLayers[tileKey].push(userLayer); + this._map.addLayer(userLayer); + }, + + _tileUnload: function(e) { + var tileKey = this._tileCoordsToKey(e.coords); + if (this._vectorTiles) { + delete this._vectorTiles[tileKey]; + } + var userLayers = this._userLayers[tileKey]; + if (!userLayers) { + return; + } + for(var i = 0; i < userLayers.length; i++) { + console.log('remove layer'); + this._map.removeLayer(userLayers[i]); + } + delete this._userLayers[tileKey]; + }, + _updateStyles: function(feat, renderer, styleOptions) { if (!(styleOptions instanceof Array)) { styleOptions = [styleOptions];