summaryrefslogtreecommitdiff
path: root/web/lib/api/v4/relation.rb
blob: 32af96cca1bff7ecd6c61ff19c943e26c8177ad2 (plain)
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
# web/lib/api/v4/relation.rb

class Taginfo < Sinatra::Base

    api(4, 'relation/roles', {
        :description => 'Member role statistics for a relation of given type.',
        :parameters => {
            :rtype => 'Relation type (required).',
            :query => 'Only show results where the role matches this query (substring match, optional).'
        },
        :paging => :optional,
        :sort => %w( role count_all_members count_node_members count_way_members count_relation_members ),
        :result => paging_results([
            [:rtype,                           :STRING, 'Relation type'],
            [:role,                            :STRING, 'Relation member role.'],
            [:count_all_members,               :INT,    'Number of members with this role.'],
            [:count_all_members_fraction,      :FLOAT,  'Number of members with this role devided by all members.'],
            [:count_node_members,              :INT,    'Number of members of type node with this role.'],
            [:count_node_members_fraction,     :FLOAT,  'Number of members of type node with this role devided by all members of type node.'],
            [:count_way_members,               :INT,    'Number of members of type way with this role.'],
            [:count_way_members_fraction,      :FLOAT,  'Number of members of type way with this role devided by all members of type way.'],
            [:count_relation_members,          :INT,    'Number of members of type relation with this role.'],
            [:count_relation_members_fraction, :FLOAT,  'Number of members of type relation with this role devided by all members of type relation.']
        ]),
        :example => { :rtype => 'multipolygon', :page => 1, :rp => 10 },
        :ui => '/relations/multipolygon#roles'
    }) do
        rtype = params[:rtype]

        relation_type_info = @db.select('SELECT * FROM relation_types').
            condition("rtype=?", rtype).
            execute()[0]

        total = @db.count('relation_roles').
            condition("rtype=?", rtype).
            condition_if("role LIKE ? ESCAPE '@'", like_contains(params[:query])).
            get_first_value().to_i

        res = @db.select('SELECT * FROM relation_roles').
            condition("rtype=?", rtype).
            condition_if("role LIKE ? ESCAPE '@'", like_contains(params[:query])).
            order_by(@ap.sortname, @ap.sortorder) { |o|
                o.role
                o.count_all_members      :count_all
                o.count_node_members     :count_nodes
                o.count_way_members      :count_ways
                o.count_relation_members :count_relations
            }.
            paging(@ap).
            execute()

        return JSON.generate({
            :page  => @ap.page,
            :rp    => @ap.results_per_page,
            :total => total,
            :url   => request.url,
            :data  => res.map{ |row| {
                :rtype                           =>  row['rtype'],
                :role                            =>  row['role'],
                :count_all_members               =>  row['count_all'].to_i,
                :count_all_members_fraction      => (row['count_all'].to_f / relation_type_info['members_all'].to_i).round_to(4),
                :count_node_members              =>  row['count_nodes'].to_i,
                :count_node_members_fraction     =>  relation_type_info['members_nodes'].to_i == 0 ? 0 : (row['count_nodes'].to_f / relation_type_info['members_nodes'].to_i).round_to(4),
                :count_way_members               =>  row['count_ways'].to_i,
                :count_way_members_fraction      =>  relation_type_info['members_ways'].to_i == 0 ? 0 : (row['count_ways'].to_f / relation_type_info['members_ways'].to_i).round_to(4),
                :count_relation_members          =>  row['count_relations'].to_i,
                :count_relation_members_fraction =>  relation_type_info['members_relations'].to_i == 0 ? 0 : (row['count_relations'].to_f / relation_type_info['members_relations'].to_i).round_to(4),
            } }
        }, json_opts(params[:format]))
    end

    api(4, 'relation/stats', {
        :description => 'Show some database statistics for given relation type.',
        :parameters => { :rtype => 'Relation type (required).' },
        :result => no_paging_results([
            [:type,  :STRING, 'Member type ("all", "nodes", "ways", or "relations")'],
            [:count, :INT,    'Number of members with this type.']
        ]),
        :example => { :rtype => 'multipolygon' },
        :ui => '/relations/multipolygon#overview'
    }) do
        rtype = params[:rtype]
        out = []

        # default values
        ['all', 'nodes', 'ways', 'relations'].each_with_index do |type, n|
            out[n] = { :type => type, :count => 0 }
        end

        @db.select('SELECT * FROM db.relation_types').
            condition('rtype = ?', rtype).
            execute() do |row|
                ['all', 'nodes', 'ways', 'relations'].each_with_index do |type, n|
                    out[n] = {
                        :type   => type,
                        :count  => row['members_' + type].to_i
                    }
                end
            end

        return JSON.generate({
            :total => 4,
            :url   => request.url,
            :data  => out
        }, json_opts(params[:format]))
    end

    api(4, 'relation/wiki_pages', {
        :description => 'Get list of wiki pages in different languages describing a relation type.',
        :parameters => { :rtype => 'Relation type (required)' },
        :paging => :no,
        :result => no_paging_results([
            [:lang,             :STRING, 'Language code.'],
            [:language,         :STRING, 'Language name in its language.'],
            [:language_en,      :STRING, 'Language name in English.'],
            [:title,            :STRING, 'Wiki page title.'],
            [:description,      :STRING, 'Short description of key from wiki page.'],
            [:image,            :HASH,   'Associated image.', [
                [:title,            :STRING, 'Wiki page title of associated image.' ],
                [:width,            :INT,    'Width of image.' ],
                [:height,           :INT,    'Height of image.' ],
                [:mime,             :STRING, 'MIME type of image.' ],
                [:image_url,        :STRING, 'Image URL' ],
                [:thumb_url_prefix, :STRING, 'Prefix of thumbnail URL.' ],
                [:thumb_url_suffix, :STRING, 'Suffix of thumbnail URL.' ]
            ]]
        ]),
        :notes => 'To get the complete thumbnail image URL, concatenate <tt>thumb_url_prefix</tt>, width of image in pixels, and <tt>thumb_url_suffix</tt>. The thumbnail image width must be smaller than <tt>width</tt>, use the <tt>image_url</tt> otherwise.',
        :example => { :rtype => 'multipolygon' },
        :ui => '/relations/multipolygon#wiki'
    }) do
        rtype = params[:rtype]

        res = @db.execute('SELECT * FROM wiki.relation_pages LEFT OUTER JOIN wiki.wiki_images USING (image) WHERE rtype = ? ORDER BY lang', rtype)

        return JSON.generate(res.map{ |row| {
                :lang             => row['lang'],
                :language         => ::Language[row['lang']].native_name,
                :language_en      => ::Language[row['lang']].english_name,
                :title            => row['title'],
                :description      => row['description'],
                :image            => {
                    :title            => row['image'],
                    :width            => row['width'].to_i,
                    :height           => row['height'].to_i,
                    :mime             => row['mime'],
                    :image_url        => row['image_url'],
                    :thumb_url_prefix => row['thumb_url_prefix'],
                    :thumb_url_suffix => row['thumb_url_suffix']
                }
            }
        }, json_opts(params[:format]))
    end

end