一个从未接触过GIS的程序员近期的GIS历程 之 silverlight地图
额,废话就不多说了,我今年3月份开始,接触了2个GIS项目,其实说是GIS,也就是操作地图-_-; 本来我以前从来没接触过GIS,心里没底,不过做了之后,感觉貌似基本的也不是很难了。说下大概的情况吧
项目一,使用的是国产地图引擎 mapengine,它的客户端是个javaapplet, 特点是客户端绘图,不过画出来的地图那是真的难看无比,就不多说了,我接手了那个项目之后,有以下几个感想:
1,从这个项目来看,地图只是一种展现形式,它的业务其实和企业管理系统比起来,那简直是太容易了,这里面唯一麻烦的就是那个地图了,但是反正是基于人家的地图引擎二次开发,所以,学一下也可以上手了。由此可见,貌似GIS项目也没那么难做:)
2,我们常做普通项目的人,优势也是有的,这个项目我接手前,客户说服务器2天死一次,经我检查,他原来的代码里,所有的数据库操作都是只打开连接而不关闭,囧, 改了就好了,呵呵,可见有的GIS程序员开发基础不够扎实啊。
项目二,是公司花钱买了个小公司的地图引擎,这个地图我不得不说,实在是太囧了,那个生成出来的地图简直奇丑无比,而且客户端的JS地图极其糟糕,不停地页面刷新,呵呵,从去年开始的项目,这地图始终是无法让人满意。于是我用siliverlight改写了一个客户端。
然后我对GIS有了点兴趣,于是下载了sharpmap进行了一番研究。
由这两个项目和sharpmap,我对GIS有了几个概念:
1,地图的矢量数据就是以下几个:点,线,多边形。我接触到的两个项目中,只见到了这几个东西。2D的地图,用这几个足矣。
2,最常用的功能,就是呈现一个地图。最多也就是在地图上面加点什么轨迹动画,叠加点车站位置什么什么的,至于拓扑关系,寻路等,反正我这两个项目里没用到,而且貌似我们公司买的这两个引擎也没有这个功能。sharpmap也没有
3, 地图的矢量数据文件的通用格式是SHP,这个用sharpmap的库里的东西可以读出来。
4,空间数据库。别被名字唬住了,空间数据库就是个普通的数据库,sqlserver的,或者access的,只是把矢量图形对象用二进制存储了而已,囧
5, sql2008自带的空间数据库,比我们公司买的那个强了不知道多少倍,何况sql2008 express还免费的说
6, 坐标转换问题:确实这个我们普通程序员是不懂什么OO投影,XX投影的,但是,貌似呈现一个2D地图,只用平面直角坐标系就OK了,至于SRID 4326之类的东西,只要数据源shp文件 SRID一致,就按照平面直角坐标系处理就完事了,反正我看sharpmap也是这么干的
7,分析多边形之间的关系。这个倒确实是难点,不过我们的比尔大门已经在sql2008里给我们都搞定了,照着用就完事了。
8,小结: 如果只是做普通的地图应用,了解以上这么点东西,足矣。
了解了以上这些,我决定动手用siliverlight做个地图。至少功能上要和公司买的那个小公司的产品一致,而且地图得比它好看。(顺便, mapengine 的 javaapplet 版的地图,也很难看,silverlight无论如何得比它强吧)
由此,我开始开发这个silverlight地图。第一步,把shp文件导入到sqlserver里。在这里,我使用了sharpmap的库,非常之简单,一下子就导入进去了。导入进去表里,有四个字段,分别记录了一个矢量图形的上下左右四个顶点。在展示地图的时候,通过where语句,把在视野内的矢量对象读取出来就可以了。好么,这个彻底摧毁了我对空间数据库的神秘感,我甚至怀疑这是不是太山寨了。
说到这里,我估计大家谁都会读取地图数据了.下一步,把读出来的矢量数据传给silverlight.这个也简单,webclient,轻松加愉快,不再废话。
然后,由silverlight进行绘图。人家silverlight干这个可是专业的,不过,这里问题来了,我小结下来问题:
对于上海市地图那如同蜘蛛网一样的路线,直接在前台线程里绘图,那你就完了。浏览器会直接挂死的。
方案一:异步绘图。我是分析传过来的矢量数据之后,不断地生成UIELEMENT对象,然后追加到Canvas画布上的。这里需要使用异步,也就是dispatcher.begininvoke() 来一次生成一个UIELEMENT,然后追加上去。追加完后,如果还有未生成的矢量图形,那么就马上再次调用begininvoke,直到绘制结束。
这样有个问题,就是地图确实是响应速度快了,但是会看到一个一个得元素如同在实时绘画一般地一个一个画上去,速度确实不够快。不过效果很酷,呵呵
方案二:在后台线程中,生成xaml,然后一次性解析并呈现。经比较,让silverlight解析xaml的表现,明显比动态添加uielement的表现强非常多。这也算是一个小发现。使用方案二,就可以解决绘图效率问题。
问题二,数据传输的问题。上海地图会传输非常大量的矢量数据过去。我抓包后看,发现这些文本信息的字节数居然比图片还大 。这下我真的囧了,本来以为文本比图片小,没想到居然倒了过来。不过我们熟悉asp.net的人自然会马上想到解决办法:gzip压缩。呵呵,这个简单,马上上网,抄了一段代码贴进去,哈哈,马上压缩掉70%。
问题三,我们是否需要传输那么多的矢量点?由于我搞来的shp文件,精度很高,所以,在缩放比很大的时候,有些点传输了也没有意义啊,因为根本就是都被压缩到一个像素里去了。而且那些点的经纬度精确到了8位小数,但是事实上,对于像素来讲,一般精确到3-4位小数就足够了,所以服务器在传数据的时候,完全可以压缩掉这些信息。这样,传输的数据量就更小了。现在经压缩,数据量已小于图片的数据量。而且是放的越大越小,和图片正好相反。
现在还有问题是:服务器暂时无法利用缓冲,因为每次查询的经纬度都不同,导致无法根据查询字符串进行cache。 每次取数都要查询20个图层,也就是进行20次数据库查询,暂时没有想出好的解决办法。
现在的进度是,正在制作客户端地图编辑工具。
效果见图:
目前阶段性成果可以在这里看到 h**p://211。136。156。198/newGIS/
呵呵,别的我不说,至少地图呈现的效果已经接近bing地图了,嘿嘿,反正比公司买的那两个引擎都要强很多。
注意,这个地址可能不久后就会失效。还有服务器可能压力过大,请大家不要把地址传出去啊,谢谢
在项目中使用silverlight的好处确实很多,原来要写N多js的东西,轻轻松松就解决了,而且反正在项目中使用,也不用去考虑什么网站用户没安装silverlight之类的,嘿嘿。
最后,本人最近似乎出现了健忘,精力不集中的现象。每天只工作了2个小时后脑子就一团浆糊,什么都写不出来了,不知道各位对此可有啥好的建议
项目一,使用的是国产地图引擎 mapengine,它的客户端是个javaapplet, 特点是客户端绘图,不过画出来的地图那是真的难看无比,就不多说了,我接手了那个项目之后,有以下几个感想:
1,从这个项目来看,地图只是一种展现形式,它的业务其实和企业管理系统比起来,那简直是太容易了,这里面唯一麻烦的就是那个地图了,但是反正是基于人家的地图引擎二次开发,所以,学一下也可以上手了。由此可见,貌似GIS项目也没那么难做:)
2,我们常做普通项目的人,优势也是有的,这个项目我接手前,客户说服务器2天死一次,经我检查,他原来的代码里,所有的数据库操作都是只打开连接而不关闭,囧, 改了就好了,呵呵,可见有的GIS程序员开发基础不够扎实啊。
项目二,是公司花钱买了个小公司的地图引擎,这个地图我不得不说,实在是太囧了,那个生成出来的地图简直奇丑无比,而且客户端的JS地图极其糟糕,不停地页面刷新,呵呵,从去年开始的项目,这地图始终是无法让人满意。于是我用siliverlight改写了一个客户端。
然后我对GIS有了点兴趣,于是下载了sharpmap进行了一番研究。
由这两个项目和sharpmap,我对GIS有了几个概念:
1,地图的矢量数据就是以下几个:点,线,多边形。我接触到的两个项目中,只见到了这几个东西。2D的地图,用这几个足矣。
2,最常用的功能,就是呈现一个地图。最多也就是在地图上面加点什么轨迹动画,叠加点车站位置什么什么的,至于拓扑关系,寻路等,反正我这两个项目里没用到,而且貌似我们公司买的这两个引擎也没有这个功能。sharpmap也没有
3, 地图的矢量数据文件的通用格式是SHP,这个用sharpmap的库里的东西可以读出来。
4,空间数据库。别被名字唬住了,空间数据库就是个普通的数据库,sqlserver的,或者access的,只是把矢量图形对象用二进制存储了而已,囧
5, sql2008自带的空间数据库,比我们公司买的那个强了不知道多少倍,何况sql2008 express还免费的说
6, 坐标转换问题:确实这个我们普通程序员是不懂什么OO投影,XX投影的,但是,貌似呈现一个2D地图,只用平面直角坐标系就OK了,至于SRID 4326之类的东西,只要数据源shp文件 SRID一致,就按照平面直角坐标系处理就完事了,反正我看sharpmap也是这么干的
7,分析多边形之间的关系。这个倒确实是难点,不过我们的比尔大门已经在sql2008里给我们都搞定了,照着用就完事了。
8,小结: 如果只是做普通的地图应用,了解以上这么点东西,足矣。
了解了以上这些,我决定动手用siliverlight做个地图。至少功能上要和公司买的那个小公司的产品一致,而且地图得比它好看。(顺便, mapengine 的 javaapplet 版的地图,也很难看,silverlight无论如何得比它强吧)
由此,我开始开发这个silverlight地图。第一步,把shp文件导入到sqlserver里。在这里,我使用了sharpmap的库,非常之简单,一下子就导入进去了。导入进去表里,有四个字段,分别记录了一个矢量图形的上下左右四个顶点。在展示地图的时候,通过where语句,把在视野内的矢量对象读取出来就可以了。好么,这个彻底摧毁了我对空间数据库的神秘感,我甚至怀疑这是不是太山寨了。
说到这里,我估计大家谁都会读取地图数据了.下一步,把读出来的矢量数据传给silverlight.这个也简单,webclient,轻松加愉快,不再废话。
然后,由silverlight进行绘图。人家silverlight干这个可是专业的,不过,这里问题来了,我小结下来问题:
对于上海市地图那如同蜘蛛网一样的路线,直接在前台线程里绘图,那你就完了。浏览器会直接挂死的。
方案一:异步绘图。我是分析传过来的矢量数据之后,不断地生成UIELEMENT对象,然后追加到Canvas画布上的。这里需要使用异步,也就是dispatcher.begininvoke() 来一次生成一个UIELEMENT,然后追加上去。追加完后,如果还有未生成的矢量图形,那么就马上再次调用begininvoke,直到绘制结束。
这样有个问题,就是地图确实是响应速度快了,但是会看到一个一个得元素如同在实时绘画一般地一个一个画上去,速度确实不够快。不过效果很酷,呵呵
方案二:在后台线程中,生成xaml,然后一次性解析并呈现。经比较,让silverlight解析xaml的表现,明显比动态添加uielement的表现强非常多。这也算是一个小发现。使用方案二,就可以解决绘图效率问题。
问题二,数据传输的问题。上海地图会传输非常大量的矢量数据过去。我抓包后看,发现这些文本信息的字节数居然比图片还大 。这下我真的囧了,本来以为文本比图片小,没想到居然倒了过来。不过我们熟悉asp.net的人自然会马上想到解决办法:gzip压缩。呵呵,这个简单,马上上网,抄了一段代码贴进去,哈哈,马上压缩掉70%。
问题三,我们是否需要传输那么多的矢量点?由于我搞来的shp文件,精度很高,所以,在缩放比很大的时候,有些点传输了也没有意义啊,因为根本就是都被压缩到一个像素里去了。而且那些点的经纬度精确到了8位小数,但是事实上,对于像素来讲,一般精确到3-4位小数就足够了,所以服务器在传数据的时候,完全可以压缩掉这些信息。这样,传输的数据量就更小了。现在经压缩,数据量已小于图片的数据量。而且是放的越大越小,和图片正好相反。
现在还有问题是:服务器暂时无法利用缓冲,因为每次查询的经纬度都不同,导致无法根据查询字符串进行cache。 每次取数都要查询20个图层,也就是进行20次数据库查询,暂时没有想出好的解决办法。
现在的进度是,正在制作客户端地图编辑工具。
效果见图:
目前阶段性成果可以在这里看到 h**p://211。136。156。198/newGIS/
呵呵,别的我不说,至少地图呈现的效果已经接近bing地图了,嘿嘿,反正比公司买的那两个引擎都要强很多。
注意,这个地址可能不久后就会失效。还有服务器可能压力过大,请大家不要把地址传出去啊,谢谢
在项目中使用silverlight的好处确实很多,原来要写N多js的东西,轻轻松松就解决了,而且反正在项目中使用,也不用去考虑什么网站用户没安装silverlight之类的,嘿嘿。
最后,本人最近似乎出现了健忘,精力不集中的现象。每天只工作了2个小时后脑子就一团浆糊,什么都写不出来了,不知道各位对此可有啥好的建议