mytest
论坛版主
论坛版主
  • 注册日期2006-12-17
  • 发帖数155
  • QQ
  • 铜币53枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:7433回复:10

WebGIS设计与实现原理

楼主#
更多 发布于:2006-12-19 13:23
<DIV><STRONG>1 </STRONG><STRONG>什么是WebGIS </STRONG></DIV>
<DIV>    我的定义是:在internet领域内,向WWW服务器请求地图数据或与之相关的操作,从而获得地图并呈现给最终用户的过程。几点共识是:客户端不必安装任何插件(当然必要的浏览器和XML支持是少不了的);服务端动态生成地图(强调这一点,是因为这样的Webgis引擎才符合工业标准。否则只能称为带有地图图片的网站)。符合上述定义的Webgis的优点是显而易见的:</DIV>
<DIV >(1)地图由服务器动态按需生成,发送给客户端只是最终生成的图片(我的经验是png格式为好),对客户端的要求降到最低。</DIV>
<DIV >(2)利用服务器的中心控制、监视和审计,保障了数据的安全和实现的一致性。</DIV>
<DIV >(3)方便部署的特征,使升级和扩展都异常简单。</DIV>
<DIV >因此,我希望以后在谈论Webgis的时候,再也不要听到Plugin、ActiveX、Applet之类的字眼。</DIV>
<DIV> </DIV>
<DIV><STRONG>2 Webgis</STRONG><STRONG>技术原理</STRONG></DIV>
<DIV>    说了一大堆,就要谈到核心实现了。别以为我在这里胡吹海侃,我确实是真的把自己的体会和经验(教训)无偿的奉献给莘莘学子。我的体会是:</DIV>
<DIV >(1)一种技术,如果太过复杂,就称不上是好技术。比如质能方程E=MC&shy;&shy;*C其简单和优美。所以,我以为宇宙的定律就是简单的规则,当然,多数我们还没发现。</DIV>
<DIV >(2)一种实现,如果要写一大堆的代码,仍然不是一种好的实现。就比如夸一个人长的美,说一千道一万,不如就2个字:好看。</DIV>
<DIV >秉承这个原则,下面介绍我的技术:</DIV>
<DIV >(1)客户端(IE)采用AJAX,直接调用服务端的Services。</DIV>
<DIV >(2)服务端编写Web Services,响应客户的请求。</DIV>
<DIV >原理就这些,为什么我就不说了,如果你不知道,说明你还需要学啊学啊学。</DIV>
<DIV> </DIV>
<DIV><STRONG>3 Webgis</STRONG><STRONG>实现</STRONG></DIV>
<DIV>    先说服务端的实现。按上面说的,就是写Web Services(Web服务)。可能目前没有比写Web Services更时髦的了。还有人说Google Web API要代替传统的Win32API。其实这完全是2种计算模式,谁也代替不了谁。许多专家就喜欢炒作,把媒体那一套应用到我们这个技术领域,误导消费者。</DIV>
<DIV>    其实,若不是浏览器大行其道,Webgis算个啥啊。这社会从来就没公平过,好好的C/S不用,非强迫我们在浏览器里搞啊搞的。没办法,就搞吧,看谁搞得过谁?</DIV>
<DIV>    写Web Services有很多语言可写,什么C#、Java、C++等等等等。需要一套称之为Webgis API的东西。设计这样一套API让AJAX调用。怎么设计呢,我会把我的接口公布出来,供大家参考漫骂。</DIV>
<DIV>    其实最重要的是服务端的地图生成引擎(引擎就是发动机)。我自己实现了一个(带VVT-i的啊),没有的要自己实现,或者买个现成的(比如MapObjects)。</DIV>
<DIV>    该说客户端了。AJAX吗,其实就是JavaScript + XMLHttpRequest(微软版本)对象啊。就别用什么Webservices.htc了,虽然是微软写的,还真他妈不好用。我从高人那里抄了一个,改了改,就用上了。看我上篇文章啊,那个是100%的源代码,没错误的啊。</DIV>
<DIV>    剩下的再说就显得多余了。画个体系结构图吧:</DIV>
<DIV> (图象怎么显示不出来??)</DIV>
<DIV align=center> </DIV>
<DIV align=center>WebGIS体系结构图</DIV>
<DIV> </DIV>
<DIV><STRONG>4 </STRONG><STRONG>小贴示</STRONG></DIV>
<DIV>    看到这里你是不是觉得恶心了,提示就提示干嘛贴示啊。不是有国内北大高人翻译《ATL 技术内幕》非满纸的“控制”。我看了就别扭,国内叫“控件”,这个还比较舒服。翻译的就别提多牵强了。</DIV>
<DIV >(1)服务端要以多线程(IIS进程)服务请求。</DIV>
<DIV >(2)地图引擎加载数据,要能够静态和动态2种模式载入。</DIV>
<DIV >(3)绝对不要想着传矢量的数据,传图片最好,哪怕未来网络带宽提高100倍。</DIV>
<DIV >(4)写的要绝对健壮,不然把IIS搞瘫了。</DIV>
<DIV >(5)记得在服务端保持客户状态啊。</DIV>
<DIV> </DIV>
<DIV><STRONG>5 </STRONG><STRONG>附录:Webgis WebServices 接口和方法</STRONG></DIV>
<DIV >也许一不小心成了标准呢?其实就是想让读者在做这方面的设计时,有个参考,反面典型也好。我把修改数据方面的API去掉了,太危险了,还是不说出来的好。</DIV>
<DIV> </DIV>
<DIV>// Webgis接口方法说明</DIV>
<DIV>// 2006年8月</DIV>
<DIV>// ATL Server Webgis Services Created by cheungmine@gmail.com</DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 关于MtkWebgisService</DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 取得服务相关信息</DIV>
<DIV>HRESULT <STRONG>about</STRONG>([out, retval] BSTR *Info);</DIV>
<DIV> </DIV>
<DIV>// 取得服务器日期时间</DIV>
<DIV>HRESULT <STRONG>svrtime</STRONG>([out, retval] mtkTime *time);</DIV>
<DIV> </DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 登入与登出, login必须是第1个调用的服务端方法</DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 登入系统, 获得用户令牌和全图URL, 以后任何方法调用必须给出令牌</DIV>
<DIV>HRESULT <STRONG>login</STRONG>([in] BSTR Username, [in] BSTR Password);</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>// 登出系统, 注销用户令牌</DIV>
<DIV>HRESULT <STRONG>logout</STRONG>();</DIV>
<DIV> </DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 基本信息</DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 当前MTK Canvas版本</DIV>
<DIV>HRESULT <STRONG>version</STRONG>([out, retval] BSTR *Ver);</DIV>
<DIV> </DIV>
<DIV>// 取得全部图层信息, 以XML内联返回</DIV>
<DIV>HRESULT <STRONG>mapinfo</STRONG>([out, retval] BSTR *xmlInfo);</DIV>
<DIV> </DIV>
<DIV>// 取得全部图层信息, 返回生成的XML的URL</DIV>
<DIV>HRESULT <STRONG>mapxml</STRONG>([out, retval] BSTR *xmlURL);</DIV>
<DIV> </DIV>
<DIV>// 取得图层信息, 以XML内联返回</DIV>
<DIV>HRESULT <STRONG>layinfo</STRONG>([in] LONG LayerIndex, [out, retval] BSTR *xmlInfo);</DIV>
<DIV> </DIV>
<DIV>// 取得图形属性信息, 以XML内联返回. 若图层索引为>=MTK_TMPLAYER_INDEX, 则在临时层上</DIV>
<DIV>HRESULT <STRONG>shpinfo</STRONG>([in] LONG LayerIndex, [in] LONG fromShapeIndex, [in] LONG fetchCount, [out, retval] BSTR *xmlInfo);</DIV>
<DIV> </DIV>
<DIV>// 取得图形属性信息, 返回生成的XML的URL. 若图层索引为>=MTK_TMPLAYER_INDEX, 则在临时层上</DIV>
<DIV>HRESULT <STRONG>shpxml</STRONG>([in] LONG LayerIndex, [in] LONG fromShapeIndex, [in] LONG fetchCount, [out, retval] BSTR *xmlURL);</DIV>
<DIV> </DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 地图浏览和点查</DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 刷新地图, 取地图imgURL</DIV>
<DIV>HRESULT <STRONG>refresh</STRONG>([out] DOUBLE* Scale, [out, retval] BSTR *imgURL);</DIV>
<DIV> </DIV>
<DIV>// 地图控制显示比例</DIV>
<DIV>HRESULT <STRONG>scale</STRONG>([out] DOUBLE* minScale, [out] DOUBLE* maxScale);</DIV>
<DIV> </DIV>
<DIV>// 按比例显示地图, 不改变当前地图中心位置</DIV>
<DIV>HRESULT <STRONG>zoom</STRONG>([in] DOUBLE Scale);</DIV>
<DIV> </DIV>
<DIV>// 指定视图位置放大或缩小地图, 指定放大缩小的百分比</DIV>
<DIV>HRESULT <STRONG>zoomat</STRONG>([in] mtkPoint Pos, [in] SHORT Percent);</DIV>
<DIV> </DIV>
<DIV>// 开窗显示地图, 指定视图上的2点</DIV>
<DIV>HRESULT <STRONG>zoomext</STRONG>([in] mtkPoint Pos1, [in] mtkPoint Pos2);</DIV>
<DIV>// 开窗显示地图, 指定地图上的2点</DIV>
<DIV>HRESULT <STRONG>zoomext2</STRONG>([in] mtkPoint Pt1, [in] mtkPoint Pt2);</DIV>
<DIV> </DIV>
<DIV>// 移动地图, 指定视图上的2点</DIV>
<DIV>HRESULT <STRONG>move</STRONG>([in] mtkPoint fromPos, [in] mtkPoint toPos);</DIV>
<DIV> </DIV>
<DIV>// 选中图形对象, 指定视图上的点. 返回对象的sid负值和所在的图层索引和对象信息</DIV>
<DIV>HRESULT <STRONG>identify</STRONG>([in] mtkPoint Pos, [out] LONG* _sid, [out] LONG* layId, [out, retval] BSTR* shpInfo);</DIV>
<DIV> </DIV>
<DIV>// 设置图层状态属性, 指定层的索引和状态名称, 状态值</DIV>
<DIV>HRESULT <STRONG>setlayer</STRONG>([in] LONG LayerIndex, [in] mtkEnumLayerState State, [in] bool bVal);</DIV>
<DIV> </DIV>
<DIV>// 以指定视图上的点为中心, 定位地图</DIV>
<DIV>HRESULT <STRONG>centerat</STRONG>([in] mtkPoint Pos);</DIV>
<DIV> </DIV>
<DIV>// 以指定地图坐标点为中心, 定位地图</DIV>
<DIV>HRESULT <STRONG>centerat2</STRONG>([in] mtkPoint Pt);</DIV>
<DIV> </DIV>
<DIV>// 地图翻页, 指定方向Up,Down,Right,Left和页面重叠百分率0%~100%"</DIV>
<DIV>HRESULT <STRONG>flip</STRONG>([in] mtkEnumFlip Direction, [in] SHORT Overlap);</DIV>
<DIV> </DIV>
<DIV>// 清除选中的对象</DIV>
<DIV>HRESULT <STRONG>clear</STRONG>();</DIV>
<DIV> </DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 地图测量, 视图上的点串</DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 地图测量, 返回距离, 面积和地图单位</DIV>
<DIV>HRESULT <STRONG>measure</STRONG>([in] mtkPoints PathPoints, [out] DOUBLE* Length, [out] DOUBLE* Area, [out] BSTR* Unit);</DIV>
<DIV> </DIV>
<DIV>// 地图测量, 返回距离, 面积和地图单位</DIV>
<DIV>HRESULT <STRONG>measure2</STRONG>([in] BSTR PathString, [out] DOUBLE* Length, [out] DOUBLE* Area, [out] BSTR* Unit);</DIV>
<DIV> </DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 坐标变换: 视图(view)与数据(data)之间的正反坐标变换</DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 取得地图当前数据坐标范围</DIV>
<DIV>HRESULT <STRONG>extent</STRONG>([out] DOUBLE* MinX, [out] DOUBLE* MinY, [out] DOUBLE* MaxX, [out] DOUBLE* MaxY);</DIV>
<DIV> </DIV>
<DIV>// 视图点变换到数据坐标点</DIV>
<DIV>HRESULT <STRONG>vp2dp</STRONG>([in] LONG VX, [in] LONG VY, [out] DOUBLE* DX, [out] DOUBLE* DY);</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>// 数据坐标点变换到视图点</DIV>
<DIV>HRESULT <STRONG>dp2vp</STRONG>([in] DOUBLE DX, [in] DOUBLE DY, [out] LONG* VX, [out] LONG* VY);</DIV>
<DIV> </DIV>
<DIV>// 视图点串变换到数据坐标点串</DIV>
<DIV>HRESULT <STRONG>vs2ds</STRONG>([in] BSTR VS, [out, retval] BSTR* DS);</DIV>
<DIV> </DIV>
<DIV>// 数据坐标点串变换到视图点串</DIV>
<DIV>HRESULT <STRONG>ds2vs</STRONG>([in] BSTR DS, [out, retval] BSTR* VS);</DIV>
<DIV> </DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 空间查询与分析</DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 重置过滤器. 清除所有以前设置的过滤器</DIV>
<DIV>HRESULT <STRONG>resetFilters</STRONG>();</DIV>
<DIV> </DIV>
<DIV>// 设置过滤器, 可以多次调用此方法以设置多个过滤器, 只要服务端支持多过滤. 返回过滤器总数</DIV>
<DIV>HRESULT <STRONG>addFilter</STRONG>([in] mtkFilter Filter, [out, retval] LONG* Count);</DIV>
<DIV> </DIV>
<DIV>// 根据条件查找图形对象, 返回查询到的对象数. 查询结果图层为临时层, 索引为i+MTK_TMPLAYER_INDEX</DIV>
<DIV>HRESULT <STRONG>findShapes</STRONG>([in] LONG LayerIndex, [in] BSTR SqlClause, [in] bool UseFilters, [out, retval] LONG* Count);</DIV>
<DIV> </DIV>
<DIV>// 生成缓冲区图形, 返回目标图形sid. 此操作都在跟踪层中</DIV>
<DIV>HRESULT <STRONG>bufferShape</STRONG>([in] LONG sid, [in] DOUBLE Distance, [out, retval] LONG* sidDst);</DIV>
<DIV> </DIV>
<DIV>// 将非跟踪层中的图形数据保存到跟踪层中, 返回图形sid</DIV>
<DIV>HRESULT <STRONG>trackShape</STRONG>([in] LONG LayerIndex, [in] LONG ShapeIndex, [out, retval] LONG* sid);</DIV>
<DIV> </DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 图形编辑</DIV>
<DIV>//////////////////////////////////////////////////////</DIV>
<DIV>// 创建新图形对象, 返回图形对象的ID</DIV>
<DIV>HRESULT <STRONG>createShape</STRONG>([in] mtkEnumGeometry GType, [out, retval] LONG* sid);</DIV>
<DIV> </DIV>
<DIV>// 向新图形对象中增加视图上的点, 象素坐标</DIV>
<DIV>HRESULT <STRONG>addPt</STRONG>([in] LONG sid, [in] mtkPoint Pos);</DIV>
<DIV> </DIV>
<DIV>// 向新图形对象中增加点, 地图坐标</DIV>
<DIV>HRESULT <STRONG>addPt2</STRONG>([in] LONG sid, [in] mtkPoint Pt);</DIV>
<DIV> </DIV>
<DIV>// 向图形对象中增加单一属性, 指明列索引0-based, 列值</DIV>
<DIV>HRESULT <STRONG>setCol</STRONG>([in] LONG sid, [in] SHORT colId, [in] BSTR colVal);</DIV>
<DIV> </DIV>
<DIV>// 清除指定sid的图形. 绘制的图形都保存在跟踪层中. sid=0全部删除</DIV>
<DIV>HRESULT <STRONG>clearShape</STRONG>([in] LONG sid);</DIV>
喜欢0 评分0
mytest
论坛版主
论坛版主
  • 注册日期2006-12-17
  • 发帖数155
  • QQ
  • 铜币53枚
  • 威望0点
  • 贡献值0点
  • 银元0个
