如何组件化开发WebGIS系统

啰嗦两句

前面聊过《探讨如何使用流行的前端技术开发WebGIS系统》,本篇基于此继续介绍。

不用再讨论兼容IE6,7了,2017年,没人再用了。。。。哈哈哈

本人目前正业余开发一套框架,后端Java+前端Angular+个人封装的UI+个人封装的地图组件,东西很多,一个人搞,这是一个漫长的过程。这也是为什么最近再Github上如此活跃的原因,也因为最近一段时间没加过班。。。除了玩游戏就只能写代码了。。

=>giscafer (Nickbing Lao)

一、后端完善的Restful接口设计有利前端组件封装

比如知乎的文章链接

1
https://zhuanlan.zhihu.com/p/24780835

可以看作一个GET请求,接口p,参数为24780835。这个接口可以查所有文章。

做WebGIS系统,后端框架,接口设计好用,能提升前端开发的效率,并且可以针对接口封装一些增删改查的组件,在angular里边,你可以封装成指令或者是controller,然后其他业务controller集成此类,就继承了该类的所有方法了。比如应用里边我封装了增删改查的操作,只要是单表的CRUD(增查改删),完全不需要写多余的CRUD代码,只需要修改一下HTML和传参。如下代码可以改为一个通用的父类Controller。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
* Test controller
*/
import popFormCtrl from './popForm.ctrl.js';
import popFormTemp from './popForm.html';
export default class TestCtrl {
// dataServiceSrv, uiNotification为依赖注入服务,其中uiNotification为laoui封装ui控件
constructor($scope, dataServiceSrv, uiNotification, $uiModal) {
"ngInject";//ES6写angularjs指定写法;作用是依赖注入上边的$scope, dataServiceSrv, uiNotification模块
this._$scope = $scope;
this._$uiModal = $uiModal;
this._dataServiceSrv = dataServiceSrv;
this._uiNotification = uiNotification;
this.tableName = 'student';
this.title = "测试页";
//查询标志位
this.loading = false;
this.deleting = false;
this.isAllChecked = false;
this.table = [];
this.query();
//过滤器自定义方法 | filter:方法名称
this.filterData=(item)=>{
return item._deleted!=true;
}
}
//测试查询
query() {
let params = {
"tableName": this.tableName
}
this.loading = true;
this._dataServiceSrv.query(params).then(data => {
if (data['result'].length) {
this.table = data['result'];
} else {
this._uiNotification.info('无数据')
}
}).finally(() => {
this.loading = false;
})
}
//新增
add() {
let params = {
title: '新增'
}
this.openPopForm(params);
}
//修改
update() {
let selectedRows = this.getSelectedRows();
if (selectedRows.length !== 1) {
let options = {
message: '请选中一条记录!', positionX: 'center', positionY: 'top', delay: 2000
}
return this._uiNotification.warning(options);
}
let params = {
title: '修改',
data: selectedRows[0]
}
this.openPopForm(params);
}
delete() {
let selectedRows = this.getSelectedRows();
console.log(selectedRows)
if (!selectedRows.length) {
let options = {
message: '请选中需要删除的记录!', positionX: 'center', positionY: 'top', delay: 2000
}
return this._uiNotification.warning(options);
}
let idArr = _.map(selectedRows, 'id');
let idValues = idArr.join(",");
let params = {
idValues: idValues,
tableName: this.tableName
}
this.deleting = true;
this._dataServiceSrv.deleteByKey(params).then((res) => {
if (res['result']) {
this._uiNotification.success('删除成功!');
for(let item of selectedRows){
item._deleted=true;
}
}else{
this._uiNotification.error('删除失败!');
}
}).finally(() => {
this.deleting = false;
})
}
//通用弹窗
openPopForm(params = {}) {
let modalInstance = this._$uiModal.open({
templateUrl: popFormTemp,
controller: popFormCtrl,
controllerAs: 'popForm',
size: 'lg',
backdrop: 'static',
resolve: {
items: () => {
return params;
}
}
});
}
selectedAll() {
this.table.forEach((item) => {
item.checked = this.isAllChecked;
})
}
check() {
this.isAllChecked = !_.some(this.table, (item) => {
return !item.checked;
});
}
selectByClick($event, item) {
if ($event.target.type !== 'checkbox') {
item.checked = !item.checked;
}
}
getSelectedRows() {
return _.filter(this.table, (item) => {
return item.checked === true;
})
}
}

可以封装的内容出CRUD外,还包括一些限制控制,通知提示,表单验证等。

因为是angular框架,双向数据绑定,比传统的jqueryUI,easyUI这堆好用的多,这么一来简单的表单页面开发起来就不费任何力气,简单复制模板修改一下就OK。

二、地图工具组件化

同理,地图工具组件化是必须的。(防转载标记,个人微信公众号:giscafer)

每个WebGIS系统都有这些一模一样的工具:全屏、放大、缩小、距离测量、面积测量、i键查询、坐标定位 等等,这些工具可以封装为无平台相关,也就是兼容所有地图js库,不管是ArcGIS API For JavaScript,还是OpenLayers 等,就比如我封装了一个叫 DMap 的地图库,里边大致结构如图:

DMap库结构图

在开发系统时,我选择了Mapbox作为地图js库,我在dmap_config.js文件中配置

1
2
DMAP_JS_TYPE:"MAPBOX"

这时候我可以自动构建打包一套Mapbox的js库(当然和原生库不一样,我封装了一些组件类,下边介绍)。同理我配置DMAP_JS_TYPE:"OL3",就表示构建OL3组件库。

构建方式用nodejs + webpack等工具开发,类似 Echarts的构建方式

然后我把组件库引入我开发的webgis系统。通过无平台相关(这表示和地图 js库无关)接口 Map 创建地图

1
2
3
4
5
6
7
map = new Map("map", {
//配置
projection: "EPSG:900913",
center: [118.665397, 47.6569168],
zoom: 5
});

另外,地图类型加载也可以封装成,通过配置地图类型比如,天地图OGC_WMTS,还是高德地图AMAP,demo《《探讨如何使用流行的前端技术开发WebGIS系统》 就是配置的高德地图。这些地图加载同样封装成无平台相关。

以下是组件封装后使用demo截图:

最终,封装好后,以后做项目不用任何代码就可以构建一个webgis系统雏形出来,这个雏形系统带有基本的表单增删改查组件、全屏、放大、缩小、距离测量、面积测量、i键查询、坐标定位 等直接可用的地图组件。

三、总结

在WebGIS系统开发里边,有较多的表单业务,封装成组件开发是最方便的,也可以找网上的一些开源库做修改,定制成自己通用的才是最好用的。

已不从事gis行业,业余有外包机会或者兼职机会希望可以接一下,所以自己定制一个前端后端一整套框架,一方面学习,一方面积累技术。工作量很大,有时间一步一步慢慢来,并且业余还得学前端技术,React Native是下一个学习目标。

此外,框架设计的时候,考虑到不加载dmap地图库的时候,就是一个完全纯净的业务系统,可以用来做其他网站,比如企业站点、博客等。

推荐文章