地籍数据属性质检功能设计与实现(改进)

【需求】

某单位不动产登记系统,在对不动产数据(包括:使用权宗地、所有权宗地、自然幢)进行入库前,要进行属性检查,判断某些属性字段是否满足规则要求。主要规则可抽象为以下几类:

1.不允许为空值

2.必须来自某一特定字典,可为一个或多个值,多个值时以指定的分隔符隔开

3.位数固定,且全部为数字,或为数字与字母混合

4.为固定的某个值

5.一些位上的值会与其他位上的值有关系

【设计】

在进行该项功能设计时,为保证可扩展性,考虑制定规则配置的规范,将规则保存到配置文件中,代码部分只做对规则的解析和判定。接口传入参数采用GeoJSON的Feature格式,其属性为Dictionary<string,object>类型的集合。

配置文件规则如下:

文件内容为JSON集合类型。featureclass指定了要质检的图层(集合,fields其待质检的属性。

一个配置项中,fields各属性字段质检规则的集合。一个属性质检规则而言

  • name属性名,该字段的名字(不区分大小写)
  • nullable表示允许为空(如配置为false表示不允许为空,若传入的要素该字段值为空,则不满足规则)
  • collection表示该项值是否来源于集合,其中seperator取值的分隔符,list取值集合(英文半角逗号间隔。取值集合为01,011,012,013”,分隔符为“;”,以下取值满足规则要求:012;”、“01;011;”、“013”、“01;012”,而如下取值不满足01012”、“01011013”、“012,013”、“011,012;013;
  • expression正则表达式,该字段取值需符合指定的正则表达式规则,如“^((G[BDEFSXY])|(J[ABCDEFSXY])|(ZW))$”(注意:部分特殊字符需进行转义,如\”应写作 “\\

如:

[
    {
        "featureclass": [
            "ZD_SHYQ",
            "ZD_SHYQ_WRK"
        ],
        "fields": [
            {
                "name": "ZDTZM",
                "nullable": false,
                "expression": "^((G[BDEFSXY])|(J[ABCDEFSXY])|(ZW))$"
            },
            {
                "name": "ZL",
                "nullable": false
            },
            {
                "name": "YT",
                "nullable": false,
                "collection": {
                    "seperator": ";",
                    "list": "01,011,012,013"
                }
            }
        ]
    },
    {
        "featureclass": [
            "ZRZ"
        ],
        "fields": [
            {
                "name": "",
                "nullable": false,
                "collection": {
                    "seperator": "",
                    "list": ""
                },
                "expression": ""
            }
        ]
    }
]
【实现】


我们定义了一个类,来实现对单个要素的质检:

using GeoJSON.Net.Feature;
using GISWebService.HttpRequestContent;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;

namespace GISWebService.Common
{
    public class CheckFieldsHelper
    {
        private static string _ConfigFileName = "CheckFields.json";
        private static List<FeatureClassRule> _FeatureClassRules = null;

        public static List<FeatureClassRule> FeatureClassRules
        {
            get
            {
                if (null == _FeatureClassRules)
                    _FeatureClassRules = Load();
                return _FeatureClassRules;
            }
        }

        private static string GetConfigFile()
        {
            string s = System.IO.Path.Combine(AppSettings.PathByKey("tempdir"), _ConfigFileName);
            return System.IO.File.Exists(s) ? s : "";
        }

        public static List<FeatureClassRule> Load()
        {
            string sPath = GetConfigFile();
            List<FeatureClassRule> ls = new List<FeatureClassRule>();
            if(!string.IsNullOrEmpty(sPath))
            {
                string sContent = System.IO.File.ReadAllText(sPath, System.Text.Encoding.Default);
                ls = Newtonsoft.Json.JsonConvert.DeserializeObject<List<FeatureClassRule>>(sContent);
            }
            return ls;
        }

        public static CheckPropertyResult Check(string featureclass, Feature feature)
        {
            CheckPropertyResult result = new CheckPropertyResult() { ObjectID = -1, FieldInfo = new List<string>() };
            Dictionary<string, object> dict = feature.Properties;
            int nA = -1;
            for (int n = 0; n < FeatureClassRules.Count; n++)
            {
                int m = FeatureClassRules[n].FeatureClassNames.FindIndex((e) => { return 0 == string.Compare(e, featureclass, true); });
                if (m >= 0)
                {
                    nA = n;
                    break;
                }
            }
            if (nA < 0)
                return new CheckPropertyResult();
            List<FieldRule> lsRule = FeatureClassRules[nA].RuleOfFields;
            foreach (var aPair in dict)
            {
                if (0 == string.Compare(aPair.Key, "objectid", true))
                    result.ObjectID = Convert.ToInt32(aPair.Value);
                FieldRule fieldRule = null;
                for (int k = 0; k < lsRule.Count; k++)
                {
                    if (0 == string.Compare(lsRule[k].FieldName, aPair.Key, true))
                    {
                        fieldRule = lsRule[k];
                        break;
                    }
                }
                if (null == fieldRule)
                    continue;

                string sValue = "";
                if (null != aPair.Value)
                    sValue = aPair.Value.ToString().Replace(" ", "");

                if (!fieldRule.Nullable)
                {
                    if (string.IsNullOrEmpty(sValue))
                    {
                        result.FieldInfo.Add(string.Format("字段 {0} 取值不允许非空", aPair.Key));
                        continue;
                    }
                }
                if (!string.IsNullOrEmpty(sValue) && null != fieldRule.RuleOfCollection)
                {
                    if (null != fieldRule.RuleOfCollection.Items && 0 < fieldRule.RuleOfCollection.Items.Count && !string.IsNullOrEmpty(fieldRule.RuleOfCollection.Seperator))
                    {
                        char[] cSeperator = fieldRule.RuleOfCollection.Seperator.ToCharArray();
                        string[] arrayValue = sValue.Split(cSeperator, StringSplitOptions.RemoveEmptyEntries);
                        foreach(var item in arrayValue)
                        {
                            if (0 > fieldRule.RuleOfCollection.Items.FindIndex(e => { return 0 == string.Compare(item, e, true); }))
                            {
                                result.FieldInfo.Add(string.Format("字段 {0} 取值不在指定的集合范围内", aPair.Key));
                                break;
                            }
                        }
                    }
                }
                if (!string.IsNullOrEmpty(sValue) && !string.IsNullOrEmpty(fieldRule.RegExp))
                {
                    if(!(new Regex(fieldRule.RegExp).IsMatch(sValue)))
                        result.FieldInfo.Add(string.Format("字段 {0} 取值不符合规范", aPair.Key));
                }
            }
            return (result.ObjectID < 0) ? new CheckPropertyResult() : result;
        }
    }
}

调用的地方比较简单,就不啰嗦了。

返回结果示例如下:

{
    "status": 0,
    "result": [
        {
            "layer": "ZRZ",
            "info": [
                {
                    "objectid": 1343,
                    "fields": [
                        "字段 ZDDM 长度不为 19 位",
                        "字段 BDCDYH 长度不为 28 位",
                        "字段 ZRZH 长度不为 24 位",
                        "字段 ZDZHTZM 不符合规范"
                    ]
                },
                {
                    "objectid": 813,
                    "fields": []
                }
            ]
        },
        {
            "layer": "ZD_SHYQ",
            "info": [
                {
                    "objectid": 780,
                    "fields": [
                        "必填字段 QLR 为空",
                        "字段 YSDM 长度不为 10 位",
                        "字段 BDCDYH 长度不为 28 位",
                        "字段 ZDTZM 不符合规范",
                        "字段 DZWTZM 不符合规范"
                    ]
                }
            ]
        }
    ]
}

猜你喜欢

转载自blog.csdn.net/a_dev/article/details/80381071