javascript - OperLayers:在获取标记时显示标记
问题描述
我正在通过 ajax 请求获取数千个点以显示在 OSM 地图上。
每次通话我都会得到 100 分。
我希望它们在获取后立即显示在地图上,而现在它们仅在所有调用(大约 20 个)完成后才会显示。
这是我的代码:
var source = new ol.source.OSM();
var map_layer = new ol.layer.Tile({
source: source
});
var map_view = new ol.View({
center: ol.proj.fromLonLat([12, 44]),
zoom: 9
});
var map = new ol.Map({
layers: [map_layer, ],
target: 'map-canvas',
view: map_view
});
var target = $(map.getTargetElement());
target.width(window.innerWidth);
target.height(window.innerHeight * 0.9);
map.updateSize();
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
var overlay = new ol.Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
map.addOverlay(overlay);
closer.onclick = function() {
overlay.setPosition(undefined);
closer.blur();
return false;
};
var markers = new ol.Collection([], {unique: true})
var vectors = new ol.source.Vector({
features: markers
});
var style = new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
src: 'pin.jpg'
})
});
var layer = new ol.layer.Vector({
source: vectors,
style: style,
});
map.addLayer(layer);
var data = [];
var url = 'some_url';
while (url) {
$.ajax({
async: false,
url: url
}).done(function(data) {
url = data.next;
var res = data.results;
for (var i=0; i<res.length; i++) {
if (res[i].latitude & res[i].longitude) {
var point = ol.proj.fromLonLat([res[i].longitude, res[i].latitude]);
var feature = new ol.Feature({
geometry: new ol.geom.Point(point),
latitude: res[i].latitude,
longitude: res[i].longitude,
})
markers.extend([feature, ]);
}
}
map.render();
});
}
您可以看到map.render()
的最后一条指令 ( ) 不应该起作用吗?它不是。
map.renderSync()
也没有帮助。
如果它可以在获取这些点的同时开始渲染地图图块,那将是完美的,现在甚至在提取完成后渲染图块。
解决方案
看起来这里的好策略是递归。仅仅进行异步调用是不够的。
虽然每次调用都是异步的(这让地图尽快开始渲染),但下一次调用是在显示前一次调用的标记后完成的。
var url = 'some_url';
var limit = 100;
var offset = 0;
var total_count = 2000;
fetch_data(offset);
function fetch_data(offset) {
$.ajax({
url: encodeURI(url + '?limit=' + limit + '&offset=' + offset)
}).done(function(data) {
var res = data.results;
for (var i=0; i<res.length; i++) {
if (res[i].latitude & res[i].longitude) {
var point = ol.proj.fromLonLat([res[i].longitude, res[i].latitude]);
var feature = new ol.Feature({
geometry: new ol.geom.Point(point),
latitude: res[i].latitude,
longitude: res[i].longitude,
})
markers.extend([feature, ]);
}
}
offset += limit;
if (offset < total_count) {
fetch_data(offset);
}
});
}
推荐阅读
- mysql - MySql根据group by对查询的行进行编号
- typescript - 我可以确保其他人不会使用相同的参数调用某个函数吗?
- vbscript - ADODB.Stream 块是否与 Response.Buffer 冲突?
- javascript - 在多维 JavaScript 数组中动态保存 Smarty 值
- android - 使用 exoplayer 从 azure 媒体服务获取令牌的 Widevine 离线许可证
- java-8 - java - 如何通过在java中迭代一个没有重复的列表来过滤记录?
- r - 如何为 rstanarm 中的 stan_lmer 多级模型指定信息先验?
- git - git pull 返回警告:监听端口 52698 的远程端口转发失败
- flutter - Flutter 将 NestedScrollView 添加到 SliverChildListDelegate 并出现 RenderFlex 错误
- python - 提高数据预处理速度 - Python 中的正则表达式