我正在从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调用使其更加手动,从而部分起作用。
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(与上面的代码一样),但无济于事。
有人能成功完成此基本数据检索功能的方法,还是可以指出我的代码中的错误?甚至为我指出一个可行的示例...
我现在花了太长时间了,可以帮上忙。
答案 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;
}
这有望为某人节省一些开发时间。