1楼#
发布于:2007-05-26 19:22
<img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" />
举报 回复(0) 喜欢(0)     评分
jinyu1123
路人甲
路人甲
  • 注册日期2006-07-05
  • 发帖数67
  • QQ
  • 铜币262枚
  • 威望0点
  • 贡献值0点
  • 银元0个
2楼#
发布于:2007-05-27 19:31
<img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" />
迷茫啊! Email : jinyu1123@163.com.
举报 回复(0) 喜欢(0)     评分
wangzheng_gis
路人甲
路人甲
  • 注册日期2007-03-22
  • 发帖数4
  • QQ
  • 铜币112枚
  • 威望0点
  • 贡献值0点
  • 银元0个
3楼#
发布于:2007-06-01 11:17
<P><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em01.gif" /></P>
<P>wo ye yao xue </P>
举报 回复(0) 喜欢(0)     评分
whmwxhanshan123
路人甲
路人甲
  • 注册日期2006-06-17
  • 发帖数3108
  • QQ
  • 铜币6445枚
  • 威望0点
  • 贡献值0点
  • 银元0个
4楼#
发布于:2007-06-01 18:13
向你请教
举报 回复(0) 喜欢(0)     评分
zxxxxj
路人甲
路人甲
  • 注册日期2007-06-22
  • 发帖数11
  • QQ
  • 铜币130枚
  • 威望0点
  • 贡献值0点
  • 银元0个
