Category Archives: 从这里发布的

从blog.newnaw.com发布的

Local方式连接时ArcGIS Server ADF程序部署的问题

如果ADF程序用Local方式连接服务,用VS时必需添加Identity。办法是VS中右键单击网站工程,Add ArcGIS Identiy。 如果部署程序的IIS机器和SOM机器是两台机器,则需要注意了。Add ArcGIS Identity对话框中,填写的用户名密码必需在SOM及其的agsusers或agsadmin组中,并且这里不能勾选加密选项。因为Add ArcGIS Identity工具使用的machine specific(开发机器)的DataProtectionConfigurationProvider方法加密,而这样的话在IIS机器上是无法识别这个加密串的。如果在Add ArcGIS Identity对话框中勾选了加密选项,而后将程序部署到了另外的IIS机器上,则可能出现以下错误: 未能使用提供程序“DataProtectionConfigurationProvider”进行解密。 解决办法是改用RSAProtectedConfigurationProvider加密办法。如果要在开发机器上加密,则需要导出custom RSA key container为xml文件,在IIS机器上还需要导入之,并且在aspx页面中也需要添加代码才行,具体步骤见:http://msdn.microsoft.com/en-us/library/2w117ede.aspx。如果只要求加密,不追究加密细节的话,可以采用一种简便办法,就是将明文的Identity拷贝到IIS机器上后,用命令行来完成RSA加密过程。步骤如下: 1、右键网站工程,Add ArcGIS Identity。填写SOM机器上的至少在agsusers组中的成员账户,机器名指定IIS机器名(IIS机器上需要创建同样的账户)。如果是域用户,则指定域名; 2、不要勾选加密选项,点击OK。此时web.config里identity节点的用户名密码是明文保存的; 3、拷贝程序文件夹到IIS机器上,建立虚拟目录,转成应用程序,赋予执行脚本权限,使用ArcGIS的应用程序池。此时浏览网站应该是正常的。如果提示地图控件没有primary map resource,确保你的服务在SOM机器上正常工作,然后关掉SOM机器的防火墙; 4、用命令行进行加密。cmd方式到WINDOWSMicrosoft.NetFrameworkv2.0.*目录,运行以下命令: aspnet_regiis -pe "system.web/identity" -app "/WMA" 其中WMA是IIS中应用程序的名称。 此时查看该网站的web.config文件,identity节点已被加密。并且程序可以正常访问。 参考:http://help.arcgis.com/en/sdk/10.0/serveradf_net/conceptualhelp/index.html#//0002000000w4000000

ArcGIS客户端API中另一种图层类型的探讨:DynamicTileMapServiceLayer

    ArcGIS客户端API(Javascript/Flex/Silverlight)中,我们最常打交道的是ArcGISDynamicMapServiceLayer和ArcGISTiledMapServiceLayer两个类,基本每个地图中都要用到。它们都可以直接将服务器端发布的地图服务(MapService)作为图层,加载到客户端程序中,分别对应了动态地图服务和缓存地图服务。这两种图层类型各有优缺点。     ArcGISDynamicMapServiceLayer(动态地图服务)通常用于实时显示经常变化的数据,支持控制单个图层可见性,可动态投影。但缺点是显示效果较差,整个服务出图较慢;ArcGISTiledMapServiceLayer可以直接加载服务器端的缓存地图服务,显示效果好,速度快,但它的缺点正是ArcGISDynamicMapServiceLayer的优点,即不支持动态投影,不能控制图层可见性,服务器端需要提前生成缓存等。     这里尝试自己来在客户端封装一个类,创建一种新的客户端图层类型。它能够综合以上两个图层的优点,而克服其各自的缺点。大致总结一下我们要达到的目的: ArcGISDynamicMap ServiceLayer ArcGISTiledMap ServiceLayer 自定义的客户端图层 实时获取最新数据 Y N Y 切片方式显示服务 N Y Y 需要提前生成缓存 Y N 客户端缓存切片加快显示速度 N Y Y 利用subdomain加速缓存加载 N Y Y 支持动态投影 Y N Y 动态指定图像输出格式 Y N Y 控制子图层可见性 Y N Y 利用LayerDefination过滤数据 Y N Y 利用TimeExtent显示时态数据 Y N Y 其它缓存服务特性 N Y Y 其它动态服务特性 Y N Y       由于这种图层类型三种客户端API(Javascript/Flex/Silverlight)均可使用,因此在这里我们就不讨论具体的实现代码,只说明一下实现思路。     首先来解决以缓存服务的方式来显示动态服务的问题。《ArcGIS客户端API中加载大量数据的几种解决办法(以Silverlight API为例)》一文中其实已经提到,主要是继承TiledMapServiceLayer,其中获取切片的GetUrl()方法,返回值是利用REST SDK中的ExportMap拼接的Url。这样,我们就并不需要提前切图,输入动态地图服务,从而达到缓存地图服务的显示效果。 … Continue reading ArcGIS客户端API中另一种图层类型的探讨:DynamicTileMapServiceLayer »

