Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 90 additions & 4 deletions doc/planar/pgr_makeMaximalPlanar.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,113 @@

.. index::
single: Planar Family ; pgr_makeMaximalPlanar - Experimental
single: makeMaximalPlanar - Experimental on v4.2
single: makeMaximalPlanar - Experimental on v4.1

|

``pgr_makeMaximalPlanar`` - Experimental
===============================================================================

``pgr_makeMaximalPlanar`` — [TBD]
``pgr_makeMaximalPlanar`` — Returns the set of edges needed to make a planar graph maximal planar.

.. include:: experimental.rst
:start-after: warning-begin
:end-before: end-warning

.. rubric:: Availability

.. rubric:: Version 4.2.0
.. rubric:: Version 4.1.0

* New experimental function.


Description
-------------------------------------------------------------------------------

[TBD]
A graph is planar if it can be drawn in two-dimensional space with no two of its
edges crossing. A planar graph is considered **maximal planar** (or fully triangulated)
if no additional edges can be added to it without violating its planarity. In a
maximal planar graph, every face (including the outer face) is a triangle.

``pgr_makeMaximalPlanar`` identifies the missing edges that need to be added to an
existing planar graph to make it maximal planar.

The main characteristics are:

* Works for **undirected** graphs.
* Returns a list of all new edges which are needed to triangulate the graph and make it maximal planar.
* If the input graph is not planar, it returns an empty set.
* The algorithm does not consider traversal costs in the calculations.
* The algorithm does not consider geometric topology in the calculations.
* Running time: :math:`O(|V| + |E|)`

|Boost| Boost Graph Inside

Signatures
-------------------------------------------------------------------------------

.. admonition:: \ \
:class: signatures

| pgr_makeMaximalPlanar(`Edges SQL`_)

| Returns set of |result-component-make|
| OR EMPTY SET

:Example: List of edges that are needed to make the graph maximal planar.

.. literalinclude:: makeMaximalPlanar.queries
:start-after: -- q1
:end-before: -- q2

Parameters
-------------------------------------------------------------------------------

.. include:: pgRouting-concepts.rst
:start-after: only_edge_param_start
:end-before: only_edge_param_end

Inner Queries
-------------------------------------------------------------------------------

Edges SQL
...............................................................................

.. include:: pgRouting-concepts.rst
:start-after: basic_edges_sql_start
:end-before: basic_edges_sql_end

Result columns
-------------------------------------------------------------------------------

Returns set of |result-component-make|

.. list-table::
:width: 81
:widths: auto
:header-rows: 1

* - Column
- Type
- Description
* - ``seq``
- ``BIGINT``
- Sequential value starting from **1**.
* - ``start_vid``
- ``BIGINT``
- Identifier of the first end point vertex of the edge.
* - ``end_vid``
- ``BIGINT``
- Identifier of the second end point vertex of the edge.

See Also
-------------------------------------------------------------------------------

* `Boost: make_maximal_planar
<https://www.boost.org/libs/graph/doc/make_maximal_planar.html>`__
* :doc:`sampledata`

.. rubric:: Indices and tables

* :ref:`genindex`
* :ref:`search`
32 changes: 32 additions & 0 deletions docqueries/planar/makeMaximalPlanar.result
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
BEGIN;
BEGIN
SET client_min_messages TO NOTICE;
SET
/* :file: This file is part of the pgRouting project.
:copyright: Copyright (c) 2020-2026 pgRouting developers
:license: Creative Commons Attribution-Share Alike 3.0 https://creativecommons.org/licenses/by-sa/3.0 */
/* -- q1 */
SELECT * FROM pgr_makeMaximalPlanar(
'SELECT id, source, target, cost, reverse_cost FROM edges'
);
seq | start_vid | end_vid
-----+-----------+---------
1 | 7 | 9
2 | 10 | 5
3 | 3 | 11
4 | 1 | 7
5 | 1 | 6
6 | 1 | 5
7 | 1 | 10
8 | 1 | 11
9 | 17 | 15
10 | 17 | 10
11 | 17 | 6
12 | 17 | 7
13 | 17 | 8
14 | 15 | 11
15 | 9 | 11
16 | 9 | 12
17 | 16 | 12
(17 rows)

/* -- q2 */
ROLLBACK;
ROLLBACK
1 change: 1 addition & 0 deletions docqueries/planar/test.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
'any' => {
'files' => [qw(
isPlanar.pg
makeMaximalPlanar.pg
)]
},

Expand Down
49 changes: 42 additions & 7 deletions include/planar/makeMaximalPlanar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#include <boost/graph/connected_components.hpp>

