Note
Go to the end to download the full example code.
Changing the Projection system for a model#
In this example we show how to change the projection system for a Polaris model.
Image credit to: https://ubc-library-rc.github.io/map-projections/content/diffs-geo-proj.html
from polaris import Polaris
from polaris.network.network import Network
from polaris.project.project_restorer import create_db_from_csv
from polaris.utils.database.db_utils import commit_and_close
from polaris.utils.database.standard_database import DatabaseType
from polaris.utils.path_utils import tempdirpath
from polaris.utils.testing.temp_model import TempModel
2025-10-29 04:55:31 UTC+0000 - No pre-existing parameter file exists for this project. Will use default
sphinx_gallery_thumbnail_path = ‘../../examples/editing_models/projections.jpg’
model_path = TempModel("Grid")
model = Polaris.from_dir(model_path)
model.upgrade()
old_net = model.network
2025-10-29 04:55:32 UTC+0000 - Upgrading Freight database at location /tmp/polaris_studio_testing/2025-10-29_04-55-31--07fbe3776db1/Grid-Freight.sqlite
2025-10-29 04:55:32 UTC+0000 - No migrations to apply
2025-10-29 04:55:32 UTC+0000 - Upgrading Freight database at location /tmp/polaris_studio_testing/2025-10-29_04-55-31--07fbe3776db1/Grid-Freight.sqlite: Done in 0:00:00.004572 seconds
2025-10-29 04:55:32 UTC+0000 - Upgrading Demand database at location /tmp/polaris_studio_testing/2025-10-29_04-55-31--07fbe3776db1/Grid-Demand.sqlite
2025-10-29 04:55:32 UTC+0000 - No migrations to apply
2025-10-29 04:55:32 UTC+0000 - Upgrading Demand database at location /tmp/polaris_studio_testing/2025-10-29_04-55-31--07fbe3776db1/Grid-Demand.sqlite: Done in 0:00:00.001136 seconds
2025-10-29 04:55:32 UTC+0000 - Upgrading Supply database at location /tmp/polaris_studio_testing/2025-10-29_04-55-31--07fbe3776db1/Grid-Supply.sqlite
2025-10-29 04:55:32 UTC+0000 - No migrations to apply
2025-10-29 04:55:32 UTC+0000 - Upgrading Supply database at location /tmp/polaris_studio_testing/2025-10-29_04-55-31--07fbe3776db1/Grid-Supply.sqlite: Done in 0:00:00.009834 seconds
2025-10-29 04:55:32 UTC+0000 - Working with file on /tmp/polaris_studio_testing/2025-10-29_04-55-31--07fbe3776db1/Grid-Supply.sqlite
WARNING
BE CAREFUL WHEN CHOOSING A PROJECTION SYSTEM. It must be projected in meters for Polaris to function properly
reprojected_folder = tempdirpath() / "new_projection"
# Let's say we choose the projection system 5069
old_net.ie.dump(reprojected_folder, target_crs=5069)
new_net_file = tempdirpath() / "Grid-Supply_reprojected.sqlite"
create_db_from_csv(new_net_file, reprojected_folder, DatabaseType.Supply, overwrite=True)
2025-10-29 04:55:34 UTC+0000 - Creating empty db: /tmp/Grid-Supply_reprojected.sqlite (jumpstart=True, with_defaults=True)
2025-10-29 04:55:34 UTC+0000 - Creating file at /tmp/Grid-Supply_reprojected.sqlite
2025-10-29 04:55:34 UTC+0000 - Adding Spatialite infrastructure to the database
2025-10-29 04:55:34 UTC+0000 - Creating Tables
2025-10-29 04:55:46 UTC+0000 - Creating Tables: Done in 0:00:11.877640 seconds
2025-10-29 04:55:46 UTC+0000 - Creating empty db: /tmp/Grid-Supply_reprojected.sqlite (jumpstart=True, with_defaults=True): Done in 0:00:11.935592 seconds
2025-10-29 04:55:46 UTC+0000 - Deleting triggers
2025-10-29 04:55:46 UTC+0000 - Deleting indices
2025-10-29 04:55:48 UTC+0000 - Recreating indices
2025-10-29 04:55:49 UTC+0000 - Creating triggers for version 20250921
We also need to update the length of a few elements in the network to be consistent with the new projection This is not strictly necessary, but minor differences may arise from how GeoPandas computes lengths
with commit_and_close(new_net_file, spatial=True) as conn:
for table in ("Link", "Road_Connectors", "Transit_Links", "Transit_Bike", "Transit_Walk"):
conn.execute(f"update {table} set length=round(ST_Length(geo), 8)")
Compute the overlay between the zone and the block group geometries
new_net = Network.from_file(new_net_file)
2025-10-29 04:55:50 UTC+0000 - Working with file on /tmp/Grid-Supply_reprojected.sqlite
Let’s compare the distances now
new_lengths = new_net.tables.get("Link")[["link", "length"]].set_index("link")
new_lengths.rename(columns={"length": "new_length"}, inplace=True)
old_lengths = old_net.tables.get("Link")[["link", "length"]].set_index("link")
old_lengths.rename(columns={"length": "old_length"}, inplace=True)
old_lengths.join(new_lengths).plot.scatter("old_length", "new_length")

<Axes: xlabel='old_length', ylabel='new_length'>
new_net.close()
old_net.close()
Total running time of the script: (0 minutes 21.932 seconds)