1
0
Fork 0
mirror of https://github.com/Luzifer/gpxhydrant.git synced 2024-11-08 15:30:00 +00:00
gpxhydrant/hydrant.go

138 lines
3 KiB
Go

package main
import (
"fmt"
"regexp"
"strconv"
"github.com/Luzifer/gpxhydrant/gpx"
"github.com/Luzifer/gpxhydrant/osm"
)
type hydrant struct {
/*
<node lat="53.58963" lon="9.70838">
<tag k="emergency" v="fire_hydrant" />
<tag k="fire_hydrant:diameter" v="100" />
<tag k="fire_hydrant:position" v="sidewalk" />
<tag k="fire_hydrant:pressure" v="4" />
<tag k="fire_hydrant:type" v="underground" />
<tag k="operator" v="Stadtwerke Wedel" />
</node>
*/
ID int64
Name string
Latitude float64
Longitude float64
Diameter int64
Position string
Pressure int64
Type string
Version int64
}
func parseWaypoint(in gpx.Waypoint) (*hydrant, error) {
infoRegex := regexp.MustCompile(`([SPLG])([UOWP])(\?|[0-9]{2,3})`)
if !infoRegex.MatchString(in.Comment) {
return nil, errWrongGPXComment
}
matches := infoRegex.FindStringSubmatch(in.Comment)
out := &hydrant{
Name: in.Name,
Latitude: roundPrec(in.Latitude, 7),
Longitude: roundPrec(in.Longitude, 7),
Pressure: cfg.Pressure,
}
switch matches[1] {
case "S":
out.Position = "sidewalk"
case "P":
out.Position = "parking_lot"
case "L":
out.Position = "lane"
case "G":
out.Position = "green"
}
switch matches[2] {
case "U":
out.Type = "underground"
case "O":
out.Type = "pillar"
case "W":
out.Type = "wall"
case "P":
out.Type = "pond"
}
if matches[3] != "?" {
diameter, err := strconv.ParseInt(matches[3], 10, 64)
if err != nil {
return nil, err
}
out.Diameter = diameter
}
return out, nil
}
func fromNode(in *osm.Node) (*hydrant, error) {
var e error
out := &hydrant{
ID: in.ID,
Version: in.Version,
Latitude: in.Latitude,
Longitude: in.Longitude,
}
validFireHydrant := false
for _, t := range in.Tags {
switch t.Key {
case "emergency":
if t.Value == "fire_hydrant" {
validFireHydrant = true
}
case "fire_hydrant:diameter":
if out.Diameter, e = strconv.ParseInt(t.Value, 10, 64); e != nil {
return nil, e
}
case "fire_hydrant:position":
out.Position = t.Value
case "fire_hydrant:pressure":
if out.Pressure, e = strconv.ParseInt(t.Value, 10, 64); e != nil {
return nil, e
}
case "fire_hydrant:type":
out.Type = t.Value
}
}
if !validFireHydrant {
return nil, fmt.Errorf("Did not find required 'emergency=fire_hydrant' tag.")
}
return out, nil
}
func (h hydrant) ToNode() *osm.Node {
out := &osm.Node{
ID: h.ID,
Version: h.Version,
Latitude: h.Latitude,
Longitude: h.Longitude,
}
out.Tags = append(out.Tags, osm.Tag{Key: "emergency", Value: "fire_hydrant"})
if h.Diameter > 0 {
out.Tags = append(out.Tags, osm.Tag{Key: "fire_hydrant:diameter", Value: strconv.FormatInt(h.Diameter, 10)})
}
out.Tags = append(out.Tags, osm.Tag{Key: "fire_hydrant:position", Value: h.Position})
out.Tags = append(out.Tags, osm.Tag{Key: "fire_hydrant:pressure", Value: strconv.FormatInt(h.Pressure, 10)})
out.Tags = append(out.Tags, osm.Tag{Key: "fire_hydrant:type", Value: h.Type})
return out
}