ArcGIS客户端API中加载大量数据的几种解决办法(以Silverlight API为例)

    REST风格的一切事物方兴未艾,ArcGIS Server的客户端API(Javascript/Flex/Silverlight API)也逐渐站上了GIS舞台的中央。虽然客户端API给我们带来了更快捷的开发体验,更丰富的展现效果,但有些(奇怪的)需求还不能直接解决。比如要求在客户端API程序中显示大量图形(上万个),乍看之下,受到平台本身的性能制约无法完成,但我们的思维和时间一样,只要挤一挤,总还是有的。本文就来讨论一下如何在客户端API程序中显示大数据量图形的问题。以Silverlight API为例。     要将几何对象显示在客户端程序中,一般我们首先想到的办法就是GraphicsLayer。将服务器端的要素通过查询或者其他方式创建成客户端的Graphic用以显示,从而进一步交互。于是有了下面几种方法。 1、Cluster     比较成熟和理智的做法是,利用Cluster效果来处理大量的Graphic。对于这种办法,ArcGIS Server中的Javascript API,Flex API和Silverlight API均能做到。下图是Silverlight API中300,000个点的展示效果。(忽略数据从服务器到客户端的传输时间)     Google Maps,Bing Maps等也都采取了这种做法。     但是,不论什么原因,就是不想采用Cluster的办法,而要看到大量密密麻麻的点时心里才觉得踏实该怎么办?对于这种需求,也有对应的解决方案。 2、直接在前台绘制Graphic     但这种办法直接受到平台性能的限制。以Flex和Silverlight为例,在不影响地图操作的情况下,视图范围内一次性能够承受的Graphic数量大约是4000-5000个。注意,相对于绘制Graphic对象的操作来说,Geometry节点的个数可以忽略,也就是说这几千个Graphic既可以是点,也可以是面。这时候你的地图看起来是这样的(4000个Graphic): 3、用ElementLayer(Silverlight API独有)来模拟GraphicsLayer      ElementLayer是Silverlight API中独有的一种图层类型,直接继承自ESRI.ArcGIS.Client.Layer,用来承载Silverlight本身的一些布局控件(Framework Element)。它的最主要的用途是使得Silverlight本身的控件能够随着地图的放大缩小而自动变化。利用它我们可以在一定程度上模拟GraphicsLayer。比如Silverlight API中的InfoWindow。     GraphicsLayer之所以只能承载一定数目的Graphic,就是因为Graphic对象本身封装的内容比较多。如果我们仅需要展示这些点,并只在上面做一些简单查询,那么可以完全用ElementLayer来替代之。直接的好处就是,可以在客户端显示更多的数据。比如一个点,我们可以用更基本的Ellipse来代替Graphic。将Graphic的Attributes存储在Ellipse.Tag中,依然可以用上面提到的InfoWindow做DataBinding。初步做了一下试验,如果用ElementLayer来模拟GraphicsLayer,在不影响地图操作的情况下,视图范围内一次性能承载的图形个数大约是20,000-25,000个。这时候你的地图看起来像是这样(20,000个Ellipse):     顺便提一下,如果想在ElementLayer中来模拟动态的地图符号,甚至是时态图层也是可以的。对于Graphic,你可以定义Symbol的ControlTemplate;对于ElementLayer,则可以直接将带有任何动画的对象直接加入其中。     上面提到的3种方法都是纯客户端的,尤其第三种办法,再没有更多工作量的情况下已经基本将客户端的性能用到了极致。但对于想看到密密麻麻点的人来说,五位数的数量级很有可能并不能满足要求。要想将展示的图形个数再提高一个或两个数量级,达到几十万甚至上百万,那么只有来借用服务器端的性能了。 4、ArcGISDynamicMapServiceLayer     直接将所要展示的数据在服务器端发布成一个MapService,在客户端通过ArcGISDynamicMapServiceLayer来加载。这样的话客户端需要展示的仅仅是一张图片,没有任何压力。功能上,如果想查询的话可以使用Identify/Find/Query Task来达到目的。下图加载了一个本机的ArcGISDynamicMapServiceLayer(AGS10,msd发布,1个实例,core i7 2.6GHz,4g内存,win7 x64),服务只有一个点图层,记录数大约650,000条:     服务器端生成这张图片的时间大约13s,进行一次IdentifyTask操作时间是0.2s。这里大部分时间都花在了服务器端对数据的绘制上,因此局域网传输图片等因素可以暂不考虑。服务器端的绘制速度受硬件和软件两个方面的影响。以ArcGIS Server 10已经无法改变,理论上只能通过提高硬件配置来达到加快出图速度的目的。     ps:采用ArcGISDynamicMapServiceLayer时可结合服务器端的点抽希办法来一起使用(抽稀方法1,抽稀方法2)。但这样就失去了密密麻麻数据带给我们的“成就感”,不在赘述。     这种办法中,客户端的压力已经完全没有了,功能上也能通过变通来实现,但展现上有两个缺点:1、数据过多的话绘制速度太慢(40w条数据大约是6.7s,12w条数据大约是2.3s,3w条数据大约是0.6s,);2、出图过程中该服务一片空白,且移动过程中也会出现“白边”的现象。如果硬件配置也无法提高,还有没有更好的办法呢?办法是有的。 5、继承TiledMapServiceLayer来达到“动态切图”的目的     在Google Fusion Tables的例子中,我们可以看到,所有的点数据都是以切片的方式展现,这样的好处是,即使出图速度较慢,用户也能看到切片一个一个的加载过程,不至于长时间一片空白;移动过程中也不会有白边现象;且浏览过的地方都会被客户端缓存,不需要再次向服务器请求,既减少了服务器压力,也加快了显示速度。但明显Google不可能为上传的每张表格都去做切片处理,ArcGIS Server中如何能达到这种效果?     首先想到的是服务切图时的“Cache On Demand”设置。但第一个用户等待的时间就是服务器完成该比例尺下切图的时间,显然太长;并且切图后如果数据有变化,那么看到的切图就和实际数据不一致了。这条路走不通。     通过继承TiledMapServiceLayer,可以利用GetUrl方法来控制如何获取每一个切片。此时如果我们以动态地图服务为资源,利用REST SDK的ExportMap操作来生成每一个切片,就达到了“动态切图”的目的。不仅如此,我们还可以在服务器端发布多个相同的服务,在GetUrl方法中轮询使用这些服务,便可以达到“并行”出图的目的。此时每个服务生成的图片都是256*256大小,所包含的记录数会少很多,速度会明显加快。本机发布3个服务时,同样比例尺下的650,000条记录,所有“切片”加载完成大约需要6s,考虑到缓存服务的加载效果,用户完全可以接受。这种方法相比ArcGISDynamicMapServiceLayer,大大提高了出图的速度和效果。     关于此方法的几点说明:如何利用比例尺、行/列号来计算一个切片的范围,可以参考《ArcGIS Server的切图原理深入》;默认情况下,浏览过的“切片”会缓存在客户端,再次浏览时服务器端就不用动态出图了。如果不想在客户端缓存“切片”,保证服务器端数据发生变化后,客户端也能随时更新,则可以在请求后面加上时间戳,达到DisableClientCache的功能;对于这种数量级的数据展示来说,一般是局域网应用,因此Identify/Find/Query与服务器端的交互完全可以接受;而且通常拥有这种数据量的用户硬件资源一般都是可充分扩展的,因此多发布几个服务来加速出图完全可行。     无图无真相,看看这种办法的效果。别忘了,在服务器端你发布的仅仅是普通的动态地图服务。     好了,这几种方法各有千秋,供各位朋友按需选择。

