0

TL;DR:

Decompose the intersection of 2 intersecting rectangles in 3 rectangles, 1 of which is the intersected area.


Hi all!

I'm currently developing some stuff that needs to visualize some data on a map. What is happening now is that every time the users moves on the map i'm making a request to an api telling:

give me all the data contained in this rectangular area (Ex ABCD) where each point is a Lat-Lng pair.

This kind of request is made every time the user moves on the map and the new visualized area is not contained in the last visualized (Ex the user has made a zoom in)

Unfortunately this kind of request is kinda heavy and i would like to make some optimization on this.

Usually when the user moves on a map what is happening (Img A) is that the new area he want to visualize (Ex abcd rectangle) intersect the old visualized area (ABCD) for which i have already loaded the data

So instead of requesting the whole new abcd rectangle it would be cool and less heavy to ask the api all the data contained in both AZcX + aXYb (Fig B)

I'm struggling finding an algorithm to calculate given the 2 intersected rectangle (ABCD and abcd) this 2 rectangles.

Any help will be appreciated, thanks


User see and fecth data for this area

      A+------------+B
       |            |
       |            |
       |            |
      D+------------+C

Img A ( the user has moved to the new abcd area)
a+-----------+c
 |           |      B
 |    A+-----|------+
 |     |     |      |
b+-----|-----+d     |
       |            |
      D+------------+C



Img B
a+-----X-----+c
 |     |     |      B
 |    A+-----Z------+
 |     |     |      |
b+----Y|-----+d     |
       |            |
      D+------------+C
FrancescoM
  • 1,400
  • 11
  • 16

1 Answers1

0

I have solved this problem quite a few time ago. I'm currently using leaflet to display my map and so, in the algorithm solution i'm referring to some leaflet classes.

Here is the javascript codes that taken 2 areas rapresented to leaflet L.LatLngBounds objects return an array of L.LatLngBounds that are the complementary areas, the areas that has to load.

Following the js algorithm :

function getComplementaryBounds(oldBounds, newBounds){
  if (!((oldBounds instanceof L.LatLngBounds) && (newBounds instanceof L.LatLngBounds))){
    return [];
  }

  var buildLatLngBound = function (nwlng, nwlat, selng, selat){
    return new L.LatLngBounds(new L.LatLng(nwlat,nwlng),new L.LatLng(selat,selng));
  }

   var nwiix = newBounds.getNorthWest().lng;
   var nwiiy = newBounds.getNorthWest().lat;
   var nwix =  oldBounds.getNorthWest().lng;
   var nwiy =  oldBounds.getNorthWest().lat;

   var seiix = newBounds.getSouthEast().lng;
   var seiiy = newBounds.getSouthEast().lat;
   var seix =  oldBounds.getSouthEast().lng;
   var seiy =  oldBounds.getSouthEast().lat;

  if (!(newBounds.contains(oldBounds))){
    switch (true) {
     case (nwiix >= nwix && nwiiy >= nwiy):
       return [buildLatLngBound(nwiix, nwiiy, seix, nwiy), buildLatLngBound(seix, nwiiy, seiix, seiiy)];
     case (nwiix <= nwix && nwiiy >= nwiy):
       return [buildLatLngBound(nwix, nwiiy, seiix, nwiy), buildLatLngBound(nwiix, nwiiy, nwix, seiiy)];
     case (nwiix <= nwix && nwiiy <= nwiy):
       return [buildLatLngBound(nwiix, nwiiy, nwix, seiiy), buildLatLngBound(nwix, seiy, seiix, seiiy)];
     case (nwiix >= nwix && nwiiy <= nwiy):
        return [buildLatLngBound(nwiix, seiy, seix, seiiy), buildLatLngBound(seix, nwiiy, seiix, seiiy)];
      }
    } else {
      return[
            buildLatLngBound(nwiix, nwiiy,    seiix,  nwiy),
            buildLatLngBound(nwiix, nwiy,     nwix,   seiy),
            buildLatLngBound(seix,  nwiy,     seiix,  seiy),
            buildLatLngBound(nwiix, seiy,     seiix,  seiiy)
            ];
    }
    return [];
  }
FrancescoM
  • 1,400
  • 11
  • 16