diff --git a/CMakeLists.txt b/CMakeLists.txt index d6254e053..8801d08e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,16 +83,16 @@ set(PLACE_4 "Grand Prince Hotel Hiroshima") set(PLACE_5 "RCC Bunka Center") -set(CH7_PLACE_1 ${PLACE_5}) -set(CH7_ID_1 ${OSMID_5}) +set(CH7_PLACE_1 ${PLACE_2}) +set(CH7_ID_1 ${OSMID_2}) set(CH7_PLACE_2 ${PLACE_1}) set(CH7_ID_2 ${OSMID_1}) -set(POINT1_LAT "-36.850329") -set(POINT1_LON "174.763094") +set(POINT1_LAT "34.399086") +set(POINT1_LON "132.453875") -set(POINT2_LAT "-36.853675") -set(POINT2_LON "174.764448") +set(POINT2_LAT "34.391111") +set(POINT2_LON "132.451490") #--------------------------------------------- # minimum versions diff --git a/docs/basic/images/sql_function/CMakeLists.txt b/docs/basic/images/sql_function/CMakeLists.txt index b03b3052c..514af76f8 100644 --- a/docs/basic/images/sql_function/CMakeLists.txt +++ b/docs/basic/images/sql_function/CMakeLists.txt @@ -3,14 +3,14 @@ # Files #--------------------- set(PGR_WORKSHOP_IMG_FILES - sql_azimuth_fixed.png - sql_route_geom.png - sql_route_names.png - sql_route_readable.png - sql_route_geom_detail.png + route_azimuth.png + route_names.png + route_readable.png + route_final.png + good_directionality.png + wrong_directionality.png ) - foreach (f ${PGR_WORKSHOP_IMG_FILES}) if (PGR_WORKSHOP_VERBOSE_DEBUG) message(STATUS " -> ${f}") diff --git a/docs/basic/images/sql_function/good_directionality.png b/docs/basic/images/sql_function/good_directionality.png new file mode 100644 index 000000000..858a61c5e Binary files /dev/null and b/docs/basic/images/sql_function/good_directionality.png differ diff --git a/docs/basic/images/sql_function/route_azimuth.png b/docs/basic/images/sql_function/route_azimuth.png new file mode 100644 index 000000000..9ee386d13 Binary files /dev/null and b/docs/basic/images/sql_function/route_azimuth.png differ diff --git a/docs/basic/images/sql_function/route_final.png b/docs/basic/images/sql_function/route_final.png new file mode 100644 index 000000000..54255900f Binary files /dev/null and b/docs/basic/images/sql_function/route_final.png differ diff --git a/docs/basic/images/sql_function/route_names.png b/docs/basic/images/sql_function/route_names.png new file mode 100644 index 000000000..571fa1ec0 Binary files /dev/null and b/docs/basic/images/sql_function/route_names.png differ diff --git a/docs/basic/images/sql_function/route_readable.png b/docs/basic/images/sql_function/route_readable.png new file mode 100644 index 000000000..2939b4ca5 Binary files /dev/null and b/docs/basic/images/sql_function/route_readable.png differ diff --git a/docs/basic/images/sql_function/sql_azimuth_fixed.png b/docs/basic/images/sql_function/sql_azimuth_fixed.png deleted file mode 100644 index 983371d40..000000000 Binary files a/docs/basic/images/sql_function/sql_azimuth_fixed.png and /dev/null differ diff --git a/docs/basic/images/sql_function/sql_route_geom.png b/docs/basic/images/sql_function/sql_route_geom.png deleted file mode 100644 index 38866b71f..000000000 Binary files a/docs/basic/images/sql_function/sql_route_geom.png and /dev/null differ diff --git a/docs/basic/images/sql_function/sql_route_geom_detail.png b/docs/basic/images/sql_function/sql_route_geom_detail.png deleted file mode 100644 index f11713d49..000000000 Binary files a/docs/basic/images/sql_function/sql_route_geom_detail.png and /dev/null differ diff --git a/docs/basic/images/sql_function/sql_route_names.png b/docs/basic/images/sql_function/sql_route_names.png deleted file mode 100644 index 532164c9f..000000000 Binary files a/docs/basic/images/sql_function/sql_route_names.png and /dev/null differ diff --git a/docs/basic/images/sql_function/sql_route_readable.png b/docs/basic/images/sql_function/sql_route_readable.png deleted file mode 100644 index b064852c4..000000000 Binary files a/docs/basic/images/sql_function/sql_route_readable.png and /dev/null differ diff --git a/docs/basic/images/sql_function/wrong_direccionality.png b/docs/basic/images/sql_function/wrong_direccionality.png new file mode 100644 index 000000000..90577cd28 Binary files /dev/null and b/docs/basic/images/sql_function/wrong_direccionality.png differ diff --git a/docs/basic/images/sql_function/wrong_directionality.png b/docs/basic/images/sql_function/wrong_directionality.png new file mode 100644 index 000000000..c1fc78dc0 Binary files /dev/null and b/docs/basic/images/sql_function/wrong_directionality.png differ diff --git a/docs/basic/images/withPoints/points_on_map.png b/docs/basic/images/withPoints/points_on_map.png index 2bc819557..d58651622 100644 Binary files a/docs/basic/images/withPoints/points_on_map.png and b/docs/basic/images/withPoints/points_on_map.png differ diff --git a/docs/basic/images/withPoints/points_routing.png b/docs/basic/images/withPoints/points_routing.png index 0d0534485..85a89cb12 100644 Binary files a/docs/basic/images/withPoints/points_routing.png and b/docs/basic/images/withPoints/points_routing.png differ diff --git a/docs/basic/sql_function.rst b/docs/basic/sql_function.rst index 270c753ac..1e5c7832c 100644 --- a/docs/basic/sql_function.rst +++ b/docs/basic/sql_function.rst @@ -6,16 +6,16 @@ SQL function ############################################################################### -.. image:: images/sql_function/sql_route_names.png +.. image:: images/sql_function/route_names.png :scale: 25% :align: center .. contents:: Chapter Contents -While pgRouting functions provide a low-level interface, developing for a higher-level -application requires these requirements to be represented directly in the SQL queries. -As these SQL queries get more complex, it is desirable to store them in PostgreSQL -stored procedures or functions. Stored procedures or functions are an effective way +While pgRouting functions provide a low-level interface, developing for a higher-level +application requires these requirements to be represented directly in the SQL queries. +As these SQL queries get more complex, it is desirable to store them in PostgreSQL +stored procedures or functions. Stored procedures or functions are an effective way to wrap application logic, in this case, related to routing logic and requirements. @@ -24,21 +24,21 @@ The function requirements The function will wrap ``pgr_dijkstra``. -The function needs to work on any of the networks designed: +The function will use: - ``vehicle_net`` -- ``taxi_net`` +- ``vehicle_penalized_net`` -The function needs to return the following routing information: +The function returns the following routing information: - ``seq`` - A unique identifier of the rows - ``id`` - The segment's identifier +- ``seconds`` - Number of seconds to traverse the segment - ``name`` - The segment's name - ``length`` - The segment's length -- ``seconds`` - Number of seconds to traverse the segment - ``azimuth`` - The azimuth of the segment -- ``route_geom`` - The routing geometry -- ``route_readable`` - The geometry in human readable form. +- ``readable`` - The geometry in human readable form. +- ``geom`` - The routing geometry .. rubric:: Design of the function @@ -50,26 +50,28 @@ output columns: ================= ========= ================= Parameter Type Description ================= ========= ================= -``edges_subset`` REGCLASS The table/view that is going to be used for processing -``source`` BIGINT The identifier of the `departure` location. -``target`` BIGINT The identifier of the `destination` location. +``source`` BIGINT The identifier of the `departure` location. +``target`` BIGINT The identifier of the `destination` location. ================= ========= ================= -.. rubric:: output columns +.. columns_start + +.. rubric:: Output columns ================== ========= ================= Name Type Description ================== ========= ================= ``seq`` INTEGER A unique number for each result row. ``id`` BIGINT The edge identifier. -``name`` TEXT The name of the segment. ``seconds`` FLOAT The number of seconds it takes to traverse the segment. +``name`` TEXT The name of the segment. ``length`` FLOAT The length in meters of the segment. ``azimuth`` FLOAT The azimuth of the segment. -``route_readable`` TEXT The geometry in human readable form. -``route_geom`` geometry The geometry of the segment in the correct direction. +``readable`` TEXT The geometry in human readable form. +``geom`` geometry The geometry of the segment in the correct direction. ================== ========= ================= +.. columns_end Additional information handling =============================================================================== @@ -80,134 +82,115 @@ When the application needs additional information, like the name of the street, Exercise 1: Get additional information ------------------------------------------------------------------------------- -.. image:: images/sql_function/sql_route_names.png +.. image:: images/sql_function/route_names.png :width: 300pt - :alt: Route showing names + :alt: Route showing names .. rubric:: Problem -* From |ch7_place_1| to |ch7_place_2| -* Get the following information: - - * ``seq`` - * ``id`` - * ``name`` - * ``seconds`` - * ``length`` +* Create a function that gets all the required information .. rubric:: Solution -* The function returns the columns asked. (line **4**) -* Rename ``pgr_dijkstra`` results to application requirements names. (line - **12**). +* The function returns the columns asked. +* Rename ``pgr_dijkstra`` results to application requirements names. * ``LEFT JOIN`` the results with ``vehicle_net`` to get the additional - information. (line **17**) + information. - * ``LEFT`` to include the row with ``id = -1`` because it does not exist on + * ``LEFT JOIN`` to include the row with ``id = -1`` because it does not exist on ``vehicle_net`` -* Test from |ch7_id_1| to |ch7_id_2| on ``vehicle_net``. (Last line) - .. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql - :linenos: :force: - :emphasize-lines: 4,12,17 :start-after: get_more_info.txt :end-before: get_read_geom.txt -.. collapse:: Query results +Using the function +=============================================================================== + +Exercise 2: Route geometry (binary format) +------------------------------------------------------------------------------- + +.. image:: images/sql_function/route_readable.png + :width: 300pt + :alt: Route showing readable - .. literalinclude:: ../scripts/basic/sql_function/get_more_info.txt +.. rubric:: Problem +Get the geometries of the route from |place_1| to |place_2| -Geometry handling -=============================================================================== +.. rubric:: Solution + +* Select the column ``geom``. + +.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql + :language: sql + :start-after: get_geom.txt + :end-before: get_azimuth.txt -From pgRouting point of view, the geometry is part of the additional -information needed on the results for an application. Therefore ``JOIN`` the -results with other tables that contain the geometry and for further processing -with PostGIS functions. +.. collapse:: Query results + + .. literalinclude:: ../scripts/basic/sql_function/get_geom.txt -Exercise 2: Route geometry (human readable) +Exercise 3: Route geometry (human readable) ------------------------------------------------------------------------------- -.. image:: images/sql_function/sql_route_readable.png +.. image:: images/sql_function/route_readable.png :width: 300pt :alt: From |ch7_place_1| to |ch7_place_2| .. rubric:: Problem -Route from the |ch7_place_1| to |ch7_place_2| - -* Additionally to the previous exercise, get the - - * geometry ``geom`` in human readable form named as ``route_readable`` +Get the geometries in readable form of the route from |place_1| to |place_2| .. rubric:: Solution -* The function returns ``route_readable``. (line **6**) -* The routing query named ``results`` in a WITH clause. (line **11**) -* The ``geom`` processed with ``ST_AsText`` to get the human readable form. - (line **19**). -* Test from |ch7_id_1| to |ch7_id_2| on ``vehicle_net``. (Last line) +* Select the column ``readable``. .. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql - :linenos: - :force: - :emphasize-lines: 6,11,19 :start-after: get_read_geom.txt :end-before: get_geom.txt -.. exercise 2 results - .. collapse:: Query results .. literalinclude:: ../scripts/basic/sql_function/get_read_geom.txt - - -Exercise 3: Route geometry (binary format) +Exercise 5: Get the azimuth ------------------------------------------------------------------------------- -.. image:: images/sql_function/sql_route_geom.png +.. image:: images/sql_function/route_azimuth.png :width: 300pt - :alt: From |ch7_place_1| to |ch7_place_2| + :alt: Route showing azimuth -.. rubric:: Problem - -Route from the |ch7_place_1| to |ch7_place_2| +There are many geometry functions in PostGIS, the workshop coveres some +of them like ``ST_AsText``, ``ST_Reverse``, ``ST_EndPoint``, ``ST_Azimuth``. -* Additionally to the previous exercise, get the +.. rubric:: Problem - * ``geom`` in binary format with the name ``route_geom`` +Get the azimuth of the geometries of the route from |place_1| to |place_2| .. rubric:: Solution -* The function returns ``route_geom``. (line **7**) -* The geometry ``geom`` of the segments (line **21**) -* Test from |ch7_id_1| to |ch7_id_2| on ``vehicle_net``. (Last line) - +* The function returns ``azimuth``. .. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql - :emphasize-lines: 7,21 - :force: - :linenos: - :start-after: get_geom.txt + :start-after: get_azimuth.txt :end-before: wrong_directionality.txt -.. collapse:: Query results +.. collapse:: results + + .. literalinclude:: ../scripts/basic/sql_function/get_azimuth.txt - .. literalinclude:: ../scripts/basic/sql_function/get_geom.txt Exercise 4: Route geometry directionality ------------------------------------------------------------------------------- -.. image:: images/sql_function/sql_route_geom_detail.png +.. image:: images/sql_function/wrong_directionality.png :width: 300pt - :alt: From |ch7_place_1| to |ch7_place_2| + :alt: wrong direccionality Visually, with the route displayed with arrows, it can be found that there are arrows that do not match the directionality of the route. @@ -215,27 +198,24 @@ arrows that do not match the directionality of the route. To have correct directionality, the ending point of a geometry must match the starting point of the next geometry -* Inspecting the detail of the results of `Exercise 2: Route geometry (human readable)`_ +* Inspecting the detail of the results of `Exercise 3: Route geometry (human readable)`_ -.. collapse:: Query: Rows where criteria is not met +.. collapse:: Rows where criteria is not met - .. literalinclude:: ../scripts/basic/sql_function/sql_function.sql - :language: sql - :start-after: wrong_directionality.txt - :end-before: fix_directionality.txt + .. literalinclude:: ../scripts/basic/sql_function/sql_function.sql + :language: sql + :start-after: wrong_directionality.txt + :end-before: fix_directionality.txt .. literalinclude:: ../scripts/basic/sql_function/wrong_directionality.txt - :language: sql .. rubric:: Problem -Route from the |ch7_place_1| to |ch7_place_2| +* Fix the directionality of the geometries and of the columns that depend on it. -* Fix the directionality of the geometries of the previous exercise - - * ``geom`` in human readable form named as ``route_readable`` - * ``geom`` in binary format with the name ``route_geom`` - * Both columns must have the geometry fixed for directionality. + * ``geom`` + * ``readable`` + * ``azimuth`` .. rubric:: Solution @@ -244,12 +224,6 @@ To get the correct direction some geometries need to be reversed: * Reversing a geometry will depend on the ``node`` column of the query to Dijkstra. -* A conditional ``CASE`` statement that returns the geometry in human readable - form: - - * Of the geometry when ``node`` is the ``source`` column. - * Of the reversed geometry when ``node`` is not the ``source`` column. - * A conditional ``CASE`` statement that returns: * The geometry when ``node`` is the ``source`` column. @@ -262,61 +236,32 @@ To get the correct direction some geometries need to be reversed: :start-after: fix_directionality.txt :end-before: good_directionality.txt -.. collapse:: results - - .. literalinclude:: ../scripts/basic/sql_function/fix_directionality.txt - Inspecting the problematic rows, the directionality has been fixed. .. collapse:: Query: Rows where criteria is not met - .. literalinclude:: ../scripts/basic/sql_function/sql_function.sql - :language: sql - :start-after: good_directionality.txt - :end-before: use_directionality.txt + .. literalinclude:: ../scripts/basic/sql_function/sql_function.sql + :language: sql + :start-after: good_directionality.txt + :end-before: final_function.txt .. literalinclude:: ../scripts/basic/sql_function/good_directionality.txt - -Exercise 5: Using the geometry -------------------------------------------------------------------------------- - -.. image:: images/sql_function/sql_azimuth_fixed.png +.. image:: images/sql_function/good_directionality.png :width: 300pt - :alt: From |ch7_place_1| to the |ch7_place_2| show azimuth - - -There are many geometry functions in PostGIS, the workshop already covered some of them like -``ST_AsText``, ``ST_Reverse``, ``ST_EndPoint``, etc. -This exercise will make use an additional function ``ST_Azimuth``. - - -.. rubric:: Problem + :alt: good direccionality -Modify the query from the previous exercise - -* Additionally obtain the azimuth in degrees of the corrected geometry. - -.. rubric:: Solution +Writing the final function +------------------------------------------------------------------------------- -* The function returns ``aximuth``. (line **8**) -* The query from previous exercise is wrapped under additional subquery. (line - **18**) -* The ``azimuth`` is processed in degrees. (line **35**). -* Test from |ch7_id_1| to |ch7_id_2| on ``vehicle_net``. (Last line) +The final function using ``vehicle_penalized_net`` .. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql :force: - :linenos: - :emphasize-lines: 8,18,35 - :start-after: use_directionality.txt + :start-after: final_function.txt :end-before: using_fn1.txt -.. collapse:: results - - .. literalinclude:: ../scripts/basic/sql_function/use_directionality.txt - Exercise 6: Using the function ------------------------------------------------------------------------------- @@ -328,40 +273,17 @@ Try the function with a combination of the interesting places: * |id_4| |place_4| * |id_5| |place_5| -Using different networks: - -- ``vehicle_net`` -- ``taxi_net`` -- ``walk_net`` - Names of the streets in the route .. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql :start-after: using_fn1.txt - :end-before: using_fn2.txt + :end-before: vw_initial.txt .. collapse:: Query results .. literalinclude:: ../scripts/basic/sql_function/using_fn1.txt -Total seconds spent in each street - -.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql - :language: sql - :start-after: using_fn2.txt - :end-before: using_fn3.txt - -.. collapse:: Query results - - .. literalinclude:: ../scripts/basic/sql_function/using_fn2.txt - -Why it does not fully work with ``walk_net``? - -.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql - :language: sql - :start-after: using_fn3.txt - -.. collapse:: Query results - - .. literalinclude:: ../scripts/basic/sql_function/using_fn3.txt +.. image:: images/sql_function/route_final.png + :width: 300pt + :alt: From |ch7_place_1| to |ch7_place_2| diff --git a/docs/basic/withPoints.rst b/docs/basic/withPoints.rst index 43a8f2335..6c04b1e5d 100644 --- a/docs/basic/withPoints.rst +++ b/docs/basic/withPoints.rst @@ -10,9 +10,10 @@ Routing using points :align: center -For more advanced requirements, you can utilize `PL/pgSQL `_. As application logic grows more complex, using PL/pgSQL -to dynamically construct SQL queries and execute them using internal variables becomes necessary. - +For more advanced requirements, you can utilize +`PL/pgSQL `_. +As application logic grows more complex, using PL/pgSQL to dynamically construct +SQL queries and execute them using internal variables becomes necessary. pgRouting functions in this chapter @@ -30,13 +31,11 @@ Requirements for routing lat,lon points geometries and works for * ``vehicle_net`` - * ``taxi_net`` - * ``walk_net`` * The function takes as input parameters: - The edges table name - - Latitude/longitude of two point + - Latitude/longitude of two points * Returns @@ -51,7 +50,6 @@ The detailed description: ================ ========== ================================================ Parameter type Description ================ ========== ================================================ -``edges_subset`` REGCLASS Edge table name identifier. ``lat1`` NUMERIC The latitude of the `departure` point. ``lon1`` NUMERIC The longitude of the `departure` point. ``lat2`` NUMERIC The latitude of the `destination` point. @@ -61,21 +59,9 @@ Parameter type Description ================ ========== ================================================ -.. rubric:: Output columns - -================== ========= ================= -Name Type Description -================== ========= ================= -``seq`` INTEGER A unique number for each result row. -``id`` BIGINT The edge identifier. -``name`` TEXT The name of the segment. -``seconds`` FLOAT The number of seconds it takes to traverse the segment. -``length`` FLOAT The length in meters of the segment. -``azimuth`` FLOAT The azimuth of the segment. -``route_readable`` TEXT The geometry in human readable form. -``route_geom`` geometry The geometry of the segment in the correct direction. -================== ========= ================= - +.. include:: sql_function.rst + :start-after: columns_start + :end-before: columns_end For this chapter, the following points will be used for testing. @@ -115,8 +101,7 @@ Get the nearest edge on the graph of the following points. .. rubric:: Solution -* Build the geometry of the points with the appropiate SRID. (lines **4** and - **10**) +* Build the geometry of the points with the appropiate SRID. * Get the union of the individual queries .. literalinclude:: ../scripts/basic/withPoints/withPoints.sql @@ -216,15 +201,15 @@ The function's signature: :start-after: wrk_withPoints.txt :end-before: signature ends -Getting the closest query: +The points SQL: * The query looks like the one on `Exercise 1: Get the nearest edge`_ * Using PostgreSQL ``format`` to make substitutions. * The first parameter is the string to be replaced * The rest are the data parameters, are the strings use for replacement. - * ``lat1``, ``lon1`` values will replace ``%2$s, %3$s`` respectively. - * ``lat2``, ``lon2`` values will replace ``%4$s, %5$s`` respectively. + * ``lat1``, ``lon1`` values will replace ``%2$s, %1$s`` respectively. + * ``lat2``, ``lon2`` values will replace ``%4$s, %3$s`` respectively. .. literalinclude:: ../scripts/basic/withPoints/withPoints.sql :language: sql @@ -233,13 +218,12 @@ Getting the closest query: :start-after: -- 0 :end-before: -- 1 -Getting the routing results: +The routing results: * The query looks like the one on `Exercise 2: Point routing` * Using PostgreSQL ``format`` to make substitutions. - * The ``edges_subset`` value will replace ``%1$I``. - * The ``closest_query`` value will replace ``%2$s``. + * The ``points_sql`` value will replace ``%1$s``. .. literalinclude:: ../scripts/basic/withPoints/withPoints.sql :language: sql @@ -248,24 +232,6 @@ Getting the routing results: :start-after: -- 1 :end-before: -- 2 -Getting the additional information: - -* The subquery looks like the one in the function created on - :doc:`sql_function`. -* A joined table can not be a variable - - * Using PostgreSQL ``format`` to make substitutions. - * To make it work on the ``walk_net``, the whole query needs to be in - ``TEXT``. - * The ``edges_subset`` value will replace ``%1$I``: - -.. literalinclude:: ../scripts/basic/withPoints/withPoints.sql - :language: sql - :force: - :linenos: - :start-after: -- 2 - :end-before: -- 3 - Building the complete query: * The complete query looks like the one in the function created on @@ -276,8 +242,8 @@ Building the complete query: :language: sql :force: :linenos: - :start-after: -- 3 - :end-before: -- 4 + :start-after: -- 2 + :end-before: -- 3 Exercise 4: Using wrk_withPoints ............................................................................... @@ -292,25 +258,15 @@ Use ``wrk_withPoints`` * Departure point is: (lat,lon) = ``(@POINT1_LAT@, @POINT1_LON@)`` * Destination point is: (lat,lon) = ``(@POINT2_LAT@, @POINT2_LON@)`` -* For ``vehicle_net``: - * Get the names of the streets of the route. +* Get the query that is been generated. +* Get the names of the streets of the route. +* Create a view to be used on QGIS. -* For ``taxi_net``: - - * Get the query that is been generated. - -* For ``walk_net``: - - * Use with default value of ``do_debug``. - * Store results on a table. - * Show the table contents. + * Test the view by listing the names of each segment of the route. .. rubric:: Solution -For ``vehicle_net``: - -* The first parameter is the table name. * The next two parameters are the latitude and longitude of the departure point. * The next two parameters are the latitude and longitude of the destination point. * Use with default value of ``do_debug``. @@ -324,8 +280,6 @@ For ``vehicle_net``: .. literalinclude:: ../scripts/basic/withPoints/use_fn_1.txt -For ``taxi_net``: - * Do a dry run by adding ``true`` to get the query that is executed. .. literalinclude:: ../scripts/basic/withPoints/withPoints.sql @@ -337,7 +291,7 @@ For ``taxi_net``: .. literalinclude:: ../scripts/basic/withPoints/warnings.txt -For ``walk_net``: +* Create the view and test it. .. literalinclude:: ../scripts/basic/withPoints/withPoints.sql :language: sql diff --git a/docs/scripts/basic/sql_function/CMakeLists.txt b/docs/scripts/basic/sql_function/CMakeLists.txt index 7b338e8fc..f6613feb3 100644 --- a/docs/scripts/basic/sql_function/CMakeLists.txt +++ b/docs/scripts/basic/sql_function/CMakeLists.txt @@ -4,25 +4,22 @@ add_custom_target(basic_sql_function_scripts) # Files #--------------------- configure_file(sql_function.sql sql_function.sql) -configure_file(images.sql images.sql) add_custom_command( TARGET basic_sql_function_scripts PRE_BUILD BYPRODUCTS - get_more_info.txt get_read_geom.txt get_geom.txt + get_azimuth.txt wrong_directionality.txt fix_directionality.txt good_directionality.txt - use_directionality.txt + final_function.txt using_fn1.txt - using_fn2.txt - using_fn3.txt + helpers.txt COMMAND psql -d city_routing -f sql_function.sql - COMMAND psql -d city_routing -f images.sql COMMENT "running sql function scripts" -) + DEPENDS sql_function.sql) diff --git a/docs/scripts/basic/sql_function/images.sql b/docs/scripts/basic/sql_function/images.sql deleted file mode 100644 index 7e8a4ada2..000000000 --- a/docs/scripts/basic/sql_function/images.sql +++ /dev/null @@ -1,9 +0,0 @@ - -CREATE OR REPLACE VIEW using_vehicle AS -SELECT * -FROM wrk_dijkstra('vehicle_net', @CH7_ID_1@, @CH7_ID_2@); - -CREATE OR REPLACE VIEW sql_route_geom AS -SELECT seq, id, geom -FROM wrk_dijkstra('vehicle_net', @CH7_ID_1@, @CH7_ID_2@) -JOIN vehicle_net USING (id); diff --git a/docs/scripts/basic/sql_function/sql_function.sql b/docs/scripts/basic/sql_function/sql_function.sql index 5831941e6..bc1e6864f 100644 --- a/docs/scripts/basic/sql_function/sql_function.sql +++ b/docs/scripts/basic/sql_function/sql_function.sql @@ -7,34 +7,11 @@ DROP FUNCTION IF EXISTS wrk_dijkstra(regclass, bigint, bigint); -- DROP FUNCTION wrk_dijkstra(regclass, bigint, bigint); CREATE OR REPLACE FUNCTION wrk_dijkstra( - IN edges_subset REGCLASS, IN source BIGINT, IN target BIGINT, - OUT seq INTEGER, OUT id BIGINT, OUT seconds FLOAT, OUT name TEXT, OUT length FLOAT -) -RETURNS SETOF record AS -$BODY$ -SELECT -seq, id, seconds, name, length -FROM ( - SELECT seq, edge AS id, node, cost AS seconds - FROM pgr_dijkstra( - 'SELECT * FROM ' || $1, - source, target) -) AS results -LEFT JOIN vehicle_net USING (id) -ORDER BY seq; -$BODY$ -LANGUAGE SQL; - -SELECT * FROM wrk_dijkstra('vehicle_net', @CH7_ID_1@, @CH7_ID_2@); - -\o get_read_geom.txt - -DROP FUNCTION wrk_dijkstra(regclass, bigint, bigint); - -CREATE OR REPLACE FUNCTION wrk_dijkstra( - IN edges_subset REGCLASS, IN source BIGINT, IN target BIGINT, - OUT seq INTEGER, OUT id BIGINT, OUT seconds FLOAT, OUT name TEXT, OUT length FLOAT, - OUT route_readable TEXT + IN source BIGINT, IN target BIGINT, + OUT seq INTEGER, OUT id BIGINT, + OUT seconds FLOAT, OUT name TEXT, OUT length FLOAT, + OUT azimuth FLOAT, OUT readable TEXT, + OUT geom GEOMETRY ) RETURNS SETOF record AS $BODY$ @@ -42,76 +19,49 @@ WITH results AS ( SELECT seq, edge AS id, node, cost AS seconds FROM pgr_dijkstra( - 'SELECT * FROM ' || $1, + -- on purpose to have wrong direccionality + 'SELECT * FROM vehicle_net', source, target) ) SELECT seq, id, seconds, name, length, - ST_AsText(geom) + degrees(ST_azimuth(ST_StartPoint(geom), ST_EndPoint(geom))), + ST_AsText(geom), + geom FROM results LEFT JOIN vehicle_net USING (id) ORDER BY seq; + $BODY$ LANGUAGE SQL; -SELECT seq, route_readable FROM wrk_dijkstra('vehicle_net', @CH7_ID_1@, @CH7_ID_2@); +\o get_read_geom.txt + +SELECT seq, readable FROM wrk_dijkstra(@CH7_ID_1@, @CH7_ID_2@); \o get_geom.txt -DROP FUNCTION wrk_dijkstra(regclass, bigint, bigint); +SELECT seq, geom FROM wrk_dijkstra(@CH7_ID_1@, @CH7_ID_2@); -CREATE OR REPLACE FUNCTION wrk_dijkstra( - IN edges_subset REGCLASS, IN source BIGINT, IN target BIGINT, - OUT seq INTEGER, OUT id BIGINT, OUT seconds FLOAT, OUT name TEXT, OUT length FLOAT, - OUT route_readable TEXT, - OUT route_geom geometry -) -RETURNS SETOF record AS -$BODY$ -WITH -results AS ( - SELECT seq, edge AS id, node, cost AS seconds - FROM pgr_dijkstra( - 'SELECT * FROM ' || $1, - source, target) -) -SELECT - seq, id, seconds, name, length, - ST_AsText(geom), - geom -FROM results -LEFT JOIN vehicle_net USING (id) -ORDER BY seq; -$BODY$ -LANGUAGE SQL; +\o get_azimuth.txt -SELECT seq, route_geom FROM wrk_dijkstra('vehicle_net', @CH7_ID_1@, @CH7_ID_2@); +SELECT seq, azimuth FROM wrk_dijkstra(@CH7_ID_1@, @CH7_ID_2@); \o wrong_directionality.txt -WITH -results AS ( - SELECT seq, id, route_geom - FROM wrk_dijkstra('vehicle_net', @CH7_ID_1@, @CH7_ID_2@) -), -compare AS ( - SELECT seq, id, lead(seq) over(ORDER BY seq) AS next_seq, - ST_AsText(ST_endPoint(route_geom)) AS id_end, - ST_AsText(ST_startPoint(lead(route_geom) over(ORDER BY seq))) AS next_id_start - - FROM results - ORDER BY seq) -SELECT * FROM compare WHERE id_end != next_id_start; +SELECT seq, azimuth, readable FROM wrk_dijkstra(@CH7_ID_1@, @CH7_ID_2@) +ORDER BY seq LIMIT 3; \o fix_directionality.txt -DROP FUNCTION wrk_dijkstra(regclass, bigint, bigint); +DROP FUNCTION IF EXISTS wrk_dijkstra_fixed(bigint, bigint); -CREATE OR REPLACE FUNCTION wrk_dijkstra( - IN edges_subset REGCLASS, IN source BIGINT, IN target BIGINT, - OUT seq INTEGER, OUT id BIGINT, OUT seconds FLOAT, OUT name TEXT, OUT length FLOAT, - OUT route_readable TEXT, - OUT route_geom geometry +CREATE OR REPLACE FUNCTION wrk_dijkstra_fixed( + IN source BIGINT, IN target BIGINT, + OUT seq INTEGER, OUT id BIGINT, + OUT seconds FLOAT, OUT name TEXT, OUT length FLOAT, + OUT azimuth FLOAT, OUT readable TEXT, + OUT geom GEOMETRY ) RETURNS SETOF record AS $BODY$ @@ -119,53 +69,45 @@ WITH results AS ( SELECT seq, edge AS id, node, cost AS seconds FROM pgr_dijkstra( - 'SELECT * FROM ' || $1, + -- on purpose to have wrong direccionality + 'SELECT * FROM vehicle_net', source, target) -) -SELECT +), +additional AS ( + SELECT seq, id, seconds, name, length, CASE - WHEN node = source THEN ST_AsText(geom) - ELSE ST_AsText(ST_Reverse(geom)) - END, + WHEN node = source THEN geom + ELSE ST_Reverse(geom) + END AS geom + FROM results + LEFT JOIN vehicle_net USING (id) + ORDER BY seq) + +SELECT seq, id, seconds, name, length, + degrees(ST_azimuth(ST_StartPoint(geom), ST_EndPoint(geom))) AS azimuth, + ST_AsText(geom), geom +FROM additional ORDER BY seq; - CASE - WHEN node = source THEN geom - ELSE ST_Reverse(geom) - END -FROM results -LEFT JOIN vehicle_net USING (id) -ORDER BY seq; $BODY$ LANGUAGE SQL; -SELECT seq, route_readable FROM wrk_dijkstra('vehicle_net', @CH7_ID_1@, @CH7_ID_2@); \o good_directionality.txt -WITH -results AS ( - SELECT seq, id, seconds, route_geom - FROM wrk_dijkstra('vehicle_net', @CH7_ID_1@, @CH7_ID_2@) -), -compare AS ( - SELECT seq, id, lead(route_geom) over(ORDER BY seq) AS next_id, - ST_AsText(ST_endPoint(route_geom)) AS id_end, - ST_AsText(ST_startPoint(lead(route_geom) over(ORDER BY seq))) AS next_id_start -FROM results -ORDER BY seq) -SELECT * FROM compare WHERE id_end != next_id_start; +SELECT seq, azimuth, readable FROM wrk_dijkstra_fixed(@CH7_ID_1@, @CH7_ID_2@) +ORDER BY seq LIMIT 3; -\o use_directionality.txt +\o final_function.txt -DROP FUNCTION wrk_dijkstra(regclass, bigint, bigint); +DROP FUNCTION IF EXISTS wrk_dijkstra_final(bigint, bigint); -CREATE OR REPLACE FUNCTION wrk_dijkstra( - IN edges_subset REGCLASS, IN source BIGINT, IN target BIGINT, - OUT seq INTEGER, OUT id BIGINT, OUT seconds FLOAT, OUT name TEXT, OUT length FLOAT, - OUT route_readable TEXT, - OUT route_geom geometry, - OUT azimuth FLOAT +CREATE OR REPLACE FUNCTION wrk_dijkstra_final( + IN source BIGINT, IN target BIGINT, + OUT seq INTEGER, OUT id BIGINT, + OUT seconds FLOAT, OUT name TEXT, OUT length FLOAT, + OUT azimuth FLOAT, OUT readable TEXT, + OUT geom GEOMETRY ) RETURNS SETOF record AS $BODY$ @@ -173,16 +115,12 @@ WITH results AS ( SELECT seq, edge AS id, node, cost AS seconds FROM pgr_dijkstra( - 'SELECT * FROM ' || $1, - source, target)), + 'SELECT * FROM vehicle_penalized_net', + source, target) +), additional AS ( SELECT seq, id, seconds, name, length, - CASE - WHEN node = source THEN ST_AsText(geom) - ELSE ST_AsText(ST_Reverse(geom)) - END AS readable, - CASE WHEN node = source THEN geom ELSE ST_Reverse(geom) @@ -191,23 +129,33 @@ additional AS ( LEFT JOIN vehicle_net USING (id) ORDER BY seq) -SELECT *, - degrees(ST_azimuth(ST_StartPoint(geom), ST_EndPoint(geom))) AS azimuth +SELECT seq, id, seconds, name, length, + degrees(ST_azimuth(ST_StartPoint(geom), ST_EndPoint(geom))) AS azimuth, + ST_AsText(geom), geom FROM additional ORDER BY seq; + $BODY$ LANGUAGE SQL; -SELECT seq, azimuth FROM wrk_dijkstra('vehicle_net', @CH7_ID_1@, @CH7_ID_2@); - \o using_fn1.txt -SELECT DISTINCT name -FROM wrk_dijkstra('vehicle_net', @CH7_ID_1@, @CH7_ID_2@); -\o using_fn2.txt -SELECT name, sum(seconds) -FROM wrk_dijkstra('taxi_net', @CH7_ID_1@, @CH7_ID_2@) -GROUP BY name; +SELECT seq, name FROM wrk_dijkstra_final(@CH7_ID_1@, @CH7_ID_2@); + +\o vw_initial.txt + +CREATE OR REPLACE VIEW vw_initial AS +SELECT *, geom::text AS tgeom FROM wrk_dijkstra(@CH7_ID_1@, @CH7_ID_2@); + +\o vw_fixed.txt + +CREATE OR REPLACE VIEW vw_fixed AS +SELECT * FROM wrk_dijkstra_fixed(@CH7_ID_1@, @CH7_ID_2@); + +\o vw_final.txt + +CREATE OR REPLACE VIEW vw_final AS +SELECT * FROM wrk_dijkstra_final(@CH7_ID_1@, @CH7_ID_2@); -\o using_fn3.txt -SELECT * -FROM wrk_dijkstra('walk_net', @CH7_ID_1@, @CH7_ID_2@); +\o helpers.txt +SELECT seq, a.azimuth = b.azimuth FROM wrk_dijkstra_fixed(@ID_1@, @ID_2@) a JOIN wrk_dijkstra(@ID_1@, @ID_2@) b USING (seq, id, seconds, name, length) WHERE a.azimuth != b.azimuth; +SELECT seq, a.azimuth = b.azimuth FROM wrk_dijkstra_fixed(@ID_1@, @ID_3@) a JOIN wrk_dijkstra(@ID_1@, @ID_3@) b USING (seq, id, seconds, name, length) WHERE a.azimuth != b.azimuth; diff --git a/docs/scripts/basic/withPoints/CMakeLists.txt b/docs/scripts/basic/withPoints/CMakeLists.txt index 3049bb54b..844611114 100644 --- a/docs/scripts/basic/withPoints/CMakeLists.txt +++ b/docs/scripts/basic/withPoints/CMakeLists.txt @@ -1,10 +1,14 @@ #--------------------- # Files #--------------------- +add_custom_target(basic_withPoints_scripts) + configure_file(withPoints.sql withPoints.sql) -configure_file(images.sql images.sql) -set(GENERATED_FILES +add_custom_command( + TARGET basic_withPoints_scripts + PRE_BUILD + BYPRODUCTS closestedges.txt route_withPoints.txt wrk_withPoints.txt @@ -13,17 +17,8 @@ set(GENERATED_FILES use_fn_3.txt file_end.txt warnings.txt -) -add_custom_command( COMMAND psql -d city_routing -f withPoints.sql 2> warnings.txt - COMMAND psql -d city_routing -f images.sql - OUTPUT ${GENERATED_FILES} - - DEPENDS withPoints.sql images.sql COMMENT "running chapter withPoints scripts" -) - -add_custom_target(basic_withPoints_scripts - DEPENDS ${GENERATED_FILES} + DEPENDS withPoints.sql ) diff --git a/docs/scripts/basic/withPoints/images.sql b/docs/scripts/basic/withPoints/images.sql deleted file mode 100644 index 31cfe6202..000000000 --- a/docs/scripts/basic/withPoints/images.sql +++ /dev/null @@ -1,42 +0,0 @@ -DROP TABLE IF EXISTS points_on_map; -WITH the_points AS ( -SELECT 1 AS id, ST_SetSRID(ST_Point(@POINT1_LON@, @POINT1_LAT@), 4326) -UNION -SELECT 2 AS id, ST_SetSRID(ST_Point(@POINT2_LON@, @POINT2_LAT@), 4326) -) -SELECT * INTO points_on_map -FROM the_points; - - -DROP TABLE IF EXISTS closest_walk; -WITH the_closest AS ( -SELECT 1 AS pid, * from pgr_findCloseEdges( - 'SELECT id, geom from walk_net', - ST_SetSRID(ST_Point(@POINT1_LON@, @POINT1_LAT@), 4326) , 0.5) - -UNION - -SELECT 2 AS pid, * from pgr_findCloseEdges( - 'SELECT id, geom from walk_net', - ST_SetSRID(ST_Point(@POINT2_LON@, @POINT2_LAT@), 4326) , 0.5) -) -SELECT * INTO closest_walk FROM the_closest; - -CREATE OR REPLACE VIEW using_vehicle AS -SELECT * FROM wrk_withPoints( - 'vehicle_net', - @POINT1_LAT@, @POINT1_LON@, - @POINT2_LAT@, @POINT2_LON@); - -CREATE OR REPLACE VIEW using_taxi AS -SELECT * FROM wrk_withPoints( - 'taxi_net', - @POINT1_LAT@, @POINT1_LON@, - @POINT2_LAT@, @POINT2_LON@); - -CREATE OR REPLACE VIEW using_walk AS -SELECT * -FROM wrk_withPoints( - 'walk_net', - @POINT1_LAT@, @POINT1_LON@, - @POINT2_LAT@, @POINT2_LON@); diff --git a/docs/scripts/basic/withPoints/withPoints.sql b/docs/scripts/basic/withPoints/withPoints.sql index 1a74dfb53..7e103acfd 100644 --- a/docs/scripts/basic/withPoints/withPoints.sql +++ b/docs/scripts/basic/withPoints/withPoints.sql @@ -1,5 +1,6 @@ \o closestedges.txt +CREATE OR REPLACE VIEW points_on_map AS SELECT 1 AS pid, * from pgr_findCloseEdges( 'SELECT id, geom from vehicle_net', ST_SetSRID(ST_Point(@POINT1_LON@, @POINT1_LAT@), 4326) , 0.5) @@ -10,6 +11,7 @@ SELECT 2 AS pid, * from pgr_findCloseEdges( 'SELECT id, geom from vehicle_net', ST_SetSRID(ST_Point(@POINT2_LON@, @POINT2_LAT@), 4326) , 0.5); +SELECT * FROM points_on_map; \o route_withPoints.txt @@ -29,80 +31,76 @@ SELECT * FROM pgr_withPoints( \o wrk_withPoints.txt -- DROP FUNCTION wrk_withPoints(regclass, bigint, bigint); + CREATE OR REPLACE FUNCTION wrk_withPoints( - IN edges_subset REGCLASS, IN lat1 NUMERIC, IN lon1 NUMERIC, IN lat2 NUMERIC, IN lon2 NUMERIC, IN do_debug BOOLEAN DEFAULT false, - OUT seq INTEGER, OUT id BIGINT, OUT seconds FLOAT, OUT name TEXT, OUT length FLOAT, - OUT route_readable TEXT, - OUT route_geom geometry, - OUT azimuth FLOAT + OUT seq INTEGER, OUT id BIGINT, + OUT seconds FLOAT, OUT name TEXT, OUT length FLOAT, + OUT azimuth FLOAT, OUT readable TEXT, + OUT geom GEOMETRY ) -- signature ends RETURNS SETOF record AS $BODY$ DECLARE - closest_query TEXT; + points_sql TEXT; resuts_query TEXT; - additional_query TEXT; final_query TEXT; BEGIN + -- 0 - closest_query := format( - $cq$SELECT 1 AS pid, * from pgr_findCloseEdges( - $q1$ SELECT id, geom from %1$I $q1$, - ST_SetSRID(ST_Point(%2$s, %3$s), 4326) , 0.5) + points_sql := format( + $cq$ + SELECT 1 AS pid, * from pgr_findCloseEdges( + $q1$ SELECT id, geom FROM vehicle_net $q1$, + ST_SetSRID(ST_Point(%1$s, %2$s), 4326) , 0.5) UNION SELECT 2 AS pid, * from pgr_findCloseEdges( - $q1$ SELECT id, geom from %1$I $q1$, - ST_SetSRID(ST_Point(%4$s, %5$s), 4326) , 0.5) - $cq$, edges_subset, lon1, lat1, lon2, lat2); + $q1$ SELECT id, geom FROM vehicle_net $q1$, + ST_SetSRID(ST_Point(%3$s, %4$s), 4326) , 0.5) + $cq$, lon1, lat1, lon2, lat2); -- 1 resuts_query := format( $$SELECT seq, edge AS id, node, cost AS seconds FROM pgr_withPoints( - 'SELECT * FROM %1$I', - '%2$s', + 'SELECT * FROM vehicle_penalized_net', + '%1$s', -1, -2) - $$, edges_subset, closest_query); + $$, points_sql); -- 2 - additional_query := format( - $$SELECT - seq, id, seconds, name, length, - CASE - WHEN node = source THEN ST_AsText(geom) - ELSE ST_AsText(ST_Reverse(geom)) - END AS readable, - - CASE - WHEN node = source THEN geom - ELSE ST_Reverse(geom) - END AS geom - FROM results - LEFT JOIN %1$I USING (id) - ORDER BY seq - $$, edges_subset); + final_query := ' + WITH + results AS (' || resuts_query || ' ), + + additional AS ( + SELECT + seq, id, seconds, name, length, + CASE + WHEN node = source THEN geom + ELSE ST_Reverse(geom) + END AS geom + FROM results + LEFT JOIN vehicle_net USING (id) + ORDER BY seq) + + SELECT seq, id, seconds, name, length, + degrees(ST_azimuth(ST_StartPoint(geom), ST_EndPoint(geom))) AS azimuth, + ST_AsText(geom), geom + FROM additional ORDER BY seq; + '; -- 3 - final_query := - 'WITH - results AS (' || resuts_query || '), - additional AS ( ' || additional_query || ') - SELECT *, degrees(ST_azimuth(ST_StartPoint(geom), ST_EndPoint(geom))) AS azimuth - FROM additional ORDER BY seq'; - - -- 4 - IF do_debug THEN RAISE NOTICE '%', final_query; RETURN; @@ -117,29 +115,19 @@ LANGUAGE plpgsql; \o use_fn_1.txt SELECT DISTINCT name -FROM wrk_withPoints( - 'vehicle_net', - @POINT1_LAT@, @POINT1_LON@, - @POINT2_LAT@, @POINT2_LON@); +FROM wrk_withPoints(@POINT1_LAT@, @POINT1_LON@, @POINT2_LAT@, @POINT2_LON@); \o use_fn_2.txt SELECT * -FROM wrk_withPoints( - 'taxi_net', - @POINT1_LAT@, @POINT1_LON@, - @POINT2_LAT@, @POINT2_LON@, - true); +FROM wrk_withPoints(@POINT1_LAT@, @POINT1_LON@, @POINT2_LAT@, @POINT2_LON@, true); \o use_fn_3.txt +CREATE OR REPLACE VIEW example AS SELECT * -INTO example -FROM wrk_withPoints( - 'walk_net', - @POINT1_LAT@, @POINT1_LON@, - @POINT2_LAT@, @POINT2_LON@); +FROM wrk_withPoints(@POINT1_LAT@, @POINT1_LON@, @POINT2_LAT@, @POINT2_LON@); -SELECT * FROM example; +SELECT seq, name FROM example; \o file_end.txt