Category Archives: GIS

Extending ArcGIS command: a case tutorial

ArcGIS command扩展:ArcGIS 9.2/C# 2的实现
Zhuotong Nan (南卓铜) ([email protected])

为什么要做扩展?

很简单,ArcGIS提供了通用的功能,但不可能提供每个大家需要的功能。而且,对一些专业(如水文)也许最实用的功能都没有。这时候便需要对现有的ArcGIS进行扩展。

如何扩展?

有很多方法了,比如AML来扩展ArcInfo Workstation——我以前写过一个AML的简要指南,Google应该能找到。在Desktop下,可以用VBA扩展,或者用任何支持COM的现代语言来扩展。这里用Visual Studio C# 2005 Express来开发。对于独立应用程序,应当购买ArcEngine。ArcEngine可以认为是ArcObjects的一个子集。

准备工作

需要ArcGIS desktop .net developer kit。如果最初安装ArcGIS 9.2的时候没有安装上,那么到安装/删除程序里去重新修改安装。注意事先机器上得已经存在.net framework SDK,如果没有,安装ArcGIS看不到.net developer kit选项。.net SDK不同于平时大家安装的redistribution .net framework runtime。请到微软官方网站下载。

安装Visual Studio C# 2005 Express,建议在安装ArcGIS desktop .net developer kit之前进行,ArcGIS desktop .net developer kit将在Visual Studio C# 2005 Express上生成一些项目模板(如ArcMap class library),应用这些模板进行开发会节省很多时间。

我们的工作

如图1所示,要在一个Document里生成多个Map(多个Data Framework),Map里的内容是时间序列的小时降水量(不同的Raster Dataset)。右图仅演示了1天24小时的图。我们的挑战是要做10天,而且必须各个图采用同样的图例。

 
图1, 小时降水量图,我们希望实现的目标

解决方法

先设计好一个Data Frame,设置好Legend(不能是sketch,否则系列图就没有意义)。然后复制24份Data Frame,应用ArcMap的页面排版功能进行排版。然后将此文档复制10份(10天)。现在的问题是如何去更改每个Data Frame里的Data Source。我们需要的是实现一个批量处理的方法。采用ArcObjects进行二次开发,生成一个Command来完成这个事情,是个不错的方案。

建立一个新项目,点击File>New Project…(图2)。因为我们只想进行基于ArcMap的扩展,这里选择ArcMap Class Library(图3),敲入项目名称“MyArcGISClassLibrary”(不包括引号)。一般而言,项目按功能进行归类,一个可以实现很多的Command或者Tools扩展。所以没有必要对每个Command或者Tool都建项目。

image
图2,新建项目

 image
图3,新建ArcMap Class Library

在随后出现的ArcGIS Project Wizard(图4),添加必要的引用。这里选择ESRI.ArcGIS.ArcMap,ESRI.ArcGIS.ArcMapUI,ESRI.ArcGIS.Carto,ESRI.ArcGIS.DataSourceGDB,ESRI.ArcGIS.DataSourceRaster,ESRI.ArcGIS.Framework,ESRI.ArcGIS.Geodatabase,ESRI.ArcGIS.System。这些都是常用的库,添加的这些库,会出现在VS项目的Reference里。如果这里不添加,也可以以后根据需要再行添加(如图4.1)。需要注意的是,这里用的ESRI.ArcGIS.DataSourceGDB是9.2新出来的File Geodatabase,据称比Personal Geodatabase性能要好,而且有更大的存储许可。点击Finish结束。

image 
图4,ArcGIS Project Wizard

image 
图4.1 可以从Solution的这个位置添加引用

该向导帮助我们添加了必要的Reference,并新建了Class1.cs。但我们不需要它。如图5所示,删除。

 image
图5,删除Class1.cs

移动Solution Explorer窗口的项目上,如图6,添加一个新项,点击New Item…。在新弹出的窗口中选择Base Command(图7)。并设置名称为"BatchedChangeDatasource.cs"。在New Item Wizard Options里选择ArcMap Command(如图8)。

image 
图6,新建Command类

image 
图7,选择Base Command

image 
图8,选择ArcMap Command

