openstreetmap

Mapping latitude and longitude from OpenStreetMap to X and Y points on Canvas in JavaScript


Tell me, I encountered the same problem. I get the coordinates of points of a particular region from an OpenStreetMap. These coordinates need to be translated into X and Y points on my Canvas in accordance with the size of the area and drawn.

For example, I have coordinates
[37.6628251, 44.7657795] [37.6636733, 44.7651791] [37.6628725, 44.7640567] [37.6637161, 44.7636559] [37.6647429, 44.7645108] [37.6656829, 44.7641975] [37.6670459, 44.7656444]

I need to place them on my Canvas, which has a size of 1240x504.
What to do?
I tried using different formulas, converting latitude and longitude to X and Y, but when drawing on Canvas, all the points are drawn in one place, since I can’t adjust them to my scale


Solution

  • I was able to resolve my issue.

    1. The first step is to convert our latitude and longitude to radians. To do this we use the formula...

      latRadian = latCoord * Math.PI / 180
      lngRadian = lngCoord * Math.PI / 180
      
    2. The next thing to do is to convert the longitude and latitude into a projection. This is done according to the formula...

      We find the projection only for latitude, the value of the projection for longitude remains unchanged, this is the radian value that was found before

      let latProjection = latRadian
      let lngProjection = Math.log(Math.tan(lngRadian) + 1 / Math.cos(lngRadian))
      
    3. Longitude and latitude are converted to the map coordinate system. This starts at the top left with [0,0] and ends at the bottom right with...

      let xPosition = (1 + latProjection / Math.PI) / 2
      let yPosition = (1 - lngProjection / Math.PI) / 2
      
    4. Let's calculate the position of the marker in decimal places, as well as the size of the tile in pixels 256

      Formula: floor (fraction (x × 2 scale) * tile size)

      Since fraction is not available in JS, we will write a function ourselves and use it to get values

      function frac(f) {
        return f % 1;
      }
      

    Now we can calculate the position of the marker.

    let xCanvasCoordinate = Math.floor(frac(xPosition * Math.pow(2, 5)) * (256 * 3))
    let yCanvasCoordinate = Math.floor(frac(yPosition * Math.pow(2, 5)) * (256 * 3))
    

    As a result, we will get coordinates [x,y] on the plane and we can place points using these values. In my task, I get the coordinates of regional boundaries from the map [latitude, longitude] and using this data, I have to build a fragment of the map on my own using canvas/svg

    for (let i = 0; i < f[0].geojson.coordinates[0].length; i++) {
        setTimeout(() => {
            let actualCoord = f[0].geojson.coordinates[0][i] //latitude and longitude
    
            let latCoord = actualCoord[0] //latitude
            let lngCoord = actualCoord[1] //longitude
    
            let latRadian = latCoord * Math.PI / 180
            let lngRadian = lngCoord * Math.PI / 180
    
            let latProjection = latRadian
            let lngProjection = Math.log(Math.tan(lngRadian) + 1 / Math.cos(lngRadian))
    
            let xPosition = (1 + latProjection / Math.PI) / 2
            let yPosition = (1 - lngProjection / Math.PI) / 2
            
            function frac(f) {
                return f % 1;
            }
    
            let xCanvasCoordinate = Math.floor(frac(xPosition * Math.pow(2, 5)) * (256 * 3))
            let yCanvasCoordinate = Math.floor(frac(yPosition * Math.pow(2, 5)) * (256 * 3))
            // Draw dots on your canvas {xCanvasCoordinate} and {yCanvasCoordinate}
        })
    }
    

    I found information on this source; whoever needs it, use it: https://www.netzwolf.info/geo/math/tilebrowser.html?lat=51.157800&lon=6.865500&zoom=14