diff --git a/docs/demo-labels.html b/docs/demo-labels.html
new file mode 100644
index 0000000..a23768c
--- /dev/null
+++ b/docs/demo-labels.html
@@ -0,0 +1,86 @@
+
+
+
+ Leaflet Map Panes Example
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Leaflet.VectorGrid.js b/src/Leaflet.VectorGrid.js
index 1aa3eab..053fafb 100644
--- a/src/Leaflet.VectorGrid.js
+++ b/src/Leaflet.VectorGrid.js
@@ -25,6 +25,8 @@ L.VectorGrid = L.GridLayer.extend({
// A data structure holding initial symbolizer definitions for the vector features.
vectorTileLayerStyles: {},
+ onEachFeature: null,
+
// 🍂option interactive: Boolean = false
// Whether this `VectorGrid` fires `Interactive Layer` events.
interactive: false,
@@ -41,21 +43,17 @@ L.VectorGrid = L.GridLayer.extend({
if (this.options.getFeatureId) {
this._vectorTiles = {};
this._overriddenStyles = {};
- this.on('tileunload', function(e) {
- var key = this._tileCoordsToKey(e.coords),
- tile = this._vectorTiles[key];
-
- if (tile && this._map) {
- tile.removeFrom(this._map);
- }
- delete this._vectorTiles[key];
- }, this);
}
this._dataLayerNames = {};
- },
+ 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);
@@ -103,11 +101,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 = 0; j < styleOptions.length; j++) {
var style = L.extend({}, L.Path.prototype.options, styleOptions[j]);
featureLayer.render(renderer, style);
@@ -186,6 +191,48 @@ L.VectorGrid = L.GridLayer.extend({
return Object.keys(this._dataLayerNames);
},
+ 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) {
styleOptions = (styleOptions instanceof Function) ?
styleOptions(feat.properties, renderer.getCoord().z) :