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)
|
// }
|