panlei
2019-08-15 6f1ae979d13028006ccdca01e310d2b5d2d53c5c
把数据定义模块儿提取出来
11个文件已修改
2个文件已添加
601 ■■■■ 已修改文件
algorithm/face/face.go 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/intrusion/intrusion.go 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/timeSlot/timeSlot.go 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
insertdata/insertDataToEs.go 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
labelFilter/readyDataForLabel.go 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
labelFilter/ruleForLabel.go 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/geoPolygon.go 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/personTrack.go 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/readyDataForRule.go 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/ruleToformula.go 214 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/timeTicker.go 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
structure/gragh.go 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
structure/rule.go 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/face/face.go
@@ -4,7 +4,7 @@
    "basic.com/pubsub/protomsg.git"
    "github.com/knetic/govaluate"
    "ruleprocess/logger"
    "ruleprocess/ruleserver"
    "ruleprocess/structure"
    "strconv"
)
@@ -13,7 +13,7 @@
}
// 过滤规则先筛选出符合条件的目标数量
func filterRule(rule *protomsg.Rule, am *ruleserver.AreaMap) ruleserver.LittleRuleResult {
func filterRule(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
        // 处理的是人脸算法 如果这条规则配置的是人脸算法,过滤完条件之后直接得出结果,因为肯定没有数量条件,自己拼接
        //logger.Info("规则的算法id和区域的算法id:", rule.SdkId, "===", am.sdkId)
        if rule.PolygonId == am.AreaId { // 算法和区域都得对的上
@@ -36,7 +36,7 @@
                    flag = "true"
                }
                logger.Info("---------人脸比对符合条件的数量为:",len(am.FilterData))
                return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" { // 人脸检测
                //logger.Debug("当前小规则是:",rule)
@@ -44,7 +44,7 @@
                    // 如果是不规矩的连接符统统返回false 规则也只能判断人脸的相似度,所以不存在别的连接符
                    if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
                        logger.Info("-----------------------过规则之前区域内的人脸数量为:",am.TargetNum)
                        var args []*ruleserver.Arg
                        var args []*structure.Arg
                        if rule.RuleWithPre == "&&" {
                            args = am.FilterData
                            //logger.Info("过滤后的args的长度为:",len(args))
@@ -77,20 +77,20 @@
                        logger.Info("过完条件后的目标数量为:",am.TargetNum)
                        if am.TargetNum > 0 {
                            logger.Info("!!!!!!!!!人脸检测成功")
                            return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                        } else {
                            return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                        }
                    } else {
                        return ruleserver.LittleRuleResult{}
                        return structure.LittleRuleResult{}
                    }
                } else {
                    return ruleserver.LittleRuleResult{}
                    return structure.LittleRuleResult{}
                }
            } else {
                return ruleserver.LittleRuleResult{}
                return structure.LittleRuleResult{}
            }
        } else {
            return ruleserver.LittleRuleResult{}
            return structure.LittleRuleResult{}
        }
}
algorithm/intrusion/intrusion.go
@@ -4,7 +4,7 @@
    "basic.com/pubsub/protomsg.git"
    "github.com/knetic/govaluate"
    "ruleprocess/logger"
    "ruleprocess/ruleserver"
    "ruleprocess/structure"
    "strconv"
)
@@ -13,11 +13,11 @@
}
// 过滤规则先筛选出符合条件的目标数量
func filterRule(rule *protomsg.Rule, am *ruleserver.AreaMap) ruleserver.LittleRuleResult {
func filterRule(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    // 处理的都是yolo数据
    if rule.PolygonId == am.AreaId { // 首先这条规则得是这个算法的规则,其次规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
            var args []*ruleserver.Arg
            var args []*structure.Arg
            if rule.RuleWithPre == "&&" {
                args = am.FilterData
            } else {
@@ -46,28 +46,28 @@
            }
            am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
            if am.TargetNum > 0 {
                return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
            } else {
                return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
            }
        } else {
            return ruleserver.LittleRuleResult{}
            return structure.LittleRuleResult{}
        }
    } else {
        return ruleserver.LittleRuleResult{}
        return structure.LittleRuleResult{}
    }
}
// 给数据库的规则表达式代参 args: 一条子规则,区域数据
func transferParameters(rule *protomsg.Rule, am *ruleserver.AreaMap) ruleserver.LittleRuleResult {
func transferParameters(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "objCount" { // 如果参数是要区域内目标数量 即yolo 人脸不会有数量
            //logger.Info("当前小规则是:---------", rule)
            //logger.Info("得出结果阶段", "比较的规则是:", rule)
            if rule.Operator == "" {
                return ruleserver.LittleRuleResult{am.SdkName, strconv.Itoa(am.TargetNum) + "" + rule.RuleWithPre, rule.Sort} // 如果后面不跟操作符就直接返回数量  比如要跟下一个区域比较数量的就直接返回本区域的数量
                return structure.LittleRuleResult{am.SdkName, strconv.Itoa(am.TargetNum) + "" + rule.RuleWithPre, rule.Sort} // 如果后面不跟操作符就直接返回数量  比如要跟下一个区域比较数量的就直接返回本区域的数量
            }
            //args := am.targetNum     targetNum 已成所有目标的总数量,这里只算yolo的
            var num int = 0
@@ -79,9 +79,9 @@
            formula := strconv.Itoa(num) + " " + rule.Operator + " " + rule.SdkArgValue
            expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
            result, _ := expression.Evaluate(nil)          // 得到数学公式的结果
            return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + " " + strconv.FormatBool(result.(bool)), rule.Sort}
            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + " " + strconv.FormatBool(result.(bool)), rule.Sort}
            // 加上关于算法的判断条件,不能只有关于规则的,有的算法本身就是一个规则,如个体静止,靠右行,所以,拿到当前子规则的sdkid来判断是否是那些特殊的规则
        }
    }
    return ruleserver.LittleRuleResult{}
    return structure.LittleRuleResult{}
}
algorithm/timeSlot/timeSlot.go
@@ -6,11 +6,11 @@
    "github.com/knetic/govaluate"
    "ruleprocess/cache"
    "ruleprocess/logger"
    "ruleprocess/ruleserver"
    "ruleprocess/structure"
    "time"
)
func TimeRuleResult(rule *protomsg.Rule, am *ruleserver.AreaMap) ruleserver.LittleRuleResult {
func TimeRuleResult(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "time_rule" { // 判断是否符合时间规
            //logger.Info("----------当前时间规则:---------", rule)
@@ -39,7 +39,7 @@
                        break
                    }
                }
                return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
            if rule.Operator == "unsatisfy" || rule.Operator == "!=" { // 不满足所选的时间规则
@@ -59,18 +59,18 @@
                        break
                    }
                }
                return ruleserver.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
        }
    }
    return ruleserver.LittleRuleResult{}
    return structure.LittleRuleResult{}
}
// 取出某个时间规则的第几天的规则段集合
func GetTimeById(id string, index int) []ruleserver.TimeRange {
func GetTimeById(id string, index int) []structure.TimeRange {
    _, cameraTimeRule := cache.GetTimeRuleById(id)
    var timeRangeList []ruleserver.Day
    var timeRangeList []structure.Day
    err := json.Unmarshal([]byte(cameraTimeRule.TimeRule), &timeRangeList)
    if err != nil {
        logger.Error("取时间规则时反序列化错误!")
insertdata/insertDataToEs.go
@@ -9,6 +9,7 @@
    "net"
    "ruleprocess/cache"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "strings"
    "time"
@@ -77,7 +78,7 @@
    IsAckAlarm      int                    `json:"isAckAlarm"`
    IsCollect       int                    `json:"isCollect"`
    IsDelete        int                    `json:"isDelete"`
    BaseInfo        []*ruleserver.BaseInfo `json:"baseInfo"`
    BaseInfo        []*structure.BaseInfo `json:"baseInfo"`
}
//  yolo行为的数据结构
@@ -115,8 +116,8 @@
// 一个face对多个规则组的归置人脸的结构体
type FaceAndRules struct {
    ruleserver.Arg
    rules []ruleserver.Result
    structure.Arg
    rules []structure.Result
}
// 往ES插数据
@@ -143,7 +144,7 @@
//    //    ChangeStatusYolo(msg)
//    //}
//}
func InsertToEs(msg ruleserver.ResultMsg) {
func InsertToEs(msg structure.ResultMsg) {
    InsertFace(msg, "")
    // 如果标签中含有持续时间首次报警的timeLabel的话则不需要过人体追踪,不然就没的插入了
    fk := ruleserver.TrackOrNot(msg.RuleResult)
@@ -162,8 +163,8 @@
}
// 往es中插入人脸数据
func InsertFace(msg ruleserver.ResultMsg, linkId string) {
    if msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]ruleserver.FaceResult)) > 0 {
func InsertFace(msg structure.ResultMsg, linkId string) {
    if msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]structure.FaceResult)) > 0 {
        logger.Info("往ES插人脸数据")
        faces := []*FaceAndRules{}
        faces = PutFace(faces,msg)
@@ -271,9 +272,9 @@
}
// 归置人脸
func PutFace(faces []*FaceAndRules,msg ruleserver.ResultMsg)[]*FaceAndRules{
    if msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]ruleserver.FaceResult)) > 0 {
        for _, faceResult := range msg.RuleResult["face"].([]ruleserver.FaceResult) {
func PutFace(faces []*FaceAndRules,msg structure.ResultMsg)[]*FaceAndRules{
    if msg.RuleResult["face"] != nil && len(msg.RuleResult["face"].([]structure.FaceResult)) > 0 {
        for _, faceResult := range msg.RuleResult["face"].([]structure.FaceResult) {
            faces = hebingFace(faces, faceResult)
        }
        return faces
@@ -281,7 +282,7 @@
        return nil
    }
}
func hebingFace(faces []*FaceAndRules, faceResult ruleserver.FaceResult) []*FaceAndRules{
func hebingFace(faces []*FaceAndRules, faceResult structure.FaceResult) []*FaceAndRules{
    for _, arg := range faceResult.Args {
        // 拿到每一张人脸
        logger.Info("归置人脸时相似者的数量:",len(arg.Liker))
@@ -309,18 +310,18 @@
            }
        }
        if !flag {
            faces = append(faces, &FaceAndRules{arg, []ruleserver.Result{faceResult.Result}})
            faces = append(faces, &FaceAndRules{arg, []structure.Result{faceResult.Result}})
        }
    }
    return faces
}
// 往es中插入yolo数据
func InsertYolo(msg ruleserver.ResultMsg, linkId string) {
    if msg.RuleResult["yolo"] != nil && len(msg.RuleResult["yolo"].([]ruleserver.Result)) > 0 {
func InsertYolo(msg structure.ResultMsg, linkId string) {
    if msg.RuleResult["yolo"] != nil && len(msg.RuleResult["yolo"].([]structure.Result)) > 0 {
        // 先判断一下数据带的规则标签是否有可以插入的
        flag := false
        for _, res := range msg.RuleResult["yolo"].([]ruleserver.Result) {
        for _, res := range msg.RuleResult["yolo"].([]structure.Result) {
            //logger.Info("定时器打的数字标签:",res.Others.TimeLabel)
            if res.Others.TimeLabel == "01" || res.Others.TimeLabel == "10" {
                flag = true
@@ -331,7 +332,7 @@
            var sdkNames string = ""
            alarmRules := []AlarmRule{}
            url := []string{}
            for _, yoloResult := range msg.RuleResult["yolo"].([]ruleserver.Result) {
            for _, yoloResult := range msg.RuleResult["yolo"].([]structure.Result) {
                if yoloResult.Others.TimeLabel == "01" || yoloResult.Others.TimeLabel == "10" {
                    // 拼出sdkname
                    //logger.Info("应该进来才对的")
@@ -351,7 +352,7 @@
                            }
                            i := protomsg.Image{}
                            err = proto.Unmarshal(bdata, &i)
                            resp1, err1 := util.DrawPolygonOnImage(msg1.Cid, i, msg1.RuleResult["yolo"].([]ruleserver.Result), weedfsUrl)
                            resp1, err1 := util.DrawPolygonOnImage(msg1.Cid, i, msg1.RuleResult["yolo"].([]structure.Result), weedfsUrl)
                            if err1 != nil {
                                logger.Error("缓存数据画框或上传图片服务器出错", err)
                            } else {
@@ -363,7 +364,7 @@
                }
            }
            linkFlag := false
            for _, yoloResult := range msg.RuleResult["yolo"].([]ruleserver.Result) {
            for _, yoloResult := range msg.RuleResult["yolo"].([]structure.Result) {
                if (yoloResult.Others.TimeLabel == "01" || yoloResult.Others.TimeLabel == "10") && yoloResult.Others.LinkCache != nil && len(yoloResult.Others.LinkCache) > 1 {
                    linkId := uuid.NewV4().String()
                    for _, msg2 := range yoloResult.Others.LinkCache {
@@ -392,7 +393,7 @@
            if len(alarmRules) > 0 {
                isAlarm = 1
                //resp, err = util.PostFormBufferData(weedfsUrl, i, uuid.NewV4().String())
                resp, err = util.DrawPolygonOnImage(msg.Cid, i, msg.RuleResult["yolo"].([]ruleserver.Result), weedfsUrl)
                resp, err = util.DrawPolygonOnImage(msg.Cid, i, msg.RuleResult["yolo"].([]structure.Result), weedfsUrl)
                if err != nil {
                    logger.Error("画框或上传图片服务器出错", err)
                } else {
@@ -467,7 +468,7 @@
        }
    }
}
func ChangeStatusYolo(msg ruleserver.ResultMsg) {
func ChangeStatusYolo(msg structure.ResultMsg) {
    logger.Info("往ES插yolo非报警状态改变数据")
    var sdkNames string = ""
    alarmRules := []AlarmRule{}
@@ -478,7 +479,7 @@
    i := protomsg.Image{}
    err = proto.Unmarshal(bdata, &i)
    //resp, err = util.PostFormBufferData(weedfsUrl, i, uuid.NewV4().String())
    resp, err := util.DrawPolygonOnImage(msg.Cid, i, msg.RuleResult["yolo"].([]ruleserver.Result), weedfsUrl)
    resp, err := util.DrawPolygonOnImage(msg.Cid, i, msg.RuleResult["yolo"].([]structure.Result), weedfsUrl)
    if err != nil {
        logger.Error("画框或上传图片服务器出错", err)
    } else {
@@ -538,7 +539,7 @@
        //os.Exit(1)
    }
}
func ChangeStatusFace(msg ruleserver.ResultMsg) {
func ChangeStatusFace(msg structure.ResultMsg) {
    logger.Info("往ES插入人脸非报警但是状态转换数据")
    // 上传大图
    // 解压缩并上传图片
@@ -595,7 +596,7 @@
        0,
        0,
        0,
        []*ruleserver.BaseInfo{},
        []*structure.BaseInfo{},
    }
    requstbody, err := json.Marshal(pervideo)
labelFilter/readyDataForLabel.go
@@ -3,7 +3,7 @@
import (
    "ruleprocess/cache"
    "ruleprocess/logger"
    "ruleprocess/ruleserver"
    "ruleprocess/structure"
    "time"
)
@@ -13,14 +13,14 @@
    CameraAddr    string
    TaskId        string
    Time          string
    Persons       []ruleserver.FaceResult
    Persons       []structure.FaceResult
    DefenceLevel  []int32
}
// 把数据装配到label
func (label *Label)DataFormatToLabel(result ruleserver.ResultMsg) {
    logger.Debug("face结果:",result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]ruleserver.FaceResult)) > 0)
    logger.Debug("yolo结果:",result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]ruleserver.Result)) > 0)
    if (result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]ruleserver.FaceResult)) > 0) || (result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]ruleserver.Result)) > 0) {
func (label *Label)DataFormatToLabel(result structure.ResultMsg) {
    logger.Debug("face结果:",result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0)
    logger.Debug("yolo结果:",result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]structure.Result)) > 0)
    if (result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0) || (result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]structure.Result)) > 0) {
        logger.Info("---------------标签过滤器赋值")
        label.CameraId = result.Cid
        camera, err := cache.GetCameraById(result.Cid)
@@ -31,14 +31,14 @@
        label.CameraAddr = camera.Addr
        label.TaskId = result.Tasklab.Taskid
        label.Time = time.Now().Format("2006-01-02 15:04:05")
        if result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]ruleserver.FaceResult)) > 0 {
            for _,faceGroup := range result.RuleResult["face"].([]ruleserver.FaceResult) {
        if result.RuleResult["face"] != nil && len(result.RuleResult["face"].([]structure.FaceResult)) > 0 {
            for _,faceGroup := range result.RuleResult["face"].([]structure.FaceResult) {
                label.Persons = append(label.Persons,faceGroup)
                label.DefenceLevel = append(label.DefenceLevel,faceGroup.AlarmLevel)
            }
        }
        if result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]ruleserver.Result)) > 0 {
            for _,yoloGroup := range result.RuleResult["yolo"].([]ruleserver.Result) {
        if result.RuleResult["yolo"] != nil && len(result.RuleResult["yolo"].([]structure.Result)) > 0 {
            for _,yoloGroup := range result.RuleResult["yolo"].([]structure.Result) {
                label.DefenceLevel = append(label.DefenceLevel,yoloGroup.AlarmLevel)
            }
        }
labelFilter/ruleForLabel.go
@@ -5,12 +5,12 @@
    "basic.com/pubsub/protomsg.git"
    "github.com/knetic/govaluate"
    "ruleprocess/logger"
    "ruleprocess/ruleserver"
    "ruleprocess/structure"
    "strconv"
    "time"
)
func Judge(msg ruleserver.ResultMsg) {
func Judge(msg structure.ResultMsg) {
    // 装配成自己可以识别的数据
    label := new(Label)
    label.DataFormatToLabel(msg)
@@ -311,7 +311,7 @@
}
// 调用目标服务器的插入接口
func pushData(urls []*protomsg.PushUrl, data ruleserver.ResultMsg) {
func pushData(urls []*protomsg.PushUrl, data structure.ResultMsg) {
    for _, url := range urls {
        logger.Debug("看看推送地址:",url.Url)
        Push("tcp://192.168.1.123:40012", data)
ruleserver/geoPolygon.go
@@ -2,6 +2,7 @@
import (
    "math"
    "ruleprocess/structure"
)
func min(num1 float64, num2 float64) float64 {
@@ -19,30 +20,10 @@
    return num1
}
//Point 坐标点
type Point struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
//Rect 检测目标
type Rect struct {
    X      float64
    Y      float64
    Width  float64
    Height float64
}
//Pointfloat 坐标点
type Pointfloat struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
//PintIsInPolygon 判断点是否在多边形内部
//point为要判断的坐标点
//polygon是多边形各点数组
func pintIsInPolygon(point Pointfloat, polygon []Point, widthScale float64, heightScale float64) bool {
func pintIsInPolygon(point structure.Pointfloat, polygon []structure.Point, widthScale float64, heightScale float64) bool {
    var nCross int = 0
    for i := 0; i < len(polygon); i++ {
@@ -72,17 +53,17 @@
}
//GetLocation 将一个给定起始坐标,宽度长度的矩形区域均分为n方份并返回中心坐标(n为单边平分数值)和面积
func getLocation(rect Rect, n int) ([]Pointfloat, float64) {
func getLocation(rect structure.Rect, n int) ([]structure.Pointfloat, float64) {
    xArr := make([]float64, n) // 用切片不用数组,数组不能用变量定义长度
    yArr := make([]float64, n)
    pointArr := make([]Pointfloat, 0, n*n)
    pointArr := make([]structure.Pointfloat, 0, n*n)
    for i := 0; i < n; i++ {
        xArr[i] = rect.X + (rect.Width/float64(2*n))*float64(2*i+1)
        yArr[i] = rect.Y + (rect.Height/float64(2*n))*float64(2*i+1)
    }
    for i := 0; i < n; i++ {
        for j := 0; j < n; j++ {
            point := Pointfloat{X: xArr[i], Y: yArr[j]}
            point := structure.Pointfloat{X: xArr[i], Y: yArr[j]}
            pointArr = append(pointArr, point)
        }
    }
@@ -91,7 +72,7 @@
}
//ComputePolygonArea 计算任意多边形面积
func computePolygonArea(polygon []Point) float64 {
func computePolygonArea(polygon []structure.Point) float64 {
    pointNum := len(polygon)
    var s float64 = 0
    if pointNum < 3 {
@@ -105,7 +86,7 @@
}
//PgsInterPercent calculate percent of two polygon intersection  计算两个多边形的重叠占比
func PgsInterPercent(pgpts []Point, box Rect, widthScale float64, heightScale float64) (percent float64) {
func PgsInterPercent(pgpts []structure.Point, box structure.Rect, widthScale float64, heightScale float64) (percent float64) {
    areapts, areaBox := getLocation(box, 10)
    var count = 0
ruleserver/personTrack.go
@@ -4,6 +4,7 @@
    "basic.com/pubsub/protomsg.git"
    "github.com/golang/protobuf/proto"
    "ruleprocess/logger"
    "ruleprocess/structure"
)
var TrackPond = make(map[string]*PersonTrack)
@@ -104,8 +105,8 @@
    return false
}
func TrackOrNot(label map[string]interface{}) bool{
    if label["yolo"] != nil && len(label["yolo"].([]Result)) > 0 {
        for _,res := range label["yolo"].([]Result) {
    if label["yolo"] != nil && len(label["yolo"].([]structure.Result)) > 0 {
        for _,res := range label["yolo"].([]structure.Result) {
            if res.TimeLabel == "10" {
                return true
            }
ruleserver/readyDataForRule.go
@@ -16,6 +16,7 @@
    "ruleprocess/cache"
    "ruleprocess/logger"
    "github.com/golang/protobuf/proto"
    "ruleprocess/structure"
    "strconv"
    "time"
)
@@ -56,20 +57,6 @@
    }
}
type BaseInfo struct {
    TableId      string  `json:"tableId"`
    TableName    string  `json:"tableName"`
    BwType       string  `json:"bwType"`
    CompareScore float64 `json:"compareScore"`
    PersonId     string  `json:"personId"`
    PersonName   string  `json:"personName"`
    PersonPicUrl string  `json:"personPicUrl"`
    PhoneNum     string  `json:"phoneNum"`
    Sex          string  `json:"sex"`
    IdCard       string  `json:"idCard"`
    MonitorLevel string  `json:"monitorLevel"`
    Content      string  `json:"content"`
}
// 以摄像机id查出跟其相关的所有任务下的所有规则组
func GetRuleGroup(cameraId string, taskId string) *protomsg.TaskGroupArgs {
@@ -110,9 +97,9 @@
    return value2
}
// 取出某个时间规则的第几天的规则段集合
func GetTimeById(id string, index int) []TimeRange {
func GetTimeById(id string, index int) []structure.TimeRange {
    _, cameraTimeRule := cache.GetTimeRuleById(id)
    var timeRangeList []Day
    var timeRangeList []structure.Day
    err := json.Unmarshal([]byte(cameraTimeRule.TimeRule), &timeRangeList)
    if err != nil {
        logger.Error("取时间规则时反序列化错误!")
@@ -137,24 +124,17 @@
    return 0
}
type TimeRange struct {
    Start string `json:"start"`
    End   string `json:"end"`
}
type Day struct {
    Day       int         `json:"day"`        // 标示当前星期几
    TimeRange []TimeRange `json:"time_range"` // 当天的几个时间段
}
// 将字符串格式的坐标序列化为Point格式
func Json2points(areaPoints string) []Point {
    var pts []Point
func Json2points(areaPoints string) []structure.Point {
    var pts []structure.Point
    if areaPoints == "[]" || areaPoints == "" {
        logger.Error("=====================此区域为全部区域")
        pts = append(pts, Point{0, 0})
        pts = append(pts, Point{0, 540})
        pts = append(pts, Point{960, 540})
        pts = append(pts, Point{960, 0})
        pts = append(pts, structure.Point{0, 0})
        pts = append(pts, structure.Point{0, 540})
        pts = append(pts, structure.Point{960, 540})
        pts = append(pts, structure.Point{960, 0})
    } else {
        err := json.Unmarshal([]byte(areaPoints), &pts)
        if err != nil {
@@ -166,7 +146,7 @@
}
// 给目标填充liker
func (arg *Arg) FillLiker(tableId []string, compareThreshold float32) {
func FillLiker(arg *structure.Arg,tableId []string, compareThreshold float32) {
    //bytes := bigCache.GetComparePersonBaseInfo(tableId, arg.Feature, compareThreshold)
    comArg := &protomsg.CompareArgs{
        TableIds:tableId,
@@ -204,7 +184,7 @@
                logger.Error("根据id查询底库信息出错!", err, "--返回值长度为:", len(table))
            }
            logger.Debug("看看这个base的对比值是多少:", Decimal(m[baseinfo.Id].CompareScore))
            base := BaseInfo{TableId: baseinfo.TableId, TableName: table[0].TableName, BwType: table[0].BwType, CompareScore: Decimal(m[baseinfo.Id].CompareScore), PersonId: baseinfo.Id, PersonName: baseinfo.PersonName, PersonPicUrl: baseinfo.PersonPicUrl, PhoneNum: baseinfo.PhoneNum, Sex: baseinfo.Sex, IdCard: baseinfo.IdCard, MonitorLevel: baseinfo.MonitorLevel, Content: baseinfo.Reserved}
            base := structure.BaseInfo{TableId: baseinfo.TableId, TableName: table[0].TableName, BwType: table[0].BwType, CompareScore: Decimal(m[baseinfo.Id].CompareScore), PersonId: baseinfo.Id, PersonName: baseinfo.PersonName, PersonPicUrl: baseinfo.PersonPicUrl, PhoneNum: baseinfo.PhoneNum, Sex: baseinfo.Sex, IdCard: baseinfo.IdCard, MonitorLevel: baseinfo.MonitorLevel, Content: baseinfo.Reserved}
            //os.Exit(1)
            arg.Liker = append(arg.Liker, &base)
        }
@@ -213,7 +193,7 @@
}
// 人脸比对
func Compare(args *SdkDatas, groupRule *protomsg.GroupRule) {
func Compare(args *structure.SdkDatas, groupRule *protomsg.GroupRule) {
    compareFlag := 0
    var tableIds []string
    var threshold float32 = 50 // 默认阈值为50
@@ -255,18 +235,18 @@
                            for _, arg := range areaMap.Args {
                                arg.Liker = arg.Liker[0:0]
                                logger.Info("清空之后看看之前打的人脸标签变了没:")
                                if args.RuleResult["face"] != nil && len(args.RuleResult["face"].([]FaceResult)) > 0 {
                                    for _, faceResult := range args.RuleResult["face"].([]FaceResult) {
                                if args.RuleResult["face"] != nil && len(args.RuleResult["face"].([]structure.FaceResult)) > 0 {
                                    for _, faceResult := range args.RuleResult["face"].([]structure.FaceResult) {
                                        for _,arg := range faceResult.Args {
                                            logger.Info("人员分值是:",arg.Score,"liker的数量为",arg.Liker)
                                        }
                                    }
                                }
                                if compareFlag == 1 {
                                    arg.FillLiker(nil, threshold)
                                    FillLiker(arg,nil, threshold)
                                }
                                if compareFlag == 2 {
                                    arg.FillLiker(tableIds, threshold)
                                    FillLiker(arg,tableIds, threshold)
                                }
                                //logger.Info("-------------------成功给liker赋值,长度为:", len(arg.Liker))
                            }
@@ -283,7 +263,7 @@
}
// 计算区域内的目标数量以及将相似度、占比、尺寸等打包
func (a *AreaMap) CountAreaObjs(arg *SdkData) {
func CountAreaObjs(a *structure.AreaMap,arg *structure.SdkData) {
    a.TargetNum = 0
    threshold := 0.0       // 相似度
@@ -298,7 +278,7 @@
        if threshold <= obj.Score && size <= float64(obj.Rects.Width*obj.Rects.Height) && intersectionper <= PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale) {
            // 这步要备齐表达式里所需要的所有参数
            a.TargetNum++
            arg1 := Arg{obj.Id,obj.Score, PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), obj.IsYolo, obj.Rects, obj.Feature, obj.ThftRes, []*BaseInfo{}}
            arg1 := structure.Arg{obj.Id,obj.Score, PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale), float64(obj.Rects.Width * obj.Rects.Height), obj.IsYolo, obj.Rects, obj.Feature, obj.ThftRes, []*BaseInfo{}}
            //logger.Println("放进去的arg:-------", arg1)
            a.Args = append(a.Args, &arg1)
            a.FilterData = append(a.FilterData, &arg1)
@@ -312,16 +292,16 @@
}
// 把sdk从数据帧上提取的按照区域分类归置
func SdkDataFormat(cameraId string, arg *SdkData, cameraPolygons []protomsg.CameraPolygon) {
func SdkDataFormat(cameraId string, arg *structure.SdkData, cameraPolygons []protomsg.CameraPolygon) {
    logger.Info("==================================本sdkData中解出来的目标数据=======================================")
    for _, photo := range arg.Photo {
        logger.Info("--------解析出来的数据---", cameraId, arg.IpcId, photo.Rects, photo.Score)
    }
    for _, polygon := range cameraPolygons {
        //logger.Println("++++++在这儿看一下区域啊:", polygon.Polygon)
        areaMap := AreaMap{CameraId: cameraId, AreaId: polygon.Id, AreaJson: polygon.Polygon, TriggerLine: polygon.TriggerLine, DirectionLine: polygon.DirectionLine}
        areaMap := structure.AreaMap{CameraId: cameraId, AreaId: polygon.Id, AreaJson: polygon.Polygon, TriggerLine: polygon.TriggerLine, DirectionLine: polygon.DirectionLine}
        // 为每个摄像机区域填充数据
        areaMap.CountAreaObjs(arg)
        CountAreaObjs(&areaMap,arg)
        arg.AreaMapList = append(arg.AreaMapList, &areaMap)
    }
}
ruleserver/ruleToformula.go
@@ -3,6 +3,7 @@
import (
    "ruleprocess/cache"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "sort"
    "strconv"
    "strings"
@@ -12,107 +13,8 @@
    "github.com/knetic/govaluate"
)
// 每个目标的参数:相似度,占比,尺寸
type Arg struct {
    Id         uint64
    Score      float64 // 区域内的目标的相似度
    Proportion float64 // 区域内的目标的占比
    Size       float64 // 区域内的目标的尺寸
    IsYolo     bool    // 是否是yolo数据
    Location   Rect    // 记下每个目标的位置参数,最后给结果装配人脸数据的时候用的到
    Feature    []byte
    ThftRes    protomsg.ThftResult
    Liker      []*BaseInfo
}
// 每个区域内的图片数据集合
type AreaMap struct {
    CameraId      string
    AreaId        string
    GroupId       string
    TaskId        string
    SdkId         string
    SdkName       string
    AreaJson      string
    TriggerLine   string
    DirectionLine string
    TargetNum     int    // 区域内目标数量
    Args          []*Arg // 区域内目标集合
    FilterData    []*Arg // 过滤后区域内目标集合
    Time          string // 当前时间(用以匹配时间规则)
    IsEffective   bool   // 规则中是否用到了此区域
    KeepRight     bool   // 是否靠右行
    IsStatic      bool   // 是否静止
}
// sdk输出的图片上单个目标的数据
type PhotoMap struct {
    Id      uint64
    Rects   Rect    // 矩形区域参数
    Score   float64 // 相似度得分(有多大程度像一个目标。人脸,人体或车等等)
    IsYolo  bool    // 是否是yolo数据
    ThftRes protomsg.ThftResult
    Feature []byte
}
// 每个算法对于当前帧画面自己提取的数据
type SdkData struct {
    TaskId      string
    IpcId       string
    IsYolo      bool
    Photo       []PhotoMap // yolo算法结构,也可以存人脸的数据,毕竟人脸中能用规则来测的还是那些参数
    KeepRight   bool       // 是否靠右行 算法判断的与上一帧图像的比较结果
    IsStatic    bool       // 是否静止
    ImageWidth  int        // 摄像机拍摄的图像宽 像素
    ImageHeight int        // 摄像机拍摄的图像高 像素
    AreaMapList []*AreaMap // 本sdk提取的数据按照区域划分后的数据集合
}
// 从算法模块儿拿来的对一帧图像各个算法提取的数据集合
type SdkDatas struct {
    CameraId   string
    TaskId     string
    Sdkdata    []*SdkData
    RuleResult map[string]interface{} // 过完规则后打的标签 face: []FaceResult, yolo: []Result
}
type ResultMsg struct {
    *protomsg.SdkMessage
    RuleResult map[string]interface{} // 过完规则后打的标签 face: []FaceResult, yolo: []Result
}
// 过规则库打上的标签
type Result struct {
    TaskId       string // 任务id
    SdkName      string
    RuleGroupId  string // 规则组id
    DefenceState bool   // 是否布防
    AlarmLevel   int32  // 报警等级
    RuleText     string // 文字版规则组
    Location     []Rect // 目标的坐标
    AlarmPolygon string // 触发的报警框
    IsLink       bool   // 是否是联动任务
    Others
}
type Others struct {
    CacheData []ResultMsg //(本组规则中含有持续时间的规则开启的定时器缓存的数据帧)
    LinkCache []ResultMsg
    TimeLabel string
}
// 过规则库打上的标签
type FaceResult struct {
    Result
    Args []Arg
}
type LittleRuleResult struct {
    SdkName string // 记录下此结果是哪个sdk的结果
    Result  string // 已包含了前置连接符
    Sort    int32
}
// 对单帧图像的判断 thisSdkDatas  当前传入的这帧数据,cacheSdkData 定时器里缓存的一帧数据 没有就返回nil  (thisSdkDatas SdkDatas, cacheSdkDatas SdkDatas)
func Judge(args *SdkDatas, message *protomsg.SdkMessage) {
func Judge(args *structure.SdkDatas, message *protomsg.SdkMessage) {
    if len(args.Sdkdata) > 0 {
        // 拿到本摄像机的区域
        cameraPolygons := GetPolygons(args.CameraId)
@@ -126,8 +28,8 @@
        //logger.Println("看下摄像机下的任务组:",taskRuleList)
        // 得到属于该摄像机的若干组任务的完整规则(跟每一条完整规则比较之后得出本张图像对于某个规则是否报警的结果。放进map,比如本帧图像的id,所碰撞成功的规则id)
        args.RuleResult = make(map[string]interface{})
        args.RuleResult["yolo"] = []Result{}
        args.RuleResult["face"] = []FaceResult{}
        args.RuleResult["yolo"] = []structure.Result{}
        args.RuleResult["face"] = []structure.FaceResult{}
        //logger.Warn("传进去之前是什么德行:",args.RuleResult["yolo"])
        if taskGroup != nil && len(taskGroup.GroupRules) > 0 {
            // 先过独立,再过联动
@@ -136,7 +38,7 @@
                taskId := taskGroup.TaskId
                //logger.Println("------------本组任务下的规则组的数量:",len(ruleList))
                temp := group.Rules // temp为一组完整规则 在此需要判断规则是否是联动规则
                label := Others{}
                label := structure.Others{}
                if len(temp) > 0 {
                    if group.SetType != "linkTask" {
                        // 独立任务的处理
@@ -149,7 +51,7 @@
                taskId := taskGroup.TaskId
                //logger.Println("------------本组任务下的规则组的数量:",len(ruleList))
                temp := group.Rules // temp为一组完整规则 在此需要判断规则是否是联动规则
                label := Others{}
                label := structure.Others{}
                if len(temp) > 0 {
                    if group.SetType == "linkTask" {
                        // groupId中含有link则为联动任务
@@ -161,7 +63,7 @@
    }
}
func RunRule(args *SdkDatas, groupRule *protomsg.GroupRule, taskId string, message *protomsg.SdkMessage, label Others) bool {
func RunRule(args *structure.SdkDatas, groupRule *protomsg.GroupRule, taskId string, message *protomsg.SdkMessage, label structure.Others) bool {
    defer func() {
        if err := recover(); err != nil {
            logger.Error("比对规则有误", err)
@@ -170,7 +72,7 @@
    logger.Info("+++++++++++规则开始运行+++++++++++++++++当前大规则--:", (*groupRule).GroupText)
    //logger.Warn("传进去之后是什么德行:",args.RuleResult["yolo"])
    Compare(args, groupRule)
    resultSplice := []*LittleRuleResult{}
    resultSplice := []*structure.LittleRuleResult{}
    sdkNames := ""
    polygonId := ""
    // 先过完条件规则
@@ -320,7 +222,7 @@
                // 打人脸标签和yolo标签
                // 最后成功报警才把符合条件的人脸数据塞进结果标签里
                // 配了人脸的算法才把人脸的数据甩出来打标签
                faces := []Arg{}
                faces := []structure.Arg{}
                faceFlag := false
                for j := 0; j < len(groupRule.Rules); j++ {
                    if groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" || groupRule.Rules[j].SdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
@@ -341,7 +243,7 @@
                //}
                logger.Warn("___________________________________________________________________________终于走完万里长征")
                // 把他们的位置数据也传下去
                locations := []Rect{}
                locations := []structure.Rect{}
                for _, sdkData := range args.Sdkdata {
                    if sdkData.IpcId == "02D54B61-0F16-C604-8567-FC4BE493C523" && sdkNames != "" { // 把yolo数据的各个目标的坐标输出方便后面画框
                        for _, areaMap := range sdkData.AreaMapList {
@@ -357,11 +259,11 @@
                    islink = false
                }
                if sdkNames != "" {
                    args.RuleResult["yolo"] = append(args.RuleResult["yolo"].([]Result), Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, locations, polygonId, islink, label,})
                    args.RuleResult["yolo"] = append(args.RuleResult["yolo"].([]structure.Result), structure.Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, locations, polygonId, islink, label,})
                    //logger.Info("-------------------yolo结果标签长度", len(args.RuleResult["yolo"].([]Result)))
                }
                if faceFlag {
                    args.RuleResult["face"] = append(args.RuleResult["face"].([]FaceResult), FaceResult{Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, []Rect{}, polygonId, islink, label,}, faces})
                    args.RuleResult["face"] = append(args.RuleResult["face"].([]structure.FaceResult), structure.FaceResult{structure.Result{taskId, sdkNames, groupRule.GroupId, groupRule.DefenceState, groupRule.AlarmLevel, groupRule.GroupText, []structure.Rect{}, polygonId, islink, label,}, faces})
                    //logger.Info("-------------------face结果标签", len(args.RuleResult["face"].([]FaceResult)))
                }
                return true
@@ -380,8 +282,8 @@
    }
}
func putFaceToResult(am *AreaMap, faceList []Arg) []Arg {
    faces := []Arg{}
func putFaceToResult(am *structure.AreaMap, faceList []structure.Arg) []structure.Arg {
    faces := []structure.Arg{}
    if len(am.FilterData) > 0 {
        for _, data := range am.FilterData {
            flag := true
@@ -399,8 +301,8 @@
    return faces
}
func putYolosToResult(am *AreaMap) []Rect {
    locations := []Rect{}
func putYolosToResult(am *structure.AreaMap) []structure.Rect {
    locations := []structure.Rect{}
    if len(am.FilterData) > 0 {
        for _, data := range am.FilterData {
            locations = append(locations, data.Location)
@@ -411,7 +313,7 @@
}
// 联动任务的处理
func LinkTask(args *SdkDatas, groupRule *protomsg.GroupRule, taskId string, message *protomsg.SdkMessage, label Others) {
func LinkTask(args *structure.SdkDatas, groupRule *protomsg.GroupRule, taskId string, message *protomsg.SdkMessage, label structure.Others) {
    // new一个定时器,如果以此groupId为标志的定时器不存在的话
    logger.Info("------------------------------------------当前是联动任务,规则是:", groupRule.GroupText)
    var flag bool = true
@@ -436,7 +338,7 @@
                }
            }
            if flag1 {
                TimeEleList[groupRule.GroupId].RuleResults = append(TimeEleList[groupRule.GroupId].RuleResults, &RuleResult{groupRule.Rules[j].CameraId, groupRule.Rules[j].Sort, "", groupRule.Rules[j].RuleWithPre, ResultMsg{}})
                TimeEleList[groupRule.GroupId].RuleResults = append(TimeEleList[groupRule.GroupId].RuleResults, &RuleResult{groupRule.Rules[j].CameraId, groupRule.Rules[j].Sort, "", groupRule.Rules[j].RuleWithPre, structure.ResultMsg{}})
            }
        }
    }
@@ -452,19 +354,19 @@
                tempMap := make(map[string]interface{})
                for k, result := range args.RuleResult {
                    if k == "yolo" {
                        tempMap[k] = []Result{}
                        for _, res := range result.([]Result) {
                            tempMap[k] = append(tempMap[k].([]Result), res)
                        tempMap[k] = []structure.Result{}
                        for _, res := range result.([]structure.Result) {
                            tempMap[k] = append(tempMap[k].([]structure.Result), res)
                        }
                    }
                    if k == "face" {
                        tempMap[k] = []FaceResult{}
                        for _, res := range result.([]FaceResult) {
                            tempMap[k] = append(tempMap[k].([]FaceResult), res)
                        tempMap[k] = []structure.FaceResult{}
                        for _, res := range result.([]structure.FaceResult) {
                            tempMap[k] = append(tempMap[k].([]structure.FaceResult), res)
                        }
                    }
                }
                va.CacheData = ResultMsg{message, tempMap}
                va.CacheData = structure.ResultMsg{message, tempMap}
                logger.Info("这个摄像机--", args.CameraId, "--被赋予了result", va.Result)
            }
        }
@@ -493,19 +395,19 @@
                    logger.Info("___________________________________________________________________联动任务报警")
                    if TimeEleList[groupRule.GroupId] != nil { // 极偶尔有情况会等于nil,不知道为啥,做个判断以防宕机
                        // 把数组里缓存的数据取出来一起报警
                        label.LinkCache = []ResultMsg{}
                        label.LinkCache = []structure.ResultMsg{}
                        for _, ruleRes := range TimeEleList[groupRule.GroupId].RuleResults {
                            label.LinkCache = append(label.LinkCache, ruleRes.CacheData)
                        }
                        logger.Debug("联动任务缓存了几个数据", len(label.LinkCache))
                        for i := 0; i < len(args.RuleResult["yolo"].([]Result)); i++ {
                            if args.RuleResult["yolo"].([]Result)[i].RuleGroupId == groupRule.GroupId { // 把联动数据追加上
                                args.RuleResult["yolo"].([]Result)[i].Others.LinkCache = label.LinkCache
                        for i := 0; i < len(args.RuleResult["yolo"].([]structure.Result)); i++ {
                            if args.RuleResult["yolo"].([]structure.Result)[i].RuleGroupId == groupRule.GroupId { // 把联动数据追加上
                                args.RuleResult["yolo"].([]structure.Result)[i].Others.LinkCache = label.LinkCache
                            }
                        }
                        for i := 0; i < len(args.RuleResult["face"].([]FaceResult)); i++ {
                            if args.RuleResult["face"].([]FaceResult)[i].RuleGroupId == groupRule.GroupId { // 把联动数据追加上
                                args.RuleResult["face"].([]FaceResult)[i].Others.LinkCache = label.LinkCache
                        for i := 0; i < len(args.RuleResult["face"].([]structure.FaceResult)); i++ {
                            if args.RuleResult["face"].([]structure.FaceResult)[i].RuleGroupId == groupRule.GroupId { // 把联动数据追加上
                                args.RuleResult["face"].([]structure.FaceResult)[i].Others.LinkCache = label.LinkCache
                            }
                        }
                    }
@@ -514,8 +416,8 @@
        } else {
            logger.Warn("数组不圆满不打标签")
            // 倒是把打的组规则标签给去掉了啊
            lens := len(args.RuleResult["yolo"].([]Result)) - 1
            args.RuleResult["yolo"] = args.RuleResult["yolo"].([]Result)[0:lens]
            lens := len(args.RuleResult["yolo"].([]structure.Result)) - 1
            args.RuleResult["yolo"] = args.RuleResult["yolo"].([]structure.Result)[0:lens]
        }
    } else { // 没有报警,
        //logger.Info("这帧图像在任务下的一整条规则下(联动任务下就是跟本摄像机像相关的小规则)的判断结果为false")
@@ -537,7 +439,7 @@
}
// 过滤规则先筛选出符合条件的目标数量
func filterRule(rule *protomsg.Rule, am *AreaMap) LittleRuleResult {
func filterRule(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" || rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" {
        // 处理的是人脸算法 如果这条规则配置的是人脸算法,过滤完条件之后直接得出结果,因为肯定没有数量条件,自己拼接
        //logger.Info("规则的算法id和区域的算法id:", rule.SdkId, "===", am.sdkId)
@@ -561,7 +463,7 @@
                    flag = "true"
                }
                logger.Info("---------人脸比对符合条件的数量为:", len(am.FilterData))
                return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" { // 人脸检测
                //logger.Debug("当前小规则是:",rule)
@@ -569,7 +471,7 @@
                    // 如果是不规矩的连接符统统返回false 规则也只能判断人脸的相似度,所以不存在别的连接符
                    if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
                        logger.Info("-----------------------过规则之前区域内的人脸数量为:", am.TargetNum)
                        var args []*Arg
                        var args []*structure.Arg
                        if rule.RuleWithPre == "&&" {
                            args = am.FilterData
                            //logger.Info("过滤后的args的长度为:",len(args))
@@ -602,27 +504,27 @@
                        logger.Info("过完条件后的目标数量为:", am.TargetNum)
                        if am.TargetNum > 0 {
                            logger.Info("!!!!!!!!!人脸检测成功")
                            return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                        } else {
                            return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                        }
                    } else {
                        return LittleRuleResult{}
                        return structure.LittleRuleResult{}
                    }
                } else {
                    return LittleRuleResult{}
                    return structure.LittleRuleResult{}
                }
            } else {
                return LittleRuleResult{}
                return structure.LittleRuleResult{}
            }
        } else {
            return LittleRuleResult{}
            return structure.LittleRuleResult{}
        }
    } else {
        // 处理的都是yolo数据
        if rule.PolygonId == am.AreaId { // 首先这条规则得是这个算法的规则,其次规则所对应的区域id要跟区域数据的id对的上
            if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
                var args []*Arg
                var args []*structure.Arg
                if rule.RuleWithPre == "&&" {
                    args = am.FilterData
                } else {
@@ -651,23 +553,23 @@
                }
                am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
                if am.TargetNum > 0 {
                    return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                    return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                } else {
                    return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                    return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                }
            } else {
                return LittleRuleResult{}
                return structure.LittleRuleResult{}
            }
        } else {
            return LittleRuleResult{}
            return structure.LittleRuleResult{}
        }
    }
}
// 如果有持续时间条件维护开启一个定时器
func duration(rule *protomsg.Rule, groupId string, am *AreaMap, args *SdkDatas, message *protomsg.SdkMessage) {
func duration(rule *protomsg.Rule, groupId string, am *structure.AreaMap, args *structure.SdkDatas, message *protomsg.SdkMessage) {
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上  配置的算法要对的上
        if rule.SdkArgAlias == "duration" { //
            logger.Info("当前小规则是:---------", rule)
@@ -682,7 +584,7 @@
            if flag {
                timeLength, _ := strconv.Atoi(rule.SdkArgValue)
                timeEle := TimeElement{N: timeLength, InitN: timeLength, AlarmFlag: false, BufferFlag: 10, CacheSdkData: ResultMsg{message, args.RuleResult}} // 扔进去一个定时器元素(并缓存当前画面帧数据)
                timeEle := TimeElement{N: timeLength, InitN: timeLength, AlarmFlag: false, BufferFlag: 10, CacheSdkData: structure.ResultMsg{message, args.RuleResult}} // 扔进去一个定时器元素(并缓存当前画面帧数据)
                //TimeEleList = make(map[string]timeElement)
                TimeEleList[groupId+"+"+rule.Id] = &timeEle // 定时器元素以当前持续时间小规则id为键
                logger.Info("创建了计数器")
@@ -692,13 +594,13 @@
}
// 给数据库的规则表达式代参 args: 一条子规则,区域数据
func transferParameters(rule *protomsg.Rule, am *AreaMap) LittleRuleResult {
func transferParameters(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "objCount" { // 如果参数是要区域内目标数量 即yolo 人脸不会有数量
            //logger.Info("当前小规则是:---------", rule)
            //logger.Info("得出结果阶段", "比较的规则是:", rule)
            if rule.Operator == "" {
                return LittleRuleResult{am.SdkName, strconv.Itoa(am.TargetNum) + "" + rule.RuleWithPre, rule.Sort} // 如果后面不跟操作符就直接返回数量  比如要跟下一个区域比较数量的就直接返回本区域的数量
                return structure.LittleRuleResult{am.SdkName, strconv.Itoa(am.TargetNum) + "" + rule.RuleWithPre, rule.Sort} // 如果后面不跟操作符就直接返回数量  比如要跟下一个区域比较数量的就直接返回本区域的数量
            }
            //args := am.targetNum     targetNum 已成所有目标的总数量,这里只算yolo的
            var num int = 0
@@ -710,13 +612,13 @@
            formula := strconv.Itoa(num) + " " + rule.Operator + " " + rule.SdkArgValue
            expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
            result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
            return LittleRuleResult{am.SdkName, rule.RuleWithPre + " " + strconv.FormatBool(result.(bool)), rule.Sort}
            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + " " + strconv.FormatBool(result.(bool)), rule.Sort}
            // 加上关于算法的判断条件,不能只有关于规则的,有的算法本身就是一个规则,如个体静止,靠右行,所以,拿到当前子规则的sdkid来判断是否是那些特殊的规则
        }
    }
    return LittleRuleResult{}
    return structure.LittleRuleResult{}
}
func timeRuleResult(rule *protomsg.Rule, am *AreaMap) LittleRuleResult {
func timeRuleResult(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "time_rule" { // 判断是否符合时间规
            //logger.Info("----------当前时间规则:---------", rule)
@@ -745,7 +647,7 @@
                        break
                    }
                }
                return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
            if rule.Operator == "unsatisfy" || rule.Operator == "!=" { // 不满足所选的时间规则
@@ -765,10 +667,10 @@
                        break
                    }
                }
                return LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
        }
    }
    return LittleRuleResult{}
    return structure.LittleRuleResult{}
}
ruleserver/timeTicker.go
@@ -3,6 +3,7 @@
import (
    "fmt"
    "ruleprocess/logger"
    "ruleprocess/structure"
    "strings"
    "time"
)
@@ -18,7 +19,7 @@
    InitN        int       // 赋值后就不变的初始值
    BufferFlag   int       // 缓冲容错位 连续n帧false才为false
    AlarmFlag    bool      // 报警标志位 定时器开启后第一次报警时会被置为true 往后再来报警也不会插进ES
    CacheSdkData ResultMsg // 定时器的缓存数据 持续时间类的开启定时器时要缓存一帧
    CacheSdkData structure.ResultMsg // 定时器的缓存数据 持续时间类的开启定时器时要缓存一帧
    GroupId      string    // 联动规则需要记录下此时的规则组id
    RuleResults  []*RuleResult
}
@@ -28,7 +29,7 @@
    Sort        int32     // 摄像机在规则组中序号
    Result      string    // 摄像机过滤数据得出的结果
    RuleWithPre string    // 摄像机之间的连接符
    CacheData   ResultMsg // 缓存当前帧数据
    CacheData   structure.ResultMsg // 缓存当前帧数据
}
func TimeTicker() {
@@ -69,7 +70,7 @@
}
// 判断是否符合定时器条件
func TimerAlarm(oth *Others, groupId string, result bool) (string) {
func TimerAlarm(oth *structure.Others, groupId string, result bool) (string) {
    var flagTime string //
    // 判断有无此规则组的定时器
    flag := false
@@ -92,7 +93,7 @@
                        logger.Debug("———————————-------------首次符合持续时间规则并报警")
                        flagTime = "10"
                        timeEle.AlarmFlag = true
                        oth.CacheData = []ResultMsg{}
                        oth.CacheData = []structure.ResultMsg{}
                        oth.CacheData = append(oth.CacheData,timeEle.CacheSdkData)
                        oth.TimeLabel = flagTime
                    }
@@ -143,7 +144,7 @@
func (p SubList) Less(i, j int) bool { return p[i].Sort < p[j].Sort }
// 结构体根据某字段排序
type resultList []*LittleRuleResult
type resultList []*structure.LittleRuleResult
func (p resultList) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p resultList) Len() int           { return len(p) }
structure/gragh.go
New file
@@ -0,0 +1,21 @@
package structure
//Point 坐标点
type Point struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
//Rect 检测目标
type Rect struct {
    X      float64
    Y      float64
    Width  float64
    Height float64
}
//Pointfloat 坐标点
type Pointfloat struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
structure/rule.go
New file
@@ -0,0 +1,126 @@
package structure
import "basic.com/pubsub/protomsg.git"
// 每个目标的参数:相似度,占比,尺寸
type Arg struct {
    Id         uint64
    Score      float64 // 区域内的目标的相似度
    Proportion float64 // 区域内的目标的占比
    Size       float64 // 区域内的目标的尺寸
    IsYolo     bool    // 是否是yolo数据
    Location   Rect    // 记下每个目标的位置参数,最后给结果装配人脸数据的时候用的到
    Feature    []byte
    ThftRes    protomsg.ThftResult
    Liker      []*BaseInfo
}
// 每个区域内的图片数据集合
type AreaMap struct {
    CameraId      string
    AreaId        string
    GroupId       string
    TaskId        string
    SdkId         string
    SdkName       string
    AreaJson      string
    TriggerLine   string
    DirectionLine string
    TargetNum     int    // 区域内目标数量
    Args          []*Arg // 区域内目标集合
    FilterData    []*Arg // 过滤后区域内目标集合
    Time          string // 当前时间(用以匹配时间规则)
    IsEffective   bool   // 规则中是否用到了此区域
    KeepRight     bool   // 是否靠右行
    IsStatic      bool   // 是否静止
}
// sdk输出的图片上单个目标的数据
type PhotoMap struct {
    Id      uint64
    Rects   Rect    // 矩形区域参数
    Score   float64 // 相似度得分(有多大程度像一个目标。人脸,人体或车等等)
    IsYolo  bool    // 是否是yolo数据
    ThftRes protomsg.ThftResult
    Feature []byte
}
// 每个算法对于当前帧画面自己提取的数据
type SdkData struct {
    TaskId      string
    IpcId       string
    IsYolo      bool
    Photo       []PhotoMap // yolo算法结构,也可以存人脸的数据,毕竟人脸中能用规则来测的还是那些参数
    KeepRight   bool       // 是否靠右行 算法判断的与上一帧图像的比较结果
    IsStatic    bool       // 是否静止
    ImageWidth  int        // 摄像机拍摄的图像宽 像素
    ImageHeight int        // 摄像机拍摄的图像高 像素
    AreaMapList []*AreaMap // 本sdk提取的数据按照区域划分后的数据集合
}
// 从算法模块儿拿来的对一帧图像各个算法提取的数据集合
type SdkDatas struct {
    CameraId   string
    TaskId     string
    Sdkdata    []*SdkData
    RuleResult map[string]interface{} // 过完规则后打的标签 face: []FaceResult, yolo: []Result
}
type ResultMsg struct {
    *protomsg.SdkMessage
    RuleResult map[string]interface{} // 过完规则后打的标签 face: []FaceResult, yolo: []Result
}
// 过规则库打上的标签
type Result struct {
    TaskId       string // 任务id
    SdkName      string
    RuleGroupId  string // 规则组id
    DefenceState bool   // 是否布防
    AlarmLevel   int32  // 报警等级
    RuleText     string // 文字版规则组
    Location     []Rect // 目标的坐标
    AlarmPolygon string // 触发的报警框
    IsLink       bool   // 是否是联动任务
    Others
}
type Others struct {
    CacheData []ResultMsg //(本组规则中含有持续时间的规则开启的定时器缓存的数据帧)
    LinkCache []ResultMsg
    TimeLabel string
}
// 过规则库打上的标签
type FaceResult struct {
    Result
    Args []Arg
}
type LittleRuleResult struct {
    SdkName string // 记录下此结果是哪个sdk的结果
    Result  string // 已包含了前置连接符
    Sort    int32
}
type TimeRange struct {
    Start string `json:"start"`
    End   string `json:"end"`
}
type Day struct {
    Day       int         `json:"day"`        // 标示当前星期几
    TimeRange []TimeRange `json:"time_range"` // 当天的几个时间段
}
type BaseInfo struct {
    TableId      string  `json:"tableId"`
    TableName    string  `json:"tableName"`
    BwType       string  `json:"bwType"`
    CompareScore float64 `json:"compareScore"`
    PersonId     string  `json:"personId"`
    PersonName   string  `json:"personName"`
    PersonPicUrl string  `json:"personPicUrl"`
    PhoneNum     string  `json:"phoneNum"`
    Sex          string  `json:"sex"`
    IdCard       string  `json:"idCard"`
    MonitorLevel string  `json:"monitorLevel"`
    Content      string  `json:"content"`
}