Data Crew is a consultancy that was started last year in Argentina. They've recently released a 1,419-line, Python-based Route Optimiser Framework.
It supports both the Chinese Postman (CPP) and Travelling Salesman (TSP) problems. The framework is meant to be easy to expand and there are plans to add support for Vehicle Routing (VRP), Capacitated VRP (CVRP) and VRP with Time Windows (VRPTW) at a later date.
In this post, I'll examine two example solvers from Data Crew's Route Optimiser Framework.
My Workstation
I'm using a 5.7 GHz AMD Ryzen 9 9950X CPU. It has 16 cores and 32 threads and 1.2 MB of L1, 16 MB of L2 and 64 MB of L3 cache. It has a liquid cooler attached and is housed in a spacious, full-sized Cooler Master HAF 700 computer case.
The system has 96 GB of DDR5 RAM clocked at 4,800 MT/s and a 5th-generation, Crucial T700 4 TB NVMe M.2 SSD which can read at speeds up to 12,400 MB/s. There is a heatsink on the SSD to help keep its temperature down. This is my system's C drive.
The system is powered by a 1,200-watt, fully modular Corsair Power Supply and is sat on an ASRock X870E Nova 90 Motherboard.
I'm running Ubuntu 24 LTS via Microsoft's Ubuntu for Windows on Windows 11 Pro. In case you're wondering why I don't run a Linux-based desktop as my primary work environment, I'm still using an Nvidia GTX 1080 GPU which has better driver support on Windows and ArcGIS Pro only supports Windows natively.
Installing Prerequisites
I'll use Python 3.12.3 and jq to help analyse the data in this post.
$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt update
$ sudo apt install \
jq \
python3-pip \
python3.12-venv
Below, I'll set up a Python Virtual Environment and install some dependencies.
$ python3 -m venv ~/.route-optimizer
$ source ~/.route-optimizer/bin/activate
$ python3 -m pip install \
contextily \
folium \
geopandas \
matplotlib \
networkx \
openpyxl \
osmnx \
pandas \
scikit-learn \
shapely
I'll clone the repo that contains the framework as well as some example scenarios that I'll walk through below.
$ git clone https://github.com/Data-Crew/route-optimizer \
~/route-optimizer
I'll use DuckDB v1.4.3, along with its H3, JSON, Lindel, Parquet and Spatial extensions, in this post.
$ cd ~
$ wget -c https://github.com/duckdb/duckdb/releases/download/v1.4.3/duckdb_cli-linux-amd64.zip
$ unzip -j duckdb_cli-linux-amd64.zip
$ chmod +x duckdb
$ ~/duckdb
INSTALL h3 FROM community;
INSTALL lindel FROM community;
INSTALL json;
INSTALL parquet;
INSTALL spatial;
I'll set up DuckDB to load every installed extension each time it launches.
$ vi ~/.duckdbrc
.timer on
.width 180
LOAD h3;
LOAD lindel;
LOAD json;
LOAD parquet;
LOAD spatial;
Parking Enforcement
The first example is a parking enforcement solver. An inspector needs the shortest path along a circuit that visits every edge at least once.
Below is the configuration file that this solver will call upon. It isolates a bounding box around La Plata, Argentina, a planned city with diagonal avenues, which is to the southeast of Buenos Aires.
This bounding box will be used to isolate the OpenStreetMap (OSM) road network for this area via the OSMnx library.
There are also three zones defined within this area, each with its own unique parking restrictions.
$ cd ~/route-optimizer
$ cat zone_config.json
{
"configuration": {
"city": "La Plata, Argentina",
"bbox": {
"description": "Bounding box (west, south, east, north)",
"west": -57.9605,
"south": -34.9210,
"east": -57.9455,
"north": -34.9095
},
"start_point": {
"description": "Start and return point (lat, lon)",
"name": "Corner of 12th and 50th",
"latitude": -34.91719,
"longitude": -57.95067
}
},
"zones": [
{
"name": "courthouse",
"description": "Courthouse Zone",
"polygon": [
[-57.957, -34.915],
[-57.949, -34.915],
[-57.949, -34.911],
[-57.957, -34.911]
],
"schedule": {
"start": "08:00",
"end": "14:00"
},
"weekdays": [0, 1, 2, 3, 4],
"weekday_names": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
"prohibited_streets": [],
"color": "pink"
},
{
"name": "downtown",
"description": "Downtown Zone",
"polygon": [
[-57.955, -34.9145],
[-57.9475, -34.9145],
[-57.9475, -34.9185],
[-57.955, -34.9185]
],
"schedule": {
"start": "08:00",
"end": "20:00"
},
"weekdays": [0, 1, 2, 3, 4, 5],
"weekday_names": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
"prohibited_streets": [],
"color": "gold"
},
{
"name": "12th_street",
"description": "12th Street Zone",
"polygon": [
[-57.955, -34.9125],
[-57.952, -34.9125],
[-57.952, -34.9195],
[-57.955, -34.9195]
],
"schedule": {
"start": "08:00",
"end": "20:00"
},
"weekdays": [0, 1, 2, 3, 4, 5],
"weekday_names": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
"prohibited_streets": [],
"color": "violet"
}
],
"route_types": {
"full": {
"name": "Full Route",
"description": "All zones (Monday to Friday 8am-8pm)",
"zones": ["courthouse", "downtown", "12th_street"]
},
"no_courthouse": {
"name": "No Courthouse",
"description": "For enforcement officers working after 2pm",
"zones": ["downtown", "12th_street"]
},
"saturday": {
"name": "Saturday",
"description": "Weekend route",
"zones": ["downtown", "12th_street"]
}
}
}
Below, I'll run the solver. This first deliverable is a map of the zone within the bounding box.
$ python3 parking_enforcement.py
======================================================================
ROUTE OPTIMIZER - PARKING ENFORCEMENT (CPP)
======================================================================
π₯ Downloading street network...
β
Network downloaded: 208 nodes, 369 edges
π Start node: 249417335
π·οΈ Labeling zones...
β’ courthouse: 39 nodes
β’ downtown: 34 nodes
β’ 12th_street: 27 nodes
π Zone summary:
zone
outside 135
courthouse 29
12th_street 27
downtown 17
Name: count, dtype: int64
πΊοΈ Generating visualization...
πΎ Map saved to: output/cpp_zones.png
Then, the full route is calculated and results in a solution that is 11.06 KM long.
======================================================================
CALCULATING OPTIMAL ROUTES
======================================================================
π CASE 1: Full Route
============================================================
π SOLVING ROUTE: FULL (CPP)
============================================================
π Route type 'full':
β’ Zones: courthouse, downtown, 12th_street
β’ Nodes: 73
β’ Edges: 123
π Solving Chinese Postman Problem (CPP)...
β οΈ Graph not strongly connected. Extracting main component...
π Eulerizing graph...
β’ 13 unbalanced nodes
β
Eulerized: 139 edges
π Finding Eulerian circuit...
β οΈ Could not create perfect Eulerian circuit
π Using approximation...
π Expanded 11 path segments with intermediate nodes
β
Route found: 119 nodes, 11.09 km
β
Route calculated (CPP):
β’ Nodes visited: 119
β’ Total distance: 11.09 km
The next calculation handles the "no courthouse" custom restrictions and produces a solution with a distance of 5.39 KM.
π CASE 2: No Courthouse (after 2pm)
============================================================
π SOLVING ROUTE: NO_COURTHOUSE (CPP)
============================================================
π Route type 'no_courthouse':
β’ Zones: downtown, 12th_street
β’ Nodes: 44
β’ Edges: 69
π Solving Chinese Postman Problem (CPP)...
β οΈ Graph not strongly connected. Extracting main component...
π Eulerizing graph...
β’ 10 unbalanced nodes
β
Eulerized: 79 edges
π Finding Eulerian circuit...
β οΈ Could not create perfect Eulerian circuit
π Using approximation...
π Expanded 4 path segments with intermediate nodes
β
Route found: 59 nodes, 5.39 km
β
Route calculated (CPP):
β’ Nodes visited: 59
β’ Total distance: 5.39 km
The next calculation handles the Saturday route and produces a solution with a distance of 5.39 KM.
π CASE 3: Saturday Route
============================================================
π SOLVING ROUTE: SATURDAY (CPP)
============================================================
π Route type 'saturday':
β’ Zones: downtown, 12th_street
β’ Nodes: 44
β’ Edges: 69
π Solving Chinese Postman Problem (CPP)...
β οΈ Graph not strongly connected. Extracting main component...
π Eulerizing graph...
β’ 10 unbalanced nodes
β
Eulerized: 79 edges
π Finding Eulerian circuit...
β οΈ Could not create perfect Eulerian circuit
π Using approximation...
π Expanded 4 path segments with intermediate nodes
β
Route found: 59 nodes, 5.39 km
β
Route calculated (CPP):
β’ Nodes visited: 59
β’ Total distance: 5.39 km
The results of the three above cases are then saved to an Excel file.
π Exporting results...
β
Results exported to: output/cpp_routes.xlsx
π Summary:
Route_Type Node_Count Distance_KM Distance_Meters
full 119 11.09 11093
no_courthouse 59 5.39 5392
saturday 59 5.39 5392
Below is the summary sheet from that file.
$ echo "FROM ST_READ('output/cpp_routes.xlsx')" \
| ~/duckdb -json \
| jq -S .
[
{
"Distance_KM": 11.09,
"Distance_Meters": 11093,
"Node_Count": 119,
"Route_Type": "full"
},
{
"Distance_KM": 5.39,
"Distance_Meters": 5392,
"Node_Count": 59,
"Route_Type": "no_courthouse"
},
{
"Distance_KM": 5.39,
"Distance_Meters": 5392,
"Node_Count": 59,
"Route_Type": "saturday"
}
]
Each case has its own sheet with its sequence list. Below is the sheet for the Saturday route.
$ ~/duckdb
.maxrows 60
SELECT sequence: Sequence::INT,
node_id: Node_ID::BIGINT,
geom: ST_POINT(Longitude, Latitude),
zone: Zone
FROM READ_XLSX('output/cpp_routes.xlsx',
sheet='saturday');
ββββββββββββ¬βββββββββββββ¬ββββββββββββββββββββββββββββββββββ¬ββββββββββββββ
β sequence β node_id β geom β zone β
β int32 β int64 β geometry β varchar β
ββββββββββββΌβββββββββββββΌββββββββββββββββββββββββββββββββββΌββββββββββββββ€
β 1 β 249417335 β POINT (-57.9510606 -34.91725) β downtown β
β 2 β 249417330 β POINT (-57.9517689 -34.9167244) β downtown β
β 3 β 249417040 β POINT (-57.9527766 -34.9176466) β 12th_street β
β 4 β 249416478 β POINT (-57.9538079 -34.9185892) β 12th_street β
β 5 β 6127585995 β POINT (-57.9546872 -34.9193893) β 12th_street β
β 6 β 6127586000 β POINT (-57.9547393 -34.918265) β 12th_street β
β 7 β 249416467 β POINT (-57.9545168 -34.9180625) β 12th_street β
β 8 β 249416459 β POINT (-57.9547554 -34.9178853) β 12th_street β
β 9 β 249418061 β POINT (-57.954798 -34.9169539) β 12th_street β
β 10 β 249417004 β POINT (-57.9548565 -34.9161046) β 12th_street β
β 11 β 249418057 β POINT (-57.9548928 -34.9155776) β 12th_street β
β 12 β 249417305 β POINT (-57.9541766 -34.9149376) β 12th_street β
β 13 β 249417664 β POINT (-57.9531609 -34.9140082) β 12th_street β
β 14 β 249417665 β POINT (-57.9522478 -34.9146926) β 12th_street β
β 15 β 249417312 β POINT (-57.9532914 -34.9155946) β 12th_street β
β 16 β 249417026 β POINT (-57.9543003 -34.9165164) β 12th_street β
β 17 β 249417033 β POINT (-57.9534809 -34.9171231) β 12th_street β
β 18 β 249417320 β POINT (-57.9524713 -34.9162031) β 12th_street β
β 19 β 249417672 β POINT (-57.9514609 -34.9152824) β downtown β
β 20 β 249417675 β POINT (-57.9507639 -34.9158047) β downtown β
β 21 β 249417679 β POINT (-57.9500587 -34.9163333) β downtown β
β 22 β 1868768411 β POINT (-57.948899 -34.9171887) β downtown β
β 23 β 249417681 β POINT (-57.9488464 -34.9172257) β downtown β
β 24 β 2761285280 β POINT (-57.9478281 -34.9163417) β downtown β
β 25 β 1868768407 β POINT (-57.9477386 -34.9162624) β downtown β
β 26 β 2714068787 β POINT (-57.9478392 -34.9161947) β downtown β
β 27 β 2761285279 β POINT (-57.9479159 -34.9162708) β downtown β
β 28 β 2761285280 β POINT (-57.9478281 -34.9163417) β downtown β
β 29 β 1868768407 β POINT (-57.9477386 -34.9162624) β downtown β
β 30 β 2714068787 β POINT (-57.9478392 -34.9161947) β downtown β
β 31 β 249417867 β POINT (-57.9496921 -34.9147895) β downtown β
β 32 β 2761285275 β POINT (-57.949781 -34.9148569) β downtown β
β 33 β 2761285277 β POINT (-57.9490549 -34.9154107) β downtown β
β 34 β 2761285279 β POINT (-57.9479159 -34.9162708) β downtown β
β 35 β 1868768411 β POINT (-57.948899 -34.9171887) β downtown β
β 36 β 1868768422 β POINT (-57.9499061 -34.9181067) β downtown β
β 37 β 249417335 β POINT (-57.9510606 -34.91725) β downtown β
β 38 β 249417330 β POINT (-57.9517689 -34.9167244) β downtown β
β 39 β 249417320 β POINT (-57.9524713 -34.9162031) β 12th_street β
β 40 β 249417312 β POINT (-57.9532914 -34.9155946) β 12th_street β
β 41 β 249417026 β POINT (-57.9543003 -34.9165164) β 12th_street β
β 42 β 249418061 β POINT (-57.954798 -34.9169539) β 12th_street β
β 43 β 6127586001 β POINT (-57.954951 -34.9170952) β 12th_street β
β 44 β 6127585996 β POINT (-57.9549152 -34.9177665) β 12th_street β
β 45 β 2760842529 β POINT (-57.9548801 -34.9183932) β 12th_street β
β 46 β 6127586000 β POINT (-57.9547393 -34.918265) β 12th_street β
β 47 β 249416467 β POINT (-57.9545168 -34.9180625) β 12th_street β
β 48 β 249417033 β POINT (-57.9534809 -34.9171231) β 12th_street β
β 49 β 249417040 β POINT (-57.9527766 -34.9176466) β 12th_street β
β 50 β 249417046 β POINT (-57.9520687 -34.9181727) β 12th_street β
β 51 β 249416487 β POINT (-57.9530977 -34.9191169) β 12th_street β
β 52 β 249416478 β POINT (-57.9538079 -34.9185892) β 12th_street β
β 53 β 249416467 β POINT (-57.9545168 -34.9180625) β 12th_street β
β 54 β 249417033 β POINT (-57.9534809 -34.9171231) β 12th_street β
β 55 β 249417320 β POINT (-57.9524713 -34.9162031) β 12th_street β
β 56 β 249417672 β POINT (-57.9514609 -34.9152824) β downtown β
β 57 β 249417675 β POINT (-57.9507639 -34.9158047) β downtown β
β 58 β 249417679 β POINT (-57.9500587 -34.9163333) β downtown β
β 59 β 249417335 β POINT (-57.9510606 -34.91725) β downtown β
ββββββββββββ΄βββββββββββββ΄ββββββββββββββββββββββββββββββββββ΄ββββββββββββββ€
β 59 rows 4 columns β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Images of each case, along with interactive maps, are then generated.
======================================================================
GENERATING ROUTE VISUALIZATIONS
======================================================================
π Route type 'full':
β’ Zones: courthouse, downtown, 12th_street
β’ Nodes: 73
β’ Edges: 123
π Route type 'no_courthouse':
β’ Zones: downtown, 12th_street
β’ Nodes: 44
β’ Edges: 69
π Route type 'saturday':
β’ Zones: downtown, 12th_street
β’ Nodes: 44
β’ Edges: 69
πΈ Generating static images...
πΊοΈ Visualizing route: CPP: Full Route (All Zones)
πΎ Route saved to: output/cpp_route_full.png
πΊοΈ Visualizing route: CPP: No Courthouse Route (After 2pm)
πΎ Route saved to: output/cpp_route_no_courthouse.png
πΊοΈ Visualizing route: CPP: Saturday Route
πΎ Route saved to: output/cpp_route_saturday.png
π Generating interactive maps (open in browser)...
πΊοΈ Generating interactive map: CPP: Full Route (All Zones)
πΎ Interactive map saved to: output/cpp_route_full.html
Open in browser and use the playback controls!
πΊοΈ Generating interactive map: CPP: No Courthouse Route (After 2pm)
πΎ Interactive map saved to: output/cpp_route_no_courthouse.html
Open in browser and use the playback controls!
πΊοΈ Generating interactive map: CPP: Saturday Route
πΎ Interactive map saved to: output/cpp_route_saturday.html
Open in browser and use the playback controls!
======================================================================
FINAL SUMMARY - CPP (Chinese Postman Problem)
======================================================================
β
Full Route: 11.09 km (119 nodes)
β
No Courthouse: 5.39 km (59 nodes)
β
Saturday: 5.39 km (59 nodes)
π Output files (all prefixed with 'cpp_'):
πΈ Static images (with street basemap):
β’ cpp_zones.png - Map of enforcement zones
β’ cpp_route_full.png - Full route
β’ cpp_route_no_courthouse.png - Afternoon route
β’ cpp_route_saturday.png - Weekend route
π Interactive maps (RECOMMENDED - open in browser):
β’ cpp_route_full.html - Full route with playback
β’ cpp_route_no_courthouse.html - Afternoon route
β’ cpp_route_saturday.html - Weekend route
π Data:
β’ cpp_routes.xlsx - Route coordinates
π‘ TIP: Open the .html files for interactive step-by-step playback!
======================================================================
Below is a capture of the interactive map of the full route. It has been sped up 9x.
Below is the static image generated of the route with no courthouse.
Below is the static image generated of the Saturday route.
Delivery Routing
Below is the second example solver. It finds the shortest possible distance a delivery driver would need to travel in order to deliver ten packages.
$ python3 delivery_route.py
======================================================================
ROUTE OPTIMIZER - DELIVERY ROUTE (TSP)
======================================================================
π¦ Scenario: A delivery driver has 10 packages to deliver.
Goal: Find the shortest route visiting all addresses.
π₯ Downloading street network...
β
Network downloaded: 208 nodes, 369 edges
π Start node: 249417335
π·οΈ Labeling zones...
β’ delivery_area: 79 nodes
π Zone summary:
zone
outside 129
delivery_area 79
Name: count, dtype: int64
π Delivery addresses (10 packages):
π¦ Package 1: Node 249417664 (-34.91401, -57.95316)
π¦ Package 2: Node 249417672 (-34.91528, -57.95146)
π¦ Package 3: Node 249417679 (-34.91633, -57.95006)
π¦ Package 4: Node 249417046 (-34.91817, -57.95207)
π¦ Package 5: Node 4771931492 (-34.91434, -57.95498)
π¦ Package 6: Node 249416993 (-34.91586, -57.95518)
π¦ Package 7: Node 249417033 (-34.91712, -57.95348)
π¦ Package 8: Node 249417862 (-34.91428, -57.95036)
π¦ Package 9: Node 249417312 (-34.91559, -57.95329)
π¦ Package 10: Node 249417335 (-34.91725, -57.95106)
βΉοΈ 10 addresses β 10 unique stops
======================================================================
CALCULATING OPTIMAL ROUTE (TSP)
======================================================================
============================================================
π SOLVING ROUTE: FULL (TSP)
============================================================
π Route type 'full':
β’ Zones: delivery_area
β’ Nodes: 79
β’ Edges: 135
π Solving Traveling Salesman Problem (TSP)...
π Nodes to visit: 10
β οΈ Graph not strongly connected. Extracting main component...
π Computing distance matrix...
π Finding optimal tour...
π Expanded 8 path segments with intermediate nodes
β
Route found: 10 stops, 37 total nodes, 3.60 km
β
Route calculated (TSP):
β’ Nodes visited: 37
β’ Total distance: 3.60 km
π Route summary:
β’ Packages: 10
β’ Unique stops: 10
β’ Route nodes: 37 (including path between stops)
β’ Total distance: 3.60 km
An Excel file of the results, along with images and an interactive map are then generated from the above solution.
======================================================================
GENERATING VISUALIZATIONS
======================================================================
πΊοΈ Generating visualization...
πΎ Map saved to: output/tsp_zone.png
π Route type 'full':
β’ Zones: delivery_area
β’ Nodes: 79
β’ Edges: 135
πΊοΈ Visualizing route: TSP: Delivery Route (10 packages)
πΎ Route saved to: output/tsp_route.png
πΊοΈ Generating interactive map: TSP: Delivery Route
πΎ Interactive map saved to: output/tsp_route.html
Open in browser and use the playback controls!
π Exporting results...
β
Results exported to: output/tsp_routes.xlsx
π Summary:
Route_Type Node_Count Distance_KM Distance_Meters
delivery_route 37 3.6 3598
======================================================================
FINAL SUMMARY - TSP (Traveling Salesman Problem)
======================================================================
β
Delivery route optimized!
β’ Packages: 10
β’ Distance: 3.60 km
β’ Estimated time: ~7 min (at 30 km/h avg)
π Output files (all prefixed with 'tsp_'):
πΈ Static images:
β’ tsp_zone.png - Delivery area map
β’ tsp_route.png - Optimized route with basemap
π Interactive map:
β’ tsp_route.html - Route with step-by-step playback
π Data:
β’ tsp_routes.xlsx - Route coordinates
======================================================================
Below is a capture of the interactive map. It has been sped up 9x.
Below is the route summary sheet.
$ echo "FROM ST_READ('output/tsp_routes.xlsx')" \
| ~/duckdb -json \
| jq -S .
[
{
"Distance_KM": 3.6,
"Distance_Meters": 3598,
"Node_Count": 37,
"Route_Type": "delivery_route"
}
]
Below is the sequence list.
SELECT sequence: Sequence::INT,
node_id: Node_ID::BIGINT,
geom: ST_POINT(Longitude, Latitude),
zone: Zone
FROM READ_XLSX('output/tsp_routes.xlsx',
sheet='delivery_route');
ββββββββββββ¬βββββββββββββ¬ββββββββββββββββββββββββββββββββββ¬ββββββββββββββββ
β sequence β node_id β geom β zone β
β int32 β int64 β geometry β varchar β
ββββββββββββΌβββββββββββββΌββββββββββββββββββββββββββββββββββΌββββββββββββββββ€
β 1 β 249417335 β POINT (-57.9510606 -34.91725) β delivery_area β
β 2 β 249417330 β POINT (-57.9517689 -34.9167244) β delivery_area β
β 3 β 249417320 β POINT (-57.9524713 -34.9162031) β delivery_area β
β 4 β 249417672 β POINT (-57.9514609 -34.9152824) β delivery_area β
β 5 β 2761285274 β POINT (-57.9504434 -34.9143554) β delivery_area β
β 6 β 249417862 β POINT (-57.950361 -34.9142803) β delivery_area β
β 7 β 249417857 β POINT (-57.9511569 -34.913688) β delivery_area β
β 8 β 249417851 β POINT (-57.9520626 -34.9130139) β delivery_area β
β 9 β 249417849 β POINT (-57.9529888 -34.9123245) β delivery_area β
β 10 β 2761285268 β POINT (-57.9530811 -34.9123952) β delivery_area β
β 11 β 249417663 β POINT (-57.9540895 -34.9133121) β delivery_area β
β 12 β 249417664 β POINT (-57.9531609 -34.9140082) β delivery_area β
β 13 β 249417665 β POINT (-57.9522478 -34.9146926) β delivery_area β
β 14 β 249417312 β POINT (-57.9532914 -34.9155946) β delivery_area β
β 15 β 249417026 β POINT (-57.9543003 -34.9165164) β delivery_area β
β 16 β 249417033 β POINT (-57.9534809 -34.9171231) β delivery_area β
β 17 β 249417320 β POINT (-57.9524713 -34.9162031) β delivery_area β
β 18 β 249417312 β POINT (-57.9532914 -34.9155946) β delivery_area β
β 19 β 249417305 β POINT (-57.9541766 -34.9149376) β delivery_area β
β 20 β 4771931492 β POINT (-57.9549762 -34.9143443) β delivery_area β
β 21 β 6040327689 β POINT (-57.9551144 -34.9142417) β delivery_area β
β 22 β 2760842520 β POINT (-57.9550254 -34.9157142) β delivery_area β
β 23 β 2760842522 β POINT (-57.9550061 -34.9159896) β delivery_area β
β 24 β 249417004 β POINT (-57.9548565 -34.9161046) β delivery_area β
β 25 β 249417026 β POINT (-57.9543003 -34.9165164) β delivery_area β
β 26 β 249417033 β POINT (-57.9534809 -34.9171231) β delivery_area β
β 27 β 249417040 β POINT (-57.9527766 -34.9176466) β delivery_area β
β 28 β 249417046 β POINT (-57.9520687 -34.9181727) β delivery_area β
β 29 β 249416487 β POINT (-57.9530977 -34.9191169) β delivery_area β
β 30 β 249416478 β POINT (-57.9538079 -34.9185892) β delivery_area β
β 31 β 249416467 β POINT (-57.9545168 -34.9180625) β delivery_area β
β 32 β 249417033 β POINT (-57.9534809 -34.9171231) β delivery_area β
β 33 β 249417320 β POINT (-57.9524713 -34.9162031) β delivery_area β
β 34 β 249417672 β POINT (-57.9514609 -34.9152824) β delivery_area β
β 35 β 249417675 β POINT (-57.9507639 -34.9158047) β delivery_area β
β 36 β 249417679 β POINT (-57.9500587 -34.9163333) β delivery_area β
β 37 β 249417335 β POINT (-57.9510606 -34.91725) β delivery_area β
ββββββββββββ΄βββββββββββββ΄ββββββββββββββββββββββββββββββββββ΄ββββββββββββββββ€
β 37 rows 4 columns β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