source: subversion/sites/www.openstreetbrowser.org/src/sql/01_multiple_functions.sql @ 29773

Last change on this file since 29773 was 20108, checked in by skunk, 10 years ago

Rather define unit conversion in seperate table

File size: 3.7 KB
Line 
1create or replace function oneof_is(text[], text)
2  returns bool
3  as $$
4declare
5  arr alias for $1;
6  val alias for $2;
7  i   int:=1;
8begin
9  for i in array_lower(arr, 1)..array_upper(arr, 1) loop
10    if arr[i]=val then
11      return true;
12    end if;
13  end loop;
14  return false;
15end;
16$$ language 'plpgsql';
17
18drop table if exists dimension_units;
19create table dimension_units (
20  id            text    not null,
21  factor        float   not null,
22  description   text    null,
23  primary key(id)
24);
25
26-- length
27insert into dimension_units values ('m'   , 1    );
28insert into dimension_units values ('mm'  , 0.001);
29insert into dimension_units values ('cm'  , 0.011);
30insert into dimension_units values ('km'  , 1000);
31insert into dimension_units values ('in'  , 0.0254);
32insert into dimension_units values ('inch', 0.0254);
33insert into dimension_units values ('ft'  , 0.3048);
34insert into dimension_units values ('feet', 0.3048);
35insert into dimension_units values ('yd'  , 0.9144);
36insert into dimension_units values ('yard', 0.9144);
37insert into dimension_units values ('mile', 1609.344);
38insert into dimension_units values ('miles',1609.344);
39insert into dimension_units values ('league',4828.032);
40insert into dimension_units values ('leagues',4828.032);
41
42-- area
43insert into dimension_units values ('acre', 4046.8564224);
44insert into dimension_units values ('acres',4046.8564224);
45insert into dimension_units values ('m2'  , 1);
46insert into dimension_units values ('m^2' , 1);
47insert into dimension_units values ('m²'  , 1);
48insert into dimension_units values ('km2' , 1000000);
49insert into dimension_units values ('km^2', 1000000);
50insert into dimension_units values ('km²' , 1000000);
51insert into dimension_units values ('a'   , 100);
52insert into dimension_units values ('ha'  , 10000);
53
54-- voltage
55insert into dimension_units values ('V'   , 1);
56insert into dimension_units values ('kV'  , 1000);
57
58create or replace function parse_number(text)
59  returns float
60  as $$
61declare
62  val      alias for $1;
63  val_n    text;
64  val_u    text;
65  numval   float;
66  unit_fac float;
67begin
68  if val ~ E'^([0-9\.,]+) *(.*)$' then
69    val_n:=substring(val from E'^([0-9\.,]+) *.*');
70    val_u:=substring(val from E'^[0-9\.,]+ *(.*)');
71
72    if val_n similar to E'^[0-9]+$' then
73      numval=cast(val_n as float);
74    elsif val_n similar to E'^[0-9]*\.[0-9]+$' then
75      numval=cast(val_n as float);
76    elsif val_n similar to E'^[0-9]*,[0-9]+$' then
77      numval=cast(replace(val_n, ',', '.') as float);
78    else
79      return null;
80    end if;
81
82    unit_fac:=(select factor from dimension_units where id=val_u);
83    if(unit_fac is null) then
84      unit_fac:=1;
85    end if;
86
87    return numval*unit_fac;
88  end if;
89
90  return null;
91end;
92$$ language 'plpgsql';
93
94create or replace function is_between(text, float, bool, float, bool)
95  returns bool
96  as $$
97declare
98  val      alias for $1;
99  numval   float;
100  floor    alias for $2;
101  ceil     alias for $4;
102  floor_eq alias for $3;
103  ceil_eq  alias for $5;
104begin
105  numval:=parse_number(val);
106
107  if(numval is null) then
108    return false;
109  end if;
110
111  if(floor is null) then
112  elsif(floor_eq=true) then
113    if numval<floor then
114      return false;
115    end if;
116  else
117    if numval<=floor then
118      return false;
119    end if;
120  end if;
121
122  if(ceil is null) then
123  elsif(ceil_eq=true) then
124    if numval>ceil then
125      return false;
126    end if;
127  else
128    if numval>=ceil then
129      return false;
130    end if;
131  end if;
132
133  return true;
134end;
135$$ language 'plpgsql';
136
137create or replace function oneof_between(text[], int, bool, int, bool)
138  returns bool
139  as $$
140declare
141  arr alias for $1;
142  i   int:=1;
143begin
144  for i in array_lower(arr, 1)..array_upper(arr, 1) loop
145    if is_between(arr[i], $2, $3, $4, $5) then
146      return true;
147    end if;
148  end loop;
149  return false;
150end;
151$$ language 'plpgsql';
Note: See TracBrowser for help on using the repository browser.