package model import ( "fmt" "math" "strconv" "strings" "github.com/jinzhu/gorm" ) type DrawZone struct { gorm.Model // ID uint `gorm:"column:id;AUTO_INCREMENT;PRIMARY_KEY"` // CreatedAt time.Time `gorm:"column:created_at;type:datetime"` // // 更新时间(由gorm框架自动更新) // UpdatedAt time.Time `gorm:"column:updated_at;type:datetime"` // // DeletedAt gorm.DeletedAt `gorm:"index"` Name string `json:"name"` Dots string `json:"dots"` } type Point struct { Lng float64 //经度X Lat float64 //维度Y } func (obj *DrawZone) Create() (err error) { err = DB.Table("draw_zones").Create(&obj).Error err = DB.Table("draw_zones").Where("id=?", obj.ID).Update("name", "电子围栏"+strconv.Itoa(int(obj.ID))).Error // err = CheckAllDevice(obj) if err != nil { return err } return nil } func (obj *DrawZone) Del() (err error) { err = DB.Table("draw_zones").Delete(&obj).Error if err != nil { return err } return nil } // db.Unscoped().Delete(&order) func (obj *DrawZone) Clear() (err error) { err = DB.Table("draw_zones").Unscoped().Where("1 = 1").Delete(&DrawZone{}).Error err = DB.Table("devices").Update(Device{BoundId: 0, IsOutBound: 0}).Error if err != nil { return err } return nil } func (obj *DrawZone) Edit() (err error) { err = DB.Model(&DrawZone{}).Update("dots", obj.Dots).Error // err = CheckAllDevice(obj) if err != nil { return err } return nil } // device := model.Device{} // code := 200 // db := model.DB.Table("devices") // if err := db.Where("sn = ?", sn).First(&device).Error; err != nil { // code = 30001 // return serializer.Response{ // Status: code, // Msg: "数据库错误", // Error: err.Error(), // } // } // return serializer.Response{ // Status: code, // Data: device, // } func (obj *DrawZone) FindByName(name string) error { // d := DrawZone{} err := DB.Table("draw_zones").Where("name=?",name).First(&obj).Error if err != nil { return err } return nil } func (obj *DrawZone) FindAll() []DrawZone { list := []DrawZone{} err := DB.Model(&DrawZone{}).Find(&list).Error if err != nil { return nil } return list } func IsPointInPolygon(point Point, points []Point) bool { N := len(points) boundOrVertex := true intersectCount := 0 precision := 2e-10 var p1, p2 Point p := point p1 = points[0] for i := 0; i <= N; i++ { if p == p1 { return boundOrVertex } p2 = points[i%N] if p.Lng < math.Min(p1.Lng, p2.Lng) || p.Lng > math.Max(p1.Lng, p2.Lng) { p1 = p2 continue } if p.Lng > math.Min(p1.Lng, p2.Lng) && p.Lng < math.Max(p1.Lng, p2.Lng) { if p.Lat <= math.Max(p1.Lat, p2.Lat) { if p1.Lng == p2.Lng && p.Lat >= math.Min(p1.Lat, p2.Lat) { return boundOrVertex } if p1.Lat == p2.Lat { if p1.Lat == p.Lat { return boundOrVertex } else { intersectCount++ } } else { xinters := (p.Lng-p1.Lng)*(p2.Lat-p1.Lat)/(p2.Lng-p1.Lng) + p1.Lat if math.Abs(p.Lat-xinters) < precision { return boundOrVertex } if p.Lat < xinters { intersectCount++ } } } } else { if p.Lng == p2.Lng && p.Lat <= p2.Lat { p3 := points[(i+1)%N] if p.Lng >= math.Min(p1.Lng, p3.Lng) && p.Lng <= math.Max(p1.Lng, p3.Lng) { intersectCount++ } else { intersectCount += 2 } } } p1 = p2 } if intersectCount%2 == 0 { //偶数在多边形内 return false } else { //奇数在多边形外 return true } } func CheckAllDevice(zone DrawZone, typ int, zoneId uint) (err error) { arr := strings.Split(zone.Dots, "&") pointArr := []Point{} for i := 0; i < len(arr); i++ { str := arr[i] subArr := strings.Split(str, ",") f1, _ := strconv.ParseFloat(subArr[0], 64) f2, _ := strconv.ParseFloat(subArr[1], 64) newPoint := Point{Lng: f1, Lat: f2} pointArr = append(pointArr, newPoint) } d := Device{} devices := d.FindAll() for i := 0; i < len(devices); i++ { d := devices[i] pointToCheck := Point{Lng: d.Lng, Lat: d.Lat} if typ==0 { if d.IsOutBound==0 { continue } if IsPointInPolygon(pointToCheck, pointArr) { fmt.Println("该点判断为界内", d.SN) err = DB.Model(&d).Where("sn=?", d.SN).Update("bound_id", zone.ID).Error err = DB.Model(&d).Where("sn=?", d.SN).Update("is_out_bound", 0).Error } else { err = DB.Model(&d).Where("sn=?", d.SN).Update("bound_id", 0).Error err = DB.Model(&d).Where("sn=?", d.SN).Update("is_out_bound", 1).Error } }else{ if d.BoundId!=zoneId { continue } if IsPointInPolygon(pointToCheck, pointArr) { fmt.Println("该点判断为界内", d.SN) err = DB.Model(&d).Where("sn=?", d.SN).Update("bound_id", zone.ID).Error err = DB.Model(&d).Where("sn=?", d.SN).Update("is_out_bound", 0).Error } else { err = DB.Model(&d).Where("sn=?", d.SN).Update("bound_id", 0).Error err = DB.Model(&d).Where("sn=?", d.SN).Update("is_out_bound", 1).Error } } } return err } // arr := strings.Split(obj.Dots, "&") // pointArr := []Point{} // for i := 0; i < len(arr); i++ { // str := arr[i] // subArr := strings.Split(str, ",") // f1, _ := strconv.ParseFloat(subArr[0], 64) // f2, _ := strconv.ParseFloat(subArr[1], 64) // newPoint := Point{Lng: f1, Lat: f2} // pointArr = append(pointArr, newPoint) // }