panlei
2019-08-16 31d7fc909556fe4116b63e3e6b9344e0513070b5
抽出人脸算法,并挂载新算法
3个文件已修改
357 ■■■■ 已修改文件
algorithm/face/face.go 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/readyDataForRule.go 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruleserver/ruleToformula.go 314 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
algorithm/face/face.go
@@ -7,9 +7,9 @@
    "ruleprocess/structure"
    "strconv"
)
func Entrance () {
// 人脸算法
func Entrance(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    return filterRule(rule,am)
}
// 过滤规则先筛选出符合条件的目标数量
@@ -18,7 +18,7 @@
        //logger.Info("规则的算法id和区域的算法id:", rule.SdkId, "===", am.sdkId)
        if rule.PolygonId == am.AreaId { // 算法和区域都得对的上
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && rule.SdkArgAlias != "time_rule"{
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && rule.SdkArgAlias != "time_rule"{ // 人脸比对
                //logger.Debug("当前小规则是:",rule)
                flag := "false"
                // 把没有相似者的人脸从filterData中删除
ruleserver/readyDataForRule.go
@@ -5,6 +5,7 @@
    "basic.com/pubsub/cache.git/esutil"
    "basic.com/pubsub/protomsg.git"
    "encoding/json"
    "errors"
    "fmt"
    "github.com/go-yaml/yaml"
    "io/ioutil"
@@ -12,6 +13,7 @@
    "nanomsg.org/go-mangos"
    "nanomsg.org/go-mangos/protocol/req"
    "nanomsg.org/go-mangos/transport/tcp"
    "net"
    "os"
    "ruleprocess/cache"
    "ruleprocess/logger"
@@ -154,7 +156,8 @@
        CompareThreshold:compareThreshold,
        Source:false,
    }
    bytes := Push("tcp://192.168.1.182:40010",comArg,sock)
    serverIp, _ := GetLocalIP()
    bytes := Push("tcp://"+serverIp+":40010",comArg,sock)
    var scResult protomsg.SdkCompareResult
    err1 := proto.Unmarshal(bytes, &scResult)
    if err1 != nil {
@@ -278,7 +281,7 @@
        if threshold <= obj.Score && size <= float64(obj.Rects.Width*obj.Rects.Height) && intersectionper <= PgsInterPercent(areaPoints, obj.Rects, widthScale, heigthScale) {
            // 这步要备齐表达式里所需要的所有参数
            a.TargetNum++
            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{}}
            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, []*structure.BaseInfo{}}
            //logger.Println("放进去的arg:-------", arg1)
            a.Args = append(a.Args, &arg1)
            a.FilterData = append(a.FilterData, &arg1)
@@ -343,3 +346,31 @@
    logger.Debug("数据推送成功!收到响应,数据长度为:",len(msg))
    return msg
}
// 获取本机ip
func GetLocalIP() (ipv4 string, err error) {
    var (
        addrs   []net.Addr
        addr    net.Addr
        ipNet   *net.IPNet // IP地址
        isIpNet bool
    )
    // 获取所有网卡
    if addrs, err = net.InterfaceAddrs(); err != nil {
        return
    }
    // 取第一个非lo的网卡IP
    for _, addr = range addrs {
        // 这个网络地址是IP地址: ipv4, ipv6
        if ipNet, isIpNet = addr.(*net.IPNet); isIpNet && !ipNet.IP.IsLoopback() {
            // 跳过IPV6
            if ipNet.IP.To4() != nil {
                ipv4 = ipNet.IP.String() // 192.168.1.1
                return
            }
        }
    }
    err = errors.New("ipv4 not found")
    return
}
ruleserver/ruleToformula.go
@@ -112,7 +112,7 @@
            }
        }
    }
    return false
}
func CallSo(sdkId string,rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult{
@@ -126,7 +126,7 @@
    if err1 != nil {
        panic("没有找到入口函数")
    }
    ruleResult := f.(func(rule *protomsg.Rule, am *structure.AreaMap))(rule,am)
    ruleResult := f.(func(rule *protomsg.Rule, am *structure.AreaMap)structure.LittleRuleResult)(rule,am)
    return ruleResult
}
@@ -156,7 +156,7 @@
            if ipcId == sdkData.IpcId {
                //logger.Info("当前走的规则是--:", sdkName, "---","")
                for _, areaMap := range sdkData.AreaMapList {
                    ruleResult := filterRule(groupRule.Rules[j], areaMap)
                    ruleResult := CallSo(sdk.Id,groupRule.Rules[j],areaMap)
                    if ruleResult.Result != "" {
                        logger.Info("条件规则结果:", ruleResult.Result)
                        // 如果结果为真,把这条规则中的区域置为有效
@@ -190,7 +190,7 @@
            sdkName := sdk.SdkName
            if ipcId == sdkData.IpcId {
                for _, areaMap := range sdkData.AreaMapList {
                    ruleResult := transferParameters(groupRule.Rules[j], areaMap)
                    ruleResult := CallSo(sdk.Id,groupRule.Rules[j],areaMap)
                    if ruleResult.Result != "" {
                        if strings.Contains(ruleResult.Result, "true") {
                            areaMap.IsEffective = true
@@ -340,7 +340,7 @@
        } else {
            // 结果为假时也要走,有时候为假的状态反转数据也需要记录下来
            //timeFlag := TimerAlarm(args, groupRule.GroupId, result.(bool))
            TimerAlarm(&label, groupRule.GroupId, result.(bool))
            //fmt.Println(timeFlag)
            return false
        }
@@ -506,134 +506,134 @@
}
// 过滤规则先筛选出符合条件的目标数量
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)
        if rule.PolygonId == am.AreaId { // 算法和区域都得对的上
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && rule.SdkArgAlias != "time_rule" {
                //logger.Debug("当前小规则是:",rule)
                flag := "false"
                // 把没有相似者的人脸从filterData中删除
                for index := 0; index < len(am.FilterData); {
                    // 将达不到阈值的相似者从相似者数组中删除
                    logger.Info("看看相似者人数:", len(am.FilterData[index].Liker))
                    if len(am.FilterData[index].Liker) == 0 {
                        // Go 语言中切片删除元素的本质是:以被删除元素为分界点,将前后两个部分的内存重新连接起来。不用怀疑,数组删除元素就这么坑爹
                        am.FilterData = append(am.FilterData[:index], am.FilterData[index+1:]...)
                    } else {
                        index++
                    }
                }
                if len(am.FilterData) > 0 {
                    flag = "true"
                }
                logger.Info("---------人脸比对符合条件的数量为:", len(am.FilterData))
                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
            }
            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" { // 人脸检测
                //logger.Debug("当前小规则是:",rule)
                if rule.Operator == "==" || rule.Operator == ">=" || rule.Operator == "<=" || rule.Operator == "<" || rule.Operator == ">" || rule.Operator == "!=" {
                    // 如果是不规矩的连接符统统返回false 规则也只能判断人脸的相似度,所以不存在别的连接符
                    if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
                        logger.Info("-----------------------过规则之前区域内的人脸数量为:", am.TargetNum)
                        var args []*structure.Arg
                        if rule.RuleWithPre == "&&" {
                            args = am.FilterData
                            //logger.Info("过滤后的args的长度为:",len(args))
                        } else {
                            args = am.Args
                            //logger.Info("没过滤的args的长度为:",len(args))
                        }
                        // 先清空过滤后的数据,再往里塞本次过滤后的数据
                        am.FilterData = am.FilterData[0:0]
                        //logger.Info("-----------------------人脸过滤的args里的数量:", len(args))
                        for _, arg := range args {
                            var formula string
                            if rule.SdkArgAlias == "score" {
                                formula = strconv.FormatFloat(arg.Score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                                logger.Info("当前相似度小公式:", formula)
                            } else if rule.SdkArgAlias == "proportion" {
                                formula = strconv.FormatFloat(arg.Proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                                logger.Info("当前占比小公式:", formula)
                            } else {
                                formula = strconv.FormatFloat(arg.Size, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                                logger.Info("当前尺寸小公式:", formula)
                            }
                            expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
                            result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
                            if result.(bool) {
                                am.FilterData = append(am.FilterData, arg) // 得到符合条件的过滤数据
                            }
                        }
                        am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
                        logger.Info("过完条件后的目标数量为:", am.TargetNum)
                        if am.TargetNum > 0 {
                            logger.Info("!!!!!!!!!人脸检测成功")
                            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                        } else {
                            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                        }
                    } else {
                        return structure.LittleRuleResult{}
                    }
                } else {
                    return structure.LittleRuleResult{}
                }
            } else {
                return structure.LittleRuleResult{}
            }
        } else {
            return structure.LittleRuleResult{}
        }
    } else {
        // 处理的都是yolo数据
        if rule.PolygonId == am.AreaId { // 首先这条规则得是这个算法的规则,其次规则所对应的区域id要跟区域数据的id对的上
            if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
                var args []*structure.Arg
                if rule.RuleWithPre == "&&" {
                    args = am.FilterData
                } else {
                    args = am.Args
                }
                // 先清空过滤后的数据,再往里塞本次过滤后的数据
                am.FilterData = am.FilterData[0:0]
                //logger.Debug("看看args:::::", args)
                for _, arg := range args {
                    var formula string
                    if rule.SdkArgAlias == "score" {
                        formula = strconv.FormatFloat(arg.Score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                        logger.Info("当前相似度小公式:", formula)
                    } else if rule.SdkArgAlias == "proportion" {
                        formula = strconv.FormatFloat(arg.Proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                        logger.Info("当前占比小公式:", formula)
                    } else {
                        formula = strconv.FormatFloat(arg.Size, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
                        logger.Info("当前尺寸小公式:", formula)
                    }
                    expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
                    result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
                    if result.(bool) {
                        am.FilterData = append(am.FilterData, arg) // 得到符合条件的过滤数据
                    }
                }
                am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
                if am.TargetNum > 0 {
                    return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
                } else {
                    return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
                }
            } else {
                return structure.LittleRuleResult{}
            }
        } else {
            return structure.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)
//        if rule.PolygonId == am.AreaId { // 算法和区域都得对的上
//
//            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a972" && rule.SdkArgAlias != "time_rule" {
//                //logger.Debug("当前小规则是:",rule)
//                flag := "false"
//                // 把没有相似者的人脸从filterData中删除
//                for index := 0; index < len(am.FilterData); {
//                    // 将达不到阈值的相似者从相似者数组中删除
//                    logger.Info("看看相似者人数:", len(am.FilterData[index].Liker))
//                    if len(am.FilterData[index].Liker) == 0 {
//                        // Go 语言中切片删除元素的本质是:以被删除元素为分界点,将前后两个部分的内存重新连接起来。不用怀疑,数组删除元素就这么坑爹
//                        am.FilterData = append(am.FilterData[:index], am.FilterData[index+1:]...)
//                    } else {
//                        index++
//                    }
//                }
//                if len(am.FilterData) > 0 {
//                    flag = "true"
//                }
//                logger.Info("---------人脸比对符合条件的数量为:", len(am.FilterData))
//                return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + flag, rule.Sort}
//            }
//            if rule.SdkId == "812b674b-2375-4589-919a-5c1c3278a97e" { // 人脸检测
//                //logger.Debug("当前小规则是:",rule)
//                if rule.Operator == "==" || rule.Operator == ">=" || rule.Operator == "<=" || rule.Operator == "<" || rule.Operator == ">" || rule.Operator == "!=" {
//                    // 如果是不规矩的连接符统统返回false 规则也只能判断人脸的相似度,所以不存在别的连接符
//                    if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
//                        logger.Info("-----------------------过规则之前区域内的人脸数量为:", am.TargetNum)
//                        var args []*structure.Arg
//                        if rule.RuleWithPre == "&&" {
//                            args = am.FilterData
//                            //logger.Info("过滤后的args的长度为:",len(args))
//                        } else {
//                            args = am.Args
//                            //logger.Info("没过滤的args的长度为:",len(args))
//                        }
//                        // 先清空过滤后的数据,再往里塞本次过滤后的数据
//                        am.FilterData = am.FilterData[0:0]
//                        //logger.Info("-----------------------人脸过滤的args里的数量:", len(args))
//                        for _, arg := range args {
//                            var formula string
//                            if rule.SdkArgAlias == "score" {
//                                formula = strconv.FormatFloat(arg.Score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
//                                logger.Info("当前相似度小公式:", formula)
//                            } else if rule.SdkArgAlias == "proportion" {
//                                formula = strconv.FormatFloat(arg.Proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
//                                logger.Info("当前占比小公式:", formula)
//                            } else {
//                                formula = strconv.FormatFloat(arg.Size, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
//                                logger.Info("当前尺寸小公式:", formula)
//                            }
//                            expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
//                            result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
//                            if result.(bool) {
//                                am.FilterData = append(am.FilterData, arg) // 得到符合条件的过滤数据
//                            }
//                        }
//                        am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
//                        logger.Info("过完条件后的目标数量为:", am.TargetNum)
//                        if am.TargetNum > 0 {
//                            logger.Info("!!!!!!!!!人脸检测成功")
//                            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
//                        } else {
//                            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
//                        }
//                    } else {
//                        return structure.LittleRuleResult{}
//                    }
//                } else {
//                    return structure.LittleRuleResult{}
//                }
//            } else {
//                return structure.LittleRuleResult{}
//            }
//        } else {
//            return structure.LittleRuleResult{}
//        }
//    } else {
//        // 处理的都是yolo数据
//        if rule.PolygonId == am.AreaId { // 首先这条规则得是这个算法的规则,其次规则所对应的区域id要跟区域数据的id对的上
//            if rule.SdkArgAlias == "score" || rule.SdkArgAlias == "proportion" || rule.SdkArgAlias == "size" { // 判断的是相似值,占比,尺寸等过滤条件,如果再有,还可以再加
//                var args []*structure.Arg
//                if rule.RuleWithPre == "&&" {
//                    args = am.FilterData
//                } else {
//                    args = am.Args
//                }
//                // 先清空过滤后的数据,再往里塞本次过滤后的数据
//                am.FilterData = am.FilterData[0:0]
//                //logger.Debug("看看args:::::", args)
//                for _, arg := range args {
//                    var formula string
//                    if rule.SdkArgAlias == "score" {
//                        formula = strconv.FormatFloat(arg.Score, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
//                        logger.Info("当前相似度小公式:", formula)
//                    } else if rule.SdkArgAlias == "proportion" {
//                        formula = strconv.FormatFloat(arg.Proportion, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
//                        logger.Info("当前占比小公式:", formula)
//                    } else {
//                        formula = strconv.FormatFloat(arg.Size, 'f', -1, 64) + " " + rule.Operator + " " + rule.SdkArgValue // 得到字符串公式
//                        logger.Info("当前尺寸小公式:", formula)
//                    }
//                    expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
//                    result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
//                    if result.(bool) {
//                        am.FilterData = append(am.FilterData, arg) // 得到符合条件的过滤数据
//                    }
//                }
//                am.TargetNum = len(am.FilterData) // 把符合条件的目标数量更新到targetNum字段
//                if am.TargetNum > 0 {
//                    return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "true", rule.Sort}
//                } else {
//                    return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + "" + "false", rule.Sort}
//                }
//
//            } else {
//                return structure.LittleRuleResult{}
//            }
//
//        } else {
//            return structure.LittleRuleResult{}
//        }
//    }
//}
// 如果有持续时间条件维护开启一个定时器
func duration(rule *protomsg.Rule, groupId string, am *structure.AreaMap, args *structure.SdkDatas, message *protomsg.SdkMessage) {
@@ -661,30 +661,30 @@
}
// 给数据库的规则表达式代参 args: 一条子规则,区域数据
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 structure.LittleRuleResult{am.SdkName, strconv.Itoa(am.TargetNum) + "" + rule.RuleWithPre, rule.Sort} // 如果后面不跟操作符就直接返回数量  比如要跟下一个区域比较数量的就直接返回本区域的数量
            }
            //args := am.targetNum     targetNum 已成所有目标的总数量,这里只算yolo的
            var num int = 0
            for _, data := range am.FilterData {
                if data.IsYolo {
                    num++
                }
            }
            formula := strconv.Itoa(num) + " " + rule.Operator + " " + rule.SdkArgValue
            expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
            result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + " " + strconv.FormatBool(result.(bool)), rule.Sort}
            // 加上关于算法的判断条件,不能只有关于规则的,有的算法本身就是一个规则,如个体静止,靠右行,所以,拿到当前子规则的sdkid来判断是否是那些特殊的规则
        }
    }
    return structure.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 structure.LittleRuleResult{am.SdkName, strconv.Itoa(am.TargetNum) + "" + rule.RuleWithPre, rule.Sort} // 如果后面不跟操作符就直接返回数量  比如要跟下一个区域比较数量的就直接返回本区域的数量
//            }
//            //args := am.targetNum     targetNum 已成所有目标的总数量,这里只算yolo的
//            var num int = 0
//            for _, data := range am.FilterData {
//                if data.IsYolo {
//                    num++
//                }
//            }
//            formula := strconv.Itoa(num) + " " + rule.Operator + " " + rule.SdkArgValue
//            expression, _ := govaluate.NewEvaluableExpression(formula) // 得到数学公式
//            result, _ := expression.Evaluate(nil)                      // 得到数学公式的结果
//            return structure.LittleRuleResult{am.SdkName, rule.RuleWithPre + " " + strconv.FormatBool(result.(bool)), rule.Sort}
//            // 加上关于算法的判断条件,不能只有关于规则的,有的算法本身就是一个规则,如个体静止,靠右行,所以,拿到当前子规则的sdkid来判断是否是那些特殊的规则
//        }
//    }
//    return structure.LittleRuleResult{}
//}
func timeRuleResult(rule *protomsg.Rule, am *structure.AreaMap) structure.LittleRuleResult {
    if rule.PolygonId == am.AreaId { // 首先规则所对应的区域id要跟区域数据的id对的上
        if rule.SdkArgAlias == "time_rule" { // 判断是否符合时间规