ArcGIS API for Silverlight加载本地Shapefile文件

      可能有些朋友还不知道如何在客户端程序中显示本地的shapefile,我在这里再介绍一下。       在线例子:http://newnaw.com/pub/sl/shapefilereader/(底图是WGS 84坐标系)       效果:       有些时候需要将本地的数据,比如shapefile,加载到客户端API程序中进行预览。思路不外乎一个,就是读取数据,然后将里面的要素显示在GraphicsLayer上面。但读取本地数据的方法有两种:上传到服务器端,用AO读取,然后将结果传回客户端处理;直接在客户端读取。       由于Esri早在1998年就公开了shapefile文件格式,因此直接写底层代码读取shapefile成为了可能,比较著名的有开源的sharpmap类库等。所以理论上可以在客户端打开本地的shapefile,解析后直接将要素转换成Graphic从而显示在GraphicsLayer之上。在09年Silverlight API刚出来的时候,前辈viswaug就已经做了这个工作。开源的项目在这里:http://esrislcontrib.codeplex.com/,上面的例子就用到了其中的shapefilereader类。里面的其他功能,比如GeoRSS和HeatMap Layer都已经被收录到了最新的SL API中。       而对于其它文件格式,比如CAD,如果有相应的类库,那么在本地直接加载也是可能的。

