2

I am trying to add multiple points on the map. Data comes from the server as a multi array.

JSFiddle.

Notice that all points share the same name (when clicking on the point)

This is the response from PHP:

[
{
name: "Parking0001",
lat: "35.1495",
lon: "33.39243"
},
{
name: "RecycleBin0001",
lat: "35.1495",
lon: "33.39243"
},
{
name: "WaterA27",
lat: "35.1495",
lon: "33.39243"
},
{
name: "WaterA12",
lat: "35.1495",
lon: "33.39243"
}
]

Something I am doing wrong and i get undefined on iconFeature in the loop

function OpeNlayers(data) {

    var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point([199, 154]),
        name: 'A point',
        population: 4000,
        rainfall: 500
    });

    var iconStyle = new ol.style.Style({
        image: new ol.style.Icon({
            anchor: [0.5, 0.5],
            anchorXUnits: 'fraction',
            anchorYUnits: 'pixels',
            src: 'icon.png'
        })
    });

    var vectorSource = new ol.source.Vector({
        features: []
    });

    var vectorLayer = new ol.layer.Vector({
        source: vectorSource
    });

    var rasterLayer = new ol.layer.Tile({
        source: new ol.source.TileJSON({
            url: 'https://a.tiles.mapbox.com/v3/aj.1x1-degrees.json',
            crossOrigin: ''
        })
    });

    $.each(data, (index, data) => {
        let iconFeature = new ol.Feature({
            geometry: new ol.geom.Point([data.lon, data.lat]).transform('EPSG:4326', 'EPSG:3857'),
            name: data.name
        })
        iconFeature.setStyle(iconStyle)
        vectorSource.addFeature(iconFeature)
    })

    var map = new ol.Map({
        target: 'map',
        layers: [rasterLayer, vectorLayer],
        view: new ol.View({
            center: ol.proj.fromLonLat([35.1495, 33.39243]),
            zoom: 7
        })
    });
}

$.post("MapMarkers.php", null, null, "json")
    .done(data => {
        OpeNlayers(data)
    }).fail(function () {
        alert("error loading data")
    });

enter image description here

  • OpenLayers sometimes doesn't like strings when it expects numbers. You could try using [Number(data.lon), Number(data.lat)] – Mike Dec 11 '19 at 9:41
  • Notice that all points share the same name on click: jsfiddle.net/5ne28wq4 – Andd Dec 11 '19 at 13:10
  • Only if you click on one without closing the previous one, Click on an empty area between points and then they appear correctly. You need to destroy before each show. – Mike Dec 11 '19 at 13:27
  • 1
    You also need a short timeout between destroy and show as destroy must complete (and it seems to have no completion callback) jsfiddle.net/c17e4Ldf – Mike Dec 11 '19 at 16:41
  • @Mike clicking on the transparent background of png images does not have an effect. Do i need to put jpeg icons? – Andd Dec 16 '19 at 9:17
2

With the limited info given, I have no trouble replicating your task and everything works just fine:

https://jsfiddle.net/k90e7rhv/

I added some console.log() to help visualize what's going on if you run it.

Your data all has the same coordinates, so it all overlaps.

For the future, I recommend adding vital information such as what versions of jQuery and OpenLayers you use. And offering a jsfiddle in your question helps yourself and others troubleshoot issues a lot.

If you still have trouble, I recommend adding more checks to ensure the data returned from your PHP is actually what you expect it to be inside the Openlayers() function. Also, avoid using function names that collide with functions used by the libraries you use. Name it 'myOpenLayers()' or something at the very least.

  • Okay, thanks for suggestion. I forked the fiddle and added click event example on the point. Notice, all points share the same name: jsfiddle.net/5ne28wq4 – Andd Dec 11 '19 at 11:53
  • 1
    Please add your fiddle and your expanded question by editing your own question. That's where people will look, not at comments. The objective is to have an answer that contains the full solution to a specific issue. Comments are just for minor clarifications, which this is not. – Senshi Dec 11 '19 at 12:46
1

I tested this briefly without calling the server and it works fine with a couple of tweaks.

Here are four points which should show up in different locations:

var data = [
    {
        name: "Parking0001",
        lat: "35.1",
        lon: "33.3"
    },
    {
        name: "RecycleBin0001",
        lat: "35.2",
        lon: "33.4"
    },
    {
        name: "WaterA27",
        lat: "35.3",
        lon: "33.5"
    },
    {
        name: "WaterA12",
        lat: "35.4",
        lon: "33.6"
    }
]
OpeNlayers(data)

It would be clearer to use a different variable name for the feature/data within the loop:

$.each(data, (idx, feature) => {
    var iconFeature = new ol.Feature({
        geometry: new ol.geom.Point(
            [feature.lon, feature.lat]
        ).transform('EPSG:4326', 'EPSG:3857'),
        name: feature.name
    })
    iconFeature.setStyle(iconStyle)
    vectorSource.addFeature(iconFeature)
})

In case it's helpful, you might not need jQuery for this:

$.each(data, (idx, feature) => {

could be swapped out almost directly for:

data.forEach(feature => {

From a quick test (using OpenLayers 6.1.1), ol.geom.Point was happy with strings and ol.Feature was happy to be given duplicate names.

It might also be worth noting that ol.style.Icon anchor defaults to fraction units at [0.5, 0.5], so you can avoid a couple of lines and write:

var iconStyle = new ol.style.Style({
    image: new ol.style.Icon({
        src: 'icon.png'
    })
});

Not the answer you're looking for? Browse other questions tagged or ask your own question.