Mapbox GL和.net核心webApi

时间:2018-11-13 11:21:22

标签: asp.net-core-webapi mapbox-gl-js

我正在从Leaflet迁移到Mapbox GL,并且遇到一些数据问题。我的webApi已经过验证,但是我无法顺利地集成它们。

根据他们的示例和我自己的研究,我放弃的方法如下:

        map = new mapboxgl.Map({
            container: 'mapdiv',
            style: 'mapbox://styles/mapbox/streets-v10'
            , center: start
            , zoom: $scope.zoom
            , transformRequest: (url, resourceType) => {
                if (resourceType === 'Source' && url.startsWith(CONFIG.API_URL)) {
                    return {
                        headers: {
                            'Authorization': 'Bearer ' + localStorageService.get("authorizationData")
                            , 'Access-Control-Allow-Origin': CONFIG.APP_URL
                            , 'Access-Control-Allow-Credentials': 'true'
                        }
                    }
                }
            }
        });

这是通过我的OAuth2令牌(或至少我认为应该是)和跨站点脚本部分CORS传递的。

在上面加上:

map.addSource(layerName, { type: 'geojson', url: getLayerURL($scope.remLayers[i]) });
map.getSource(layerName).setData(getLayerURL($scope.remLayers[i]));

也尝试无济于事:

map.addSource(layerName, { "type": 'geojson', "data": { "type": "FeatureCollection", "features": [] }});
map.getSource(layerName).setData(getLayerURL($scope.remLayers[i]));

尽管没有错误,但Fiddler并未显示对我的图层webApi的任何请求。所有其他显示,但Mapbox似乎没有提高它们。

网址看起来像: http://localhost:49198/api/layer/?bbox=36.686654090881355,34.72821077223763,36.74072742462159,34.73664000652042&dtype=l&id=cf0e1df7-9510-4d03-9319-d4a1a7d6646d&sessionId=9a7d7daf-76fc-4dd8-af4f-b55d341e60e4

因为这不起作用,所以我尝试使用现有的$ http调用使其更加手动,从而部分起作用。

map = new mapboxgl.Map({
            container: 'mapdiv',
            style: 'mapbox://styles/mapbox/streets-v10'
            , center: start
            , zoom: $scope.zoom
            , transformRequest: (url, resourceType) => {
                if (resourceType === 'Source' && url.startsWith(CONFIG.API_URL)) {
                    return {
                        headers: {
                            'Authorization': 'Bearer ' + localStorageService.get("authorizationData")
                        }
                    }
                }
            }
        });

               map.addSource(layerName,
                    {
                        "type": 'geojson',
                        "data": { "type": "FeatureCollection", "features": [] }
                    });

棘手的部分是知道何时运行数据检索调用。我唯一能找到的地方是在地图数据事件上,现在看起来像这样:

map.on('data', function (e) {
            if (e.dataType === 'source' && e.isSourceLoaded === false && e.tile === undefined) {
                // See if the datasource is known
                for (var i = 0; i < $scope.remLayers.length; i++) {
                    if (e.sourceId === $scope.remLayers[i].name) {
                        askForData(i)
                    }
                }
            }
        });

    function askForData(i) {
        var data = getBBoxString(map);
        var mapZoomLevel = map.getZoom();
        if (checkZoom(mapZoomLevel, $scope.remLayers[i].minZoom, $scope.remLayers[i].maxZoom)) {
            mapWebSvr.getData({
                bbox: data, dtype: 0, id: $scope.remLayers[i].id, buffer: $scope.remLayers[i].isBuffer, sessionId
            },  
                function (data, indexValue, indexType) {
                    showNewData(data, indexValue, indexType);
                },
                function () {
                    // Not done yet.
                },
                i,
                0
            );
        }
}

    function showNewData(ajxresponse, index, indexType) {
        map.getSource($scope.remLayers[index].name).setData(ajxresponse);
        map.getSource($scope.remLayers[index].name).isSourceLoaded = true;
    }

这一切都只有一个例外。它不断触发。其中一些呼叫会为网络呼叫返回大量数据,因此目前还不是解决方案。 就像它永远不会对数据感到满意,即使将其显示在地图上一样! 数据事件上有一个参数isSourceLoaded,但未将其设置为true。 我已经搜索了一个示例,尝试在许多地方设置isSourceLoaded(与上面的代码一样),但无济于事。

有人能成功完成此基本数据检索功能的方法,还是可以指出我的代码中的错误?甚至为我指出一个可行的示例...

我现在花了太长时间了,可以帮上忙。

1 个答案:

答案 0 :(得分:0)

经过一番磨合后,我有一个解决方案。 一封Mapbox电子邮件指出了填充事件中的数据-我现在正在做。 但是,这并不是我一直在寻找的解决方案,因为当地图移动,缩放等时数据需要刷新-需要进一步查找。 经过更多的检查,找到了解决方案。 更改边界框时,对呈现事件使用代码打击将要求提供信息。

        var renderStaticBounds = getBoundsString(map.getBounds());
        map.on('render', function (e) {
            if (renderStaticBounds != getBoundsString(map.getBounds())) {
                renderStaticBounds = getBoundsString(map.getBounds());
                for (var i = 0; i < $scope.remLayers.length; i++) {
                    askForData(i);
                }
            }
        });
        function getBoundsString(mapBounds) {
            var left = mapBounds._sw.lng;
            var bottom = mapBounds._sw.lat;
            var right = mapBounds._ne.lng;
            var top = mapBounds._ne.lat;
            return left + ',' + bottom + ',' + right + ',' + top;
        }

这有望为某人节省一些开发时间。