资讯详情

资讯详情

JTT 697.7交通地理信息数据元标准:从字段定义到建表落地的实操指南

简介《JTT 697.7-2014 交通信息基础数据元 第7部分》是交通运输行业标准属于《交通信息基础数据元》系列的第7部分专门规定道路运输信息基础数据元的编制原则、分类方法、具体内容与值域代码。该标准覆盖基本信息、行政许可、日常管理、行政执法、应急管理等功能域的数据元定义适用于交通信息化项目设计、数据库建模、数据字典编制、接口开发与标准合规审查等场景可为系统架构师、数据管理员和运维人员提供权威参考。压缩包内含1个PDF文件总大小约1.03MB为标准正式文本便于在线查阅和打印归档该版本为2015年实施的现行有效标准取代2007年旧版内容更贴合当前道路运输管理需要发布至今已有664人浏览学习。通过阅读该PDF读者可完整获得道路运输信息基础数据元的分类框架、核心数据项及配套代码表可用于核对本单位数据资产、优化业务系统数据结构并为跨部门数据交换与共享提供统一语言。1. 同一段路十个系统十种写法JTT 697.7 先把“位置”字段统一了再说同一段路A 系统的数据库里叫“起点经度”B 系统的接口文档里叫“X坐标”C 系统的数据交换文件干脆给了一个字符串“116.44355,39.92017”。三套数据汇到一起位置对不上、报表没法出负责对接的人抱着字段清单查了一整天最后发现只是字段命名和格式不一致。这是所有做交通数据的人都撞过的墙。JT/T 697.7-2014标题里常见的写法是 JTT 697.7-2014就是用来拆这堵墙的标准交通信息基础数据元系列的第 7 部分集中定义交通地理信息这类带空间属性的基础数据元从经度纬度、行政区划代码到桩号、路线编号、坐标参照系。它的作用不是塞给你一堆死字段而是给每一个地理相关字段约定一套固定的标识、名称、类型、格式和值域。这篇笔记我按自己做数据仓库和接口对接的经验把它拆成能直接落库、能用来写校验 SQL 的实操路径适合数据架构、接口开发、数据治理三类人参考。2. 数据元标准怎么读把属性、类型和标识符先吃透很多团队拿到 JTT 697.7-2014 直接翻数据元目录看到几百个字段就头晕然后挑几个名字像的复制进建表脚本结果验收时被专家问一句“这个数据元的标识符是多少”就卡住了。读这种标准先别急着抄字段先弄懂一个数据元本身长什么样。JTT 697 系列第 1 部分定了总则第 7 部分按同样的规则定义地理信息数据元属性结构是一致的。2.1 以“起点经度”为例一个数据元由哪些属性定义一个数据元不是“一个字段名”那么简单它是由一组属性描述的完整定义。我一般拿到目录先看一个典型案例把属性拆开后面所有字段都能照这个套路理解。下表整理的是地理信息数据元里最常出现的核心属性属性用“起点经度”举例作用数据元标识符一组数字编码跨系统引用的唯一键中文名称起点经度给人看的标准名英文名称startLongitude 之类给程序和接口设计用定义路线起点的经度坐标十进制度表示消除歧义数据类型N数值型决定存储方式表示格式N..10,6决定长度和小数位值域-180180决定校验规则同义名称经度、起点X坐标兼容老系统叫法这里最容易被忽略的是“定义”和“同义名称”。定义解决歧义比如“高程”指的是海拔高还是相对高差必须写清楚同义名称解决兼容老系统里叫“纬度”新系统里叫“lat”靠同义名称确认是同一个东西。落地时我习惯要求建表脚本里每一列的注释都写标准中文名和标识符而不是只写日常叫法这样审计和对接都有据可查。值域这个属性在交通地理信息里特别关键。经度不是“随便一个数字”它有边界有单位可能还有坐标系依赖。标准里给的范围是十进制度下的 -180180如果你在字段里存了“116°26′32″”类型就错了因为那是度分秒格式字符串不是数值。所以读属性时单位、类型、值域三个要连在一起看。2.2 数据类型与表示格式标准里的 C..6、N..10,6 对应数据库什么类型数据元目录里几乎每个字段都带一个表示格式写法类似 C..6、N..10,6、DT。这个写法来自数据元标准化的通用规则字符型用 C 表示数值型用 N 表示日期时间型用 DT 表示C 后面的数字是最大字符数N 后面的两组数字分别是最大总长度和小数位数。比如 N..10,6 表示最长 10 位数字、其中 6 位小数注意这里的位数是“上限”不是说每条记录都得填满。落到数据库时我常用的对应关系如下表表示格式含义建议数据库类型说明C..4最多 4 个字符VARCHAR(4) 或 CHAR(4)定长代码用 CHAR 更省空间C..6最多 6 个字符CHAR(6)行政区划代码固定 6 位用定长C..20最多 20 个字符VARCHAR(20)路线编号、标识码之类N..8,2最多 8 位2 位小数NUMERIC(8,2)面积、里程等数值N..10,6最多 10 位6 位小数NUMERIC(10,6)经纬度坐标DT日期时间DATETIME标准里一般要求精确到秒这里要说一个血泪经验表示格式里 N..10,6 的“10”是总位数包含小数位不包含负号位。经度最大值是 180加上 6 位小数整数部分 3 位加小数 6 位共 9 位再加负号正好 10 个字符位置。实际建表时会发现 180.123456 这种值用 NUMERIC(9,6) 是存不下的整数部分 3 位加小数 6 位等于 9 位数字看起来刚好但带符号或超 180 的值就悬了。所以我统一用 NUMERIC(10,6) 给经度纬度留余量纬度虽然只有 -9090也保持一致省得两种字段两种长度校验和索引都不好写。2.3 数据元标识符为什么跨系统引用时不能自己编一套标识符是数据元在标准体系里的身份证。JTT 697 系列的标识符编码规则由第 1 部分总则统一规定按业务分类给一段编码空间第 7 部分的地理信息数据元在分配到的区间内编排。这意味着两件事第一标识符在系列标准里唯一第二标识符的编号语义不能只看后几位必须结合分类码理解。实际交换场景里很多系统的接口文档不写中文名直接引用标准标识符。比如交换文件里一个字段标注为“对应 JTT 697.7 数据元标识符 XXX”接收方一看就知道这是经度还是纬度格式是什么。如果团队自造一套编号比如“lon01”“wd002”对接时对方在标准里查不到就得靠人工猜这就是典型的“字段没对齐”事故源头。我一般的做法是建一张映射表把标准标识符、数据元中文名称、数据库列名、接口 key 四列放一起。这张表比任何文档都好用新同事接手时查它写接口文档时参考它做数据质量检查时也用它的值域信息。标准里每一条数据元都有同义名称映射表里保留一列“历史叫法”老系统迁移时靠这一列完成自动匹配比人工翻旧文档快得多。3. 从目录到建表用第 7 部分的数据元设计一张路段位置信息表标准读完了就得干活。最典型的落地场景是新建一张业务表里面带位置信息。现实中有两种做法一种是把数据元目录里所有地理信息字段全建进去另一种是业务要什么建什么但字段属性全按标准来。我见过第一种做法的结果一张表两百多列大部分是空的维护成本极高。正确姿势是先圈定业务范围再从目录里挑子集。3.1 先按业务场景挑数据元一张业务表只取目录的一个子集以“路段基础位置信息表”为例业务上需要记录一个路段的编码、起终点行政区划、起终点经纬度、起点高程、桩号和坐标系信息。从 JTT 697.7 的地理信息数据元目录里我按用途挑了下面这几个每个都明确类型和值域数据元用途类型/格式值域/说明路段编码C..20业务系统内唯一建主键起点行政区划代码C..6引用行政区划代码标准6 位数字终点行政区划代码C..6同上允许为空起点经度N..10,6十进制度-180180起点纬度N..10,6十进制度-9090终点经度N..10,6同上终点纬度N..10,6同上起点高程N..8,2单位米建议加业务范围校验桩号C..20字符串文本格式坐标系标识C..16枚举值见第 4 章挑数据元的判断标准就三条业务过程是否真的要用这个字段做查询或计算标准里是否有现成定义字段是否属于这个表的主题域。比如“路段编码”和“路线编号”是两个东西前者是一条具体路段的实例标识后者是路线名称编码不能混。如果业务只到路段级路线编号就不必放进这张表。3.2 建表语句与字段映射一份可直接改的 MySQL DDL选定数据元后下一步就是建表。我给的 DDL 是完全按上述数据元属性定的字段名用英文名对应注释写标准中文名这样代码和标准对得上CREATE TABLE section_location ( route_sec_code VARCHAR(20) NOT NULL COMMENT 路段编码, start_region CHAR(6) NOT NULL COMMENT 起点行政区划代码, end_region CHAR(6) NULL COMMENT 终点行政区划代码, start_lon NUMERIC(10,6) NOT NULL COMMENT 起点经度(十进制度), start_lat NUMERIC(10,6) NOT NULL COMMENT 起点纬度(十进制度), end_lon NUMERIC(10,6) NULL COMMENT 终点经度, end_lat NUMERIC(10,6) NULL COMMENT 终点纬度, start_elevation NUMERIC(8,2) NULL COMMENT 起点高程(米), chainage VARCHAR(20) NULL COMMENT 桩号,如K12350, coord_sys VARCHAR(16) NOT NULL DEFAULT CGCS2000 COMMENT 坐标系标识, data_source VARCHAR(64) NULL COMMENT 数据来源, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (route_sec_code), KEY idx_start_region (start_region), KEY idx_start_lonlat (start_lon, start_lat) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT路段基础位置信息表;这段 DDL 里几个选择值得说一下。经度纬度用 NUMERIC 而不用 DOUBLE这在前面的映射表提到过数值型在等值查询和导出时行为可预期不会出现 116.4439999 这种浮点尾巴。起点行政区划用 CHAR(6) 定长因为它是固定 6 位代码定长字段在 MySQL 里检索和存储都有优势还能隐式拦住位数不够的脏数据。桩号用 VARCHAR(20)它本质是展示型编码不是数值不能参与数值计算。coord_sys 字段是很多表里没有的但我觉得必加。坐标系是地理信息数据元的地基加了它后续即使混入不同坐标系的坐标也能靠这个字段回溯和转换。默认值设 CGCS2000 是基于当前行业做法如果你的项目明确用 WGS-84就设 WGS-84关键是一张表里只能有一种默认值不能一半一个。3.3 接口 JSON 字段契约key、单位、坐标顺序都要写在文档里建完表只是内部问题接口交换才是标准发挥价值的地方。我见过的翻车现场是数据库列名用 snake_case接口 key 用驼峰两边还没映射关系联调时全靠开发互相问。正确做法是接口 key 直接沿用字段英文名同时把数据元标识符写进接口文档的字段描述里。一个路段位置信息的出参示例{ routeSecCode: G108-015, start: { regionCode: 110101, lon: 116.44355, lat: 39.92017, elevation: 42.5 }, end: { regionCode: 110102, lon: 118.17207, lat: 40.91623, elevation: 68.3 }, chainage: K12350, coordSys: CGCS2000, updateTime: 2024-06-01T08:30:00Z }这个 JSON 里每个 key 都对应数据元的英文名称单位在文档里固定为度、米、ISO 8601 时间。特别注意 start 对象里 lon 在 lat 前面这是和地理数据交换常见惯例对齐的方式很多协议和工具默认 x 坐标经度在前。如果团队习惯把纬度放前面必须有显式文档说明否则下游拿去做地图展示时会发现点在镜像位置。接口契约里还要写清楚两个约定一是缺省值规则比如 end 对象坐标为 null 时表示该路段终点位置未采集不能默认填 0因为经度 0 度纬度 0 度是真实位置不是空值二是 coordSys 必须参与传输不能因为库里有默认值就不传否则接收方拿到数据无法判断坐标系。这两条在标准里不会直接写但属于把标准落地时必须补充的工程约束。4. 值域、坐标与格式数据交换里最容易对不齐的三层约束建表只是第一步真正让数据能跨系统流动的是约束。JTT 697.7 里的地理信息数据元有三层约束最容易被忽略值域、坐标系、格式。这三层任何一个不一致数据合流时都是灾难。4.1 引用型值域与枚举型值域行政区划代码这类字段怎么约束值域分两种一种引用别的标准一种直接枚举。行政区划代码属于前者取值来源是行政区划代码国家标准6 位数字前两位省级、中间两位地级、后两位区县。这种字段的校验不能只查位数还得查代码是否真实存在不然“110199”这种假代码也过得了位数检查。枚举型值域的例子是坐标系标识常见取值有 CGCS2000、WGS-84、GCJ-02、BD-09。标准给出的是坐标系数据元的取值框架具体落到枚举时我一般在应用层维护一张字典表把代码值和显示名分开代码值显示名称说明CGCS20002000国家大地坐标系当前行业主导坐标系WGS-84世界大地测量系统GPS 原始输出常用GCJ-02国测局加密坐标国内地图产品常用BD-09百度坐标百度系产品专用字典表的优势是代码值稳定、显示名可改。比如坐标系改名了只改字典表的显示名数据里的代码值不用动。这个思路也适用于道路等级、路面类型这类枚举型数据元库表里存数字代码或短代码接口输出时映射成中文不要让中文直接进库否则写错一个字统计就分叉了。对引用型值域我建议在建表时加一层存在性验证。简单做法是导入一张区划代码表写约束时 JOIN 检查复杂做法是引入标准代码服务。中小项目用前者就够关键是别让校验停留在“6 位数字”这种表面规则。4.2 坐标系与经纬度精度存坐标不能“有数就行”坐标系是地理信息类数据元里最容易被无视、后果又最严重的属性。WGS-84 和 CGCS2000 在当前精度下差异很小通常可以视为一致但 GCJ-02 是加密坐标和 WGS-84 的偏差能达到几百米BD-09 又在 GCJ-02 基础上二次偏移。如果不带坐标系标识就把坐标入库画地图时点位飞到路外排错时根本无从下手。精度问题同样要命。经纬度小数位和实际精度有对应关系6 位小数约 0.1 米5 位约 1.1 米4 位约 11 米3 位约 110 米。如果统一用 N..10,6 存储0.1 米精度对于路段位置足够但老系统导出的数据如果只有 3 位小数入库后是补零还是拒收要在数据治理规则里说清楚。我一般规定接口交换必须给 6 位小数缺位不补零按实际位数接收但入库时统一规范到 6 位。还有一个格式坑是度分秒和十进制的混用。老系统里常见“116°26′32″”标准要求十进制度转换就得写换算。一行 SQL 就能算SELECT 116 26/60 32.5/3600;换算本身不难难的是识别哪些字段是度分秒、哪些已经是十进制以及批量转换时保留原始值。我对这种字段的标准做法是加一列“原始坐标格式”标记转换后的坐标进业务字段原始值留档方便回查。4.3 入库校验 SQL一条语句拦截非法坐标、区划代码和桩号约束写清楚了还得有手段落地。下面这条 SQL 是我用来做入库前质量检查的示例覆盖了经纬度范围、区划代码位数、高程范围、桩号格式四类检查SELECT route_sec_code, CASE WHEN start_lon BETWEEN -180 AND 180 AND start_lat BETWEEN -90 AND 90 AND end_lon BETWEEN -180 AND 180 AND end_lat BETWEEN -90 AND 90 THEN OK ELSE ERR END AS lonlat_check, CASE WHEN CHAR_LENGTH(start_region) 6 AND start_region REGEXP ^[0-9]{6}$ THEN OK ELSE ERR END AS region_check, CASE WHEN start_elevation BETWEEN -200 AND 10000 THEN OK ELSE ERR END AS elev_check, CASE WHEN chainage REGEXP ^[KGC]?[0-9][]?[0-9]$ THEN OK ELSE ERR END AS chainage_check FROM section_location;这段 SQL 的检查逻辑分四块。lonlat_check 用 BETWEEN 判断经度纬度边界经度超 180 或纬度超 90 直接标错这一条能拦下大量手工录入的脏数据。region_check 同时校验位数和数字组成CHAR_LENGTH 保证 6 位REGEXP 保证全是数字两个条件缺一不可。elev_check 的高程范围 -200 到 10000 米是行业里常见的合理区间死海湖面以下约 -430 米珠峰约 8848 米这个区间基本覆盖全球极端值实际项目按你的业务范围调。chainage_check 的正则值得解释桩号是字母和数字的组合K 代表公里后面的数字是偏移量加号是分隔符。这个正则允许前缀字母和数字段但要注意它只是通用示意不同路段管理单位的桩号规则有差异比如有的带支线字母有的用负号表示反向。所以正则一定要按本单位实际规则调整直接照搬网上的正则反而会误杀。5. 真实项目落地避坑数据元标准五个典型翻车现场标准是理想的数据是野生的。下面这五个坑是我在真实项目里反复见过的每一个都对应 JTT 697.7 落地过程中最容易出的问题写下来能给后来人省点时间。5.1 地图上差几百米坐标系混用是头号问题现象从三个系统接入的同一路段坐标画到地图上点点分散最近的距离几十米远的差出三四百米。 原因A 系统给出的 GPS 原始坐标是 WGS-84B 系统直接从地图产品取点给的是 GCJ-02C 系统做了二次偏移给的是 BD-09。三套数据入库时都没记录坐标系图上看就是三坨点。 解决给位置表补 coord_sys 字段存量数据按来源系统批量回填坐标系新数据入口强制校验坐标系标识坐标转换统一走一个转换服务转换后保留原始坐标字段。另外要提醒一句坐标系转换是有损的GCJ-02 转 WGS-84 只能做到接近不能完全还原所以原始值必须留底。5.2 经纬度用 DOUBLE 存每次导出精度都不一样现象接口返回的经度每次格式化后有细微差异有一次是 116.44355000000001另一次是 116.44355。下游拿去和别的系统比对等值匹配永远对不上。 原因DOUBLE 是浮点类型存储的是近似值MySQL 对 DOUBLE 的显示和导出会做舍入事务里的中间值也可能变化。 解决改用 NUMERIC(10,6) 存坐标从根本上消除浮点问题如果存量表已经是 DOUBLE导出时用 FORMAT 或 ROUND 统一到 6 位小数再输出而不是靠客户端处理。教训就是分层设计时别贪方便数值型字段按人的习惯用定点数数据库的“够用”和数据的“稳定”是两回事。5.3 桩号当数值排序K11100 排到了 K2900 后面现象报表里按桩号排序路段结果 K11100 排到了 K2900 后面肉眼一看顺序全乱。 原因桩号被设计成字符串但排序时有人直接按字符串排序字符串比较是一位一位比的“K11”的首位“K”和“K2”的首位相同第二位“1”小于“2”所以 K11 排在 K2 前面逻辑上没错业务上不对。 解决桩号不能只存原始字符串。规范做法是加两个字段一个是原始桩号字符串保留展示用另一个是数值化的累计里程单位米入库时解析填入。比如 K2900 解析成 2900 米K11100 解析成 11100 米排序和范围查询都用数值列。解析规则要写清楚K 代表公里加号后是米数遇到带字母后缀的桩号要单独定义处理规则。5.4 行政区划代码 6 位、3 位、中文名混着填现象行政区划代码列里有的填 6 位数字有的填 2 位省级代码有的直接填“某某区”中文汇总统计时省份维度对不上区县维度更是没法看。 原因数据来源系统各自的定义不同有的按省级汇总只需要 2 位有的老系统用中文名做下拉框导出时就带出了汉字。入库时又没有做格式强制。 解决代码列统一按 CHAR(6) 存 6 位数字应用层做三重校验位数、全数字、在行政区划代码表里存在。对于只提供 2 位或中文名的来源入库前做一个映射转换层把来源值映射成 6 位代码。映射表本身也按 JTT 697.7 的风格维护来源值、标准代码值、备注三列这样以后新增来源系统时直接加映射行不用改表结构。5.5 标准文档在手字段名依然对不上现象新系统和老系统联调新系统说“我们按 JTT 697.7 建的字段”老系统说“我们一直这么叫的”两边打开标准文档一对发现老系统的“路线名”和新系统的“道路名称”指向同一个数据元但代码对不上接口联调僵住了。 原因双方都没有把标准数据元标识符作为交换依据只用了中文名或英文名做映射。中文名在不同系统里有简称、别名、历史叫法英文名更是各编各的。 解决所有接口字段描述里带上数据元标识符交换文件里也保留一列标识符而不是只放中文名。团队内部维护一张“标准标识符、标准中文名、系统内字段名、历史叫法”的映射表新老系统各自填一列联调时拿这张表做轴对齐比扯皮高效得多。这个习惯一旦养成后续主数据治理也顺了。6. 收进日常节奏一张数据元合规自检清单标准落地的最后一步是形成习惯。我给自己团队规定了一套自检清单每次新建表或者改接口过一遍这张表再提测能挡掉大部分低级问题检查项自查内容对应章节字段命名是否使用标准英文名注释是否含标准中文名第 2、3 章标识符字段描述里是否标注了数据元标识符第 2 章数据类型坐标是否用 NUMERIC代码是否用 CHAR第 2、3 章表示格式长度和小数位是否符合 N..10,6 这类规定第 2 章值域枚举字段是否登记字典表引用字段是否可查证第 4 章坐标系是否有 coord_sys 字段默认值是否约定统一第 4 章桩号是否同时保留原始字符串和数值化排序列第 4、5 章校验入库前是否跑了范围、格式、存在性三类检查第 4 章映射表标准标识符、库字段、接口 key 是否有四列映射第 5 章清单里的每一项都能在标准原文里找到依据但标准不会替你做工程决策。比如默认坐标系选哪个、桩号怎么解析、枚举值怎么扩展这些都要结合项目实际定定了就要写进接口文档写进字典表写进建表注释。这几年我接手过好几张位置相关的表凡是后面出问题的回溯下来基本都是当初“先建了再说字段名随手起坐标数据先糊进去”留下的债。反过来说凡是按标准把标识符、格式、值域一次定清楚的表后面做数据交换、做质量检查、做信令分析几乎没折腾过。如果你正准备拿 JTT 697.7-2014 做新系统的字段定义我的建议是从一张表和一张映射表开始别贪大求全。先把你业务里最常用的二三十个数据元按标准确认一遍落到建表语句和接口契约里跑通后再扩展。标准是拿来用的不是拿来供奉的用起来的过程中遇到标准覆盖不到的业务字段按标准的风格补自定义数据元做好标识符规划同样可以纳入体系。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →