Openlayers 在使用 Ajax 检索后显示标记

Openlayers show markers after retrieving with Ajax

我有这段显示地图的代码,我还在 Ajax 调用中获得了标记点。

它似乎在 Ajax return 成功之前生成了地图。我不知道如何在 Ajax 调用 return 成功时更新地图。

我是否应该将 Ajax 调用之外的所有内容都移动到我调用 Ajax 成功的函数中?

    var jsonData = '';
    let userData = null;

    $.ajax({
        url : "getBackyards.php",
        type: "POST",
        cache: false,
        data:{id:"1"},
        success:function(result){
            console.log(result);
            var stringified = JSON.stringify(result);
            console.log(jsonData);      
            jsonData = JSON.parse(stringified);
            console.log(jsonData);      
        },
    });
    
    
    /*
    var jsonData =
    {
        "odessa": {
            "title": "Odessa Restaurant, Kyiv",
            "long": 30.5191,
            "lat": 50.4227,
            "imgSrc": "https://media-cdn.tripadvisor.com/media/photo-s/04/49/ca/08/odessa-restaurant.jpg",
            "url": "https://odessarest.com.ua"
        },
        "example": {
            "title": "Example marker",
            "long": 31.5191,
            "lat": 51.4227,
            "imgSrc": "https://images-na.ssl-images-amazon.com/images/I/61PcbNuRRfL._SX425_.jpg",
            "url": "https://mobiletechtracker.co.uk/"
        }
    };
    */
    
    var modal = document.getElementById("myModal");
    var span = document.getElementsByClassName("close")[0];
    
    span.onclick = function() {
        closeModal();
    }

    // When the user clicks anywhere outside of the modal, close it
    window.onclick = function(event) {
        if (event.target == modal)
            closeModal();
    }

    function closeModal() {
        modal.style.display = "none";
    }

    function createStyle(src, img) {
        return new ol.style.Style({
            image: new ol.style.Icon(({
                anchor: [0.5, 0.96],
                crossOrigin: 'anonymous',
                src: src,
                img: img,
                imgSize: img ? [img.width, img.height] : undefined
            }))
        });
    }
    
    var iconFeatures = [];
    
    setIconFeatures();
    
    function setIconFeatures() {
        for(var key in jsonData) {          
            var jsonItem = jsonData[key];
        
            var iconFeature = new ol.Feature(new ol.geom.Point(ol.proj.fromLonLat([jsonItem.long, jsonItem.lat])));
            iconFeature.setId(key);
            iconFeature.set('style', createStyle('http://test.brugminbaghave.dk/img/BMB-logo.svg', undefined));
            iconFeatures.push(iconFeature);
        }
    }

    var distance = document.getElementById('distance');
    var source = new ol.source.Vector({features: iconFeatures});

    var unclusteredLayer = new ol.layer.Vector({
        source: source,
        style: function(feature) {
            return feature.get('style');
        },
        maxResolution: 2000
    });

    var clusterSource = new ol.source.Cluster({
        distance: parseInt(distance.value, 10),
        source: source
    });

    var styleCache = {};
    
    var clusters = new ol.layer.Vector({
        source: clusterSource,
        style: function(feature) {
            var size = feature.get('features').length;
            var style = styleCache[size];
            if (!style) {
                style = new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        stroke: new ol.style.Stroke({
                            color: '#fff'
                        }),
                        fill: new ol.style.Fill({
                            color: '#3399CC'
                        })
                    }),
                    text: new ol.style.Text({
                        text: size.toString(),
                        fill: new ol.style.Fill({
                            color: '#fff'
                        })
                    })
                });
                styleCache[size] = style;
            }
            return style;
        },
        minResolution: 2001
    });

    var raster = new ol.layer.Tile({
        source: new ol.source.OSM()
    });

    var map = new ol.Map({
        target: 'map',
        layers: [raster, clusters, unclusteredLayer],
        view: new ol.View({
            center: ol.proj.fromLonLat([9.5191, 55.4227]),
            zoom: 6
        })
    });

    distance.addEventListener('input', function() {
        clusterSource.setDistance(parseInt(distance.value, 10));
    });

    map.on('click', function(event) {
        map.forEachFeatureAtPixel(event.pixel, function(feature,layer) {
            var key = feature.getId();      
            if (key in jsonData) {
                var jsonItem = jsonData[key];
                
                document.getElementById("modalTitle").innerText = jsonItem.title;
                document.getElementById("modalImage").src = jsonItem.imgSrc;
                document.getElementById("modalUrl").href = jsonItem.url;
            
                modal.style.display = "block";
            }
            else if (map.getView().getZoom() < 7) {
                map.getView().fit(feature.getGeometry(), {padding: [170, 50, 30, 150], minResolution: 1000});
            }
        });
    });

    map.on('pointermove', function(evt) {
        map.getTargetElement().style.cursor =
            map.hasFeatureAtPixel(evt.pixel) ? 'pointer' : '';
    });