ArcGIS for iOS开发中Base SDK Missing的解决办法

      目前ArcGIS API for iOS的版本是1.0final,而它本身是用iOS SDK 4.0.2版本编译的,所以要求开发环境的iOS SDK是3.2或4版本以上。于是你按照要求,下载了最新的iOS SDK 4.2(November 22,2010)和ArcGIS API for iOS 1.0并安装之后,在XCode中按照ArcIGS模板新建一个简单的View-based ArcGIS Mapping Application,但这是会发现出现Base SDK Missing的编译错误。       Google一下,这个问题很普遍,解决办法就是Project->Edit Project Settings->Build标签页中的将默认的Base SDK从3.2版本选择成现有的iOS SDK 4.2。可这样依旧不能解决问题。关键还有一个步骤,Project->Set Active Target,选择成你现在的工程。尽管你会看到,Project->Set Active Target中只有你现在工程的名称,并且已经打钩了,但你仍然要用鼠标点击一下。       之后编译,便会在模拟器中看到HelloMap程序了。

将socks代理转为http代理

      之前使用ssh账户和myentunnel作为上国际互联网的代理,但是这个代理本身是socks类型。而ie浏览器只支持http方式的代理,所以将127.0.0.1:7070设置到ie代理后是没有作用的。       而利用Privoxy这个工具,就可以将socks代理转成http代理。转换方法如下: 修改Privoxy的配置文件,找到listen-address这一行,将其修改为:“listen-address  127.0.0.1:6060 ”, 6060也就是你需要的http代理的端口; 再找到“forward-socks5”这一行,去掉前面的注释标记#,将这一行修改为“forward-socks5   /               127.0.0.1:7070  . ”, 7070也就是socks代理的端口; 重启Privoxy就可以了。       最后在ie代理中填入127.0.0.1:6060,就可以访问国际互联网了。此时,也可以很方便的让别人的机器使用你的6060端口来上国际互联网~       这样做是为什么呢?因为有些软件,比如windows live writer,只支持http类型的代理,因此Privoxy还是很给力的。对了,这篇日志就是用windows live writer写的。

ArcGIS API for Silverlight中的InfoWindow

        ArcGIS API for Silverlight自带Maptip,鼠标悬停触发;但对于Javascript API和Flex API中由单击事件触发的InfoWindow,许多朋友一直想要这种效果。         目前2.1版的api中给出了基于Toolkit的InfoWindow例子,如果觉得它不好用或者不满意,可以参考我这个基于ElementLayer实现的InfoWindow的例子。

其实我的qq一直是隐身的

        有同志说一天看不到我,其实我的qq一直是隐身的。         一般来说,只要不出差,一周里我会5*8小时在线,我的qq一般也是5*8小时隐身。而又一般来说,我是不出差的。         只要你不在qq上问我技术问题,我都会立刻进行回复;如果你问技术问题,我会故意拖延若干分钟至若干小时不等再给你回复,这样就显的我比较忙一些,也许你下次就不会在这么问了。因为技术问题讲起来比较麻烦,只靠打字是说不清楚的,而我又很懒,所以很讨厌在qq上回答技术问题;再说对于技术我也只是略懂皮毛,如果因为我的懒和水平不够而产生了歧义,对于问题的解答也是没有任何帮助的。         不过如果你通过电话来问我技术问题,那你肯定能听到一个非常热情和尽可能全面的解答。         有图有真相,看看我过去几个礼拜和接下来的几个礼拜将要做的一些事情。         接下来的事情(其实真不喜欢这个白色的东西)。。。