5楼#
发布于:2007-08-05 13:24
<P>该技术的关键是减轻客户端的数据流量。不知是否这样理解。</P>
举报 回复(0) 喜欢(0)     评分
arongbaobao
路人甲
路人甲
  • 注册日期2007-06-18
  • 发帖数11
  • QQ
  • 铜币149枚
  • 威望0点
  • 贡献值0点
  • 银元0个
6楼#
发布于:2007-08-22 12:17
<img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em02.gif" />
举报 回复(0) 喜欢(0)     评分
chenyuxin
路人甲
路人甲
  • 注册日期2008-08-28
  • 发帖数23
  • QQ
  • 铜币170枚
  • 威望0点
  • 贡献值0点
  • 银元0个
7楼#
发布于:2009-10-20 19:17
<img src="images/post/smile/dvbbs/em02.gif" /><img src="images/post/smile/dvbbs/em01.gif" />
举报 回复(0) 喜欢(0)     评分
fengfan
路人甲
路人甲
  • 注册日期2007-06-07
  • 发帖数1
  • QQ
  • 铜币106枚
  • 威望0点
  • 贡献值0点
  • 银元0个
8楼#
发布于:2009-12-12 21:51
<P>这也许是我第一个回帖。</P>
<P>如果一个技术仅仅使用比较新的ajax  + WebServices 实现。是不是路太窄了点?对标题的感觉。</P>
举报 回复(0) 喜欢(0)     评分
lzd851212
外卖仔
外卖仔
  • 注册日期2009-05-20
  • 发帖数57
  • QQ
  • 铜币275枚
  • 威望-1点
  • 贡献值0点
  • 银元0个
9楼#
发布于:2010-05-07 10:39
看不懂
举报 回复(0) 喜欢(0)     评分
上一页
游客

返回顶部