Skip to content

Commit b0a8bc6

Browse files
authoredJan 31, 2025··
Merge pull request #2300 from joto/fix-get-node
Fix problem in slim mode with two-state processing of nodes
2 parents f900e2c + 8d1a55e commit b0a8bc6

File tree

3 files changed

+264
-4
lines changed

3 files changed

+264
-4
lines changed
 

‎src/middle-pgsql.cpp

+14-4
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ std::size_t middle_query_pgsql_t::get_way_node_locations_flatnodes(
522522

523523
osmium::Location middle_query_pgsql_t::get_node_location_db(osmid_t id) const
524524
{
525-
auto const res = m_db_connection.exec_prepared("get_node", id);
525+
auto const res = m_db_connection.exec_prepared("get_node_location", id);
526526
if (res.num_tuples() == 0) {
527527
return osmium::Location{};
528528
}
@@ -729,11 +729,14 @@ void build_node(osmid_t id, pg_result_t const &res, int res_num, int offset,
729729
{
730730
osmium::builder::NodeBuilder builder{*buffer};
731731
builder.set_id(id);
732+
builder.set_location(osmium::Location{
733+
(int)std::strtol(res.get_value(res_num, offset + 0), nullptr, 10),
734+
(int)std::strtol(res.get_value(res_num, offset + 1), nullptr, 10)});
732735

733736
if (with_attributes) {
734-
set_attributes_on_builder(&builder, res, res_num, offset);
737+
set_attributes_on_builder(&builder, res, res_num, offset + 3);
735738
}
736-
pgsql_parse_json_tags(res.get_value(res_num, offset + 1), buffer, &builder);
739+
pgsql_parse_json_tags(res.get_value(res_num, offset + 2), buffer, &builder);
737740
}
738741

739742
/**
@@ -1261,7 +1264,7 @@ middle_pgsql_t::get_query_instance()
12611264
m_store_options);
12621265

12631266
if (m_store_options.nodes) {
1264-
mid->prepare("get_node",
1267+
mid->prepare("get_node_location",
12651268
render_template(
12661269
"SELECT id, lon, lat FROM {schema}\"{prefix}_nodes\""
12671270
" WHERE id = $1::int8"));
@@ -1270,6 +1273,13 @@ middle_pgsql_t::get_query_instance()
12701273
render_template(
12711274
"SELECT id, lon, lat FROM {schema}\"{prefix}_nodes\""
12721275
" WHERE id = ANY($1::int8[])"));
1276+
1277+
mid->prepare(
1278+
"get_node",
1279+
render_template("SELECT lon, lat, tags{attribute_columns_use}"
1280+
" FROM {schema}\"{prefix}_nodes\" o"
1281+
" {users_table_access}"
1282+
" WHERE o.id = $1::int8"));
12731283
}
12741284

12751285
mid->prepare("get_way",

‎tests/bdd/flex/node-add.feature

+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
Feature: Adding nodes to a flex database
2+
3+
Background:
4+
Given the style file 'test_output_flex_node.lua'
5+
6+
And the OSM data
7+
"""
8+
n11 v1 dV Tt1=yes x1 y1
9+
n12 v1 dV Tt2=yes x2 y2
10+
n13 v1 dV Ttboth=yes x3 y3
11+
n14 v1 dV Ttboth=yes x4 y4
12+
r30 v1 dV Tt=ag Mn11@,n12@mark,n13@,n14@mark
13+
"""
14+
When running osm2pgsql flex with parameters
15+
| --slim |
16+
17+
Then table osm2pgsql_test_t1 contains exactly
18+
| node_id |
19+
| 11 |
20+
Then table osm2pgsql_test_t2 contains exactly
21+
| node_id |
22+
| 12 |
23+
Then table osm2pgsql_test_tboth contains exactly
24+
| node_id |
25+
| 13 |
26+
| 14 |
27+
28+
29+
Scenario: node is not relevant
30+
Given an empty grid
31+
And the OSM data
32+
"""
33+
n10 v1 dV Tt=ag x0 y0
34+
r30 v2 dV Tt=ag Mn10@,n11@,n12@mark,n13@,n14@mark
35+
"""
36+
When running osm2pgsql flex with parameters
37+
| --slim | -a |
38+
39+
Then table osm2pgsql_test_t1 contains exactly
40+
| node_id |
41+
| 11 |
42+
Then table osm2pgsql_test_t2 contains exactly
43+
| node_id |
44+
| 12 |
45+
Then table osm2pgsql_test_tboth contains exactly
46+
| node_id |
47+
| 13 |
48+
| 14 |
49+
50+
51+
Scenario: add to t1
52+
Given an empty grid
53+
And the OSM data
54+
"""
55+
n10 v1 dV Tt1=yes x0 y0
56+
r30 v2 dV Tt=ag Mn10@,n11@,n12@mark,n13@,n14@mark
57+
"""
58+
When running osm2pgsql flex with parameters
59+
| --slim | -a |
60+
61+
Then table osm2pgsql_test_t1 contains exactly
62+
| node_id |
63+
| 10 |
64+
| 11 |
65+
Then table osm2pgsql_test_t2 contains exactly
66+
| node_id |
67+
| 12 |
68+
Then table osm2pgsql_test_tboth contains exactly
69+
| node_id |
70+
| 13 |
71+
| 14 |
72+
73+
74+
Scenario: add to t2
75+
Given an empty grid
76+
And the OSM data
77+
"""
78+
n10 v1 dV Tt2=yes x0 y0
79+
r30 v2 dV Tt=ag Mn10@mark,n11@,n12@mark,n13@,n14@mark
80+
"""
81+
When running osm2pgsql flex with parameters
82+
| --slim | -a |
83+
84+
Then table osm2pgsql_test_t1 contains exactly
85+
| node_id |
86+
| 11 |
87+
Then table osm2pgsql_test_t2 contains exactly
88+
| node_id | rel_ids |
89+
| 10 | {30} |
90+
| 12 | {30} |
91+
Then table osm2pgsql_test_tboth contains exactly
92+
| node_id |
93+
| 13 |
94+
| 14 |
95+
96+
97+
Scenario: add to t1 and t2
98+
Given an empty grid
99+
And the OSM data
100+
"""
101+
n10 v1 dV Tt1=yes,t2=yes x0 y0
102+
r30 v2 dV Tt=ag Mn10@mark,n11@,n12@mark,n13@,n14@mark
103+
"""
104+
When running osm2pgsql flex with parameters
105+
| --slim | -a |
106+
107+
Then table osm2pgsql_test_t1 contains exactly
108+
| node_id |
109+
| 10 |
110+
| 11 |
111+
Then table osm2pgsql_test_t2 contains exactly
112+
| node_id | rel_ids |
113+
| 10 | {30} |
114+
| 12 | {30} |
115+
Then table osm2pgsql_test_tboth contains exactly
116+
| node_id |
117+
| 13 |
118+
| 14 |
119+
120+
121+
Scenario: add to tboth (only stage1)
122+
Given an empty grid
123+
And the OSM data
124+
"""
125+
n10 v1 dV Ttboth=yes x0 y0
126+
r30 v2 dV Tt=ag Mn10@,n11@,n12@mark,n13@,n14@mark
127+
"""
128+
When running osm2pgsql flex with parameters
129+
| --slim | -a |
130+
131+
Then table osm2pgsql_test_t1 contains exactly
132+
| node_id |
133+
| 11 |
134+
Then table osm2pgsql_test_t2 contains exactly
135+
| node_id |
136+
| 12 |
137+
Then table osm2pgsql_test_tboth contains exactly
138+
| node_id | rel_ids |
139+
| 10 | NULL |
140+
| 13 | NULL |
141+
| 14 | {30} |
142+
143+
144+
Scenario: add to tboth (stage1 and stage2)
145+
Given an empty grid
146+
And the OSM data
147+
"""
148+
n10 v1 dV Ttboth=yes x0 y0
149+
r30 v2 dV Tt=ag Mn10@mark,n11@,n12@mark,n13@,n14@mark
150+
"""
151+
When running osm2pgsql flex with parameters
152+
| --slim | -a |
153+
154+
Then table osm2pgsql_test_t1 contains exactly
155+
| node_id |
156+
| 11 |
157+
Then table osm2pgsql_test_t2 contains exactly
158+
| node_id |
159+
| 12 |
160+
Then table osm2pgsql_test_tboth contains exactly
161+
| node_id | rel_ids |
162+
| 10 | {30} |
163+
| 13 | NULL |
164+
| 14 | {30} |

‎tests/data/test_output_flex_node.lua

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
2+
local tables = {}
3+
4+
tables.t1 = osm2pgsql.define_node_table('osm2pgsql_test_t1', {
5+
{ column = 'tags', type = 'hstore' },
6+
{ column = 'geom', type = 'point', not_null = true },
7+
})
8+
9+
tables.t2 = osm2pgsql.define_node_table('osm2pgsql_test_t2', {
10+
{ column = 'tags', type = 'hstore' },
11+
{ column = 'rel_ids', type = 'text' },
12+
{ column = 'geom', type = 'point', not_null = true },
13+
})
14+
15+
tables.tboth = osm2pgsql.define_node_table('osm2pgsql_test_tboth', {
16+
{ column = 'tags', type = 'hstore' },
17+
{ column = 'rel_ids', type = 'text' },
18+
{ column = 'geom', type = 'point', not_null = true },
19+
})
20+
21+
local n2r = {}
22+
23+
local function get_ids(data)
24+
if data then
25+
local ids = {}
26+
for rel_id, _ in pairs(data) do
27+
ids[#ids + 1] = rel_id
28+
end
29+
table.sort(ids)
30+
return '{' .. table.concat(ids, ',') .. '}'
31+
end
32+
end
33+
34+
function osm2pgsql.process_node(object)
35+
if object.tags.t1 then
36+
tables.t1:insert{
37+
tags = object.tags,
38+
geom = object:as_point()
39+
}
40+
end
41+
42+
if osm2pgsql.stage == 2 and object.tags.t2 then
43+
local ids = get_ids(n2r[object.id])
44+
if ids then
45+
tables.t2:insert{
46+
rel_ids = ids,
47+
geom = object:as_point()
48+
}
49+
end
50+
end
51+
52+
if object.tags.tboth then
53+
local ids = get_ids(n2r[object.id])
54+
tables.tboth:insert{
55+
tags = object.tags,
56+
rel_ids = ids,
57+
geom = object:as_point()
58+
}
59+
end
60+
end
61+
62+
local function node_member_ids(relation)
63+
local ids = {}
64+
for _, member in ipairs(relation.members) do
65+
if member.type == 'n' and member.role == 'mark' then
66+
ids[#ids + 1] = member.ref
67+
end
68+
end
69+
return ids
70+
end
71+
72+
function osm2pgsql.select_relation_members(relation)
73+
return { nodes = node_member_ids(relation) }
74+
end
75+
76+
function osm2pgsql.process_relation(object)
77+
for _, member in ipairs(object.members) do
78+
if member.type == 'n' and member.role == 'mark' then
79+
if not n2r[member.ref] then
80+
n2r[member.ref] = {}
81+
end
82+
n2r[member.ref][object.id] = true
83+
end
84+
end
85+
end
86+

0 commit comments

Comments
 (0)
Please sign in to comment.