|
@@ -0,0 +1,290 @@
|
|
|
+package common
|
|
|
+
|
|
|
+import (
|
|
|
+ "fmt"
|
|
|
+ "iot_manager_service/app/device/dao"
|
|
|
+ "math"
|
|
|
+ "sort"
|
|
|
+ "strconv"
|
|
|
+)
|
|
|
+
|
|
|
+//计算空气质量转换等级
|
|
|
+func CalculateAirQuality(airQuality string) string {
|
|
|
+ d, err := strconv.ParseFloat(airQuality, 64)
|
|
|
+ if err != nil {
|
|
|
+ panic(err.Error())
|
|
|
+ }
|
|
|
+ val := "-"
|
|
|
+ if d <= 50 {
|
|
|
+ val = "优"
|
|
|
+ } else if d > 50 && d <= 100 {
|
|
|
+ val = "良"
|
|
|
+ } else if d > 100 && d <= 150 {
|
|
|
+ val = "轻度污染"
|
|
|
+ } else if d > 150 && d <= 200 {
|
|
|
+ val = "中度污染"
|
|
|
+ } else if d > 200 && d < 300 {
|
|
|
+ val = "重度污染"
|
|
|
+ } else if d > 300 {
|
|
|
+ val = "严重污染"
|
|
|
+ }
|
|
|
+ return val
|
|
|
+}
|
|
|
+
|
|
|
+// 计算aqi值对应的等级
|
|
|
+func getPollutionDegree(aqi float64) int {
|
|
|
+ pollutionDegree := 1
|
|
|
+ if aqi <= 50 {
|
|
|
+ pollutionDegree = 1
|
|
|
+ } else if aqi > 50 && aqi <= 100 {
|
|
|
+ pollutionDegree = 2
|
|
|
+ } else if aqi > 100 && aqi <= 150 {
|
|
|
+ pollutionDegree = 3
|
|
|
+ } else if aqi > 150 && aqi <= 200 {
|
|
|
+ pollutionDegree = 4
|
|
|
+ } else if aqi > 200 && aqi <= 300 {
|
|
|
+ pollutionDegree = 5
|
|
|
+ } else if aqi > 300 {
|
|
|
+ pollutionDegree = 6
|
|
|
+ }
|
|
|
+ return pollutionDegree
|
|
|
+}
|
|
|
+
|
|
|
+// 计算aqi值对应的等级
|
|
|
+func getDegree(pollutionDegree int) string {
|
|
|
+ if pollutionDegree == 1 {
|
|
|
+ return "优"
|
|
|
+ } else if pollutionDegree == 2 {
|
|
|
+ return "良"
|
|
|
+ } else if pollutionDegree == 3 {
|
|
|
+ return "轻度污染"
|
|
|
+ } else if pollutionDegree == 4 {
|
|
|
+ return "中度污染"
|
|
|
+ } else if pollutionDegree == 5 {
|
|
|
+ return "重度污染"
|
|
|
+ } else if pollutionDegree == 6 {
|
|
|
+ return "严重污染"
|
|
|
+ }
|
|
|
+ return "数据错误"
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 计算每种污染物项目 P的空气质量分指数
|
|
|
+ *
|
|
|
+ * @param cp 污染物项目P的质量浓度
|
|
|
+ * @param r 污染物项目P所在数组中的行号
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+func countPerIaqi(cp float64, r int) float64 {
|
|
|
+ bph := 0 // 与 cp相近的污染物浓度限值的高位值
|
|
|
+ bpl := 0 // 与 cp相近的污染物浓度限值的低位值
|
|
|
+ iaqih := 0 // 与 bph对应的空气质量分指数
|
|
|
+ iaqil := 0 // 与 bpl对应的空气质量分指数
|
|
|
+ iaqip := 0 // 当前污染物项目P的空气质量分指数
|
|
|
+ // 空气质量分指数及对应的污染物项目浓度限值
|
|
|
+ aqiArr := [][]int{{0, 50, 100, 150, 200, 300, 400, 500}, {0, 35, 75, 115, 150, 250, 350, 500},
|
|
|
+ {0, 50, 150, 250, 350, 420, 500, 600}, {0, 2, 4, 14, 24, 36, 48, 60},
|
|
|
+ {0, 40, 80, 180, 280, 565, 750, 940}, {0, 160, 200, 300, 400, 800, 1000, 1200},
|
|
|
+ {0, 50, 150, 475, 800, 1600, 2100, 2620}, {0, 100, 160, 215, 265, 800}}
|
|
|
+
|
|
|
+ min := aqiArr[r][0]
|
|
|
+ index := len(aqiArr[r]) - 1
|
|
|
+ max := aqiArr[r][index]
|
|
|
+ if cp <= float64(min) || cp >= float64(max) {
|
|
|
+ return 0
|
|
|
+ } else {
|
|
|
+ // 对每种污染物的bph、bpl、iaqih、iaqil进行赋值
|
|
|
+ for i := 0; i < r+1; i++ {
|
|
|
+ for j := 0; j < len(aqiArr[0]); j++ {
|
|
|
+ if cp < float64(aqiArr[i][j]) {
|
|
|
+ bph = aqiArr[i][j]
|
|
|
+ bpl = aqiArr[i][j-1]
|
|
|
+ iaqih = aqiArr[0][j]
|
|
|
+ iaqil = aqiArr[0][j-1]
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 计算污染物项目 P的空气质量分指数
|
|
|
+ iaqip = (iaqih-iaqil)/(bph-bpl)*(int(cp)-bpl) + iaqil
|
|
|
+ bg := math.Ceil(float64(iaqip))
|
|
|
+ float, err := strconv.ParseFloat(fmt.Sprintf("%.4f", bg), 64)
|
|
|
+ if err != nil {
|
|
|
+ panic(err.Error())
|
|
|
+ }
|
|
|
+ return float
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 根据提供污染物的各项指标,对AQI进行计算
|
|
|
+ *
|
|
|
+ * @param pmtw PM2.5
|
|
|
+ * @param pmte PM10
|
|
|
+ * @param co 一氧化碳浓度
|
|
|
+ * @param no2 二氧化氮浓度
|
|
|
+ * @param o3 臭氧浓度
|
|
|
+ * @param so2 二氧化硫浓度
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+func CountAqi(pmtw float64, pmte float64, co float64, no2 float64, o3 float64, so2 float64) *dao.AqiData {
|
|
|
+ var pmtwIaqi float64 = getPm25IAQI(pmtw)
|
|
|
+ var pmteIaqi float64 = getPm10IAQI(pmte)
|
|
|
+ var coIaqi float64 = getCoIAQI(co)
|
|
|
+ var no2Iaqi float64 = getNo2IAQI(no2)
|
|
|
+ var o3Iaqi float64 = getO3OneHourIAQI(o3)
|
|
|
+ var so2Iaqi float64 = getSo2IAQI(so2)
|
|
|
+ var aList []dao.AqiData
|
|
|
+ //// 初始化对象数组
|
|
|
+ if pmtwIaqi != 0 {
|
|
|
+ aList = append(aList, dao.AqiData{Name: "PM2.5", Aqi: pmtwIaqi})
|
|
|
+ }
|
|
|
+ if pmteIaqi != 0 {
|
|
|
+ aList = append(aList, dao.AqiData{Name: "PM10", Aqi: pmteIaqi})
|
|
|
+ }
|
|
|
+ if coIaqi != 0 {
|
|
|
+ aList = append(aList, dao.AqiData{Name: "CO", Aqi: coIaqi})
|
|
|
+ }
|
|
|
+ if no2Iaqi != 0 {
|
|
|
+ aList = append(aList, dao.AqiData{Name: "NO2", Aqi: no2Iaqi})
|
|
|
+ }
|
|
|
+ if o3Iaqi != 0 {
|
|
|
+ aList = append(aList, dao.AqiData{Name: "O3", Aqi: o3Iaqi})
|
|
|
+ }
|
|
|
+ if so2Iaqi != 0 {
|
|
|
+ aList = append(aList, dao.AqiData{Name: "SO2", Aqi: so2Iaqi})
|
|
|
+ }
|
|
|
+ sort.Slice(aList, func(i, j int) bool {
|
|
|
+ f := aList[i].Aqi - aList[j].Aqi
|
|
|
+ if f > 0 {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ })
|
|
|
+ var aqi dao.AqiData
|
|
|
+ if len(aList) > 0 {
|
|
|
+ aqi = aList[len(aList)-1]
|
|
|
+ } else {
|
|
|
+ aqi = dao.AqiData{"PM10", 0.0}
|
|
|
+ }
|
|
|
+ return &aqi
|
|
|
+}
|
|
|
+
|
|
|
+func getPm25IAQI(pmtw float64) float64 {
|
|
|
+ if pmtw > 0 {
|
|
|
+ return countPerIaqi(pmtw, 1)
|
|
|
+ }
|
|
|
+ return 0
|
|
|
+}
|
|
|
+
|
|
|
+func getPm10IAQI(pmte float64) float64 {
|
|
|
+ if pmte > 0 {
|
|
|
+ return countPerIaqi(pmte, 2)
|
|
|
+ }
|
|
|
+ return 0
|
|
|
+}
|
|
|
+
|
|
|
+func getCoIAQI(co float64) float64 {
|
|
|
+ if co > 0 {
|
|
|
+ return countPerIaqi(co, 3)
|
|
|
+ }
|
|
|
+ return 0
|
|
|
+}
|
|
|
+
|
|
|
+func getNo2IAQI(no2 float64) float64 {
|
|
|
+ if no2 > 0 {
|
|
|
+ return countPerIaqi(no2, 4)
|
|
|
+ }
|
|
|
+ return 0
|
|
|
+}
|
|
|
+
|
|
|
+func getO3OneHourIAQI(o3One float64) float64 {
|
|
|
+ if o3One > 0 {
|
|
|
+ return countPerIaqi(o3One, 5)
|
|
|
+ }
|
|
|
+ return 0
|
|
|
+}
|
|
|
+
|
|
|
+func getSo2IAQI(so2 float64) float64 {
|
|
|
+ if so2 > 0 {
|
|
|
+ return countPerIaqi(so2, 6)
|
|
|
+ }
|
|
|
+ return 0
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 计算风向角度,转换成中文方向
|
|
|
+ *
|
|
|
+ * @param windDirection
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+func CalculateDirection(windDirection string) string {
|
|
|
+ d, _ := strconv.ParseFloat(windDirection, 64)
|
|
|
+ val := "-"
|
|
|
+ if d > 337.5 || d < 22.5 {
|
|
|
+ //Namezh: "北", Name: "N", Center: 0, DirectionA: 337.5, DirectionB: 22.5
|
|
|
+ val = "北"
|
|
|
+ } else if d > 22.5 && d < 67.5 {
|
|
|
+ //Direction{Namezh: "东北", Name: "NE", Center: 45, DirectionA: 22.5, DirectionB: 67.5}
|
|
|
+ val = "东北"
|
|
|
+ } else if d > 67.5 && d < 112.5 {
|
|
|
+ //Namezh:"东", Name:"E", Center:90, DirectionA:67.5, DirectionB:112.5
|
|
|
+ val = "东"
|
|
|
+ } else if d > 112.5 && d < 157.5 {
|
|
|
+ //Namezh: "东南", Name: "SN", Center: 135, DirectionA: 112.5, DirectionB: 157.5
|
|
|
+ val = "东南"
|
|
|
+ } else if d > 157.5 && d < 202.5 {
|
|
|
+ //Namezh: "南", Name: "S", Center: 180, DirectionA: 157.5, DirectionB: 202.5
|
|
|
+ val = "南"
|
|
|
+ } else if d > 202.5 && d < 247.5 {
|
|
|
+ //Namezh: "西南", Name: "SW", Center: 225, DirectionA: 202.5, DirectionB: 247.5
|
|
|
+ val = "西南"
|
|
|
+ } else if d > 247.5 && d < 292.5 {
|
|
|
+ //Namezh: "西", Name: "W", Center: 270, DirectionA: 247.5, DirectionB: 292.5
|
|
|
+ val = "西"
|
|
|
+ } else if d > 292.5 && d < 337.5 {
|
|
|
+ //Namezh: "西北", Name: "NW", Center: 315, DirectionA: 292.5, DirectionB: 337.5
|
|
|
+ val = "西北"
|
|
|
+ }
|
|
|
+ return val
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 计算风速等级
|
|
|
+ *
|
|
|
+ * @param speed
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+func CalculateSpeed(speed string) string {
|
|
|
+ //风力等级范围
|
|
|
+ d, _ := strconv.ParseFloat(speed, 64)
|
|
|
+ val := "-"
|
|
|
+ if d >= 0.0 && d <= 0.2 {
|
|
|
+ val = "无风"
|
|
|
+ } else if d >= 0.3 && d <= 1.5 {
|
|
|
+ val = "软风(一级)"
|
|
|
+ } else if d >= 1.6 && d <= 3.3 {
|
|
|
+ val = "轻风(二级)"
|
|
|
+ } else if d >= 3.4 && d <= 5.4 {
|
|
|
+ val = "微风(三级)"
|
|
|
+ } else if d >= 5.5 && d <= 7.9 {
|
|
|
+ val = "和风(四级)"
|
|
|
+ } else if d >= 8.0 && d <= 10.7 {
|
|
|
+ val = "清劲风(五级)"
|
|
|
+ } else if d >= 10.8 && d <= 13.8 {
|
|
|
+ val = "强风(六级)"
|
|
|
+ } else if d >= 13.9 && d <= 17.1 {
|
|
|
+ val = "疾风(七级)"
|
|
|
+ } else if d >= 17.2 && d <= 20.7 {
|
|
|
+ val = "大风(八级)"
|
|
|
+ } else if d >= 20.8 && d <= 24.4 {
|
|
|
+ val = "烈风(九级)"
|
|
|
+ } else if d >= 24.5 && d <= 28.4 {
|
|
|
+ val = "狂风(十级)"
|
|
|
+ } else if d >= 28.5 && d <= 32.6 {
|
|
|
+ val = "暴风(11级)"
|
|
|
+ } else if d > 32.6 {
|
|
|
+ val = "台风(12级)"
|
|
|
+ }
|
|
|
+ return val
|
|
|
+}
|