3

I'm trying to use PostgreSQL and PostGIS to return locations within a specific box bound.

Example

  • User has a map view on Google Maps

  • Google API returns box bounds using map.getBounds() - in my specific issue, the bounds from google maps are

    north: "51.52070000000002", 
    south: "51.52070000000002", 
    west: "-0.13450000000000184", 
    east: "-0.13450000000000184"
    

    and I'm using ST_MakeEnvelope() like so:

    ST_MakeEnvelope(-0.13450000000000184, 51.52070000000002, 
                    -0.13450000000000184, 51.52070000000002, 
                    4326)
    
  • I have a locations table in my db with columns longitude, latitude and geom where geom is indexed with GIST and created by ST_SetSRID(ST_MakePoint(longitude::numeric,latitude::numeric), 4326);

  • The SQL query just to sense check is

    select geom && ST_MakeEnvelope(-0.13450000000000184, 51.52070000000002, 
                                   -0.13450000000000184, 51.52070000000002, 
                                   4326)
    

    where geom is SRID=4326;POINT(-0.1309 51.5162) and which should return true but returns false instead

  • I also had this query

    SELECT   id,     
             ST_Y(ST_MakePoint(longitude, latitude)) AS y,
             ST_X(ST_MakePoint(longitude, latitude)) AS x 
    FROM     map_locations ml
    WHERE    ST_SetSRID(ST_MakeBox2D(ST_Point(latitude, longitude), 
                                     ST_Point(longitude, latitude) ),          
                        4326)  
          && ST_MakeEnvelope(-0.13450000000000184, 51.52070000000002, 
                             -0.13450000000000184, 51.52070000000002, 
                             4326) 
    

    but these created box bounds in the incorrect places.

  • I also tried ST_WITHIN() and ST_CONTAINS() with the same result

What am I doing wrong?

3
  • 5
    If you look at the coordinates of what you get with getBounds you'll notice that they do not make a box but a point.
    – user30184
    Commented Mar 24 at 22:00
  • -0.33 does not fall between -0.13 and -0.13
    – Ian Turton
    Commented Mar 25 at 9:40
  • I also had this query SELECT id, ST_Y(ST_MakePoint(longitude, latitude)) AS y, ST_X(ST_MakePoint(longitude, latitude)) AS x FROM map_locations ml WHERE ST_SetSRID( ST_MakeBox2D( ST_Point(latitude, longitude), ST_Point(longitude, latitude) ), 4326 ) && ST_MakeEnvelope(-0.13450000000000184, 51.52070000000002, -0.13450000000000184, 51.52070000000002, 4326) but these created box bounds in the incorrect places. I also tried ST_WITHIN and ST_CONTAINS with the same result Commented Mar 25 at 10:20

1 Answer 1

3

I formatted the question body to make this a bit more visible: the coordinates you said you got from map.getBounds() make up a box with zero area - it's effectively a point, as immediately pointed out by @user30184.

For that to match with &&, the geom in your map_locations would have to happen to be that exact same point, a line (more or less) running through it, a polygon that covers that spot or a collection that includes one of those.


That ST_MakeBox2D() could cover 12.5%-25% of the surface of the globe in some cases:

ST_MakeBox2D(ST_Point(latitude, longitude), 
             ST_Point(longitude, latitude) )

ST_Point() accepts lon/lat:

geometry ST_Point(float x, float y);

For geodetic coordinates, X is longitude and Y is latitude

So on the North Pole:

with cte as (select st_setsrid(ST_MakeBox2D(ST_Point(90,0),
                                            ST_Point(0,90)),
                               4326) AS geom )
select st_astext(geom),
       st_area(st_transform(geom,3857)) as area_in_3857,
       st_area(geom::geography(Polygon,4326)) as area_as_geography
from cte;
st_astext area_in_3857 area_as_geography
POLYGON((0 0,0 90,90 90,90 0,0 0)) 2.429835233887958e+15 63758202715511.07

It still won't necessarily && with your geom, and if it does, I'm not sure that's really what you wanted to find.

5
  • Thanks for answering! and your point about the getBounds() makes sense. With this then, how would i go about finding those matching locations within the coordinates that i get back from the getBounds function? Commented Mar 26 at 19:39
  • @KennSeangpachareonsub My guess would be that you accidentally called .getNorthEast() twice (or .getSouthWest() twice) on the LatLngBounds you got from getBounds(), which is why you get the same lat/lon - could be something else, but you're not showing that part of your solution. If you fix how you get the bounds so that you don't re-use one corner, you'll get different points, which will let you construct a non-zero-area box/envelope. Then a && or st_intersects() will be able to find whatever you got in that area.
    – Zegarek
    Commented Mar 26 at 20:08
  • If for some reason you can't fix .getBounds() getting you the same corner twice, you'll have to figure out whether that's the NE or SW and I guess you could reconstruct the bounds by generating the other corner by shifting the one you have by .getZoom(). Problem is, things like this or ST_Expand()ing around the one point you have might result in not quite the same bounds, hence not quite the same shapes getting caught by the subsequent &&. Plus, that's patching a bug you probably could remove at the source, by figuring out why you're getting just one corner from .getBounds().
    – Zegarek
    Commented Mar 26 at 20:15
  • If you make sure you're not re-using a corner, then maybe .setZoom() was too high, or you're making the bounds dependent on a set of points containing just a single point, like here. I'm not sure max zoom would result in zero-area bounds, though.
    – Zegarek
    Commented Mar 26 at 20:30
  • thanks for all this, actually ended up figuring it out a minute a go. For some reason getBounds returns the same corner for the west and east coordinates. Doing getBounds().getSouthWest() and .getNorthEast() ended up doing the job and returned different values for all 4 corners Commented Mar 26 at 20:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.