点击OK,Wizard生成足够多的东西(如图9),我们在此基础上再写一些代码以完成我们的预期功能。

image 
图9,Wizard生成的代码框架按Ctrl+S保存此Solution。Solution名称设成MyArcGISClassLibrary.sln。

(下一节我们将介绍代码的作用,和如何添加自己的功能以实现既定目标。)

GeneratePolygonsByPoints utility

Purpose: to generate polygons (rectangles) by connecting neighboring points

Author: Zhuotong Nan
Email: [email protected]
Date: Nov 21, 2007

ver: 1.0.0

Usage: GeneratePolygonsByPoints [data_file_name] {output shapefile name}
Rows*Cols (for ex, 260*250): (enter numbers of rows and cols for the source data file with
a format rows*cols. Incorrect input will stop the tool.)

data_file_name: source data file name; path can be included.
output shapefile name: optional, as its literal stated. path can be includes.

Supporting environment: Microsoft dotnet framework 2.0, ArcGIS 9.2 with dotnet assemblies, as
well as a valid ArcInfo license.

Remarks: Data file should be organized row by row (you should know exact row and column
number, which will be required to be entered after starting), starting from lower left corner.
In my initial case, the data file is generated by a modified Read_XMRG2 utility for XMRG
radar data file. The modified Read_XMRG2 will generate data with geographical coordinates
instead of HRAP coordinates as does original Read_XMRG2. Anyway, GeneratePolygonsByPoints
will also run against data file generated by original Read_XMRG2, however, with output
shapefile being in HRAP coordination.

Data file content looks like following:

-121.177570 37.897155 0.000000
-121.132468 37.907464 0.000000
-121.087345 37.917746 0.000000
-121.042201 37.928001 0.000000
-120.997037 37.938229 0.000000

The first column is longitude, second latitude, and the third precipitation value. The first
two columns represent that cells’ lower left coordinations. The first row indicates the lower
left cell; second is the next cell right to the first cell; after finishing a row, then begin
a row up the first row, and move upwards.

Output shapefile will be of geographic NAD83 datum. The first two columns will be converted
to points’ geographic location. Values (precp value in above example) will be lost. A new
field named "Index" will be generated to record this polygon’s lower left corner’s coordination
with a format of "lat_lon", for ex. 37.897155_-121.177570 for the first created cell. However,
you cannot depend on this field to link original source data file. In order to do link, you can
"ID" field in shapefile attribute table, which increases by one in consitence with source data
file.

As stated above, each cell is referred by its lower left corner’s coordination. The most upper
cells cannot be generated due to missing of necessary points (we only have lower edge’s
coord). Likewise, the most right cells are also missed.

The distribution also includes a test data file: xmrg0101199900z.out, with a 39*48 (rows*cols)
dimension.

For more information, please contact the author at [email protected].

ArcIMS ArcXML 元数据搜索中文关键词问题

或者在c#代码中直接用中文字符构建 SEARCH_METADATA将搜索失败,提示非法的ArcXML
解决方法是使用中文的unicode表示,即旞类似的方式
提供了一个转换函数:

/// <summary>
/// 将汉字变成 黑&27827;的ascii编码
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public static string UnicodeEncode(string text)
{
char[] chars = System.Web.HttpUtility.HtmlEncode(text).ToCharArray();
System.Text.StringBuilder result = new System.Text.StringBuilder(text.Length + (int)(text.Length * 0.1));

foreach (char c in chars)
{
int value = Convert.ToInt32(c);
if (value > 127)
result.AppendFormat("&#{0};", value);
else
result.Append(c);
}

return result.ToString();
}

ESRI本身提供的metadata explorer搜索中文关键词时有问题,是因为它的代码将中文解释成了 &amp;26789;类似,而不是梥,可能是将&再次解释了,搜索时将不返回结果。不知道9.1及以后版本的arcims metadata explorer里是否已经更正。

ArcCatalog使用iso元数据标准

