/**
* BeNomad BeMap JavaScript API - MapLibre v5 - 3D Buildings
*
* Usage:
* map.add3DBuildings({
* sourceId: 'openmaptiles',
* sourceLayer: 'building',
* heightProperty: 'render_height',
* color: '#ddd',
* opacity: 0.8,
* minZoom: 14
* });
*/
bemap.MapLibreMap.prototype.add3DBuildings = function(options) {
var opts = options || {};
var _this = this;
this._buildingsLayerId = this._uniqueId('buildings-3d');
var config = {
id: this._buildingsLayerId,
type: 'fill-extrusion',
paint: {
'fill-extrusion-color': opts.color || '#aaa',
'fill-extrusion-height': ['get', opts.heightProperty || 'height'],
'fill-extrusion-base': ['get', opts.baseHeightProperty || 'min_height'],
'fill-extrusion-opacity': opts.opacity !== undefined ? opts.opacity : 0.6
}
};
if (opts.minZoom) config.minzoom = opts.minZoom;
if (opts.sourceId) config.source = opts.sourceId;
if (opts.sourceLayer) config['source-layer'] = opts.sourceLayer;
// Cancellation token — flipped by remove3DBuildings so a queued
// deferred add can't resurrect the layer (Bug 9).
var token = { cancelled: false };
this._3dBuildingsTokens = this._3dBuildingsTokens || {};
this._3dBuildingsTokens[this._buildingsLayerId] = token;
// If GeoJSON data is provided directly
if (opts.data) {
var sourceId = this._uniqueId('buildings-src');
var addBuildings = function() {
if (token.cancelled) return;
if (!_this.native.getSource(sourceId)) {
_this.native.addSource(sourceId, { type: 'geojson', data: opts.data });
config.source = sourceId;
_this.native.addLayer(config);
}
};
if (this.native.isStyleLoaded()) { addBuildings(); } else { this.native.on('load', addBuildings); }
} else {
// Use existing source (e.g., from vector tiles in the style)
var addFromSource = function() {
if (token.cancelled) return;
if (config.source && !_this.native.getLayer(_this._buildingsLayerId)) {
_this.native.addLayer(config);
}
};
if (this.native.isStyleLoaded()) { addFromSource(); } else { this.native.on('load', addFromSource); }
}
// Register in the active-effects bar so customers can tear it down
// with one click. Bug 13 / Part 3.
if (typeof this._registerEffect === 'function') {
this._registerEffect('3DBuildings', function () { _this.remove3DBuildings(); });
}
return this;
};
bemap.MapLibreMap.prototype.remove3DBuildings = function() {
// Cancel any pending deferred add (Bug 9 race).
if (this._buildingsLayerId && this._3dBuildingsTokens && this._3dBuildingsTokens[this._buildingsLayerId]) {
this._3dBuildingsTokens[this._buildingsLayerId].cancelled = true;
delete this._3dBuildingsTokens[this._buildingsLayerId];
}
if (this._buildingsLayerId) {
try {
if (this.native.getLayer(this._buildingsLayerId)) {
this.native.removeLayer(this._buildingsLayerId);
}
} catch(e) {}
this._buildingsLayerId = null;
}
if (typeof this._unregisterEffect === 'function') this._unregisterEffect('3DBuildings');
return this;
};