`
252190908
  • 浏览: 227798 次
文章分类
社区版块
存档分类
最新评论

“青岛供电段供电运行检测监控系统"项目总结

阅读更多

这个项目已经完成好几个月了,一直没有写总结。现在把这篇总结补上。


青岛供电段供电运行检测监控系统 概述

该系统是济南铁路局的一个试验项目,由硬件和软件两部分组成。硬件方面由另一家公司负责在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的使用方法见我另一篇文章:使用GeoServer-2.3发布地图

在本项目中,我们需要让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解决了。。。好险!如果是在公司的话,估计第二天我就不用来上班了。。


这是自己参与的第一个项目,回想起来,感觉又可笑又感慨。可笑的是自己当时经验不足,犯了不少低级错误,现在想想真是非常丢人;感慨的是,如果没有第一次的历练,自己永远也具备不了独立做项目的能力。当时我才大一,还有的是时间。如果是在公司上班犯这些错误,那。。后果不堪设想。。。。。
分享到:
评论

相关推荐

    煤矿供电监控系统的研究现状与发展趋势

    简要介绍了煤矿供电监控系统的结构与功能,从监测与保护装置、通信传输网络、监控与操作软件等几方面分析了近年国内的研究进展;针对系统功能,重点探讨了防越级跳闸功能与故障诊断和预警功能的研究进展,并指出了系统...

    监控系统维护制度.docx

    监控系统维护制度全文共2页,当前为第1页。监控系统维护制度全文共2页,当前为第1页。监控系统维护制度 监控系统维护制度全文共2页,当前为第1页... 第三条 用户权限 为保证监控系统的有序运行,在集中监控中心和区域监

    供电监控系统设计.pdf

    供电监控系统方案设计 1 《控制系统软件设计 1》设计方案报告 综合项目:供电监控系统 一.设计任务 随着电力事业的快速发展, 目前对于骨干输变电线路上的超高压变电站 (500KV,220KV,及绝大部分 110KV 变电站)大多...

    煤矿供电监控系统的设计

    针对目前煤矿供电系统自动化程度较低的问题,提出了采用STM32(ARM)系列控制器为下位机主控芯片,以上位机为监控室界面的自动化煤矿供电监控系统。下位机通过相应的传感器对主要物理变量进行测量,并通过串口发送到监控...

    电池供电远程监控系统方案

    电池供电远程监控系统方案电池供电远程监控系统方案

    煤矿供电远程监测监控系统设计及应用

    在煤矿开采过程中,因井下供电系统不科学使用造成的意外事故频频发生。任何煤矿的安全问题都是重中之重,在生产过程中...介绍煤矿供电远程监测监控系统结构设计,系统主要功能及特点分析及应用说明3个方面展开详细叙述。

    企业供电系统及运行(第五版)习题册参考答案-A04-1339.pdf

    企业供电系统及运行(第五版)习题册参考答案-A04-1339.pdf

    煤矿供电系统运行方式的比较分析

    煤矿供电系统运行方式直接影响系统的安全可靠性和运行的经济性。在符合《煤矿安全规程》相关要求下,目前煤矿供电系统主要采用完全分列、电源线路一主一备、主变压器分列运行等方式,但各种运行方式都有其优缺点。通过...

    《铁道供电远动系统运行与维护》教学课件3.5数据通信方式.pdf

    《铁道供电远动系统运行与维护》教学课件3.5数据通信方式.pdf《铁道供电远动系统运行与维护》教学课件3.5数据通信方式.pdf《铁道供电远动系统运行与维护》教学课件3.5数据通信方式.pdf《铁道供电远动系统运行与维护...

    供电监控系统在煤矿供电中的应用

    此时,在原来供电系统的基础上进行了供电监控系统改造与构建,采用当今先进的科技,具备完善的保护、测量、控制与监视功能。系统利用IEC61850的GOOSE通信技术,在井下供电出现故障时,采取下级闭锁上级的闭锁模式,切断离...

    Matlab地铁牵引供电系统建模与仿真

    Matlab地铁牵引供电系统建模与仿真 Matlab地铁牵引供电系统建模与仿真 Matlab地铁牵引供电系统建模与仿真 Matlab地铁牵引供电系统建模与仿真 Matlab地铁牵引供电系统建模与仿真 Matlab地铁牵引供电系统建模与仿真 ...

    基于KJ360的井下供电远程监控自动化系统

    将井下变电所高低压开关进行改造,利用电力监控分站将各高低压开关纳入光纤环网,并将信号上传至地面电力监控系统,建立矿井变电所无人值守监测监控系统,能够在地面调度中心集中监控井下变电所的运行工况,同时发生故障...

    煤矿井下供电监控系统设计

    设计了一种基于远程网络的供电监控系统。利用C8051F040 MCU设计监控单元,对供电参数及保护装置运行状态等数据进行采集,通过构建以太网网络完成数据共享与现场信息上传,实现对供电设备状态的远程监测、故障预警。研究...

    企业供电系统与运行

    中国劳动保障出版社的中等职业技术学校电工类通用教材《企业供电系统与运行》第4版的配套课件

    企业供电系统及运行试题

    企业供电系统的考试试题,使用于中专班教学

    6安防监控系统维保方案.doc

    三、维保服务中的一些注意事项 在对监控系统设备进行维护过程中,应对一些情况加以防范,尽可能使设备的运行 正常,主要需做好防潮、防尘、防腐、防雷、防干扰的工作。 1、防潮、防尘、防腐 对于监控系统的各种采集...

    井工煤矿供电系统的大分列运行

    本文结合煤矿安全规程对供电的要求、相关技术规范等,对井工煤矿供电系统的运行方式进行了探讨,结合某煤炭集团公司生产矿井的运行经验,说明了大分列运行对缩小停电范围、提高供电连续可靠性、降低系统短路容量、减少...

    矿井供电监测监控系统技术方案研究

    平煤股份二矿原有的井下供电系统存在很多不足,直接影响矿井安全发展。...新方案的实施提高了用工工效,实现了综合保护器的兼容,同时根据各种历史数据可以方便开展检修工作,确保了供电系统的安全可靠运行。

    2021-电工杯-A 高铁牵引供电系统运行数据分析及等值建模.pdf

    数学建模;数模竞赛;2021-电工杯-A题:高铁牵引供电系统运行数据分析及等值建模

Global site tag (gtag.js) - Google Analytics