0

I'm trying to get the features of each MultiPoint-point when i click on a point in my openlayers map (4.6.5). The points shows on the map.

I want to add a pop-up on each feature when i click on the points in my MultiPoint array. Each individual point consists of [LON, LAT, TIME].

In have previously achieved this with a "LineString" geometry. So i wonder if this a problem with "MULTIPOINT" as geometry?

My click function looks like this:

 map.on('click', function (evt) {
    var pointfeature = map.forEachFeatureAtPixel(evt.pixel, function (feature, vectorLayer) {

        if (feature) {
console.log(feature)
           var coordinate = evt.coordinate;
            var hdms = 
ol.coordinate.toStringHDMS(ol.proj.transform(coordinate, 'EPSG:3857', 
'EPSG:4326'));

        var geometry = feature.getGeometry(); 
        var mypoint = geometry.getClosestPoint(coordinate);
        var pointtoshow = point[1];
        content.innerHTML = '<p>feature </p>';
        overlay.setPosition(coordinate);
        }
        return feature;
    });
});

My geojsonObject looks like this:

var geojsonObject = {
    'type': 'FeatureCollection',
    'crs': {
        'type': 'name',
        'properties': {
            'name': 'EPSG:3857'
        }
    },
    'features':[
'type': 'Feature',
            'geometry': {
                'type': 'MultiPoint',
                'coordinates': 
                    mycoordinates().map(function (x) {

                        return ol.proj.transform([x[0], x[1]], 
   'EPSG:4326', 'EPSG:3857')
                    })
                ,
                "properties": {
                    "Time": mycoordinates().map(function (x)         
                {
                        return x[2]
                })
            }
        },{
        'type': 'Feature',
        'geometry': {
            'type': 'Point', 
            'coordinates': ol.proj.transform([refpointlon, refpointlat], 
        'EPSG:4326', 'EPSG:3857') 
        }]
};

What i get from the console.log(feature) is the following:

Hk {Wa: {…}, qa: {…}, oa: {…}, g: 1, xp: 2, …}
N: {geometry: No}
Wa: {}
a: "geometry"
ab: {change:geometry: Array(1), change: Array(1), propertychange:         
Array(1)}
c: undefined
f: null
g: 1
i:
Ch: Hk {Wa: {…}, qa: {…}, oa: {…}, g: 1, xp: 2, …}
Dh: ƒ b(b)
Eh: false
listener: ƒ ()
target: No {Wa: {…}, qa: {…}, oa: {…}, g: 1, xp: 1, …}
type: "change"
__proto__: Object
j: undefined
oa: {change:geometry: Array(1), change: Array(1), propertychange:         
Array(1)}
qa: {}
xp: 2
__proto__: Vc

But this does not contain the feature coordinates, and not the feature property: TIME, as spesified in the geojsonobject.

Any suggestions for why i don't get the individual feature-information??

10
  • If i choose another feature, it gives me: Hk {Wa: {…}, qa: {…}, oa: {…}, g: 1, xp: 4, …} N: geometry: C { .......... Which is C for Circle i think. Then if i choose my MultiPoint-feature I get the follwoing: Hk {Wa: {…}, qa: {…}, oa: {…}, g: 1, xp: 2, …} N: geometry: No {Wa: ...........What means "No", is it trying to tell me that it is NOT a geometry?
    – otk
    May 6, 2019 at 7:56
  • You can grab the geometry using feature.getGeometry() (which you did there, so I don't know where is the problem actually). And the property can be grabbed with feature.get('time').
    – dmh126
    May 6, 2019 at 8:00
  • If i do feature.getGeometry(), i get this: No {Wa: {…}, qa: {…}, oa: {…}, g: 1, xp: 1, …} However, it does not contain the properties I so badly need. If i do feature.get('time'), i only get "undefined"
    – otk
    May 6, 2019 at 8:11
  • And what about feature.get('Time'). I missed the capital 'T' before.
    – dmh126
    May 6, 2019 at 8:17
  • I corrected for that, does not help. :)
    – otk
    May 6, 2019 at 8:19

1 Answer 1

1

Leave the time value in the coordinates, just as you would for GPX:

var geojsonObject = {
    'type': 'FeatureCollection',
    'crs': {
        'type': 'name',
        'properties': {
            'name': 'EPSG:3857'
        }
    },
    'features':[
'type': 'Feature',
            'geometry': {
                'type': 'MultiPoint',
                'coordinates': 
                    mycoordinates().map(function (x) {
                        // include time in coordinates
                        return ol.proj.transform(x, 'EPSG:4326', 'EPSG:3857')
                    })
                ,
                "properties": {
                    "Time": mycoordinates().map(function (x)         
                {
                        return x[2]
                })
            }
        },{
        'type': 'Feature',
        'geometry': {
            'type': 'Point', 
            'coordinates': ol.proj.transform([refpointlon, refpointlat], 
        'EPSG:4326', 'EPSG:3857') 
        }]
};

Then you can get the time from the result of getClosestPoint():

map.on('click', function (evt) {
    var pointfeature = map.forEachFeatureAtPixel(evt.pixel, function (feature, vectorLayer) {

        if (feature) {
console.log(feature)
           var coordinate = evt.coordinate;
            var hdms = 
ol.coordinate.toStringHDMS(ol.proj.transform(coordinate, 'EPSG:3857', 
'EPSG:4326'));

        var geometry = feature.getGeometry(); 
        var mypoint = geometry.getClosestPoint(coordinate);
        var time = mypoint[2];
        content.innerHTML = '<p>feature </p>';
        overlay.setPosition(coordinate);
        }
        return feature;
    });
});

Here's a simple example using coordinates from a GPX linestring as a multipoint and displaying time when the mouse moves over a point https://jsfiddle.net/tbod7g05/

As OpenLayers only supports two extra coordinate properties (intended for altitude and time) if you needed more you could use the "altitude" to pass an index to your other properties:

var geojsonObject = {
    'type': 'FeatureCollection',
    'crs': {
        'type': 'name',
        'properties': {
            'name': 'EPSG:3857'
        }
    },
    'features':[
'type': 'Feature',
            'geometry': {
                'type': 'MultiPoint',
                'coordinates': 
                    mycoordinates().map(function (x, index) {
                       return ol.proj.transform([x[0], x[1], index], 
   'EPSG:4326', 'EPSG:3857')
                     })
                ,
                "properties": {
                    "Time": mycoordinates().map(function (x)         
                {
                        return x[2]
                })
            }
        },{
        'type': 'Feature',
        'geometry': {
            'type': 'Point', 
            'coordinates': ol.proj.transform([refpointlon, refpointlat], 
        'EPSG:4326', 'EPSG:3857') 
        }]
};


map.on('click', function (evt) {
    var pointfeature = map.forEachFeatureAtPixel(evt.pixel, function (feature, vectorLayer) {

        if (feature) {
console.log(feature)
           var coordinate = evt.coordinate;
            var hdms = 
ol.coordinate.toStringHDMS(ol.proj.transform(coordinate, 'EPSG:3857', 
'EPSG:4326'));

        var geometry = feature.getGeometry(); 
        var mypoint = geometry.getClosestPoint(coordinate);
        var index = mypoint[2];
        var time = feature.get('Time')[index];
        content.innerHTML = '<p>feature </p>';
        overlay.setPosition(coordinate);
        }
        return feature;
    });
});
2
  • Hi, tnx for the suggestion. What if i have more properties then just the 'time'?
    – otk
    May 6, 2019 at 12:21
  • As long as your time and other property arrays are in the same order as the points so you could pass the index value in the coordinates. I've added that to the code.
    – Mike
    May 6, 2019 at 12:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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