随笔 - 33  文章 - 0 评论 - 162 trackbacks - 46
<2009年7月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

与我联系

搜索

 

常用链接

留言簿

我的标签

随笔分类

随笔档案

相册

收藏夹

积分与排名

  • 积分 - 51910
  • 排名 - 1178

最新评论

阅读排行榜

评论排行榜

http://www.newmediacampaigns.com/page/jquery-vs-flash-for-interactive-map

可以用在对一个小的地区,例如风景区,城镇做在线的地图演示。效果还不错。不是每个要用到在线地图的地方都需要GIS 。

posted @ 2009-03-26 18:32 Ren 阅读(177) | 评论 (0)编辑

最近开始尝试用ArcGIS Server 9.3的Javascript API进行WebGIS系统的开发,这个项目需要实现矢量要素的编辑功能,同时我们又不希望使用ADF进行开发,因此需要自己来实现一些简单的地图编辑功能。还好需求只是对简单的点图层进行编辑,而这个功能早在ArcIMS时代我们就已经搞定了。现在有了Javascirpt API,更加方便我们开发编辑功能。

我们对地图控件进行了配置,使其体验与桌面的编辑功能类似,即点击编辑,弹出编辑工具条,然后选择所要编辑的图层,往上面添加点。整个逻辑已经重复了很多很多遍了。在编辑的过程中,用户还可能使用放大缩小等浏览控件来对地图进行范围上的更新。

为了尽量的减少开发量,我们使用了Javascirpt API内置的Draw工具条和Navigation工具条。在编辑的时候激活Draw工具条,在浏览的时候激活Navigation工具条,这个逻辑也没有问题。

但是问题很快出现了,在用户处于编辑状态时,如果需要放大地图,则要点击放大按钮,这时需要调用DrawToolbar的deactivate方法,如果再次启动则调用activate(...)方法,这逻辑上也没问题,但今天调试的时候发现一个bug,即如果用户点击了放大按钮,我们调用了DrawToolbar的deactivate方法,而后用户又点击了缩小按钮或漫游按钮,DrawToolbar的deactivate方法被再次调用,这时鼠标与地图的交互就出现了问题,拉框矩形并没有随着鼠标移动的轨迹正确的移动。经调试发现这个bug只在多次调用DrawToolbar的deactivate方法时出现。

于是迅速的查了一下Javacript api的sdk,看有没有DrawToolbar的某个属性表明当前是激活还是未激活状态的属性,可惜是没有,那么我们就只有用一个全局的变量来标识当前DrawToolbar的状态了,于是,如下的代码可以绕过这个比较明显的bug:

//是否启用Draw工具条
var EnableDraw = false;
//激活绘制图形工具条(Workaround:因为它没有属性表明状态,所以用一个全局变量来对其状态进行标识)
function ActivateDrawToolbar()
{
    console.log(EnableDraw);
    
if (EnableDraw === true)
    {
        
return;
    }
    
else
    {
        EnableDraw 
= true;
        drawToolbar.activate(esri.toolbars.Draw.POINT);
    }
    console.log(EnableDraw);
}
//停止绘制图形工具条(Workaround:因为它没有属性表明状态,所以用一个全局变量来对其状态进行标识)
function DeactivateDrawToolbar()
{
    console.log(EnableDraw);
    
if (EnableDraw === true)
    {
        drawToolbar.deactivate();
        EnableDraw 
= false;
    }
    
else
    {
        
return;
    }
    console.log(EnableDraw);
}

记录下来免得大家犯类似的错误。

 

posted @ 2008-10-30 00:41 Ren 阅读(244) | 评论 (1)编辑

ESRI终于发布了基于Silverlight的地图示例,其中使用了DeepZoom技术,地图的体验很好,地址见

http://resources.esri.com/arcgisserver/adf/dotnet/index.cfm?fa=codeGalleryDetails&scriptID=15746

 

posted @ 2008-08-15 01:08 Ren 阅读(831) | 评论 (1)编辑

原文地址

Web地图通常包含底图(提供影像和位置信息)和功能性的专题图层(包含业务信息)。例如提供实时交通信息的在线地图服务,其中街道图是底图,一般情况下不会变化,可以作为其他Web地图应用的底图。交通信息是专题图层,在实时动态更新。本文描述了几种在叠加底图和专题层时常用的模式。

