Search code examples
javascriptgisopenlayers

OpenLayers draw LineString with real width in meters


I tried to draw a polyLine (road lane) with width in meters using the latest stable OpenLayers library, but it didn't have the correct real width (checked on top of Google Maps layer). This is the code snippet that works for me:

polyLineFeature.setStyle((feature, resolution) => {
    const lineString = feature.getGeometry();
    const lineStyles = [
        new Style({
            stroke: new Stroke({
                width:
                    laneWidth /
                    resolution /
                    getPointResolution("EPSG:3857", 1, lineString.getCoordinateAt(0.5)),
                lineCap: "square",
            }),
        }),
    ];
    return lineStyles;
});

I use the default projection everywhere (web mercator).

But I don't get the reason why do I have to divide the real width in meters by the current resolution AND another resolution that is relevant within the actual area. Is this explained anywhere?


Solution

  • WebMercator 3857 is a bad projection with respect to distances. It introduces a huge distortion as you move away from the equator (that's why Greenland looks so big on the map while in reality it is a fairly small piece of land).

    By dividing the width by getPointResolution, you are effectively correcting this distortion.

    If you were using another projection that preserve distances, such as UTM, you wouldn't have to do this division (or, if you did, the value of getPointResolution would be 1)