您可以移动所有内容,但至少需要将 setIconFeatures 调用移动到 ajax 回调,然后将功能添加到源而不是使用创建源功能

var jsonData = '';
let userData = null;
var iconFeatures = [];
var source = new ol.source.Vector();

$.ajax({
    url : "getBackyards.php",
    type: "POST",
    cache: false,
    data:{id:"1"},
    success:function(result){
        console.log(result);
        var stringified = JSON.stringify(result);
        console.log(jsonData);      
        jsonData = JSON.parse(stringified);
        console.log(jsonData);   
        setIconFeatures();
        source.addFeatures(iconFeatures);
    },
});


/*
var jsonData =
{
    "odessa": {
        "title": "Odessa Restaurant, Kyiv",
        "long": 30.5191,
        "lat": 50.4227,
        "imgSrc": "https://media-cdn.tripadvisor.com/media/photo-s/04/49/ca/08/odessa-restaurant.jpg",
        "url": "https://odessarest.com.ua"
    },
    "example": {
        "title": "Example marker",
        "long": 31.5191,
        "lat": 51.4227,
        "imgSrc": "https://images-na.ssl-images-amazon.com/images/I/61PcbNuRRfL._SX425_.jpg",
        "url": "https://mobiletechtracker.co.uk/"
    }
};
*/

var modal = document.getElementById("myModal");
var span = document.getElementsByClassName("close")[0];

span.onclick = function() {
    closeModal();
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
    if (event.target == modal)
        closeModal();
}

function closeModal() {
    modal.style.display = "none";
}

function createStyle(src, img) {
    return new ol.style.Style({
        image: new ol.style.Icon(({
            anchor: [0.5, 0.96],
            crossOrigin: 'anonymous',
            src: src,
            img: img,
            imgSize: img ? [img.width, img.height] : undefined
        }))
    });
}

function setIconFeatures() {
    for(var key in jsonData) {          
        var jsonItem = jsonData[key];
    
        var iconFeature = new ol.Feature(new ol.geom.Point(ol.proj.fromLonLat([jsonItem.long, jsonItem.lat])));
        iconFeature.setId(key);
        iconFeature.set('style', createStyle('http://test.brugminbaghave.dk/img/BMB-logo.svg', undefined));
        iconFeatures.push(iconFeature);
    }
}

var distance = document.getElementById('distance');

var unclusteredLayer = new ol.layer.Vector({
    source: source,
    style: function(feature) {
        return feature.get('style');
    },
    maxResolution: 2000
});

var clusterSource = new ol.source.Cluster({
    distance: parseInt(distance.value, 10),
    source: source
});

var styleCache = {};

var clusters = new ol.layer.Vector({
    source: clusterSource,
    style: function(feature) {
        var size = feature.get('features').length;
        var style = styleCache[size];
        if (!style) {
            style = new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 10,
                    stroke: new ol.style.Stroke({
                        color: '#fff'
                    }),
                    fill: new ol.style.Fill({
                        color: '#3399CC'
                    })
                }),
                text: new ol.style.Text({
                    text: size.toString(),
                    fill: new ol.style.Fill({
                        color: '#fff'
                    })
                })
            });
            styleCache[size] = style;
        }
        return style;
    },
    minResolution: 2001
});

var raster = new ol.layer.Tile({
    source: new ol.source.OSM()
});

var map = new ol.Map({
    target: 'map',
    layers: [raster, clusters, unclusteredLayer],
    view: new ol.View({
        center: ol.proj.fromLonLat([9.5191, 55.4227]),
        zoom: 6
    })
});

distance.addEventListener('input', function() {
    clusterSource.setDistance(parseInt(distance.value, 10));
});