Bing 地图地形叠加无法读取未定义的 属性 'set_style'

Bing maps Topography Overlay Cannot read property 'set_style' of undefined

我正在尝试根据 Bing 地图上的 地形叠加层 进行缩放,我想为每个缩放级别加载不同的图像并在缩放更改。

我将每个 TopographicOverlay 存储在一个名为 UO 的数组中,用于每个缩放级别。默认级别是 UO[0],一切都按预期进行,直到我移动函数以在主函数(称为 startm)之外的图层(称为 insertOverlay)中插入对象。

换句话说,我的地图不是静态的。它是动态变化的,我需要能够从 startm() 之外的函数调用它的方法。

错误信息如下:

Uncaught TypeError: Cannot read property 'set_style' of undefined

var img;
var overlays = [];
var LastOverlayZoom = -1;

function startm(){
    var mapOptions = {
        credentials: "FAKECREDENTIAL",
        customizeOverlays: true,
        mapTypeId: Microsoft.Maps.MapTypeId.aerial
    };
    radar = new Microsoft.Maps.Map(document.getElementById("map_canvas"), mapOptions);

    var viewRect = Microsoft.Maps.LocationRect.fromCorners(
                      new Microsoft.Maps.Location(-23.40367, -68.82516),
                      new Microsoft.Maps.Location(-23.41825, -68.80178));

    radar.setView({bounds: viewRect});

    //
    TopographicOverlay.prototype = new Microsoft.Maps.CustomOverlay();

    showOverlay(0);
}

var UO = [];
function showOverlay(zoom){
    if(zoom >= 0){
        if(LastOverlayZoom!=0){
            if(LastOverlayZoom>0){
                hideOverlay(UO[LastOverlayZoom]);
                UO[LastOverlayZoom]=[];
            }
            if(LastOverlayZoom !=- 1 && 0 == 0){
                LastOverlayZoom = 0;
                return false;
            }
            console.log('Showing zoom 0');
            LastOverlayZoom = 0;
            UO[0] = [];
            UO[0].push(new TopographicOverlay(Microsoft.Maps.LocationRect.fromCorners(new Microsoft.Maps.Location(-23.4, -68.84), new Microsoft.Maps.Location(-23.39, -68.83)), 'https://bingmapsisdk.blob.core.windows.net/isdksamples/topographicMap.gif', radar));
            UO[0].push(new TopographicOverlay(Microsoft.Maps.LocationRect.fromCorners(new Microsoft.Maps.Location(-23.4, -68.83), new Microsoft.Maps.Location(-23.39, -68.82)), 'https://bingmapsisdk.blob.core.windows.net/isdksamples/topographicMap.gif', radar));
            UO[0].push(new TopographicOverlay(Microsoft.Maps.LocationRect.fromCorners(new Microsoft.Maps.Location(-23.4, -68.82), new Microsoft.Maps.Location(-23.39, -68.81)), 'https://bingmapsisdk.blob.core.windows.net/isdksamples/topographicMap.gif', radar));
            UO[0].push(new TopographicOverlay(Microsoft.Maps.LocationRect.fromCorners(new Microsoft.Maps.Location(-23.4, -68.81), new Microsoft.Maps.Location(-23.39, -68.8)), 'https://bingmapsisdk.blob.core.windows.net/isdksamples/topographicMap.gif', radar));
            UO[0].push(new TopographicOverlay(Microsoft.Maps.LocationRect.fromCorners(new Microsoft.Maps.Location(-23.41, -68.84), new Microsoft.Maps.Location(-23.4, -68.83)), 'https://bingmapsisdk.blob.core.windows.net/isdksamples/topographicMap.gif', radar));
            UO[0].push(new TopographicOverlay(Microsoft.Maps.LocationRect.fromCorners(new Microsoft.Maps.Location(-23.41, -68.83), new Microsoft.Maps.Location(-23.4, -68.82)), 'https://bingmapsisdk.blob.core.windows.net/isdksamples/topographicMap.gif', radar));
            UO[0].push(new TopographicOverlay(Microsoft.Maps.LocationRect.fromCorners(new Microsoft.Maps.Location(-23.41, -68.82), new Microsoft.Maps.Location(-23.4, -68.81)), 'https://bingmapsisdk.blob.core.windows.net/isdksamples/topographicMap.gif', radar));
            UO[0].push(new TopographicOverlay(Microsoft.Maps.LocationRect.fromCorners(new Microsoft.Maps.Location(-23.41, -68.81), new Microsoft.Maps.Location(-23.4, -68.8)), 'https://bingmapsisdk.blob.core.windows.net/isdksamples/topographicMap.gif', radar));
            insertOverlay(UO[0]);
        }
    }
}