底图和专题层在维护和显示的策略上有很大区别。在创建Web地图时,最好的办法是将二者分开处理。底图不需要经常更新,可以事先缓存成图片存在服务器上,而专题层则需要考虑数据实时更新和加快显示速度。
将底图和专题层分离需要在ArcMap中创建至少两个地图文档(.mxd),并在ArcGIS Server中发布成独立的地图服务,最后在Web地图中成为叠加的两个地图服务层。地图服务层由于是从地图文档发布来的,所以是包含很多图层的容器。

如果你对Web地图比较陌生,可能理解起来有困难。也许你的公司只有一个包含许多许多图层的地图文档要发布,为了性能和灵活性,最好是将其拆分成目的明确的多个地图文档进行发布,然后针对不同的地图服务采用相应的策略。

显示底图的策略

为了追求最快的地图显示速度,底图应该进行缓存,缓存是预先生成好的图片,当用户请求时直接从服务器读取。底图和它的缓存易于维护,因为它们通常不会变化,即使变化了,也可以更新缓存。底图通常包括影像,街道,地形或者其他为专题图层提供背景的图形(示例)。

你的底图可以来自在线的地图服务,也可以是自己的地图文档,在线的地图服务例如ArcGIS Online。通过ESRI提供的Javascript扩展,你也可以在自己的Web地图中使用Google Maps和Microsoft Virtual Earth提供的地图服务。

如果上述地图服务无法满足需求,你可以将自己的高分辨率地图通过ArcMap制作为地图文档,然后用ArcGIS Server发布并建立缓存。建立缓存时,如果选择将所有图层融合,性能将达到最好。但发布后就无法控制单个图层的显示与隐藏了。处理这部分需要隐藏的图层,你应该将它们发布成单独的地图服务作为底图,或者,专题图层。

在建立缓存时,最佳做法是只对需要显示的区域进行缓存。默认设置下,缓存工具会对整个地图文档的全图区域建立缓存。但ArcGIS Server9.3可以通过一个矢量文件指定需要建立缓存的区域,这在地图显示区域是条带状时尤其有用,不需要为大片空白区域浪费系统资源了。

当你的系统资源更加紧张,而要建立缓存的区域非常大时,可以考虑仅在用户请求时建立缓存。更加灵活的策略是对热点区域通过指定矢量文件预先建立缓存,而其他区域在请求时建立缓存,这样只有在第一个用户访问时会感觉到显示的延迟。

当底图的数据被更改时,需要对缓存进行更新,通过只更新修改了数据的区域,可以节省系统资源。这时要注意那些被设置为请求时建立缓存的区域,它们同样需要更新。最简单的办法是删除这些图片,在请求时重新创建缓存。

还可以将建立缓存工作保存为脚本,在半夜或周末,用户访问量较少时进行,减小对网站的影响。

显示专题图层的策略

将专题图层显示为客户端图形

专题图层上的图形是客户端渲染的,服务器端发回的是图形数据。当用户缩放、漫游或点击地图时,可以查看可视区域内的客户端图形,这种方式有几点好处:
保证了只加载用户需要的图形;
对图形的渲染消耗客户端的CPU,而减轻了服务器的负担;
如果数据被修改过,用户能够马上看到最新的数据;
可以将图层渲染的功能交给客户端的JavaScript,从而提供更好的符号和标注功能(示例),并且能够控制图层的隐藏。

这个例子将地块作为客户端图形叠加在底图上,并且只有在放大到一定范围后才显示,这样避免了回传大量的数据,地块没有标注,但点击后可以立即看到相应信息。

你甚至可以选择在用户点击地图前不显示图形,例如这个地图,只有在用户点击影像上的某个位置时才显示该位置的地块形状。

在客户端图形上标注是一个难题,尽管在图形上显示文字很容易实现,但没有很好的客户端标注引擎来决定文字的显示位置,避免标注信息的重叠。由于图形和属性信息都已经加载到客户端,所以响应用户鼠标点击或停放事件,在弹出的信息窗口中显示标注是一个解决之道。更高级的应用是在信息窗口中通过表格、图表或其他方式展示数据。

采用这种客户端图形的显示策略,你需要特别注意避免用户请求过多的图形。这种情况很可能使浏览器抓狂,并且占用大量的带宽。因此,你需要设计你的程序来应对这种问题。

 地图服务有一个MaxRecordCount的选项,决定了每次最多请求的图形数量。默认值为500。根据需要你可以调整这个值,或者设定用户在缩放到某个比例尺时才开始请求这些图形,避免超过上限。

ArcGIS Server REST和SOAP Web服务都提供了查询地图服务的功能,通过QueryFeatures、Identify和Find操作实现。Javascript API和Web ADF框架将这些操作封装在QueryTask中。

