2

Google returns the current lat and lon, but the lower left lat and lon and upper right lat and lon are calculated. I have not been able to figure out how it's calculated.

Does anyone know if it's a static distance? a percentage difference? How is it calculated?

Chicago, IL

current lat 41.8781136
current lon -87.6297982 
lower left lat  40.3781136
lower left lon  -89.8743648   
upper right lat 43.3781136
upper right lon -85.3852316

New York

current lat 40.7127753
current lon -74.0059728
lower left lat  39.2127753
lower left lon  -76.26396172
upper right lat 42.2127753
upper right lon -71.74798388

UPDATE:

Knowing it's 103.5 miles from center to the left side and right side,and knowing its 103.5 miles from center to the top and bottom boundry.

Using the current lat and lon point, how do I calculate the lower left and upper right points?

I assume PostGIS has a function for this?

Jim Jones
  • 18,404
  • 3
  • 35
  • 44
user2012677
  • 5,465
  • 6
  • 51
  • 113
  • 1
    It is the rectangular bounds of the city's polygon. – geocodezip Jan 18 '20 at 06:10
  • when I looked at them they seem farther away than is needed for a city boundary. Are you sure? – user2012677 Jan 18 '20 at 06:13
  • They look pretty close to me: http://www.geocodezip.com/geoxml3_test/v3_BoundsVsGeocoder.html (the NYC bounds look a little larger than absolutely required, but seem reasonable to display the city. – geocodezip Jan 19 '20 at 21:07

1 Answers1

7

As the data suggests, the BBOX is calculated based on the lower left and upper right coordinates. You can create a BBOX by replicating the x and y coordinates from the existing to the missing corners, that is from lower left and upper right to upper left and lower right, e.g. the y value of the upper left corner is the same as the one at the upper right corner.

Using PostGIS you can pass this data to the ST_Envelope function and it will generate a BBOX automatically.

Chicago BBOX:

SELECT ST_AsText(ST_MakeEnvelope(-89.8743648,40.3781136,-85.3852316,43.3781136,4326));

                                                           st_astext                                                           
-------------------------------------------------------------------------------------------------------------------------------
 POLYGON((-89.8743648 40.3781136,-89.8743648 43.3781136,-85.3852316 43.3781136,-85.3852316 40.3781136,-89.8743648 40.3781136))
(1 Zeile)

enter image description here

If you reverse engineer this polygon with the function ST_Extent you'll get the same coordinate pairs you provided to generate it:

SELECT ST_Extent('POLYGON((-89.8743648 40.3781136,-89.8743648 43.3781136,-85.3852316 43.3781136,-85.3852316 40.3781136,-89.8743648 40.3781136))')

                     st_extent                      
----------------------------------------------------
 BOX(-89.8743648 40.3781136,-85.3852316 43.3781136)
(1 Zeile)

Creating a BBOX based on a point

An easy approach to crate a BBOX around a point is to draw a buffer with ST_Buffer and use it as a parameter with the ST_Envelope function, e.g. POINT(-87.6297982 41.8781136) - Chicago, IL.

SELECT 
  ST_AsText(
   ST_Envelope(
    ST_Buffer(
     ST_GeomFromText('POINT (-87.6297982 41.8781136)',4326),1)));

 st_astext                                                           
-------------------------------------------------------------------------------------------------------------------------------
 POLYGON((-88.6297982 40.8781136,-88.6297982 42.8781136,-86.6297982 42.8781136,-86.6297982 40.8781136,-88.6297982 40.8781136))
(1 Zeile)

enter image description here

In case you're wondering why the BBOX does not have the same size in all dimensions: Calculations using GEOMETRY and GEOGRAPHY are made differently, and so are their results. GEOGRAPHY calculates the coordinates over an spherical surface (which can be much slower than GEOMETRY) and uses meters as unit of measurement, while GEOGRAPHY uses a planar projection and uses the SRS unit.

Create a 100 miles (160.934 km) BBOX around a point:

SELECT 
  ST_AsText(
  ST_Envelope(
   ST_Rotate(
    ST_Buffer(
     ST_GeomFromText('POINT (-87.6297982 41.8781136)',4326)::GEOGRAPHY,160934)::GEOMETRY,0)));

 st_astext                                                                                        
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 POLYGON((-89.5681600538661 40.4285062983098,-89.5681600538661 43.327349928921,-85.6903925527536 43.327349928921,-85.6903925527536 40.4285062983098,-89.5681600538661 40.4285062983098))
(1 Zeile)

enter image description here

Extracting only the lower left and upper right corners

In case you're only interested in the lower left and upper right corners of your BBOX, just use ST_Extent as described above.

SELECT 
  ST_Extent(
   ST_Envelope(
    ST_Rotate(
     ST_Buffer(
      ST_GeomFromText('POINT (-87.6297982 41.8781136)',4326)::GEOGRAPHY,160934)::GEOMETRY,0)));

 st_extent                                 
