Search code examples
javascriptprototypecluster-analysisweb-worker

Javascript Worker losing properties


I'm working on a webApp which shows clustered lightning occurrences on a map (so a huge cluster is like a thunderstorm formation).

To avoid 'freezing' the user interface, i'm using a Javascript Worker to perform the clustering. The problem happens when the algorithm finishes, because it returns a custom object which 'loses' some properties after i send it to the main page:

//inside Worker.js
var cluster = new DBSCAN(e.data.params).run();
self.postMessage({"cluster": cluster});

The cluster object is basically an array of GeoPoint objects, so:

cluster[0]

is a GeoPoint object like this

function GeoPoint(lat, lng){
    this.lat_ = lat;
    this.lng_ = lng;
}
GeoPoint.prototype.lat = function(){ return this.lat_;}
GeoPoint.prototype.lng = function(){ return this.lng_;}

When i send this object with self.postMessage i lose the lat() and lng() functions, which i need to draw the polygons. The lat_ and lng_ properties are intact though.

What can i do to overcome this? Right now i'm simply looping over the results and reconstructing the GeoPoint objects, it works but seems very bad.

Thanks for any advice!

EDIT: I need those functions because the drawing code will perform a sorting on the lat lon points, before it can calculate the convex hull.


Solution

  • What can i do to overcome this?

    Nothing - the cloning algorithm used by postMessage does not transport prototypes and functions. Reconstructing them on the other side is necessary.

    Right now i'm simply looping over the results and reconstructing the GeoPoint objects, it works but seems very bad.

    No, that's what needs to be done:

    var newCluster = messageData.cluster.map(function(likeapoint) {
        var point = new GeoPoint();
        for (p in likeapoint)        // maybe a static list of copied property names
            point[p] = likeapoint[p];// is faster, but not as flexible
        return point;
    })
    
    // since all properties are settable as arguments in this specific case:
    var newCluster = messageData.cluster.map(function(likeapoint) {
        return new GeoPoint(likeapoint.lat_, likeapoint.long_);
    })