| | 1 | = Load your network data and create a network topology = |
|---|
| | 2 | |
|---|
| | 3 | Some network data already comes with a network topology that can be used with |
|---|
| | 4 | pgRouting immediately. But usually the data is in a different format than we |
|---|
| | 5 | need for pgRouting. Often network data is stored in the Shape file format (.shp) |
|---|
| | 6 | and we can use PostGIS' shape2postgresql converter to import the data into the |
|---|
| | 7 | database. OpenStreetMap stores its data as XML and it has its own importing |
|---|
| | 8 | tools for PostgreSQL database. |
|---|
| | 9 | |
|---|
| | 10 | Later we will use the osm2pgrouting converter. But it does much more than the |
|---|
| | 11 | basic steps for simple routing, so we will start this workshop with the minimum |
|---|
| | 12 | required attributes. |
|---|
| | 13 | |
|---|
| | 14 | == Load the network data == |
|---|
| | 15 | |
|---|
| | 16 | After creating the workshop database and adding the PostGIS and pgRouting |
|---|
| | 17 | functions to this database (see previous chapter), we load the sample data to |
|---|
| | 18 | our database: |
|---|
| | 19 | {{{ |
|---|
| | 20 | psql -U postgres routing |
|---|
| | 21 | \i /home/foss4g/ways_without_topology.sql |
|---|
| | 22 | }}} |
|---|
| | 23 | |
|---|
| | 24 | Note: The SQL dump file was made from a database which already had PostGIS |
|---|
| | 25 | functions loaded, so it will report errors during import that these functions |
|---|
| | 26 | already exist. You can ignore these errors. |
|---|
| | 27 | |
|---|
| | 28 | Let's see witch tables have been created: |
|---|
| | 29 | {{{ |
|---|
| | 30 | \d |
|---|
| | 31 | |
|---|
| | 32 | List of relations |
|---|
| | 33 | Schema | Name | Type | Owner |
|---|
| | 34 | --------+------------------+-------+---------- |
|---|
| | 35 | public | geometry_columns | table | postgres |
|---|
| | 36 | public | spatial_ref_sys | table | postgres |
|---|
| | 37 | public | ways | table | postgres |
|---|
| | 38 | (3 rows) |
|---|
| | 39 | |
|---|
| | 40 | \d ways |
|---|
| | 41 | |
|---|
| | 42 | Table "public.ways" |
|---|
| | 43 | Column | Type | Modifiers |
|---|
| | 44 | ----------+------------------+----------- |
|---|
| | 45 | gid | integer | not null |
|---|
| | 46 | length | double precision | |
|---|
| | 47 | name | character(200) | |
|---|
| | 48 | the_geom | geometry | |
|---|
| | 49 | Indexes: |
|---|
| | 50 | "ways_pkey" PRIMARY KEY, btree (gid) |
|---|
| | 51 | Check constraints: |
|---|
| | 52 | "enforce_dims_the_geom" CHECK (ndims(the_geom) = 2) |
|---|
| | 53 | "enforce_geotype_the_geom" CHECK (geometrytype(the_geom) = 'MULTILINESTRING'::text OR the_geom IS NULL) |
|---|
| | 54 | "enforce_srid_the_geom" CHECK (srid(the_geom) = 4326) |
|---|
| | 55 | }}} |
|---|
| | 56 | |
|---|
| | 57 | == Create network topology == |
|---|
| | 58 | |
|---|
| | 59 | Having your data imported into a PostgreSQL database usually requires one more |
|---|
| | 60 | step for pgRouting. You have to make sure that your data provides a correct |
|---|
| | 61 | network topology, which consists of links with source and target ID each. |
|---|
| | 62 | |
|---|
| | 63 | If your network data doesn't have such network topology information already |
|---|
| | 64 | you need to run the "assign_vertex_id" function. This function assigns a source |
|---|
| | 65 | and a target ID to each link and it can "snap" nearby vertices within a |
|---|
| | 66 | certain tolerance. |
|---|
| | 67 | |
|---|
| | 68 | {{{ |
|---|
| | 69 | assign_vertex_id('<table>', float tolerance, '<geometry column', '<gid>') |
|---|
| | 70 | }}} |
|---|
| | 71 | |
|---|
| | 72 | First we have to add source and target column, then we run the assign_vertex_id |
|---|
| | 73 | function ... and wait. |
|---|
| | 74 | {{{ |
|---|
| | 75 | ALTER TABLE ways ADD COLUMN source integer; |
|---|
| | 76 | ALTER TABLE ways ADD COLUMN target integer; |
|---|
| | 77 | SELECT assign_vertex_id('ways', 0.00001, 'the_geom', 'gid'); |
|---|
| | 78 | }}} |
|---|
| | 79 | |
|---|
| | 80 | Note: The dimension of the tolerance parameter depends on your data projection. |
|---|
| | 81 | Usually it's either "degrees" or "meters". Because OSM data has a very good |
|---|
| | 82 | quality for Cape town we can choose a very small "snapping" tolerance: |
|---|
| | 83 | 0.00001 degrees |
|---|
| | 84 | |
|---|
| | 85 | == Add indices == |
|---|
| | 86 | |
|---|
| | 87 | Fortunately we didn't need to wait too long because the data is small. But your |
|---|
| | 88 | network data might be very large, so it's a good idea to add an index on source, |
|---|
| | 89 | target and geometry column. |
|---|
| | 90 | {{{ |
|---|
| | 91 | CREATE INDEX source_idx ON ways(source); |
|---|
| | 92 | CREATE INDEX target_idx ON ways(target); |
|---|
| | 93 | CREATE INDEX geom_idx ON ways USING GIST(the_geom GIST_GEOMETRY_OPS); |
|---|
| | 94 | }}} |
|---|
| | 95 | |
|---|
| | 96 | After these steps our routing database look like this: |
|---|
| | 97 | {{{ |
|---|
| | 98 | \d |
|---|
| | 99 | |
|---|
| | 100 | List of relations |
|---|
| | 101 | Schema | Name | Type | Owner |
|---|
| | 102 | --------+---------------------+----------+---------- |
|---|
| | 103 | public | geometry_columns | table | postgres |
|---|
| | 104 | public | spatial_ref_sys | table | postgres |
|---|
| | 105 | public | vertices_tmp | table | postgres |
|---|
| | 106 | public | vertices_tmp_id_seq | sequence | postgres |
|---|
| | 107 | public | ways | table | postgres |
|---|
| | 108 | (5 rows) |
|---|
| | 109 | |
|---|
| | 110 | \d ways |
|---|
| | 111 | |
|---|
| | 112 | Table "public.ways" |
|---|
| | 113 | Column | Type | Modifiers |
|---|
| | 114 | ----------+------------------+----------- |
|---|
| | 115 | gid | integer | not null |
|---|
| | 116 | length | double precision | |
|---|
| | 117 | name | character(200) | |
|---|
| | 118 | the_geom | geometry | |
|---|
| | 119 | source | integer | |
|---|
| | 120 | target | integer | |
|---|
| | 121 | Indexes: |
|---|
| | 122 | "ways_pkey" PRIMARY KEY, btree (gid) |
|---|
| | 123 | Check constraints: |
|---|
| | 124 | "enforce_dims_the_geom" CHECK (ndims(the_geom) = 2) |
|---|
| | 125 | "enforce_geotype_the_geom" CHECK (geometrytype(the_geom) = 'MULTILINESTRING'::text OR the_geom IS NULL) |
|---|
| | 126 | "enforce_srid_the_geom" CHECK (srid(the_geom) = 4326) |
|---|
| | 127 | }}} |
|---|
| | 128 | |
|---|
| | 129 | Now we are ready for routing with Dijkstra algorithm! |
|---|