首页 > 解决方案 > 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()也没有帮助。

如果它可以在获取这些点的同时开始渲染地图图块,那将是完美的,现在甚至在提取完成后渲染图块。

标签: javascriptgisopenlayersopenstreetmap

解决方案


看起来这里的好策略是递归。仅仅进行异步调用是不够的。

虽然每次调用都是异步的(这让地图尽快开始渲染),但下一次调用是在显示前一次调用的标记后完成的。


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);
    }
    });
}

推荐阅读