Skip to content

Commit

Permalink
Clean up electrification columns and SQL functions (#88)
Browse files Browse the repository at this point in the history
With the power of lua's multi-return, the SQL functions to calculate
electrification fields are not needed anymore.
  • Loading branch information
hiddewie authored Aug 3, 2024
1 parent c6617cf commit dc4f5b9
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 126 deletions.
57 changes: 35 additions & 22 deletions import/openrailwaymap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,18 @@ local railway_line = osm2pgsql.define_table({
{ column = 'maxspeed_forward', type = 'text' },
{ column = 'maxspeed_backward', type = 'text' },
{ column = 'preferred_direction', type = 'text' },
{ column = 'electrified', type = 'text' },
{ column = 'deelectrified', type = 'text' },
{ column = 'frequency', type = 'text' },
{ column = 'voltage', type = 'text' },
{ column = 'frequency', type = 'real' },
{ column = 'voltage', type = 'integer' },
{ column = 'electrification_state', type = 'text' },
{ column = 'future_frequency', type = 'real' },
{ column = 'future_voltage', type = 'integer' },
{ column = 'gauge', type = 'text' },
{ column = 'construction_railway', type = 'text' },
{ column = 'construction_electrified', type = 'text' },
{ column = 'construction_frequency', type = 'text' },
{ column = 'construction_voltage', type = 'text' },
{ column = 'construction_gauge', type = 'text' },
{ column = 'proposed_railway', type = 'text' },
{ column = 'proposed_electrified', type = 'text' },
{ column = 'proposed_frequency', type = 'text' },
{ column = 'proposed_voltage', type = 'text' },
{ column = 'disused_railway', type = 'text' },
{ column = 'abandoned_railway', type = 'text' },
{ column = 'abandoned_name', type = 'text' },
{ column = 'abandoned_electrified', type = 'text' },
{ column = 'razed_railway', type = 'text' },
{ column = 'razed_name', type = 'text' },
{ column = 'preserved_railway', type = 'text' },
Expand Down Expand Up @@ -215,6 +209,29 @@ function train_protection(tags)
return nil, 0
end

local electrification_values = osm2pgsql.make_check_values_func({'contact_line', 'yes', 'rail', 'ground-level_power_supply', '4th_rail', 'contact_line;rail', 'rail;contact_line'})
function electrification_state(tags, ignore_future_states)
local electrified = tags['electrified']

if electrification_values(electrified) then
return 'present', tonumber(tags['voltage']), tonumber(tags['frequency'])
end
if (not ignore_future_states) and electrification_values(tags['construction:electrified']) then
return 'construction', tonumber(tags['construction:voltage']), tonumber(tags['construction:frequency'])
end
if (not ignore_future_states) and electrification_values(tags['proposed:electrified']) then
return 'proposed', tonumber(tags['proposed:voltage']), tonumber(tags['proposed:frequency'])
end
if electrified == 'no' and electrification_values(tags['deelectrified']) then
return 'deelectrified', nil, nil
end
if electrified == 'no' and electrification_values(tags['abandoned:electrified']) then
return 'abandoned', nil, nil
end

return nil, nil, nil
end

-- TODO clean up unneeded tags

local railway_station_values = osm2pgsql.make_check_values_func({'station', 'halt', 'tram_stop', 'service_station', 'yard', 'junction', 'spur_junction', 'crossover', 'site'})
Expand Down Expand Up @@ -419,6 +436,8 @@ function osm2pgsql.process_way(object)
if railway_values(tags.railway) then
local railway_train_protection, railway_train_protection_rank = train_protection(tags)

local current_electrification_state, voltage, frequency = electrification_state(tags, true)
local _, future_voltage, future_frequency = electrification_state(tags, false)
railway_line:insert({
way = object:as_linestring(),
railway = tags['railway'],
Expand All @@ -439,24 +458,18 @@ function osm2pgsql.process_way(object)
maxspeed_forward = tags['maxspeed:forward'],
maxspeed_backward = tags['maxspeed:backward'],
preferred_direction = tags['railway:preferred_direction'],
electrified = tags['electrified'],
deelectrified = tags['deelectrified'],
frequency = tags['frequency'],
voltage = tags['voltage'],
electrification_state = current_electrification_state,
frequency = frequency,
voltage = voltage,
future_frequency = future_frequency,
future_voltage = future_voltage,
gauge = tags['gauge'],
construction_railway = tags['construction:railway'],
construction_electrified = tags['construction:electrified'],
construction_frequency = tags['construction:frequency'],
construction_voltage = tags['construction:voltage'],
construction_gauge = tags['construction:gauge'],
proposed_railway = tags['proposed:railway'],
proposed_electrified = tags['proposed:electrified'],
proposed_frequency = tags['proposed:frequency'],
proposed_voltage = tags['proposed:voltage'],
disused_railway = tags['disused:railway'],
abandoned_railway = tags['abandoned:railway'],
abandoned_name = tags['abandoned:name'],
abandoned_electrified = tags['abandoned:electrified'],
razed_railway = tags['razed:railway'],
razed_name = tags['razed:name'],
preserved_railway = tags['preserved:railway'],
Expand Down
98 changes: 7 additions & 91 deletions import/sql/functions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -292,115 +292,31 @@ BEGIN
END;
$$ LANGUAGE plpgsql;

-- Get state of electrification
-- TODO move to import
CREATE OR REPLACE FUNCTION railway_electrification_state(railway TEXT, electrified TEXT,
deelectrified TEXT, abandoned_electrified TEXT, construction_electrified TEXT,
proposed_electrified TEXT, ignore_future_states BOOLEAN) RETURNS TEXT AS $$
DECLARE
state TEXT;
valid_values TEXT[] := ARRAY['contact_line', 'yes', 'rail', 'ground-level_power_supply', '4th_rail', 'contact_line;rail', 'rail;contact_line'];
BEGIN
state := NULL;
IF electrified = ANY(valid_values) THEN
return 'present';
END IF;
IF electrified = 'no' THEN
state := 'no';
END IF;
IF NOT ignore_future_states AND construction_electrified = ANY(valid_values) THEN
RETURN 'construction';
END IF;
IF NOT ignore_future_states AND proposed_electrified = ANY(valid_values) THEN
RETURN 'proposed';
END IF;
IF state = 'no' AND deelectrified = ANY(valid_values) THEN
RETURN 'deelectrified';
END IF;
IF state = 'no' AND abandoned_electrified = ANY(valid_values) THEN
RETURN 'abandoned';
END IF;
RETURN state;
END;
$$ LANGUAGE plpgsql;

-- Get voltage for given state
CREATE OR REPLACE FUNCTION railway_voltage_for_state(state TEXT, voltage TEXT, construction_voltage TEXT, proposed_voltage TEXT) RETURNS INTEGER AS $$
BEGIN
IF state = 'present' THEN
RETURN railway_to_int(voltage);
END IF;
IF state = 'construction' THEN
RETURN railway_to_int(construction_voltage);
END IF;
IF state = 'proposed' THEN
RETURN railway_to_int(proposed_voltage);
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;

-- Get frequency for given state
CREATE OR REPLACE FUNCTION railway_frequency_for_state(state TEXT, frequency TEXT, construction_frequency TEXT, proposed_frequency TEXT) RETURNS FLOAT AS $$
BEGIN
IF state = 'present' THEN
RETURN railway_to_float(frequency);
END IF;
IF state = 'construction' THEN
RETURN railway_to_float(construction_frequency);
END IF;
IF state = 'proposed' THEN
RETURN railway_to_float(proposed_frequency);
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;

-- Get label for electrification
CREATE OR REPLACE FUNCTION railway_electrification_label(electrified TEXT, deelectrified TEXT,
construction_electrified TEXT, proposed_electrified TEXT, voltage TEXT, frequency TEXT,
construction_voltage TEXT, construction_frequency TEXT, proposed_voltage TEXT,
proposed_frequency TEXT) RETURNS TEXT AS $$
CREATE OR REPLACE FUNCTION railway_electrification_label(voltage INT, frequency REAL) RETURNS TEXT AS $$
DECLARE
volt TEXT;
freq TEXT;
volt_int INTEGER;
kilovolt NUMERIC(3, 1);
volt_text TEXT;
freq_text TEXT;
BEGIN
-- Select right values for voltage and frequency part of the label
IF railway_no_to_null(electrified) IS NOT NULL OR railway_no_to_null(deelectrified) IS NOT NULL THEN
volt := voltage;
freq := frequency;
ELSIF railway_no_to_null(construction_electrified) IS NOT NULL THEN
volt := construction_voltage;
freq := construction_frequency;
ELSIF railway_no_to_null(proposed_electrified) IS NOT NULL THEN
volt := proposed_voltage;
freq := proposed_frequency;
ELSE
RETURN NULL;
END IF;
-- Grounded sections
IF volt = '0' THEN
IF voltage = 0 THEN
RETURN '0V';
END IF;
-- Round voltage nicely
volt_int := railway_to_int(volt);
volt_int := voltage::INT;
IF volt_int < 1000 THEN
volt_text := volt || 'V';
volt_text := voltage || 'V';
ELSIF volt_int % 1000 = 0 THEN
volt_text := (volt_int/1000)::TEXT || 'kV';
ELSE
volt_text := round((volt_int::FLOAT / 1000::FLOAT)::numeric, 1) || 'kV';
END IF;
-- Output voltage and frequency
IF freq = '0' THEN
IF frequency = 0 THEN
RETURN volt_text || ' =';
END IF;
IF freq IS NOT NULL THEN
RETURN volt_text || ' ' || freq || 'Hz';
IF frequency IS NOT NULL THEN
RETURN volt_text || ' ' || frequency || 'Hz';
END IF;
RETURN volt_text;
END;
Expand Down
23 changes: 10 additions & 13 deletions import/sql/tile_views.sql
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ CREATE OR REPLACE VIEW railway_line_high AS
railway_speed_label(speed_arr) AS speed_label,
train_protection_rank,
train_protection,
electrification_state_without_future AS electrification_state,
railway_voltage_for_state(electrification_state_without_future, voltage, construction_voltage, proposed_voltage) AS voltage,
railway_frequency_for_state(electrification_state_without_future, frequency, construction_frequency, proposed_frequency) AS frequency,
electrification_state,
voltage,
frequency,
electrification_label,
railway_voltage_for_state(future_electrification_state, voltage, construction_voltage, proposed_voltage) AS future_voltage,
railway_frequency_for_state(future_electrification_state, frequency, construction_frequency, proposed_frequency) AS future_frequency,
future_voltage,
future_frequency,
railway_to_int(gauge0) AS gaugeint0,
gauge0,
railway_to_int(gauge1) AS gaugeint1,
Expand Down Expand Up @@ -94,15 +94,12 @@ CREATE OR REPLACE VIEW railway_line_high AS
railway_direction_speed_limit(preferred_direction,maxspeed, maxspeed_forward, maxspeed_backward) AS speed_arr,
train_protection_rank,
train_protection,
railway_electrification_state(railway, electrified, deelectrified, abandoned_electrified, NULL, NULL, true) AS electrification_state_without_future,
railway_electrification_label(electrified, deelectrified, construction_electrified, proposed_electrified, voltage, frequency, construction_voltage, construction_frequency, proposed_voltage, proposed_frequency) AS electrification_label,
railway_electrification_state(railway, electrified, deelectrified, abandoned_electrified, construction_electrified, proposed_electrified, false) AS future_electrification_state,
frequency,
electrification_state,
voltage,
construction_frequency,
construction_voltage,
proposed_frequency,
proposed_voltage,
frequency,
railway_electrification_label(COALESCE(voltage, future_voltage), COALESCE(frequency, future_frequency)) AS electrification_label,
future_voltage,
future_frequency,
railway_desired_value_from_list(1, COALESCE(gauge, construction_gauge)) AS gauge0,
railway_desired_value_from_list(2, COALESCE(gauge, construction_gauge)) AS gauge1,
railway_desired_value_from_list(3, COALESCE(gauge, construction_gauge)) AS gauge2,
Expand Down

0 comments on commit dc4f5b9

Please sign in to comment.