File: to_postgres.hpp

package info (click to toggle)
pgrouting 4.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 17,332 kB
  • sloc: cpp: 21,315; sql: 10,419; ansic: 9,795; perl: 1,142; sh: 919; javascript: 314; xml: 182; makefile: 29
file content (217 lines) | stat: -rw-r--r-- 6,791 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*PGR-GNU*****************************************************************
File: to_postgres.hpp

Copyright (c) 2025-2026 pgRouting developers
Mail: project@pgrouting.org

------

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

 ********************************************************************PGR-GNU*/

#ifndef INCLUDE_CPP_COMMON_TO_POSTGRES_HPP_
#define INCLUDE_CPP_COMMON_TO_POSTGRES_HPP_
#pragma once

#include <vector>
#include <cstddef>

#include "c_types/contractionHierarchies_rt.h"
#include "c_types/iid_t_rt.h"
#include "c_types/routes_t.h"

#include "cpp_common/path.hpp"
#include "cpp_common/base_graph.hpp"
#include "cpp_common/alloc.hpp"
#include "cpp_common/identifiers.hpp"


namespace pgrouting {
namespace to_postgres {
namespace detail {

/** @brief Count results that are going to be passed to postgres */
size_t count_rows(const std::vector<std::vector<double>>&);

}  // namespace detail

/** @brief Vector of vertices id are saved on a C array
 *
 * @param[in] graph Created graph with the base Graph
 * @param[in] data data[i] -> the ith element of the vector contains the vertex id
 * @param[out] count The size of the vector
 * @param[out] tuples The C array of bigint
 *
 * bigint results[i]
 */
template <class G>
void get_vertexId(
            const G &graph,
            const std::vector<typename G::V> &data,
            size_t &count,
            int64_t* &tuples) {
    count = data.size();
    tuples = pgrouting::pgr_alloc(count, tuples);

    size_t seq = 0;
    for (auto const &v : data) {
        tuples[seq] = graph.graph[v].id;
        ++seq;
    }
}

/** @brief Stored results on a vector are saved on a C array
 *
 * @param[in] graph Created graph with the base Graph
 * @param[in] results results[i] -> the ith element of the vector contains the results
 * @param[out] result_count The size of the vector
 * @param[out] result_tuples The C array of <bigint, bigint, float>
 *
 * <bigint, bigint, float> =  < i , 0, results[i] >
 *
 * Currently works for pgr_betweennessCentrality
 */
template <class G>
void vector_to_tuple(
            const G &graph,
            const std::vector<double> results,
            size_t &result_count,
            IID_t_rt **result_tuples) {
    result_count = results.size();
    *result_tuples = pgrouting::pgr_alloc(result_count, (*result_tuples));

    size_t seq = 0;
    for (typename G::V v_i = 0; v_i < graph.num_vertices(); ++v_i) {
        (*result_tuples)[seq].from_vid = graph[v_i].id;
        /*
         * These 2 lines are specifically for pgr_betweennessCentrality
         */
        (*result_tuples)[seq].to_vid = 0;
        (*result_tuples)[seq].cost = graph.is_directed()? results[v_i] / 2.0 : results[v_i];
        seq++;
    }
}

/** @brief Stored results on a vector are saved on a C array
 *
 * @param[in] graph Created graph with the base Graph
 * @param[in] matrix matrix[i,j] -> the i,j element contains the results
 * @param[out] tupcount the size of the C array
 * @param[out] tuples The C array of <bigint, bigint, float>
 *
 * <bigint, bigint, float> =  <i , j, results[i,j]>
 *
 * Currently works for
 * - pgr_johnson
 * - pgr_floydWarshall
 */
template <class G>
void matrix_to_tuple(
        const G &graph,
        const std::vector<std::vector<double>> &matrix,
        size_t &tupcount,
        IID_t_rt* &tuples) {
    tupcount = detail::count_rows(matrix);
    tuples = pgr_alloc(tupcount, tuples);

    size_t seq = 0;
    for (typename G::V v_i = 0; v_i < graph.num_vertices(); v_i++) {
        for (typename G::V v_j = 0; v_j < graph.num_vertices(); v_j++) {
            if (v_i == v_j) continue;
            if (matrix[v_i][v_j] != (std::numeric_limits<double>::max)()) {
                tuples[seq].from_vid = graph[v_i].id;
                tuples[seq].to_vid = graph[v_j].id;
                tuples[seq].cost =  matrix[v_i][v_j];
                seq++;
            }
        }
    }
}

/** @brief returns results to the SQL function
    @param [in] graph created graph
    @param [out] return_tuples tuples containing the results to pass to the SQL function
    @param [out] count string stream containing log information

  Currently works for pgr_contractionHierarchies
*/
template <class G>
void graph_to_tuple(
        G &graph,
        contractionHierarchies_rt **return_tuples,
        size_t *count) {
    using pgrouting::pgr_alloc;
    auto modified_vertices(graph.get_modified_vertices());
    auto shortcut_edges(graph.get_shortcuts());

    (*count) = modified_vertices.size() + shortcut_edges.size();
    (*return_tuples) = pgr_alloc((*count), (*return_tuples));
    size_t sequence = 0;

    for (const auto id : modified_vertices) {
        auto v = graph.get_V(id);
        int64_t* contracted_vertices = NULL;
        auto vids = graph[v].contracted_vertices();
        int64_t o = graph.get_vertex_order(id);
        int64_t m = graph.get_vertex_metric(id);

        contracted_vertices = pgr_alloc(vids.size(), contracted_vertices);

        int count = 0;
        for (const auto id : vids) {
            contracted_vertices[count++] = id;
        }
        (*return_tuples)[sequence] = {
            id,
            const_cast<char*>("v"),
            -1, -1, -1.00,
            contracted_vertices,
            count,
            o, m};

        ++sequence;
    }

    int64_t eid = 0;
    for (auto e : shortcut_edges) {
        auto edge = graph[e];
        int64_t* contracted_vertices = NULL;
        const auto vids(edge.contracted_vertices());
        pgassert(!vids.empty());

        contracted_vertices = pgr_alloc(vids.size(), contracted_vertices);
        int count = 0;
        for (const auto vid : vids) {
            contracted_vertices[count++] = vid;
        }
        (*return_tuples)[sequence] = {
            --eid,
            const_cast<char*>("e"),
            edge.source, edge.target, edge.cost,
            contracted_vertices, count, -1, -1};
        ++sequence;
    }
}

/*
 * @brief Via Routes save on a C array
 */
size_t get_viaRoute(std::deque<pgrouting::Path>&, Routes_t**);

}  // namespace to_postgres
}  // namespace pgrouting

#endif  // INCLUDE_CPP_COMMON_TO_POSTGRES_HPP_