为了系统只使用iso标准,ArcCatalog(以下称ac)做为发布端,需要做如下工作:

  1. 关闭fgdc和geo-network同步器。在metata菜单里,使用set working synchronizer命令关闭两者。
  2. 建立一个vba宏,删除xml里的fgdc标签。edn有现成可用的宏,在esri的edn开发网站上搜索 delete FGDC metadata,估计就可以找到。(或向我索要)建立好了,在ac里选择上需要处理的文档,支持宏即好。其实分析一下,就只有几个标签,手工去删除也不难。而且最好能有个自己的工具去批量删除。
  3. 关闭 arcims server上的基于内容的 validation功能,用处不大,那是为metadata explorer设计的,如果不用explorer,这个功能就没多大用处了,而且此功能实质是检查 fgdc标签的内容(或者说iso的内容处在低于fgdc内容的优先级别上)。

SQL server master库损坏的解决方案

SQL server 2k master db corruption due to power cutoff, causing sql server cannot start up. In this server, ArcSDE 9 and ArcIMS 9 are associated with Sql Server 2k sp4. and worse, no backup have been created prior to this disaster.
solution:
1. Backup possibly effected dbs, i.e., sde db, and westdc db.
2. run rebuildm.exe to reconstruct the master db. all logins are lost after that operation. sde amd westdc dbs cannot be found in the rebuilt master db.
3. attach the original sde db and westdc db using sa as the db owner.
4. create lost logins, for example, westdc, sde, etc. Fortunately, I have backed up all these information.
5. using enterprise manager, open sde and westdc dbs, isolated users can be found under the users leaf. So we have to assign the appropriate logins to those isolated users. use commands as follow:
USE sde;
GO
sp_change_users_login @Action=’Report’;
GO
USE westdc;
GO
sp_change_users_login @Action=’update_one’, @UserNamePattern=’westdc’, @LoginName=’westdc’;
GO
the first set of commands is used to report the isolated users in database sde. the second set of commands will assign an existing login named westdc to the isolated user westdc.
6. restart the arcsde service, then arcims services. DONE!
Lessons:
We always are required to backup databases in a regular interval.

南宅影像图

最近google Earth更新了一些数据,浏览到我家的时候,发现可能是由于附近有个海事边哨,覆盖我老家的是一景分辨率较高的影像(估计是QuickBird这类),可以分辨到我们家的屋顶,剪裁下来与大家共享。

IMapPtr在vc里编译提示没定义

上午有人问在他的MFC程序里,为什么IMapPtr不能用,在编译的时候说没定义。
首先我们要明白IMapPtr是什么东西,在COM里,有一种叫智能指针(smart pointer),通过此类指针,COM可以安全地构造和析构。一般通过_COM_SMARTPTR_TYPEDEF(<interface>, __uuidof(<interface>))宏来定义,对IMap扩展后相当于:
typedef _com_ptr_t<_com_IIID<IMap, __uuidof(IMap)>> IMapPtr;
这部分工作在vc里导入 type library时完成,vc通过 #import来完成,import会自动生成 .tlh和.tli,这些typedef即在 .tlh里定义。
在ArcEngine编程中,一般在vc环境设置中include进 ArcSDK.h,和*.olb所在目录,在stdafx.h里增加 #include <ArcSDK.h>后,就可以在代码中直接用象IMapPtr这类指针了。
包括ArcSDK.h时要求事先定义ESRI_WINDOWS,这样arcsdk.h事实是调用 windows_sdk.h,编译时可能会有一些警告,可以忽略,或者通过#pragma warning(disable : 4192) 来忽略特定的警告。
 
如果上述工作后仍有问题,你应该有理由怀疑你的ArcEngine安装可能不完整了。

ArcGIS installation error 1904

With prompt like failed to register.

Solution: this is due to the embedded DEP (data execution protection). Change the parameter of boot.ini “NoExecute=OptIn” to “NoExecute=AlwaysOff” to work around this problem. After installation, please set it back to OptIn.

ArcGIS License server & firewall

为使得ArcGIS License Server通过 windows firewall 被其它机器所使用,需要如下 配置:
1. open License.dat or *.lic obtained from ESRI company,remember the port specified in the host line, commonly 27000, or 27004
2. specify the port used by arcgis.exe, for ex.
VENDOR ARCGIS PORT=1234 
(in my computer, it is 1025 by default)
3. open your firewall configuration window, add ports for manager (as item 1), 
as well as for arcgis.exe (as item 2) respectively
 
done!