#include "c_types/ii_t_rt.h"
#include "cpp_common/edge_t.hpp"
#include "cpp_common/messages.hpp"
#include "cpp_common/base_graph.hpp"
#include "cpp_common/interruption.hpp"
Expand All @@ -58,7 +59,47 @@ class Pgr_makeMaximalPlanar : public pgrouting::Pgr_messages {
typedef typename G::E_i E_i;

std::vector<II_t_rt> makeMaximalPlanar(G &graph) {
return generateMakeMaximalPlanar(graph);
/* Find how many connected components this graph has */
std::vector<size_t> component(boost::num_vertices(graph.graph));
auto num_components = boost::connected_components(
graph.graph, &component[0]);

if (num_components == 1) {
/* Simple case: single connected graph — process directly */
return generateMakeMaximalPlanar(graph);
}

/* Multi-component case: split the graph into connected sub-graphs */
log << "Graph has " << num_components
<< " connected components. Processing each independently.\n";

/* Collect edges per component using vertex component labels */
std::vector<std::vector<Edge_t>> comp_edges(num_components);
E_i ei, ei_end;
for (boost::tie(ei, ei_end) = edges(graph.graph);
ei != ei_end; ++ei) {
V src_v = boost::source(*ei, graph.graph);
size_t c = component[src_v];
Edge_t e;
e.id = graph[*ei].id;
e.source = graph[src_v].id;
e.target = graph[boost::target(*ei, graph.graph)].id;
e.cost = graph[*ei].cost;
e.reverse_cost = -1;
comp_edges[c].push_back(e);
}

std::vector<II_t_rt> all_results;
for (size_t c = 0; c < num_components; ++c) {
if (comp_edges[c].empty()) continue;
G sub_graph;
sub_graph.insert_edges(comp_edges[c]);
auto sub_results = generateMakeMaximalPlanar(sub_graph);
all_results.insert(
all_results.end(),
sub_results.begin(), sub_results.end());
}
return all_results;
}

private:
Expand Down Expand Up @@ -119,12 +160,6 @@ class Pgr_makeMaximalPlanar : public pgrouting::Pgr_messages {
return std::vector<II_t_rt>();
}

std::vector<size_t> component(boost::num_vertices(graph.graph));
auto num_components = boost::connected_components(graph.graph, &component[0]);
if (num_components > 1) {
throw std::string("Graph is not connected. Please run pgr_makeConnected first.");
}

std::vector<II_t_rt> results;
planar_visitor vis(results, graph);

Expand Down
50 changes: 47 additions & 3 deletions locale/en/LC_MESSAGES/pgrouting_doc_strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: pgRouting v4.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-06-05 13:26+0000\n"
"POT-Creation-Date: 2026-06-16 15:22+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down Expand Up @@ -12897,10 +12897,54 @@ msgid ""
msgstr ""

#, fuzzy
msgid "pgr_makeMaximalPlanar"
msgid "``pgr_makeMaximalPlanar`` - Experimental"
msgstr "pgr_isPlanar"

msgid "(Documentation to be added later)"
msgid ""
"``pgr_makeMaximalPlanar`` — Returns the set of edges needed to make a planar "
"graph maximal planar."
msgstr ""

msgid ""
"A graph is planar if it can be drawn in two-dimensional space with no two of "
"its edges crossing. A planar graph is considered **maximal planar** (or "
"fully triangulated) if no additional edges can be added to it without "
"violating its planarity. In a maximal planar graph, every face (including "
"the outer face) is a triangle."
msgstr ""

msgid ""
"``pgr_makeMaximalPlanar`` identifies the missing edges that need to be added "
"to an existing planar graph to make it maximal planar."
msgstr ""

msgid ""
"Returns a list of all new edges which are needed to triangulate the graph "
"and make it maximal planar."
msgstr ""

msgid "If the input graph is not planar, it returns an empty set."
msgstr ""

msgid "The algorithm does not consider traversal costs in the calculations."
msgstr ""

msgid "The algorithm does not consider geometric topology in the calculations."
msgstr ""

msgid "Running time: :math:`O(|V| + |E|)`"
msgstr ""

#, fuzzy
msgid "pgr_makeMaximalPlanar(`Edges SQL`_)"
msgstr "pgr_isPlanar"

msgid "List of edges that are needed to make the graph maximal planar."
msgstr ""

msgid ""
"`Boost: make_maximal_planar <https://www.boost.org/libs/graph/doc/"
"make_maximal_planar.html>`__"
msgstr ""

msgid "``pgr_maxCardinalityMatch``"
Expand Down
36 changes: 33 additions & 3 deletions locale/pot/pgrouting_doc_strings.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: pgRouting v4.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-06-05 13:26+0000\n"
"POT-Creation-Date: 2026-06-16 15:22+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down Expand Up @@ -10990,10 +10990,40 @@ msgstr ""
msgid "`Boost: make connected <https://www.boost.org/libs/graph/doc/make_connected.html>`__"
msgstr ""

msgid "pgr_makeMaximalPlanar"
msgid "``pgr_makeMaximalPlanar`` - Experimental"
msgstr ""

msgid "(Documentation to be added later)"
msgid "``pgr_makeMaximalPlanar`` — Returns the set of edges needed to make a planar graph maximal planar."
msgstr ""

msgid "A graph is planar if it can be drawn in two-dimensional space with no two of its edges crossing. A planar graph is considered **maximal planar** (or fully triangulated) if no additional edges can be added to it without violating its planarity. In a maximal planar graph, every face (including the outer face) is a triangle."
msgstr ""

msgid "``pgr_makeMaximalPlanar`` identifies the missing edges that need to be added to an existing planar graph to make it maximal planar."
msgstr ""

msgid "Returns a list of all new edges which are needed to triangulate the graph and make it maximal planar."
msgstr ""

msgid "If the input graph is not planar, it returns an empty set."
msgstr ""

msgid "The algorithm does not consider traversal costs in the calculations."
msgstr ""

msgid "The algorithm does not consider geometric topology in the calculations."
msgstr ""

msgid "Running time: :math:`O(|V| + |E|)`"
msgstr ""

msgid "pgr_makeMaximalPlanar(`Edges SQL`_)"
msgstr ""

msgid "List of edges that are needed to make the graph maximal planar."
msgstr ""

msgid "`Boost: make_maximal_planar <https://www.boost.org/libs/graph/doc/make_maximal_planar.html>`__"
msgstr ""

msgid "``pgr_maxCardinalityMatch``"
Expand Down
Loading