I am building a location-based service in Go and using spatial data (latitude and longitude) to group units. I need to group these units dynamically based on the user’s zoom level and geographical proximity.
Here is the problem I’m facing:
I have a database of units that contain spatial data (latitude, longitude, and geometry points).
I want to group the units based on proximity to a given latitude and longitude.
The grouping should be dynamic, such that:
When the user is zoomed out (low zoom), the units should be grouped at a broader level (like by country or region).
When the user is zoomed in (high zoom), the units should be grouped at a more granular level (like by city or neighborhood).
The data should be fetched dynamically based on the zoom level, so that when the user zooms in or out, new data is fetched and grouped accordingly.
Example:
If the user zooms out (zoom level 5 or less), the system should group units at the country or regional level.
If the user zooms in (zoom level 10 or higher), the units should be grouped by city or neighborhood.
I’m using Go with the gorm ORM, and the spatial data is stored using PostGIS in a PostgreSQL database.
What I’ve tried:
I attempted to use ST_DWithin for spatial queries in PostgreSQL to fetch units within a certain distance from the specified lat/lng.
I also implemented a grouping function that adjusts the radius based on the zoom level.
However, I’m unsure how to dynamically group the units at different levels (country, region, city, etc.) based on the zoom level and ensure that it fetches the correct data as the user zooms in or out.
My question:
How can I implement dynamic spatial grouping based on zoom level in Go with PostgreSQL and PostGIS? What’s the best approach for dynamically adjusting the groupings (country, region, city) based on the zoom level and proximity?
How can i develop a api that works like this
https://www.adquick.com/billboard-locations
I want a feature like in the above website
2
Answers
To handle dynamic spatial grouping based on zoom levels, you’ll want to leverage PostGIS’s clustering capabilities. I’ve implemented something similar before, and here’s what worked well:
The main trick is using ST_ClusterDBSCAN with different radiuses based on zoom. Create a simple mapping first – something like country-level grouping for zooms 1-5, regional for 6-9, city for 10-12, and neighborhood for 13+. Each level gets its own grouping radius.
Your query can then use ST_DWithin to grab points in the viewport, and ST_ClusterDBSCAN to group them. The clustering function is particularly nice because it handles density-based clustering automatically – much better than trying to reinvent that wheel in Go.
A basic query structure would be:
The radius parameter should vary with zoom level. At country level you might use 500km, dropping down to maybe 10km for neighborhood level.
Performance-wise, make sure you’ve got spatial indexes set up properly. They make a huge difference once your dataset grows. A simple GiST index on your geometry column will do wonders.
In your Go code, just wrap this in a function that takes lat/lng/zoom/viewport as parameters. Let PostGIS handle the spatial stuff – it’s way more efficient than trying to do distance calculations in Go.
Hope this helps! Let me know if you need any clarification on the approach.
If you already have a hierarchy with the respective boundaries geometries just group based on elements that ST_Within or ST_Contains according to the zoom. level.