system: [SYSTEM]

user: 3. 关键技术 3.1. 服务器端数据库设计 在后台数据库设计方面，如果将用户上传的表格，直接做为数据库中的一张表来存储，表格在数据库中的字段名必须使用英文名称，虽然这种设计会使后台库表设计以及前端代码逻辑变得简便，但是这种设计使得表格字段在浏览器端显示为英文名称，英文字段名不利于用户的阅读，从而降低了用户的使用体验。这在库表设计上提出了新的要求，在尽可能满足用户需求的情况下，也不会使库表设计的逻辑过于复杂。 本平台通过数据存储表和字段信息表结合使用，可以解决以上的问题，数据存储表用来存储表的数据，表中的字段设计采用虚拟字段V1，V2，…，Vi。考虑到后期表格管理的可扩展性，在数据存储表中预留50个字段，虽然这样会浪费少量计算机内存资源，但是通过预留字段可以很好的解决字段添加和删除的问题。字段信息表用来存储字段的中英文映射信息，所有的数据库表的字段映射信息都记录在这张表中。 3.2. 前端脚本实现空间数据的管理 前端通过Geoserver2013提供的SQLScript和WebSQL API [ 6 ] 实现数据的上传、读取、修改等操作。空间数据管理应用，如图2。 3.2.1. 数据导入 空间数据的导入分为图层的导入以及属性数据的导入。图层的导入格式支持shp格式，属性数据支持csv格式导入。现有的csv格式的数据导入都是通过将文件整个网络传到服务器端特定目录下，然后利用服务器端语言进行读取然后存入数据库表中，本文通过在前端HTML5技术解析表格文本，通过数据服务接口直接保存到数据库中，这种方法可以减少服务器端压力[ 7 ] 。 前端HTML和CSS设计好用户上传表格的界面。属性表格数据导入，传统的在Web端表格导入方法都是将csv文件整个传到服务器端，利用服务器端语言来读取该表格中的数据然后存入数据库中，最后删除该临时上传的表格。本系统通过HTML5提供的FileReader API [ 8 ] 合使用input标签元素，type属性设置为file，利用该API提供的readAsText()方法读取表格中的数据保存在浏览器内存中，该方法第一个参数为获取的file对象，第二个参数为设置的读取文件的编码方式，默认是UTF-8，由于csv格式默认使用GB2312编码方式，所以这里编码方式要设置成GB2312。通过该方法可以实现在前端读取表格数据。 图1. 系统架构图 图2. 空间数据管理应用 读取完成后执行onload回调函数[ 9 ] 中，参数data是存储数据的二维数组，对数据进行处理，将数据分成两部分，一部分存储字段映射信息，另一部分存储数据记录，有了字段映射信息后，需要用户手动填写所有的字段的类型，字段对应的单位信息。通过WebSQL中的SQLTask、SQLExec和SQLInsert接口将数据传入后台服务器中存储，实现表格的创建以及字段信息和表格记录的插入。在传输中浏览器会通过gzip进行数据压缩，提高数据的传输速度。 图层的导入是通过Geoserver提供的Geoutil接口，将shp文件转成数据库要素表，转成的要素表既包含几何信息也包含属性信息，在前端显示的时候将几何信息字段隐藏。 3.2.2. 数据的查询与展示 现有的数据管理系统，在空间数据管理界面上，属性数据的字段都为英文名称，对于非专业用户来说阅读起来相当困难，如果采用中文命名字段名，会增加数据库的不稳定性，容易出现错误。本平台采用字段映射表，存储前端显示字段名和后台存储字段名的对应关系，在请求空间数据之前先请求字段映射信息，从而解决中文字段显示的问题，提高用户的体验。 前端实现方法。根据用户选取的数据表，通过WebSQL接口查询字段映射表中对应的所有字段信息，将查询得到的字段信息分别以数组形式保存在内存中，包括字段真实名数组，字段类型数组，字段别名数组，字段对应单位数组，为后续表格的可视化显示做准备，最后根据请求得到的字段真实名数组通过WebSQL接口的SQLQuery方法获取数据。 在web端显示数据，数据量的大小直接影响页面响应速度的快慢，当数据记录数达到数十万乃至上百万条时，甚至会导致浏览器的崩溃，直接影响用户的体验。本系统在前端显示数据时采用分页显示的方法，当用户点击某一页时只请求相应页的数据。具体流程：通过查询表格总的记录数，以及用户选择的每页显示记录条数，通过这两个参数就可以动态计算出每页的起始和终止记录的id号，以及总的页数，然后通过select语句中提供的limit子句限制每次返回记录的数量为用户选择的每页显示数量，offset子句限制数据取的基准点(displayStart)，这个基准点可以根据选择的页数和每页显示条数在前端动态的计算出来。具体的SQL语句为：select V1，V2.. from tab1 limit displaylength offset displayStart。通过这种后端分页显示方法可以很好的解决请求数据过慢的问题，提高用户体验。 SQL查询功能。用户可以根据需要任意查询符合条件的数据，在查询条件界面中选择查询条件，在查询字段界面中选择查询结果中要显示的字段。设计该模块时，查询条件和查询字段中每个字段别名都对应一个真实字段名Vi，这个真实字段名被存储在标签的自定义属性(data-real)中，查询字段界面中每个显示字段的html片段的代码为： 其中自定义属性data-real记录该字段对应的真实字段名，data-unit记录该字段的单位，data-type记录该字段的类型。同样查询条件中的字段，运算符，查询值以及逻辑运算符都是通过自定义属性来记录。当用户点击确定查询数据时，通过收集用户选择的标签选项的data-real属性值构成select语句的查询字段，收集用户输入的查询条件构成select查询语句的where条件子句，然后通过WebSQL接口提供的SQLQuery方法查询数据，对于SQL查询的数据不采用分页的方式显示，而是一次性将所要查询的数据请求回来，采取这种设计方式的目的，首先SQL查询出的数据是经过用户筛选的，相对于全部查询出来的数据量小，其次用户对于查询出来的数据往往需要进行图表分析，数据的另存等平台提供的其他功能，所有这些提供的功能都是在前端完成，所以前端必须缓存这些数据。 3.2.3. 数据在Web前端的动态管理 由于绘制的表格提供数据的编辑功能，所以需要每个单元格都可以编辑以及整个表格具有插入、删除记录的功能。对于提供单元格编辑功能，在前端动态生成表格的时候给每个单元格插入一个input标签，并把单元格的值赋给这个input标签，所有的input标签绑定change事件，当改变了表格中的值时，用JSON格式动态的记录改变的信息。当添加一行记录时，通过操作DOM在表格的末尾添加一行，将该行的信息保存的内存中。 表格前端编辑功能的具体设计。本技术在编辑数据的时候，将数据分成两部分，一部分是表格中显示的数据，这部分数据是从服务器端请求回来的。另一部分是前端新添加的数据。之所以将数据分成两部分是因为对于前端新添加的数据在数据库中只会进行插入操作，而从服务器端请求来的数据会进行更新和删除操作，采用这种分类设计在前端进行增删改时更加方便和高效。 当修改某一行的信息时，通过之前绑定的input的change事件结合Javascript的DOM查询能够得到该行的所有信息。采用JSON格式[ 10 ] 存储该行修改的数据信息，首先会把该行的id号作为键名，对应的值也是JSON格式的数据，该子JSON数据是以字段真实名Vi作为键名，修改后的值作为该键对应的值，具体存储格式代码：{1:{'V1':value， 'Vi':valuei}i:{'V1':value， 'Vi':valuei}......}。当记录是客户端新添加的数据时，存储格式改：{new1:{'V1':value，'Vi':valuei}newn:{'V1':value，'Vi':valuei}......}。当删除某一行数据时，采用数组记录该行的id号，存储格式为：['1'， '2'， 'i'，.......]。有了以上三种数据就可以分别用来进行更新，添加和删除操作。 当用户编辑完成后，点击保存，这时会进行批量的更新，添加和删除操作，前端按照后台约定的接口准备好传输参数，通过后台提供的WebSQL接口的SQLTask方法实现批量执行SQL语句的功能，根据数据的特点，更新和添加使用后台提供的SQLExec方法，删除使用SQLDelete方法。 3.2.4. 空间数据的关联 对于空间属性数据和用户自己上传的属性数据可以进行空间关联，用户只需手动选择需要关联的字段，将改关联信息记录在数据库表中。建立关联关系后，在地图上进行点查，多边形查询后就可以显示关联后两个表格中的所有相关的信息，如果关联的字段信息是空间位置字段，还可以根据关联的表格中的字段生成相应的专题图。