最近有研究Cesium如何加载百度注记图层,看到网上有大佬提供了BaiduImageryProvider包装类,确实可以加载百度注记,但是发现叠加到三维场景球面后发现背景非透明,效果如下图所示:
function BaiduImageryProvider(options) {
this._errorEvent = new Cesium.Event();
this._tileWidth = 256;
this._tileHeight = 256;
this._maximumLevel = 19;
this._minimumLevel = 1;
let southwestInMeters = new Cesium.Cartesian2(-33554054, -33746824);
let northeastInMeters = new Cesium.Cartesian2(33554054, 33746824);
this._tilingScheme = new Cesium.WebMercatorTilingScheme({
rectangleSouthwestInMeters: southwestInMeters,
rectangleNortheastInMeters: northeastInMeters
});
this._rectangle = this._tilingScheme.rectangle;
let resource = Cesium.Resource.createIfNeeded(options.url);
this._resource = resource;
this._tileDiscardPolicy = undefined;
this._credit = undefined;
this._readyPromise = undefined;
this._defaultAlpha = 1;
}
Object.defineProperties(BaiduImageryProvider.prototype, {
url: {
get: function () {
return this._resource.url;
}
},
proxy: {
get: function () {
return this._resource.proxy;
}
},
tileWidth: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError('tileWidth must not be called before the imagery provider is ready.');
}
return this._tileWidth;
}
},
tileHeight: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError('tileHeight must not be called before the imagery provider is ready.');
}
return this._tileHeight;
}
},
maximumLevel: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError('maximumLevel must not be called before the imagery provider is ready.');
}
return this._maximumLevel;
}
},
minimumLevel: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError('minimumLevel must not be called before the imagery provider is ready.');
}
return this._minimumLevel;
}
},
tilingScheme: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError('tilingScheme must not be called before the imagery provider is ready.');
}
return this._tilingScheme;
}
},
tileDiscardPolicy: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError('tileDiscardPolicy must not be called before the imagery provider is ready.');
}
return this._tileDiscardPolicy;
}
},
rectangle: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError('rectangle must not be called before the imagery provider is ready.');
}
return this._rectangle;
}
},
errorEvent: {
get: function () {
return this._errorEvent;
}
},
ready: {
get: function () {
return this._resource;
}
},
readyPromise: {
get: function () {
return this._readyPromise;
}
},
credit: {
get: function () {
if (!this.ready) {
throw new Cesium.DeveloperError('credit must not be called before the imagery provider is ready.');
}
return this._credit;
}
},
defaultAlpha: {
get: function () {
return this._defaultAlpha;
}
}
});
BaiduImageryProvider.prototype.requestImage = function (x, y, level, request) {
let r = this._tilingScheme.getNumberOfXTilesAtLevel(level);
let c = this._tilingScheme.getNumberOfYTilesAtLevel(level);
x = x - r / 2;
y = c / 2 - y - 1;
if (x < 0) {
x = 'M' + (-x);
}
if (y < 0) {
y = 'M' + (-y);
}
let s = this.url.replace("{x}", x).replace("{y}", y).replace("{z}", level).replace("{s}", Math.floor(10 * Math.random()));
return Cesium.ImageryProvider.loadImage(this, s);
};
module.exports = BaiduImageryProvider;
viewer.imageryLayers.addImageryProvider(
new BaiduImageryProvider({
url: "http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=sl&v=017",
})
)
问题:调试查看png背景为透明,见下图所示:
经过两天的摸索,发现是ImageryProvider对象中hasAlphaChannel导致,该值默认为false,大概意思是
图像提供者是否提供了图像包括一个Alpha通道。如果此属性为false,则Alpha通道(如果存在)将被忽略。如果此属性为true,则将处理没有alpha通道的任何图像好像他们的alpha到处都是1.0。当此属性为false时,内存使用情况并且减少了纹理上载时间。
解决方法:将该属性设置为true即可,完善上述BaiduImageryProvider包装类