-
Notifications
You must be signed in to change notification settings - Fork 0
/
api.go
132 lines (114 loc) · 5.19 KB
/
api.go
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
package main
import (
"encoding/json"
"time"
)
// IncidentFeatureCollection A GeoJSON FeatureCollection representing a collection of incidents
type IncidentFeatureCollection struct {
Type string `json:"type"`
Features []IncidentFeature `json:"features"`
}
// IncidentFeature is a GeoJSON feature for an individual incident (but mostly filled with data from its latest report)
type IncidentFeature struct {
Type string `json:"type"`
UUID string `json:"id"`
Geometry json.RawMessage `json:"geometry"`
Properties IncidentProperties `json:"properties"`
}
// IncidentProperties is a collection of properties for an individual report included in a IncidentFeature GeoJSON response.
type IncidentProperties struct {
ReportUUID string `json:"reportUuid"`
Guid string `json:"guid"`
Title string `json:"title"`
Link string `json:"link"`
Category string `json:"category"`
Pubdate time.Time `json:"pubdate"`
FirstSeen time.Time `json:"firstSeen"`
LastSeen time.Time `json:"lastSeen"`
AlertLevel string `json:"alertLevel"`
Location string `json:"location"`
CouncilArea string `json:"councilArea"`
Status string `json:"status"`
FireType string `json:"fireType"`
Fire bool `json:"fire"`
Size string `json:"size"`
ResponsibleAgency string `json:"responsibleAgency"`
Extra string `json:"extra"`
}
// Takes a slice of incident features and returns it wrapped in a GeoJSON FeatureCollection
func incidentFeatureCollectionForIncidentFeatures(fea []IncidentFeature) IncidentFeatureCollection {
return IncidentFeatureCollection{"FeatureCollection", fea}
}
// Returns a slice of IncidentFeatures. The slice contains the latest report for all incidents marked as current
func currentIncidentsWithLatestReport() (incidents []IncidentFeature, err error) {
// Select the latest report for all current incidents
stmt, err := db.Prepare(`SELECT DISTINCT ON (i.uuid) r.uuid, incident_uuid,
guid, title, link, category, timezone('UTC', pubdate),
alert_level, location, council_area, status, fire_type,
fire, size, responsible_agency, extra,
timezone('UTC', lower(i.current_from)) as first_seen,
timezone('UTC', upper(i.current_from)) as last_seen,
ST_AsGeoJSON(geometry)
FROM incidents i
JOIN reports r ON i.uuid = r.incident_uuid
WHERE i.current = true
ORDER BY i.uuid, r.pubdate DESC`)
if err != nil {
return
}
defer stmt.Close()
rows, err := stmt.Query()
if err != nil {
return
}
for rows.Next() {
var ip IncidentProperties
var fea IncidentFeature
var geom string
err = rows.Scan(&ip.ReportUUID, &fea.UUID, &ip.Guid, &ip.Title, &ip.Link, &ip.Category, &ip.Pubdate, &ip.AlertLevel, &ip.Location, &ip.CouncilArea, &ip.Status, &ip.FireType, &ip.Fire, &ip.Size, &ip.ResponsibleAgency, &ip.Extra, &ip.FirstSeen, &ip.LastSeen, &geom)
if err != nil {
return
}
// Report properties needs to be placed within a IncidentFeature
// and the IncidentFeature needs to be adjusted based on ip content
fea.Type = "Feature"
fea.Properties = ip
fea.Geometry = json.RawMessage([]byte(geom))
incidents = append(incidents, fea)
}
return
}
// Takes a UUID and returns a IncidentFeature representing that incident
func incidentFeatureForUUID(uuid string) (IncidentFeature, error) {
fea := IncidentFeature{}
// Select the latest report for the requested incident
stmt, err := db.Prepare(`SELECT DISTINCT ON (i.uuid) r.uuid,
guid, title, link, category, timezone('UTC', pubdate),
alert_level, location, council_area, status, fire_type,
fire, size, responsible_agency, extra,
timezone('UTC', lower(i.current_from)) as first_seen,
timezone('UTC', upper(i.current_from)) as last_seen,
ST_AsGeoJSON(geometry)
FROM incidents i
JOIN reports r ON i.uuid = r.incident_uuid
WHERE i.current = true
AND i.uuid = $1
ORDER BY i.uuid, r.created_at DESC`)
if err != nil {
return fea, err
}
defer stmt.Close()
var ip IncidentProperties
var geom string
err = stmt.QueryRow(uuid).Scan(&ip.ReportUUID, &ip.Guid, &ip.Title, &ip.Link, &ip.Category, &ip.Pubdate, &ip.AlertLevel, &ip.Location, &ip.CouncilArea, &ip.Status, &ip.FireType, &ip.Fire, &ip.Size, &ip.ResponsibleAgency, &ip.Extra, &ip.FirstSeen, &ip.LastSeen, &geom)
if err != nil {
return fea, err
}
// Incident properties needs to be placed within a ReportFeature
// and the IncidentFeature needs to be adjusted based on ip content
fea.Type = "Feature"
fea.Properties = ip
fea.UUID = uuid
fea.Geometry = json.RawMessage([]byte(geom))
return fea, nil
}