// Define custom constructor for the overlay
function TopographicOverlay(bounds, image, map) {
    this.bounds = bounds;
    this.image = image;
    this.map = map;
    this.img = document.createElement('img');
}

// Implement the onAdd method to set up DOM element, and use setHtmlElement bind it with the overlay
TopographicOverlay.prototype.onAdd = function () {
    this.img = document.createElement('img');
    this.img.src = this.image;
    this.img.className = 'topographicOverlay';
    this.img.style.width = '100%';
    this.img.style.height = '100%';
    this.img.style.zIndex = '0';
    this.img.style.position = 'absolute';
    this.img.style.pointerEvents = 'none';
    this.setHtmlElement(this.img);
};

// Implement the onLoad method to perform custom operations of rendering the DOM element
TopographicOverlay.prototype.onLoad = function () {
    this.repositionOverlay();
    //repositionOverlay(this);
    //Microsoft.Maps.Events.addHandler(this.map, 'viewchange', repositionOverlay(this));
};

TopographicOverlay.prototype.repositionOverlay = function () {
    var topLeft = this.map.tryLocationToPixel(this.bounds.getNorthwest(), Microsoft.Maps.PixelReference.control);
    var bottomRight = this.map.tryLocationToPixel(this.bounds.getSoutheast(), Microsoft.Maps.PixelReference.control);
    if (topLeft && bottomRight) {
        this.img.style.left = topLeft.x + 'px';
        this.img.style.top = topLeft.y + 'px';
        this.img.style.width = (bottomRight.x - topLeft.x) + 'px';
        this.img.style.height = (bottomRight.y - topLeft.y) + 'px';
        this.img.style.zIndex = 0;
    }
};

function insertOverlay(UOl){ // muestra mapa sobrepuesto, UO es la lista de imagenes de un zoom específico
    UOl.forEach(function(UOimagery){
        console.log(UOimagery.image);
        radar.layers.insert(UOimagery);
    });
}
<script type="text/javascript" src="https://www.bing.com/api/maps/mapcontrol?callback=startm" async defer></script>
<div id="map_canvas" style="width:100%; height:100%; min-height:500px;"></div>

我该如何解决这个错误?

我做错了什么?

我的第一个想法是 startm 函数在它下面的所有代码完全加载之前被调用。如果 Bing Maps SDK 的脚本标记位于包含您的代码的脚本之前,就会发生这种情况。脚本标记的“异步”部分也可能是此处问题的一部分。尝试在此函数失败的地方添加一个断点,并检查它是否未定义。由于它看起来是一个全局函数,如果它是未定义的,那么它还没有被加载到页面中。

另一个可以尝试的方法是将 insertOverlay 函数移到代码中更高的位置,以便它在 startm 函数之前加载。

您似乎正在尝试在地图上创建动画天气叠加层。如果您不打算使用 Bing Maps,您可能想看看 Azure Maps。 Azure Maps 将天气数据作为其平台的一部分,以图块层的形式提供。下面是一个示例,可让您对这些数据进行动画处理:https://azuremapscodesamples.azurewebsites.net/?sample=Animated%20tile%20layer