这个项目已经完成好几个月了,一直没有写总结。现在把这篇总结补上。
青岛供电段供电运行检测监控系统 概述
该系统是济南铁路局的一个试验项目,由硬件和软件两部分组成。硬件方面由另一家公司负责在200多个铁路监测点上安装传感设备,以监测温度, B值等铁路部门所感兴趣的数据。每隔几十分钟,监测数据就会自动上传到POSTGRES数据库。我们软件的任务是,将数据库中的数据以表格、图表、地图等形式展示出来。其中,我负责GIS地图(地理信息系统)的开发,包括地图的绘制(ArcGis,
UDig)、地图发布(GeoServer)、地图展示(OpenLayers, JavaScript)和部分数据库查询操作(JPA)。该项目使用 Seam-2.3框架,以JBoss-7.1为web应用服务器。
系统登陆界面如下:
主界面如下:
GIS界面如下:
学到的东西
虽然之前有Win32桌面应用开发基础和Java语言基础,但这次的GIS系统跟它们完全不搭边。这让我在老师分配下来任务时一度认为几乎不可能完成。其实老师的意思也是让我边学边做。。好吧,开干!
ArcGis
ArcGis是一套专业的,用于处理地理数据的软件。编辑地图用ArcMap就如同处理图片要使用PhotoShop一样自然。因此我的首要任务就是学习如何使用ArcMap。由于这套软件只能在Windows上运行,于是我不得不先在Windows下开发地图,然后再切换回Ubuntu编写Java代码。
首先我从网上下载到了全国铁路规划图、全国省区和地级市规划图。地图矢量图文件以.shp结尾,而地图中的元素信息(如点元素的label)则保存在*.dbf文件中,用excel就能打开查看。 打开ArcMap,将所有shp文件导入,便得到全国省区,地级市和铁路规划图。这里我们只需要山东地图,所以要将无用的部分cut掉。在地图上右键选择“开始编辑”,用选择工具选中除山东省以外的部分,再按键盘上的Del键删除。这是一种很笨的方法,不过很有效。这时候老师发现,地图上少了一条铁路,或许是因为这条线路不太起眼所以没画上吧。于是我干脆自己给添上了。在编辑模式下,单击浮动工具栏上的线型元素,在模板中选中铁路样式,最后再在起点和终点拖出一条直线即可。完成编辑后要点击
"保存并完成编辑",否则修改不会生效。
这部分没有任何技术含量,完全是在拖鼠标,比较无聊。
GeoServer和PostGIS
GeoServer是一个免费、开源的地图服务器,采用Java编写而成。其实我们平时所看到的百度地图,Google Map都是类似于GeoServer这样的地图服务器软件所返回的图片数据。我们可以将shp文件直接发布到GeoServer中,也可以让GeoServer从数据库中获取地图数据。当用户请求到来时,GeoServer(大多数情况下)会以图片的形式返回地图数据。
在本项目中,我们需要让GeoServer从Postgre数据库中读取地图数据而不是直接发布shp文件。因此还需要安装PostGis-2.0,来为Postgre添加保存地理数据的功能,并将shp文件导入到数据表中。过程大致如下:
进入Postgre根目录的bin目录下,执行以下命令将shp文件转换为sql语句:
shp2pgsql -s "4326" -W "GBK" D:\demo\map\sd_city.shp sd_city > D:\sd_city.sql
执行以下命令执行包含地理数据的sql语句:
psql -d shandong -f D:\sd_city.sql -U postgres -W
注意,位于bin目录下的shp2pgsql.exe是PostGIS提供的工具,如果没有安装PostGis,shp2pgsql.exe就不存在。
SLD样式
SLD是一种类似于xml的标记语言,用于规定GeoServer如何渲染几何元素,在功能上类似于CSS。例如 shp中包含一些点元素,则SLD可以用来指定这些点的背景色,边框,大小,label的显示位置等。示例如下:
<FeatureTypeStyle>
<Rule>
<PointSymbolizer>
<Graphic>
<Mark>
<WellKnownName>circle</WellKnownName>
<Fill>
<CssParameter name="fill">#FF0000</CssParameter>
</Fill>
</Mark>
<Size>6</Size>
</Graphic>
</PointSymbolizer>
</Rule>
</FeatureTypeStyle>
这会让点显示为红色:
而
<FeatureTypeStyle>
<Rule>
<PointSymbolizer>
<Graphic>
<Mark>
<WellKnownName>triangle</WellKnownName>
<Fill>
<CssParameter name="fill">#009900</CssParameter>
<CssParameter name="fill-opacity">0.2</CssParameter>
</Fill>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">2</CssParameter>
</Stroke>
</Mark>
<Size>12</Size>
</Graphic>
</PointSymbolizer>
</Rule>
</FeatureTypeStyle>
能让点显示为带边框的绿色三角形:
这就是SLD的作用。在不同的缩放级别下显示不同的元素,也可以通过SLD来完成。最终,这个项目所用的地图使用了较为复杂的SLD,比如把线(Line)元素渲染成
就需要100多行SLD。
OpenLayers
有了地图服务器,也有了地图,接下来如何才能让用户在浏览器中看到地图呢?这就是OpenLayers的功能了。OpenLayers是一个用于开发WebGIS客户端的JavaScript库。我们可以使用OpenLayers向提供WMS(Web Map Service)服务的GeoServer发送请求,将返回的地图图片显示在浏览器中,并添加导航,经纬度显示,缩放,popup等功能。
发送请求的代码示例如下:
// 向GeoServer请求地图
function initMap() {
map = new OpenLayers.Map(
"main_map",
{ // 设置允许的缩放范围
'minScale': '2300000',
'maxScale': '80000' // 1km
}
);
wmsLayer = new OpenLayers.Layer.WMS(
"JiNan Railroad",
"http://" + window.location.hostname + ":" + window.location.port + "/geoserver/Demo/wms",
{
'service': 'WMS',
'version': '1.1.1',
'request': 'GetMap',
'layers': 'jinan',
'styles': '',
'format': 'image/png',
'TILED': true // 告诉geoserver启用缓存
}
);
}
其中OpenLayers.Map的第一个参数"main_map"是一个div的id,OpenLayers会将地图显示到这个div中。
添加图层,添加控件,设置缩放中心的代码示例如下:
// 添加control
map.addControl(new OpenLayers.Control.MousePosition()); // 鼠标位置
map.addControl(new OpenLayers.Control.ScaleLine()); // 比例尺
map.addControl(new OpenLayers.Control.PanZoomBar()); // 缩放条
map.removeControl(map.getControlsByClass('OpenLayers.Control.Zoom')[0]); //删除默认控件
// 添加layers
map.addLayer(vector_layer);
map.addLayer(markersLayer);
map.addLayer(wmsLayer);
// 设置默认缩放级别和缩放中心
if(!map.getCenter()) {
map.setCenter(new OpenLayers.LonLat(118.5, 36.5),0);
}
地图页面的JS代码共有600多行,实现的功能如下:
1. 向地图中添加mark点,分三类,分别是受电弓、B值、温度。不同的点用不同的图片表示。
2. 每隔10分钟向服务器发送一个ajax请求,以更新mark点数据。
3. 鼠标点击mark点会显示popup框,可以查看该监测点的各项数据,和摄像头照片。
4. 地图右下角滚动显示mark点的更新信息,并提供 '在地图中标出' 功能。
5. 读取后台生成的JSON数据。
其中第2个功能的实现思路为,在地图页面中添加一个隐藏的iframe,在iframe所指向的子页面中通过RichFaces的a4j标签发送ajax请求,最后在子页面中调用父页面的JS函数将得到的数据传到父页面(地图页面)中。
iframe:
<iframe src="JsonUpdateData.seam" width="0" height="0"></iframe>
JsonUpdateData.xhtml:
<h:form>
<a:poll id="poll" interval="600000" enabled="true" render="update-frame" />
</h:form>
<a:outputPanel id="update-frame">
<h:outputText id="jsonDataUpdate" value='#{alarmAction.getRecentEquipData("empty") }' />
<script type="text/javascript">
console.log('iframe: update data');
var jsonStr = document.getElementById("jsonDataUpdate").innerHTML;
var jsonObj = eval('(' + jsonStr + ')');
function reset() {
// 1秒后再更新测量数据
if(parent.onUpdateData(jsonObj) == false) {
console.log(new Date().toLocaleTimeString() + ':更新测量数据失败,1秒后重试');
setTimeout(reset, 1000);
}
}
reset();
</script>
</a:outputPanel>
子页面调用父页面的方法,只需用parent.fun()即可。
在页面中通过EL表达式生成Json将后台数据传到前台
后台通过JPA查询数据库,将设备数据封装成AlarmInfo对象,然后在页面中通过EL表达式调用AlarmAction的getEquipJson()方法来生成JSON数据。示例如下:
JavaScript代码:
var equipments = #{alarmAction.getEquipJson()};
Java代码:
public String getEquipJson() {
List<Equipment> list = entityManager.createQuery("select e from Equipment e order by e.code")
.getResultList();
StringBuilder str = new StringBuilder("{");
for(Equipment e : list) {
str.append("'" + e.getCode() + "':" +
"{ 'id':'" + e.getId().toString() + "'," +
"'name':'" + e.getName() + "'," +
"'low':'" + e.getAlarmLow() + "'," +
"'high':'" + e.getAlarmHigh() + "'," +
"'code':'" + e.getCode() + "'," +
"'type':'" + e.getType() + "'," +
"'yPos':'" + e.getGisX().toString() + "'," +
"'xPos':'" + e.getGisY().toString() + "'," +
"'status':'" + e.getStatus() + "'},"
);
}
int lastIndex = str.lastIndexOf(",");
str.replace(lastIndex, lastIndex + 1, "}");
return str.toString();
}
学到的非技术内容
1. 要随时重构你的代码,想方设法提高程序可读性。否则,你可能改Bug的时候连自己的代码是啥意思都记不着了。(非常非常重要
)
2. 尽量多写注释。
3. 在localhost上运行正常,永远不能确定在服务器上也能正常运行。
4. 遇到问题时用Google而不是Baidu。
5. 提高JavaScript水平。
6. 一定要把需求搞明白再开始工作。
7. 有人催你的时候一定不要急,否则你更搞不定。
8. 有问题尽量自己解决,不到万不得以不要打扰别人。(别人或许比你更忙)
9.熬夜是得不偿失的。
10. 只阅读英文资料。
小事件
有一次,铁路局的领导要来视察,这个项目是重点视察内容。这时程序已经部署到服务器上了,而我的地图偏偏出了些问题。于是我开始debug。如果单单如此倒也没什么,要命的是,客户那边还一遍遍给我们打电话催,问bug解决没。这时老师就帮我挡着,说快了,一会就好了。而我呢,满头大汗在找错误,心想,完了,我死定了。。然后我悲剧地发现这个错误不是改一行两行就能解决的,而是一个逻辑错误。。在催促的压力下,30分钟后,bug解决了。。。好险!如果是在公司的话,估计第二天我就不用来上班了。。
这是自己参与的第一个项目,回想起来,感觉又可笑又感慨。可笑的是自己当时经验不足,犯了不少低级错误,现在想想真是非常丢人;感慨的是,如果没有第一次的历练,自己永远也具备不了独立做项目的能力。当时我才大一,还有的是时间。如果是在公司上班犯这些错误,那。。后果不堪设想。。。。。
分享到:
相关推荐
简要介绍了煤矿供电监控系统的结构与功能,从监测与保护装置、通信传输网络、监控与操作软件等几方面分析了近年国内的研究进展;针对系统功能,重点探讨了防越级跳闸功能与故障诊断和预警功能的研究进展,并指出了系统...
监控系统维护制度全文共2页,当前为第1页。监控系统维护制度全文共2页,当前为第1页。监控系统维护制度 监控系统维护制度全文共2页,当前为第1页... 第三条 用户权限 为保证监控系统的有序运行,在集中监控中心和区域监
供电监控系统方案设计 1 《控制系统软件设计 1》设计方案报告 综合项目:供电监控系统 一.设计任务 随着电力事业的快速发展, 目前对于骨干输变电线路上的超高压变电站 (500KV,220KV,及绝大部分 110KV 变电站)大多...
针对目前煤矿供电系统自动化程度较低的问题,提出了采用STM32(ARM)系列控制器为下位机主控芯片,以上位机为监控室界面的自动化煤矿供电监控系统。下位机通过相应的传感器对主要物理变量进行测量,并通过串口发送到监控...
电池供电远程监控系统方案电池供电远程监控系统方案
在煤矿开采过程中,因井下供电系统不科学使用造成的意外事故频频发生。任何煤矿的安全问题都是重中之重,在生产过程中...介绍煤矿供电远程监测监控系统结构设计,系统主要功能及特点分析及应用说明3个方面展开详细叙述。
企业供电系统及运行(第五版)习题册参考答案-A04-1339.pdf
煤矿供电系统运行方式直接影响系统的安全可靠性和运行的经济性。在符合《煤矿安全规程》相关要求下,目前煤矿供电系统主要采用完全分列、电源线路一主一备、主变压器分列运行等方式,但各种运行方式都有其优缺点。通过...
《铁道供电远动系统运行与维护》教学课件3.5数据通信方式.pdf《铁道供电远动系统运行与维护》教学课件3.5数据通信方式.pdf《铁道供电远动系统运行与维护》教学课件3.5数据通信方式.pdf《铁道供电远动系统运行与维护...
此时,在原来供电系统的基础上进行了供电监控系统改造与构建,采用当今先进的科技,具备完善的保护、测量、控制与监视功能。系统利用IEC61850的GOOSE通信技术,在井下供电出现故障时,采取下级闭锁上级的闭锁模式,切断离...
Matlab地铁牵引供电系统建模与仿真 Matlab地铁牵引供电系统建模与仿真 Matlab地铁牵引供电系统建模与仿真 Matlab地铁牵引供电系统建模与仿真 Matlab地铁牵引供电系统建模与仿真 Matlab地铁牵引供电系统建模与仿真 ...
将井下变电所高低压开关进行改造,利用电力监控分站将各高低压开关纳入光纤环网,并将信号上传至地面电力监控系统,建立矿井变电所无人值守监测监控系统,能够在地面调度中心集中监控井下变电所的运行工况,同时发生故障...
设计了一种基于远程网络的供电监控系统。利用C8051F040 MCU设计监控单元,对供电参数及保护装置运行状态等数据进行采集,通过构建以太网网络完成数据共享与现场信息上传,实现对供电设备状态的远程监测、故障预警。研究...
中国劳动保障出版社的中等职业技术学校电工类通用教材《企业供电系统与运行》第4版的配套课件
企业供电系统的考试试题,使用于中专班教学
三、维保服务中的一些注意事项 在对监控系统设备进行维护过程中,应对一些情况加以防范,尽可能使设备的运行 正常,主要需做好防潮、防尘、防腐、防雷、防干扰的工作。 1、防潮、防尘、防腐 对于监控系统的各种采集...
本文结合煤矿安全规程对供电的要求、相关技术规范等,对井工煤矿供电系统的运行方式进行了探讨,结合某煤炭集团公司生产矿井的运行经验,说明了大分列运行对缩小停电范围、提高供电连续可靠性、降低系统短路容量、减少...
平煤股份二矿原有的井下供电系统存在很多不足,直接影响矿井安全发展。...新方案的实施提高了用工工效,实现了综合保护器的兼容,同时根据各种历史数据可以方便开展检修工作,确保了供电系统的安全可靠运行。
数学建模;数模竞赛;2021-电工杯-A题:高铁牵引供电系统运行数据分析及等值建模