You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

weather.go 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package main
  2. import (
  3. "fmt"
  4. "image"
  5. "image/draw"
  6. "image/png"
  7. "math"
  8. "os"
  9. "regexp"
  10. "strconv"
  11. "time"
  12. "github.com/nfnt/resize"
  13. "github.com/oliamb/cutter"
  14. )
  15. var (
  16. weatherCoordPattern = regexp.MustCompile(`[-+]?\d*\.\d+|\d+`)
  17. lastWeatherFilename string
  18. lastWeatherInfoFilename string
  19. weatherUSMap image.Image
  20. weatherUSMapHeight int
  21. weatherUSMapWidth int
  22. )
  23. type coordBox struct {
  24. lat1 float64
  25. lon1 float64
  26. lat2 float64
  27. lon2 float64
  28. }
  29. func convertCoord(coord string) float64 {
  30. f, _ := strconv.ParseFloat(coord, 32)
  31. return f
  32. }
  33. func degToRad(deg float64) float64 {
  34. return deg * math.Pi / 180
  35. }
  36. func addWeatherInfo(name string) {
  37. lastWeatherInfoFilename = name
  38. cfg := parseRecvFile(name)
  39. crds, ok := cfg["Coordinates"]
  40. if !ok {
  41. return
  42. }
  43. dbg("Evaluating coords: %s\n", crds)
  44. match := weatherCoordPattern.FindAllStringSubmatch(crds, -1)
  45. if len(match) != 4 {
  46. return
  47. }
  48. coords := coordBox{
  49. lat1: convertCoord(match[0][0]),
  50. lon1: convertCoord(match[1][0]),
  51. lat2: convertCoord(match[2][0]),
  52. lon2: convertCoord(match[3][0]),
  53. }
  54. yTopCoord := 1.0799224683069641
  55. coords.lat1 = yTopCoord - math.Asinh(math.Tan(degToRad(coords.lat1)))
  56. coords.lat2 = yTopCoord - math.Asinh(math.Tan(degToRad(coords.lat2)))
  57. var x1, x2, y1, y2 int
  58. x1 = int((coords.lon1 + 130.781250) * 7162 / 39.34135)
  59. x2 = int((coords.lon2 + 130.781250) * 7162 / 39.34135)
  60. y1 = int(coords.lat1 * 10426.37065288477)
  61. y2 = int(coords.lat2 * 10426.37065288477)
  62. f, err := os.Open("USMap.png")
  63. if err != nil {
  64. logger.Fatal(err)
  65. }
  66. defer f.Close()
  67. m, err := png.Decode(f)
  68. if err != nil {
  69. logger.Fatal(err)
  70. }
  71. width, height := (x2 - x1), (y2 - y1)
  72. cropped, err := cutter.Crop(m, cutter.Config{
  73. Width: width,
  74. Height: height,
  75. Anchor: image.Point{x1, y1},
  76. Mode: cutter.TopLeft,
  77. })
  78. if err != nil {
  79. logger.Fatal(err)
  80. }
  81. weatherUSMap = cropped
  82. weatherUSMapHeight = height
  83. weatherUSMapWidth = width
  84. dbg("Created cropped map: (%d, %d)\n", width, height)
  85. }
  86. func convertToRGBA(im image.Image) *image.RGBA {
  87. bounds := im.Bounds()
  88. rgba := image.NewRGBA(bounds)
  89. for x := bounds.Min.X; x < bounds.Max.X; x++ {
  90. for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
  91. rgba.Set(x, y, im.At(x, y))
  92. }
  93. }
  94. return rgba
  95. }
  96. func addWeatherImage(name string) {
  97. dbg("Adding weather image: %s\n", name)
  98. if weatherUSMap == nil {
  99. logger.Println("Unable to save map as we did not get configuration")
  100. return
  101. }
  102. f, err := os.Open(name)
  103. if err != nil {
  104. logger.Fatal(err)
  105. }
  106. defer f.Close()
  107. m, err := png.Decode(f)
  108. if err != nil {
  109. return
  110. }
  111. resized := resize.Resize(uint(weatherUSMapWidth), uint(weatherUSMapHeight), m, resize.NearestNeighbor)
  112. im := image.NewRGBA(weatherUSMap.Bounds())
  113. draw.Draw(im, im.Bounds(), weatherUSMap, im.Bounds().Min, draw.Src)
  114. draw.Draw(im, im.Bounds(), resized, resized.Bounds().Min, draw.Over)
  115. now := time.Now().Format(time.RFC3339)
  116. path := fmt.Sprintf("%s/Weather - %s.png", *outDir, now)
  117. f, err = os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0666)
  118. if err != nil {
  119. logger.Fatal(err)
  120. }
  121. defer f.Close()
  122. if err = png.Encode(f, im); err != nil {
  123. logger.Fatal(err)
  124. }
  125. lastWeatherFilename = name
  126. }