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