动态地图服务

展示专题图层的第二种方式是动态地图服务。在动态地图服务中,服务器端根据请求区域绘制好地图,发送给客户端,在浏览器中叠加动态地图和缓存的地图。(译注:由于叠加时动态地图要透明,所以一般是png格式)。

 这个例子展示了这种做法。
动态地图服务是处理专题图层的传统做法,这种方式加重了服务器的负担,为了提高性能,对动态地图要尽量减少显示的图层和采用尽可能简单的符号。
动态地图将当前区域内所有可见图层的数据都进行了展示,包括用户不太需要的图层。没有必要将所有这些图层都展示给用户,因此动态地图往往提供用户隐藏某些图层的功能,例如用户只关心电力网络时,对电力节点设施等图层可以隐藏,减轻服务端动态生成地图的压力。
Javascript API通过ArcGISDynamicMapServiceLayer发布动态地图,ADF通过Map Resouce发布动态服务,REST和SOAP Web服务通过ExportMapImage操作提供动态地图。

将专题图层显示为缓存的地图服务

 第三种方式是将专题图层也发布为缓存的地图服务,当你的专题数据更新不是很频繁,或者更新只影响很小范围时比较适用。

 这个例子是将专题图层进行缓存,然后与缓存的底图进行叠加的效果。但是这个例子同样展示了这种做法的缺点。当你在地图上缩放时,只能在几个级别上看到缓存的专题图层。因为在比例尺较大时,对专题图层的缓存要耗费相当的系统资源,而且频繁的更新数据和缓存会对程序造成较大的影响。
综观以上三种技术,可知缓存可以满足用户最苛刻的性能要求,因为浏览器只需要从服务器获取现成的图片即可。当你浏览一个缓存地图时,不需要等待地图绘制或者数据传输的过程。同时,缓存保证了最佳的制图效果,尽管制图效果在建立缓存时相当耗费服务器资源。
当你为专题图层建立缓存时,选择与底图相同的切图方案是非常必要的。切图方案设定了建立缓存的比例尺和级别,只有在底图和缓存的专题图层比例尺匹配时,才能进行叠加。相同的切图方案还包括相同的投影方式。只需要地图文档的投影相同即可,而单个图层的投影可以不同。
使用PNG 8格式的图片建立缓存是推荐的做法。PNG 24在IE6和之前版本中不能透明化。JPG则根本不提供透明,当考虑相同的切图方案时,图片的格式不必匹配,也可以进行叠加。
与缓存底图相似,对专题图层的缓存也可以脚本化和定期进行,只是比底图的更新频率更高。当第一次建立专题图层的缓存时,建议记录下所需的时间,做到心中有数。如果专题图层在较大比例尺时才进行显示,可以减少建立缓存的级别,并且采用较尽可能简单的渲染方式和标注。
Javascript API通过ArcGISTiledMapServiceLayer发布缓存后的地图服务,Web ADF使用map resource,REST 和SOAP Web 服务也提供了相应接口访问缓存后的地图服务。

 

 

posted @ 2008-08-09 23:16 Ren 阅读(1722) | 评论 (4)编辑
不知道算不算bug
今天为了验证REST和ADF方式下是否都会动态生成缓存,于是手工把arcgiscache目录下某个地图服务的缓存删除了,结果REST和ADF两种方式访问该地图服务都显示空白页面,并且firebug报所有发送的请求都找不到资源。窃以为是因为Server将生成的缓存信息记录在了某个位置,请求发送到Server的时候,先在这个位置找是不是有缓存,如果有,就直接GET缓存的图片,如果没有,就生成缓存。但我没有发现这个记录缓存信息的文件。
出现这个错误以后,更令人不能接受的是,Manager显示,这个地图服务始终在运行,就是说,ArcSOC读取缓存发现没有找到缓存,它并没有放弃查找,而是在继续徒劳的寻找早已被我删掉的缓存文件。不知道这个工作会不会超时,反正我是等了半个小时ArcSOC发现还在运行中。

如果这算是Bug的话,大家以后千万别学我手工删除缓存文件,后果很严重,不管是重启SOM,还是重启服务器,都没办法再让这个地图服务正常起来。


