1

I'm extracting a couple of geometries with overpass turbo and need to "normalize" their shape from lat-lon to [[0-1][0-1]] coordinates.

The first thing I've tried is probably pretty wrong: get highest & smallest lat-lon values in the geometry and remap them to 0-1. This is the JS code:

function (geometry) {
    let biggestLat = geometry[0][0];
    let biggestLong = geometry[0][1];

    for (let i = 0; i < geometry.length; i++) {
        if (biggestLat < geometry[i][0]) {
            biggestLat = geometry[i][0];
        }

        if (biggestLong < geometry[i][1]) {
            biggestLong = geometry[i][1];
        }
    }

    let smallestLat = geometry[0][0];
    let smallestLong = geometry[0][1];

    for (let i = 0; i < geometry.length; i++) {
        if (smallestLat > geometry[i][0]) {
            smallestLat = geometry[i][0];
        }

        if (smallestLong > geometry[i][1]) {
            smallestLong = geometry[i][1];
        }
    }

    let coordinatesArray = [];

    for (let i = 0; i < geometry.length; i++) {

        let lat = this.map_range(geometry[i][0], smallestLat, biggestLat, 0, 1);
        let lon = this.map_range(geometry[i][1], smallestLong, biggestLong, 0, 1);
        coordinatesArray.push([lat, lon]);

    }

    return coordinatesArray
}

And the result is obviously pretty off:

comparison

I've been reading about the different projection methods and that I need to decide for one, but I don't really understand which I should use in this case. Mercator seems to be wrong?

To summarize my aim: I want to scale any Geometry i get from osm to the same size in a x,y coordinate system. Can anyone explain me how to do it correctly or what framework to use to do the calculation? I've been using turf.js in other projects.

2

So actually, what I missed, is to reverse the mercator projection. Then everything was fine:

function mercator (longitude, latitude) {
  var radius = 6378137;
  var max = 85.0511287798;
  var radians = Math.PI / 180;
  var point = {};

  point.x = radius * longitude * radians;
  point.y = Math.max(Math.min(max, latitude), -max) * radians;
  point.y = radius * Math.log(Math.tan((Math.PI / 4) + (point.y / 2)));

  return point;
}

I got it from http://mikefowler.me/journal/2014/06/10/drawing-geojson-in-a-canvas

I also messed up the long lat order + taking the relation of the bounding box of the shape into account:

function normalizeGeometry(geometry) {
    let biggestLong = geometry[0][0];
    let biggestLat = geometry[0][1];

    for (let i = 0; i < geometry.length; i++) {
        if (biggestLong < geometry[i][0]) {
            biggestLong = geometry[i][0];
        }
        if (biggestLat < geometry[i][1]) {
            biggestLat = geometry[i][1];
        }
    }

    let smallestLong = geometry[0][0];
    let smallestLat = geometry[0][1];

    for (let i = 0; i < geometry.length; i++) {
        if (smallestLat > geometry[i][1]) {
            smallestLat = geometry[i][1];
        }

        if (smallestLong > geometry[i][0]) {
            smallestLong = geometry[i][0];
        }
    }

    // calculate Ratio
    let width = biggestLong - smallestLong;
    let height = biggestLat - smallestLat;
    let ratio;

    let smallestLatRemap = 0;
    let biggestLatRemap = 1;
    let smallestLonRemap = 0;
    let biggestLonRemap = 1;

    if (width > height) { // landscape
        ratio = height / width;
        let shift = 1 - ratio;
        smallestLatRemap += shift / 2;
        biggestLatRemap -= shift / 2;
    } else if (width < height) { // portrait
        ratio = width / height;
        let shift = 1 - ratio;
        smallestLonRemap += shift / 2;
        biggestLonRemap -= shift / 2;
    } else { // square ratio
    }

    let coordinatesArray = [];

    for (let i = 0; i < geometry.length; i++) {
        let lon = this.map_range(geometry[i][0], smallestLong, biggestLong, smallestLonRemap, biggestLonRemap);
        let lat = this.map_range(geometry[i][1], smallestLat, biggestLat, biggestLatRemap, smallestLatRemap);
        coordinatesArray.push([lon, lat]);
    }

    return coordinatesArray
}

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.