WebGIS开发期末实习
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
WebGIS实习报告——H7N9信息查询系统
——10地信刘运
学号:320100942771
日期:2013/5/12 一、实习目的
掌握利用ArcGIS Server + Flex开发B/S的WebGIS系统的原理、设计流程和开发过程,进一步理解B/S设计架构,掌握WebGIS理论,学习GIS开发方法。
二、实习内容和要求
对实验数据实现网上发布;界面友好、操作简单、方便;查询返回的属性数据全部以弹出窗口(页面)表现。
功能要求:
基本功能1和2是必须的,其他按个人能力进行开发。
1.基本操作功能,包括:缩放、漫游、全图、图层/图例控制;
2.查询功能,包括:空间查属性(包括查看、拉框查询)、属性查空间(关键字查询和组合条件查询);
3.超链接,要求在地图上用鼠标单选任一个点对象时可以链接到与该对象相关的子系统(可以是一个页面);
4.统计专题图,要求能查看所选区域的统计专题图(饼图、直方图)
5.图层及注记显示控制,要求能按不同的放大尺度显示注记的内容。
6.缩略图单独框架中显示,即将缩略图从现在的MapFrame中移至一个独立的框架中。
三、实习数据
ArcGIS Online地形图,中国行政区划面矢量图,各省行政中心点矢量图,H7N9各省病例统计数据,各省患者信息数据。
四、开发环境
Win7旗舰版+IIS+ArcGIS Server 10+ArcGISDesktop+Flex Bulider3+ArcGIS API1.3 For Flex+IE9
五、实习原理
利用ArcGIS Server发布的地图服务,通过REST接口访问,在Flex富客户端架构下,利用Flex Builder集成开发工具,开发B/S架构的WebGIS应用,如下图1.1。
<图1.1>
B/S架构:客户端不需要安装专门的软件,只需要浏览器即可,浏览器通过Web服务器与数据库进行交互,可以方便的在不同平台下工作;服务器端可采用高性能计算机,并安装Oracle、Sybase、Informix等大型数据库。
B/S结构简化了客户端的工作,它是随着Internet 技术兴起而产生的,对C/S技术的改进,但该结构下服务器端的工作较重,对服务器的性能要求更高。
1)地图发布原理
首先利用ArcGIS Desktop编辑、处理相关数据后,通过ArcGIS Server发布地图文档数据,再根据服务需要,发布相关类型的服务。
ArcGIS Server不仅可以发布地图服务(Map Service)也可以发布其他类型的服务,比如地理服务(Geometry Service)。
2)Flex开发原理
在FB集成开发环境下,需要ArcGIS Server提供的地图服务,和相应的API开发组件包,才能进行快速的WebGIS开发。
地图服务是WebGIS最底层的服务。
所有的功能都是基于ArcGIS Server提供的服务开发的,而API则提供了利用ArcGIS Server服务的快速开发的组件,如图1.2。
Flex开发环境是基于MXML和ActionScript。
MXML是基于XML的组件布局标记语言。
MXML标签与ActionScript类或者类中的属性是相对应的。
当编译Flex应用程序的时候,Flex解析MXML标签并且生成相应的ActionScript类,然后这些ActionScript类会被编译成SWF字节码存储到一个SWF文件中,如图1.3。
<图1.2> <图1.3>
六、系统设计
系统架构设计图:
数据设计:
数据以ArcGIS Online的世界地形图数据作为底图。
用地形图的原因主要是该图的文字信息较少,方便查询各省信息,此外地形图颜色配置协调,给人舒适感,提高用户体验。
全国行政区矢量图包括各省H7N9的确认人数,死亡人数,康复人数,形式等级,提供全国H7N9分布信息。
各省行政中心点矢量包括该省H7N9患者的一些基本信息,提供患者的病例信息。
功能设计:
该系统是H7N9信息查询系统,主要提供H7N9患者信息及其分布信息。
为提高用户体验,进行了一些功能的取舍。
放大,缩小,平移按钮取消,图层控制功能也取消,因为没有必要提供给用户该功能。
为方便用户浏览地图,前一视图、后一视图和全图均竖直布置在左边,均用图标代替文字。
为增强查询信息效果,均以弹出窗口显示查询结果,并在地图中高亮显示。
为提高H7N9信息的总体认识,设计了扇形和柱形统计图,方便用户从总体上了解H7N9在全国的分布,以及H7N9在全国分布形势。
此外,为获取进一步的H7N9新闻,设计了相关新闻功能,以便获取H7N9最新动态。
七、实习内容
1、地图文档制作
本次实习,需要准备中国行政区划矢量数据、各省行政中心矢量图和H7N9各省统计数据。
数据通过ArcGIS Desktop进行属性表编辑,设置符号样式。
结果如图1.4所示。
注:地图文档数据一定要有空间参考,否则地图服务无法访问。
<图1.4>
2、地图文档发布
2.1数据发布准备
数据发布需先设置一个共享文件夹,ArcGIS Server才能访问地图文档数据并发布。
具体操作略。
2.2发布地图文档
登陆ArcGIS Server Manager账户,访问共享文件夹中的mxd文档,发布地图文档数据(默认发布地图服务,如有其它需求,可再发布其它服务)。
发布成功则显示该地图文档的缩略图。
如图1.5.
<图1.5>
3、WebGIS功能开发
3.1配置开发环境
本次实习采用的是FB3版本,API1.3版本,因为网上基于这个环境开发的教程比较多,学习起来容易上手。
环境的配置主要是添加API1.3中的lib或swc文件。
如图1.6。
<图1.6>
此外,调试时最好使用IE浏览器进行调试,以免出现不必要的麻烦。
3.2功能开发
基于FB集成开发环境的开发语言是MXML和ActionScript语言。
开发过程中也可以使用可视化开发模式。
一般来说代码与可视化结合开发速度较快。
开发过程包括,功能实现和各组件的布局样式设置。
在开发的过程中,代码需要经常进行调试,以期达到理想效果。
八、实习成果
7.1实习总效果图
7.2、基本导航和信息浏览功能
7.3、属性查询功能
1、输入查询
在“H7N9省份统计”面板中,输入想要查询的省份,如江苏,则会弹出一个结果面板,给出查询结果,并在地图中高亮显示,如图1.7。
如果移动鼠标到江苏省上,则会出现tip 提示,如图1.8。
<图1.7>
<图1.8>
2、空间查询
2.1患者信息空间查询
当鼠标移动到图中的粉红色圆圈中时,即各省行政中心城市时,显示该省H7N9患者的相关信息,如图1.9。
当鼠标移开的时候,信息自动隐藏。
<图1.9>
2.2各省H7N9信息统计空间查询
单击地图中任何省份,弹出一个引用窗口,包含了该省H7N9的所有信息。
2.3统计功能
1、扇形图统计
单击统计面板中的扇形图按钮,则弹出扇形图统计结果。
可以查看各省H7N9比例状况。
2、柱形图统计
单击统计面板中的柱形图按钮,则弹出柱形图统计结果。
可以查看各省H7N9排行状况及具体数目。
2.4链接新闻功能
点击右下角的“相关新闻”链接,则自动打开新窗口,连接到网易H7N9专题新闻页面,以供查询者获取相关消息。
九、实习总结
通过本次实习,掌握了基本的WebGIS设计和开发过程,并学习了一种Flex开发方式,收获颇丰。
总结以下几点心得:
1、数据是系统之源
再好的系统没了数据,也就是一堆废码,有了好的数据,系统也能上几个层次。
当然数据的设计与相关的功能有关,应仔细考虑功能的流程而设计数据结构和功能,防止数据冗余。
2、系统目的要明确
虽然实习设计的系统很小,但麻雀虽小,五脏俱全。
无论进行何种系统设计,系统的目的一定得明确,否则可能会出现数据设计问题,系统功能复杂,系统布局混乱。
3、系统开发要走流程
无论何种系统的开发,都有一定的开发流程和技术规范。
如果不遵守,则会遇到开发中断,重新开发等问题,造成精力浪费。
我就碰到过有同学直接copy代码,研究了半天,才发现数据设计有问题,只得重新来过。
4、开发环境配置很重要
之前遇到过同学拿到参考代码就直接复制黏贴,运行出错的状况,结果发现示例代码开发环境与自己配置的环境不一样。
有一份好的教程和好的开发环境,开发起来事半功倍。
5、Google 百度得充分利用
有的同学遇到问题,动不动就到处问人。
其实一般而言,后人出现的问题,前人一般遇到过,且早就解决了,利用好Google和百度,是提高开发效率的重要因素。
6、充分利用API示例代码和ArcGIS Resource资源
可能有的同学不了解示例代码的好处,一个劲的网上找资源,结果找了一大堆复杂的示例代码。
我也因为这个走过很多冤枉路。
后来得知API示例代码和ArcGIS Resource资源才是最好的教程。
7、先看懂示例代码,再开发功能
相同的功能,具有类似的代码,看懂一个功能,便知道该功能如何修改以期实现自己想要的功能。
在开发的过程中,需要理解功能的核心原理,这也是学习开发的一条快速之路、总之,开发并不是一件容易的事情,你需要学习很多方面的知识,比如开发语言,系统原理等。
只有你遇到过很多的问题,调试过很多的bug,你才能真正取得进步。
如果你想玩代码玩个痛快,那必须先让代码玩你个痛快。
这是我这次实习最深的感受。
附:实习源代码
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="/2006/mxml"
xmlns:esri="/2008/ags"
pageTitle="中国各省H7N9分布统计"
styleName="plain" width="1360" height="668">
<mx:Canvas id="cav" width="1360" height="668">
<esri:Map id="ChinaMap" mouseMove="onMouseMove(event)"
mapClick="mapClickHandler(event)" logoVisible="false" visible="true"> <esri:ArcGISDynamicMapServiceLayer
url="http://lzuliuyun/ArcGIS/rest/services/China/MapServer"/> <esri:ArcGISDynamicMapServiceLayer
url="/ArcGIS/rest/services/ChinaOnlineCommu nity/MapServer"/>
<esri:GraphicsLayer id="myGraphicsLayer"/>
<esri:GraphicsLayer
graphicProvider="{lastIdentifyResultGraphic}"/>
<esri:GraphicsLayer id="clickGraphicsLayer"/>
<esri:extent>
<esri:Extent id = "esriMapExtent" xmin="86" ymin="22"
xmax="128" ymax="46"/>
</esri:extent>
</esri:Map>
<mx:Label x="131" y="25" text="H7N9信息查询" width="223" height="39" color="#0DB674" fontWeight="bold" fontSize="30" fontFamily="Times New Roman"/>
<mx:Image x="53" y="10" source="file:///C|/Users/hp/Desktop/h7.jpg" width="70" height="70" />
<mx:Button click="navToolbar.zoomToPrevExtent()" enabled="true" labelPlacement="left" icon="@Embed(source='assets/goback.png')" x="10" y="120"/>
<mx:Button click="navToolbar.zoomToNextExtent()"
enabled="{!navToolbar.isLastExtent}"
icon="@Embed(source='assets/goto.png')" x="10" y="90"/>
<mx:Button click="navToolbar.zoomToFullExtent()"
icon="@Embed(source='assets/FullExtent.png')" x="10" y="150"/> <mx:Panel title="H7N9省份统计" layout="horizontal"
backgroundColor="#77C4EC" borderStyle="solid" width="175.15"
height="65" x="1150" y="10">
<mx:TextInput width="83" id="qText" enter="doQuery()" text="江苏" height="23"/>
<mx:Button label="查询"
click="myGraphicsLayer.clear();doQuery()" width="57" height="23"/> </mx:Panel>
<mx:TitleWindow id="twind" visible="false" showCloseButton="true" y="94" width="175.15" height="120" layout="absolute"
backgroundColor="#9CECBA" barColor="#39E6AB" borderColor="#49F1AC"
x="1150" >
<mx:Label id="lbl1" x="10" y="8" text="Label"
fontWeight="bold"/>
<mx:Label id="lbl2" x="10" y="34" text="Label"
fontWeight="bold"/>
<mx:Label id="lbl3" x="10" y="57" text="Label"
fontWeight="bold"/>
</mx:TitleWindow>
<mx:Panel x="948" y="10" width="175.15" height="65"
layout="absolute" title="统计" backgroundColor="#30EA11"
barColor="#30EA11" borderColor="#30EA11" themeColor="#30EA11"> <mx:Button x="10" y="2" label="扇形图" click="pie.visible=true"/>
<mx:Button x="83" y="2" label="柱形图" click="col.visible=true"/> </mx:Panel>
<mx:ColumnChart id="col" width="730" height="248"
showDataTips="true" dataProvider="{H7N9Num}" x="10" y="382"
visible="false">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="省份"/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries xField="省份" yField="number"/>
</mx:series>
</mx:ColumnChart>
<mx:PieChart id="pie" width="248" height="248"
dataProvider="{H7N9Num}" y="382" x="1075" visible="false">
<mx:series>
<mx:PieSeries field="number" labelPosition="callout" labelFunction="chartLabel" fontSize="10"/>
</mx:series>
</mx:PieChart>
<mx:HBox fontSize="11" color="#38D3CA" fontWeight="bold" x="20"
y="645">
<mx:Label text="经度: {mapCoordX.toFixed(4)}" paddingBottom="0" width="100" y="655" x="20"/>
<mx:Label text="纬度: {mapCoordY.toFixed(4)}" paddingBottom="0" width="100" y="655" x="20"/>
</mx:HBox>
<mx:Label x="1287" y="640" text="相关新闻" width="51"
click="openUrl()" textDecoration="underline" toolTip="点击"
color="#0521CB" fontWeight="bold"/>
</mx:Canvas>
<esri:Navigation id="navToolbar" map="{ChinaMap}"/>
<esri:SimpleMarkerSymbol id="clickPtSym" style="x" color="0xFF0000" size="12"/>
<esri:SimpleLineSymbol id="slsIdentify" style="solid"
color="0x00FF00" width="2" alpha="1"/>
<esri:SimpleMarkerSymbol id="smsIdentify" style="diamond"
color="0x00FF00" size="15"/>
<esri:SimpleFillSymbol id="sfsIdentify"/>
<esri:SimpleMarkerSymbol id="defaultSymbol" color="#F69696"
style="circle" size="10" alpha="0.5" >
<esri:SimpleLineSymbol/>
</esri:SimpleMarkerSymbol>
<esri:IdentifyTask id="identifyTask" concurrency="last"
url="http://lzuliuyun/ArcGIS/rest/services/China/MapServer"/> <esri:QueryTask id="queryTask"
url="http://lzuliuyun/ArcGIS/rest/services/China/MapServer/1"> </esri:QueryTask>
<esri:Query id="query"
text="{qText.text}"
returnGeometry="true"
spatialRelationship="esriSpatialRelEnvelopeIntersects"> <esri:outFields>
<mx:String>solution</mx:String>
<mx:String>queren</mx:String>
<mx:String>kangfu</mx:String>
</esri:outFields>
</esri:Query>
<mx:initialize>
<![CDATA[
import com.esri.ags.Graphic;
import com.esri.ags.tasks.FeatureSet;
import com.esri.ags.tasks.Query;
import com.esri.ags.tasks.QueryTask;
import mx.controls.Alert;
import mx.rpc.AsyncResponder;
import com.esri.ags.events.MapMouseEvent;
import com.esri.ags.geometry.Geometry;
import com.esri.ags.geometry.MapPoint;
import Symbol;
import com.esri.ags.tasks.IdentifyParameters;
import com.esri.ags.tasks.IdentifyResult;
//实例化QueryTask并且把图层0作为参数,图层0就是Cities图层
var queryTask : QueryTask = new
QueryTask("http://lzuliuyun/ArcGIS/rest/services/China/MapServer/0");
var query : Query = new Query();
//设置查询语句
query.where = "经度 > 10";
//设置是否返回Geometry
query.returnGeometry = true;
//设置查询需要返回的字段
query.outFields = ["省","信息"];
//进行查询
queryTask.execute(query, new AsyncResponder( onResult, onFault ));
//查询完成后调用方法
function onResult( featureSet : FeatureSet, token : Object = null ) : void
{
for each( var myGraphic : Graphic in featureSet.features ) {
//为城市点添加鼠标移动上去的事件监听
myGraphic.addEventListener(MouseEvent.ROLL_OVER,maouseOverHandler);
//为城市点添加鼠标移开的事件监听
myGraphic.addEventListener(MouseEvent.ROLL_OUT,maouseOutHandler);
//显示城市点的样式
myGraphic.symbol = defaultSymbol;
//添加到GraphicsLayer进行显示
myGraphicsLayer.add( myGraphic );
}
}
//查询错误后调用方法,显示错误信息
function onFault( info : Object, token : Object = null) : void {
Alert.show( info.toString() );
}
]]>
</mx:initialize>
<mx:Script>
<![CDATA[
import com.esri.ags.Graphic;
import com.esri.ags.tasks.FeatureSet;
import com.esri.ags.tasks.Query;
import mx.controls.Alert;
import mx.rpc.AsyncResponder;
private function doQuery() : void
{
queryTask.execute( query, new AsyncResponder( onResult, onFault ));
function onResult( featureSet : FeatureSet, token : Object = null ) : void
{
for each ( var myGraphic : Graphic in
featureSet.features )
{
// ToolTip
//twind.title=featureSet.displayFieldName;
lbl1.text= "情况"+myGraphic.attributes.solution; lbl2.text= "已确认"+myGraphic.attributes.queren+"人";
lbl3.text= " 康复"+
myGraphic.attributes.kangfu+"人";
twind.visible=true;
// show on map
myGraphic.toolTip="情况
"+myGraphic.attributes.solution+"已确认"+myGraphic.attributes.queren+"人" + "康复"+ myGraphic.attributes.kangfu+"人";
myGraphicsLayer.add( myGraphic );
}
}
function onFault( info : Object, token : Object = null ) : void
{
Alert.show( info.toString() );
}
}
]]>
</mx:Script>
<mx:Script>
<![CDATA[
import com.esri.ags.Graphic;
import com.esri.ags.events.MapMouseEvent;
import com.esri.ags.geometry.Geometry;
import Symbol;
import com.esri.ags.tasks.IdentifyParameters;
import com.esri.ags.tasks.IdentifyResult;
import mx.controls.Alert;
import mx.rpc.AsyncResponder;
[Bindable]
private var lastIdentifyResultGraphic:Graphic;
private function mapClickHandler(event:MapMouseEvent):void {
clickGraphicsLayer.clear();
var identifyParams:IdentifyParameters = new IdentifyParameters();
identifyParams.returnGeometry = true;
identifyParams.tolerance = 3;
identifyParams.width = ChinaMap.width;
identifyParams.height = ChinaMap.height;
identifyParams.geometry = event.mapPoint;
identifyParams.mapExtent = ChinaMap.extent;
identifyParams.spatialReference =
ChinaMap.spatialReference;
var clickGraphic:Graphic = new Graphic(event.mapPoint, clickPtSym);
identifyTask.execute(identifyParams, new
AsyncResponder(myResultFunction, myFaultFunction, clickGraphic));
clickGraphicsLayer.add(clickGraphic);
}
private function myResultFunction(results:Array, clickGraphic:Graphic = null):void
{
if (results && results.length > 0)
{
var result:IdentifyResult = results[0];
var resultGraphic:Graphic = result.feature;
switch (resultGraphic.geometry.type)
{
case Geometry.MAPPOINT:
{
resultGraphic.symbol = smsIdentify;
break;
}
case Geometry.POLYLINE:
{
resultGraphic.symbol = slsIdentify;
break;
}
case Geometry.POLYGON:
{
resultGraphic.symbol = sfsIdentify;
break;
}
}
lastIdentifyResultGraphic = resultGraphic;
// update clickGraphic (from mouse click to returned feature)
clickGraphic.symbol = new InfoSymbol(); // use default renderer
clickGraphic.attributes = resultGraphic.attributes; }
}
private function myFaultFunction(error:Object,
clickGraphic:Graphic = null):void
{
Alert.show(String(error), "识别出错");
}
]]>
</mx:Script>
<mx:Script>
<![CDATA[
import com.esri.ags.Graphic;
import com.esri.ags.tasks.FeatureSet;
import com.esri.ags.tasks.Query;
import mx.controls.Alert;
import mx.rpc.AsyncResponder;
import com.esri.ags.events.MapMouseEvent;
import com.esri.ags.geometry.Geometry;
import com.esri.ags.geometry.MapPoint;
import Symbol;
import com.esri.ags.tasks.IdentifyParameters;
import com.esri.ags.tasks.IdentifyResult;
//实例化cityInfo.mxml
private const m_content:cityInfo=new cityInfo();
//覆写createChildren方法,对infoWindow进行设置
override protected function createChildren():void
{
super.createChildren();
//不显示标题头
belVisible = false;
//设置显示内容
Window.content = m_content;
//不显示关闭按钮
Window.closeButtonVisible = false;
}
//鼠标移上去事件显示infoWindow
private function maouseOverHandler(event:MouseEvent):void {
//获取当前鼠标移动上去的点对象
var graphic:Graphic=Graphic(event.target);
//转换成MapPoint
var mapPoint:MapPoint=MapPoint(graphic.geometry);
//设置cityInfo.mxml的AREANAME
m_content.省 = graphic.attributes.省;
//设置cityInfo.mxml的CLASS
m_content.信息 = graphic.attributes.信息;
//设置cityInfo.mxml的CAPITAL
//m_content.纬度 = graphic.attributes.纬度;
//设置cityInfo.mxml的ST
// m_content.ST = graphic.attributes.ST;
//设置cityInfo.mxml的POP2000
//m_content.POP2000 = graphic.attributes.POP2000;
//显示infoWindow
Window.show(mapPoint);
}
//鼠标移开事件隐藏infoWindow
private function maouseOutHandler(event:MouseEvent):void {
Window.hide();
]]>
</mx:Script>
<mx:Script>
<![CDATA[
import com.esri.ags.geometry.MapPoint;
[Bindable] private var mapCoordX:Number = 0;
[Bindable] private var mapCoordY:Number = 0;
private function onMouseMove(event:MouseEvent):void
{
var mapPoint:MapPoint =
ChinaMap.toMapFromStage(event.stageX, event.stageY);
mapCoordX = mapPoint.x;
mapCoordY = mapPoint.y;
}
]]>
</mx:Script>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var H7N9Num:ArrayCollection=new ArrayCollection
([{省份:"浙江",number:46},
{省份:"上海",number:33},
{省份:"江苏",number:27},
{省份:"江西",number:5},
{省份:"安徽",number:4},
{省份:"河南",number:4},
{省份:"福建",number:3},
{省份:"湖南",number:2},
{省份:"山东",number:2},
{省份:"北京",number:1},
{省份:"台湾",number:1},
{省份:"其他",number:0}]);
private function
chartLabel(DataItem:Object,field:String,index:int,dataPercent:Number) :String
{
var num:Number=Math.round(dataPercent);
return DataItem.省份+num+"%";
]]>
</mx:Script>
<mx:Script>
<![CDATA[
internal function openUrl():void
{
navigateToURL(new
URLRequest("/s2013/qlg/"), "_blank");
}
]]>
</mx:Script>
</mx:Application>。