posted @ 2008-07-17 01:17 Ren 阅读(138) | 评论 (0)编辑
ASP.NET AJAX推出也有一段时间了,当初宣称的AJAX客户端脚本可以脱离服务器端脚本,在诸如html,php等平台上使用,但像微软不少其他产品一样,这个肥大的,性能低下,毫无艺术感的框架正在被大家所诟病。越来越多的人想要脱离这个客户端脚本,脱离AJAX提供的客户端控件,用更精炼更高效的框架来调用服务器端方法。很显然,目前最火的js库是JQuery。
但是要很好的将JQuery和ASP.NET AJAX无缝的结合还是需要一点耐心的,建议从这篇文章入手:
http://encosia.com/2008/03/27/using-jquery-to-consume-aspnet-json-web-services/
ASP.NET AJAX转换.net对象和json对象的功能还是很不错的,如何用jquery来接受asp.net服务返回的json对象是关键,这篇文章讲得比较清楚,但是作者很快意识到实际使用两者结合时还有一些问题,于是写了另一篇文章进行了修正:
http://encosia.com/2008/06/05/3-mistakes-to-avoid-when-using-jquery-with-aspnet-ajax/
经过这篇文章的修正,基本上可以很好的掌握两者的结合方法了。

但这两篇文章是将如何用jquery来调用asp.net的web服务的,如果你想调用页面上的方法,则可以看看这两个脚本:
http://plugins.jquery.com/project/ajaxdotnet
http://schotime.net/jMsAjax.aspx
后者还可以将asp.net AJAX的古怪时间格式转换成更常用的格式,非常推荐。
posted @ 2008-07-17 00:07 Ren 阅读(585) | 评论 (0)编辑
为了节省文件大小,应该把多个Silverlight控件放在一个XAP文件里,例如Page1.xaml和Page2.xaml。第一次加载哪一个可以在App的Startup事件的处理事件中选择性加载。
private void Application_Startup(object sender, StartupEventArgs e)
{
    
// Load the main control
    this.RootVisual 
= new Page1();
    // 或者加载Page2
    //this.RootVisual = new Page2();
}

如果要判断,可以通过StartupEventArgs对象的InitParams集合,这是一个键/值对集合,向它传入初始化参数。方法如下:
<asp:Silverlight ID="Xaml1" runat="server" ... InitParameters="Author=renji,Url=http://renji.cnblogs.com,Role=User"/>
或在Object里面:
<param name="initParams" value="Author=renji,Url=http://renji.cnblogs.com,Role=User/>
 
这样在App.xaml.cs中就可以检查值了:
if (!e.InitParams.ContainsKey("Role"))
{
    this.RootVisual = new Page1();
}
else
{
    switch (e.InitParams["Role"])
    {
        case "User":
            this.RootVisual = new Page1();
            break;
        case "Admin":
            this.RootVisual = new Page2();
            break;
        default:
            throw new Exception("缺少权限信息");
    }
}
posted @ 2008-03-07 23:25 Ren 阅读(321) | 评论 (1)编辑
我们的小组成员之间经常通过网络邻居来拷贝东西,但是很久以来,就有这么一个问题,经常共享了一个文件夹以后,对方却被拒绝访问。这种情况出现是随机的,时而共享就没问题,时而就无论共享什么都拒绝访问。从前我们的土办法是把要共享的文件都拷到一个总是能共享的文件夹里面去。这也不行,有些文件实在太大了。今天我终于开始思考这个终极问题,TM的到底能不能解决这个烦人的东西。
结果这个解决方法就是那么的简单,把everyone添加到那个要共享的文件夹的安全组里面。属性--安全--添加--everyone。之后,整个世界清静了。
posted @ 2008-03-06 23:16 Ren 阅读(1860) | 评论 (4)编辑
MSDN上已新增了Silverlight 2 beta 1的文档,请到此处查看。

posted @ 2008-03-05 10:19 Ren 阅读(337) | 评论 (0)编辑
在即将到来的MIX08上将有演示S60上的Silverlight,消息来自Livesino,当Flasher们还在以为这是个1.0的玩意儿的时候,商业的力量已经开始渗透到手机平台厂商了。当然普及手机上网的日子还很漫长,但是这一天终究得到来。即使是脱机的手机游戏,也是个不可估量的市场。
微软是个有钱的对手,你不会愿意跟有钱的对手打仗,因为他玩得起。如果微软还是老一套,拼命的复制你,频繁的升级超过你,直到蚕食掉大部分的份额,那么Adobe真的得当心了。而且几乎没有悬念微软还是会这么干。而且这一次恐怕更快,因为熟悉C#,熟悉Javascript的人实在太多了,门槛太低了。
posted @ 2008-03-04 22:24 Ren 阅读(327) | 评论 (1)编辑