Search code examples
leafletgeolocationgisgeospatiallatitude-longitude

Dividing long and lat coordinates into sub-coordinates(smaller squares)?


I have 2 long, lat points of a rectangle(bottom left and top right) and I want to divide this rectangle into smaller ones based on a base area (long and lat) I already have. I already know that I can't deal with long and lat as distance measured with meters and kilometres but degrees on an approximation of Earth's surface shape.

The points taken is extracted by leaflet with a 4326 SRID and so are the original points. I need the centre of the "smaller squares" or the long and lat coordinates.

For example, this is my base rectangle 24.639567,46.782406 24.641452,46.785413 and for the rectangle, I want to divide 24.584749,46.612782 24.603323,46.653809.


Solution

  • First, let's turn your two points into a leaflet bounds object:

    const bounds - L.latLngBounds(point1, point2)
    

    Now let's pick a sample interval, meaning how many sub-rectangles across the width and height of your bounds. For example, a sampling size of 10 would give 100 sub-rectangles (10 x 10), though if your sub-rectangles don't need the same aspect-ratio as your main bounds, you could choose two separate sampling intervals (one for x and one for y)

    const samplingInterval = 10 // easy to change
    

    To properly interpolate through your main bounds, we'll grab the corners of it, as well as the width in longitude degrees, and height in latitude degrees, called dLat and dLng (for delta):

    const sw = bounds.getSouthWest();
    const nw = bounds.getNorthWest();
    const ne = bounds.getNorthEast();
    
    const dLat = ne.lat - sw.lat;
    const dLng = ne.lng - nw.lng;
    

    Now we can build an array of new bounds extrapolated from the original:

    let subBounds = [];
    
    for (let i = 0; i < samplingInterval - 1; i++){
      for (let j = 1; j < samplingInterval; j++){
        const corner1 = [
          sw.lat + (dLat * i) / samplingInterval,
          sw.lng + (dLng * j) / samplingInterval
        ];
        const corner2 = [
          sw.lat + (dLat * (i + 1)) / samplingInterval,
          sw.lng + (dLng * (j + 1)) / samplingInterval
        ];
        subBounds.push(L.latLngBounds(corner1, corner2));
      }
    }
    

    Now to get the centers of these bounds, you can call .getCenter() on them:

    const centerPoints = subBounds.map(bounds => bounds.getCenter());
    

    Working codesandbox