---------------------------------------------------------------------------
 BOX(-89.5681600538661 40.4285062983098,-85.6903925527536 43.327349928921)
(1 Zeile)

Further reading:

Jim Jones
  • 18,404
  • 3
  • 35
  • 44
  • How do you calculate the bbox with just the point coordinates of the zip code? – user2012677 Jan 18 '20 at 12:08
  • I also do not think it is boarding just the city, I think it’s a radius, maybe 100 miles? – user2012677 Jan 18 '20 at 12:10
  • How do you specify miles vs meters in your sql code? – user2012677 Jan 18 '20 at 12:36
  • knowing it's 103.5 miles, using the current lat and lon point, how do I calculate the lower left and upper right points? I assume PostGIs has a function for this? – user2012677 Jan 18 '20 at 12:44
  • I answered the km->ml question here: https://stackoverflow.com/a/51889638/2275388 :) – Jim Jones Jan 18 '20 at 13:03
  • the function ST_Envelope already does everything for you, as you already passed the two required corners. Or you mean you just have the center point and want to create the BBOX? This would be a slightly different question ;) – Jim Jones Jan 18 '20 at 13:05
  • Yes, I only have the center point and need to calculate the bbox – user2012677 Jan 18 '20 at 13:06
  • How did you graph the box? I would like to graph 200 lat/lng points with their radius and visualize on a map. – user2012677 Jan 21 '20 at 03:57
  • https://stackoverflow.com/questions/59841660/qgis-postgis-map-pointslat-and-long-with-raduis-on-usa-map – user2012677 Jan 21 '20 at 12:56
  • 1
    @arilwan hey there. you mean how to plot the bbox? In this answer I probably used the pgAdmin geometry viewer. Another way would be to visualise the geometries using `QGIS`: https://stackoverflow.com/a/59841814/2275388 – Jim Jones Jul 09 '20 at 10:46
  • @JimJones this answer describes exactly the task at hand. How do you show the `bbox` on the map? You copied the coordinates and input to Google map or call some PostGIS function to draw it? After filtering some trips within the `bbox`, I would like to show the bounding area in the article as well. – arilwan Jul 09 '20 at 10:47
  • Great, not aware of `pgAdmin`'s geometry viewer. – arilwan Jul 09 '20 at 10:48
  • 1
    @arilwan another option for debugging purposes, in case you don't have pgAdmin 4 installed, is to copy the WKT of your geometry in a WKT Viewer like : http://arthur-e.github.io/Wicket/sandbox-gmaps3.html and here the pgadmin 4 viewer: https://blog.rustprooflabs.com/2018/09/pgadmin4-geometry-viewer – Jim Jones Jul 09 '20 at 10:50
  • 1
    you make my day. I already have pgAdmin 4 installed. – arilwan Jul 09 '20 at 10:51
  • @JimJones this is a question I asked https://stackoverflow.com/questions/62813492/postgresql-show-trips-within-a-bounding-box – arilwan Jul 09 '20 at 11:08
  • @JimJones Thanks for the detailed description. This returns a different result when using `ST_AsGeoJSON`. When I use `ST_Extent` in PostGIS, I get back something like `BOX(-87 41, -86 43)`. But when I wrap that in `ST_AsGeoJson`, I get... five pairs of coordinates (?!?). Same thing happens with your query above. – zup_zup Sep 11 '20 at 06:30
  • @ari A bounding box is just a polygon. PostGIS has a BOX(2d and 3d) data type that sort of makes the polygon of a BBOX more compact. I believe GeoJSON has no such type, therefore it represents BBOXes as polygons - which is basically the same thing. The same will happen with WKT, e.g. `SELECT ST_AsGeoJson(ST_Extent(geom))`, `SELECT ST_AsText(ST_Extent(geom))`. Does it answer your question? – Jim Jones Sep 11 '20 at 10:33
  • @JimJones Ah so GeoJSON adds an extra pair of coordinate to make it a polygon (making it 5 pairs of coordinates)? Is there any way to extract the `BOX(-87 41, -86 43)` result set into JSON such that only the lower left and upper right corner coordinates are returned? – zup_zup Sep 11 '20 at 17:18
  • 1
    @ari to your question: yes, a rectangle needs 5 points:) the first and last ones are identical , so that it is clear where the polygon closes. – Jim Jones Sep 11 '20 at 17:32
  • @JimJones Thank you, that explains it. I did not understand how GeoJSON works exactly. I have a follow up question if you are able to assist: https://stackoverflow.com/questions/63854862/use-bounding-box-from-postgis-in-vanilla-postgres-query – zup_zup Sep 11 '20 at 22:22
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/221357/discussion-between-ari-and-jim-jones). – zup_zup Sep 12 '20 at 00:21