0

I've been working with OL4 for a few months now but this is the first time I try to calculate an area and after some research looks like Turf.js seems like the way to go.

First, allow me to add all the code which, IMO, is relevant here, projection-wise:

This is where I add all the features to the map:

proj4.defs("EPSG:3795", "+proj=lcc +lat_1=23 +lat_2=21.7 +lat_0=22.35 +lon_0=-81 +x_0=500000 +y_0=280296.016 +datum=NAD27 +units=m +no_defs");

var parser = new ol.format.WMSGetFeatureInfo();
var ajaxCall = $.ajax({
    url: url,
    success: function(response) {
        results = parser.readFeatures(response);
        $.each(results, function(i, v) {
            var feature = v;
            feature.setGeometry(v.getGeometry().clone().transform('EPSG:3795', 'EPSG:3857'));
            vector.getSource().addFeature(feature);
        });
    }
});

This is my view definition:

var view = new ol.View({
        center: ol.extent.getCenter(
            ol.proj.transformExtent(extent, 'EPSG:4326', 'EPSG:3857')
        ),
        zoom: 11.7
});

I have two layers on the map and I am trying to calculate the area of the intersection between two features, each belonging to one of the layers. This is how I am calculating the area:

        var g1 = feature.getGeometry(); //<-- 'feature' comes from openlayers' event 'forEachFeatureAtPixel'

        var gc1 = g1.getCoordinates();
        var gt1 = g1.getType();
        var poly1 = getTurfHelper(gt1, gc1);
        $.each(__map.getLayerByName('layer2').getSource().getFeatures(), function(i, f) {
            var gt2 = f.getGeometry().getType();
            var gc2 = f.getGeometry().getCoordinates();
            var poly2 = getTurfHelper(gt2, gc2);
            var intersection = turf.intersect(poly1, poly2);
            if (intersection !== undefined && intersection !== null) {
                console.log(turf.area(intersection));
            }
        });

function getTurfHelper(type, coordinates) {
    if (type === 'Polygon') {
        return turf.polygon(coordinates);
    } else if (type === 'MultiLineString') {
        return turf.multiLineString(coordinates);
    } else if (type === 'MultiPolygon') {
        return turf.multiPolygon(coordinates);
    } else if (type === 'Point') {
        return turf.point(coordinates);
    } else if (type === 'LineString') {
        return turf.lineString(coordinates);
    } else if (type === 'Feature') {
        var geometry = {
            "type": "Feature",
            "coordinates": coordinates
        };
        return turf.feature(geometry);
    }
    return undefined;
}

Now, the problem at hand:

20450142473549.008 is what I am getting as an area. According to turf's docs, turf.area's result is in square meters and in my test data the intersection should be somewhere around 8000m^2 which is why I think I'm doing something really wrong. Maybe it's a projection issue or maybe just not using turf properly. Any help appreciated.

0

1 Answer 1

0

Turf.js works with GeoJSON. GeoJSON default projection is "EPSG:4326" and Turf.js uses this projection (if "EPSG:4326" can be considered a projection...).

From your code, you are using geometry using "EPSG:3857".

Turf will always do "bad" calculations as you do not provide the coordinates in the "right" projection.

Change EPSG:3857 to EPSG:4326 and it should work.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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