《插件式GIS应用框架的设计与实现》《GIS for Web应用开发之道》
《插件式GIS应用框架的设计与实现》的购买地址有电子工业出版社的网上书店(北京)、SOHI书店(北京)、中国图书网(北京)、天下书城网络书店(西安)、中国教育在线极速商城、中国科技金书网、中国互动出版网和淘宝网。此外,当当网、卓越网、博库书城和ESRI中国书店也有货。

《GIS for Web应用开发之道》目前已经可以在搜海书店、互动出版网China-pub、电子工业出版社网上书店、当当网和博库书城购买。
在《插件式GIS应用框架的设计与实现》出版的过程中,我曾经与众多GISer进行过互动交流,讨论过许多关于本书的问题,也回答了许多疑问。下面是有些关于本书问题的考虑和回答:
- 为什么要写这本书?
2006年,我在武汉大学出版社出版了《ArcObjects开发基础与技巧》一书,我对这本书是比较满意的,它确实讲的是基础,而不是一本辞典,它介绍了AO(或者说AE)的许多基本知识点,我认为它们都是“积木块”,本书告诉读者某块“积木”是用来干什么的、它与旁系的“积木”的关系等等。我们对某项知识内容的入门大抵如此门道,包括后来出现的若干本关于AO、AE的书都没有跳出这个套路。
只会砌墙的泥工是成不了建筑师的,熟悉了积木块以后,该学习点什么内容来提升自己的开发水平和能力呢,这是一个让编程入门者经常郁闷的话题和问题,而这本书,就是为AO或AE的入门者准备的,我无需再详细讲解积木块,但我会告诉你如何用积木块搭建模型。
- 这本书能让我精通ArcGIS Engine吗?
不能!如果你有这个想法和期待,我强烈建议你不要购买本书,它会让你非常失望的。这本书不是为对AO、AE一窍不通的人准备的,也不是为试图“精通”AE开发的人准备的。我从来不看诸如《7天精通×××》或《21天精通×××》之类的书籍,如果一门知识能够通过一本书来精通的话,只有三种可能:1.这本书在撒谎 2.这门知识过于浅薄 3.精通者的被取代性很强。
- 为什么这本书的内容故意留下许多“破绽”和“漏洞”,也不附带代码光盘?
我经常阅读IT方面的技术书籍,发现了一个问题,书籍在细节上写的越详细,真正看的人就越少,或者说看完了多思考的人就越少。其原因,与“书非借不能读也”差不多。所以在本书中,我留下了许多“破绽”,但解决的方法,我也同时介绍了。至于不附带代码光盘,一是增加成本,其二也与前因类似,代码都写的这么详细了,还需要给出代码吗?不亲自敲敲代码,这本书估计也就白买了。
- 为什么出现与主题似乎无关的算法一章?
算法这一章与主题的确没有太大的关系,但如何从算法思路到逻辑实现,其实是程序员,特别是GIS程序员进阶必须走过的路程。许多GISer太依赖现成的GIS组件了,完全丧失了自我学习提高的能力,这一章的内容,也就是给个demo,让读者不要忘记算法的重要性。
- 对于“破绽”如何解决?
对于书中留下的“破绽”和不足,我将在博客中陆续回答大家都问题,并贴出必要的改进代码。
《插件式GIS应用框架的设计与实现》在当当的销售情况:
1. 2008年11月,在“自然科学”类书籍中排名33位
2. 2008年12月,在“自然科学”类数据中排名15位
Related Items
Comments
谢谢,能够解决大家都问题,正是本书的目的所在![]()
前些日子买了一本<<插件式GIS应用框架的设计与实现>>一书,怎么不知道如何下载资源代码,请作者提点。
年前买了一本,感觉受益匪浅.谢谢作者.
最近我发现一个问题.按照书中156页的方法设置事件,结果鸟瞰图不能绘出地图数据,是空白的.我发现似乎事件并没有触发,因此DockForm_ItenAdd方法没被调用.为什么?
后来我做了如下尝试
1.在类DockForm中定义一个变量:
private IMap pFocusMap;
2.将原有的事件设置语句改为:
pFocusMap = this.hook.MapControl.ActiveView.FocusMap;
((ESRI.ArcGIS.Carto.IActiveViewEvents_Event)pFocusMap).ItemAdded += new ESRI.ArcGIS.Carto.IActiveViewEvents_ItemAddedEventHandler(DockForm_ItemAdded);
这样地图就可以在鸟瞰窗口绘制出来.
不过我觉得类DockForm中定义private IMap pFocusMap,毕竟它实际指向的不是自身窗口的FocusMap.所以我试不添加private IMap pFocusMap,直接将事件设置语句改为:
((ESRI.ArcGIS.Carto.IActiveViewEvents_Event)this.hook.MapControl.ActiveView.FocusMap).ItemAdded += new ESRI.ArcGIS.Carto.IActiveViewEvents_ItemAddedEventHandler(DockForm_ItemAdded);
结果发现鸟瞰窗口不能绘制地图.为什么?请赐教.
这本书对我帮助很大,谢谢作者。
我也遇到了鸟瞰窗体的问题,在程序中加入mxd文档时,鸟瞰图的地图数据是空白的,这是为什么呢?应该如何解决呢?请教作者
这是因为在AE中,加入MXD的函数不会触发AddItem事件,你可以自己包装一个加载对象。
多谢作者的解答,问题已经解决了。十分感谢!看你的书受益匪浅
感谢作者的这本书,我也正在拜读中。
在符号控件应用这一节里,我不知道怎么在快捷菜单中传入m_App和m_tocControl,期待你的解答,谢谢!
在AE库的快捷菜单对象中传入m_App和m_tocControl很难,基本不可能,这是因为AE的快速开发框架与我们设计的框架有根本的区别,在快捷菜单对象这里没有交集。如果真要在快捷菜单中像ICommand那样传入,只能通过Janus产生自己的快捷菜单对象才行。
非常感谢作者的这本书,让我学到了很多东西,我在学习过程中遇到了一个问题,就是在作者提到测试一下_App对象(98页)时,遇到了几个问题,一个是97页初始化主框架对象中的this._App.StatusBar=this.StatusBar时出错,我将后边改为this.uiStatusBar后就可以了,另一个是:“NBGIS.PluginEngine.Application”不会实现接口成员“NBGIS.PluginEngine.IApplication.PageLayoutControl”,不知是什么原因,MapControl都能实现,怎么它就实现不了啊?恳请作者回答。
1.你在窗体中添加的状态栏对象名为uiStatusBar而非StatusBar;
2.接口定义了PageLayoutControl没有?你需要检查,另外,你是否将该控件放置到了窗体上?
cl 于 2009-2-28 22:16:07 回复谢谢蒋老师的回答,我在IApplication中定义了了,IPageLayoutControlDefault PageLayoutControl{get;set},在类Application中也实现了,在MainGIS窗体中也添加了该控件,一试运行就提示上述错误,是不是我哪出错了,必须得重新再写代码啊?
蒋老师:
你好!
我在学习<插件式。。>在做书上的例子时出现一个问题,
错误 1 可访问性不一致: 属性类型“System.Collections.Generic.Dictionary<string,NBGIS.PluginEngine.IMenuDef>”比属性“NBGIS.PluginEngine.ParsePluginCollection.GetIMenuDefs”的可访问性低
这个问题出在哪儿?帮忙指点一番,谢谢了!
using System;
using System.Collections.Generic;
using System.Text;
namespace NBGIS.PluginEngine
{
interface IMenuDef :IPlugin
{
string Caption { get;}
string Name { get;}
long ItemCount {get;}
void GetItemInfo(int pos, IItemDef itemDef);
}
}
解决了! 是interface IMenuDef :IPlugin
的问题: 是我大意了!
应该写成 public interface IMenuDef :IPlugin
张亚 于 2009-2-27 23:19:00 回复IDE添加的接口都要手动改成PUBLIC
作者:你好!
我也是你的读者, 我在调用Geoprocessor时出现了问题。
如果我没有添加IGeoProcessorResult对象,则运行没有问题,并且也可以计算出正确的结果,但我加上IGeoProcessorResult对象之后,就会出现异常:COMExceptionwasunhandled
Error HRESULT E_FAIL has been returned from a call to a COM component.
请作者给点建议,感激不尽!
这个异常的原因太丰富了,基本上不能起到诊断作用
呵呵,蒋兄你好,我也是你大作的拜读者之一,看到“2.6.3 插件的动态加载和对象生成”这一节对其中的“AppLog”感到比较迷惑,不知其从何而来?
还望蒋兄指点一二,呵呵本人是菜鸟!
呵呵呵
看到后面了,是在不好意思!
呵呵原来是日志!
呵呵,老蒋你好,我也是你大作的拜读者之一,看到“2.6.3 插件的动态加载和对象生成”这一节对其中的“AppLog”感到比较迷惑,不知其从何而来?我直接添加了一个自动命名的app.config 按书上把代码写上不行,请指点
还望老蒋指点一二,呵呵本人是菜鸟!
继续往后看,到2.7就明白了
UICommand .Click +=new CommandEventHandler(UICommand_Click);读3.2.3的时候这个地方提示UICommand_Click上下文中不存在
UITool.Click +=new CommandEventHandler(UITool_Click);也同样的错误
请指点
当你在IDE中键入UICommand .Click +=后,就会自动出现后面的代码,并自动生成方法,但如果你是手工键入,肯定会出问题,即UICommand_Click方法不存在。
为什么我编译程序时会出现The assembly 'Janus.Windows.UI.v3, Version=3.5.0.0, Culture=neutral, PublicKeyToken=21d5517571b185bf' is not registered for COM Interop. Please register it with regasm.exe /tlb. NBGIS.PluginEngine
你的Janus大概过期了
可是我刚下的啊,我再看看吧,郁闷
去下载我给的试用版软件
我做ICommand插件实例时,编译好后,将dll放入到宿主程序相同目录下的plugin文件夹中,启动宿主程序后,却没有出现MainTools和添加数据按钮,我所有的程序编译都没有错误。
我检查了好几遍也不知道为什么,这是怎么回事啊?急
编译能编译出什么问题来?插件式框架是后期解译生成插件对象的,在debug环境下调试下。
呵呵,我后来一句一句调试了一下,原来在PluginHandle把工具名字写错了,太粗心了
老蒋我想问一下,为什么我按照你第4章的做完后,宿主程序运行后MainTool上只显示一个加载数据的图标,其它的图标不显示,必须选择Customize才能显示。为什么啊?
ps:下面是我在class MainToolbar中改的
public void GetItemInfo(int pos, IItemDef itemDef)
{
switch (pos)
{
case 0:
itemDef.ID = "GEMGIS.MainTools.cAddData";
itemDef.Group = false;
break;
case 1:
itemDef.ID = "GEMBGIS.MainTools.cZoomIn";
itemDef.Group = false;
break;
case 2:
itemDef.ID = "GEMBGIS.MainTools.cPan";
itemDef.Group = false;
break;
default:
break;
}
}
public long ItemCount
{
get { return 3; }
}
我建议你三个item都用能够显示的那个对象试试,看是插件的问题,还是插件引擎的问题
在做同步时:
//产生一个地图容器IMaps对象
IMaps maps = new Maps();
我机子里有IMaps接口,但是没有Maps这个类,为什么啊?
看到后面明白了,还要在工程里新建一个Maps类
196页在LayerMenu里,m_App和m_tocControl是怎么定义和初使化的?
蒋兄,我在做鸟瞰插件时,当宿主程序加载地图后,鸟瞰地图上什么也不显示,我调试了一下,发现鸟瞰插件里的DockForm_ItemAdd根本不运行,插件的代码都没有问题,插件引擎是好的也没问题,这是怎么回事啊?是不是要在DockForm的Load里加地图啊?
uplusplus 于 2009-5-19 16:50:40 回复顶起,我也是遇到这个问题
Spook 于 2009-8-16 16:13:36 回复顶一下,希望能给也详细的解答(鹰眼问题)!
宿主地图控件的3个事件OnExtentUpdated、ItemAdded和ContestsCleared中,只有OnExtentUpdated是在MapControl中能找到,ItemAdded和ContestsCleared是Carto里的,在MapControl的事件里找不到,怎么办?
jbttm 于 2009-3-20 22:49:34 回复从IActiveView的事件接口中查找
Zaza 于 2009-3-22 10:48:25 回复我知道是在IActiveView的事件接口中,但我不会触发,您教教我吧,我是初学者。谢谢了啊
鸟瞰地图中,如果加载 MXD文件鸟瞰地图就不显示,而且如果加载的SHAPE文件没有定义坐标也不显示
类LayerMenu中,您给出的OnClick函数代码中出现m_App和m_tocControl这个两个变量,每次程序运行到m_App.MainPlatform.Activate();后就出错了,我想问您的是怎样定义和初始化这两个变量的,期待您的回答
LayerMenu是继承自BaseCommand,后者有个OnCreate方法,传入hook对象
关于符号控件的问题 于 2009-3-22 11:55:39 回复LayerMenu是继承自BaseCommand,后者有个OnCreate方法,传入hook对象,这我明白。但是OnClick方法中并没有对m_App和m_tocControl进行定义和初始化。您把LayerMenu的代码给出来吧,我想这样更简洁明了。期待您的回答
我也遇到34楼的问题,ItemAdded和ContestsCleared没有触发,调试中我都跟了,还没有找出哪的问题,望指点
我用c#写了一个类库,在本机编译并做安装包的时候注册到categories 的地理处理目录
但是安装包在别的机器上安装无法实现注册[EMAIL]enpingwu@gmail.com[/EMAIL]
一般都是环境问题
蒋兄,您好!我读到第四章 框架插件设计时,做了个AddData的插件,运行之后,宿主程序并不会自动加载工具条,每次都需要手动添加,请问这是什么原因?
蒋兄您好,我想自己做一个计算DEM体积的插件,类似ArcToolbox里surface Volume工具。我不做成插件的形式,命令能用,但是做插件后,老是不行,
class Vol:GEMGIS.PluginEngine.ICommand
{
void NBGIS.PluginEngine.ICommand.OnClick()
{
cmd.OnClick();
}
void NBGIS.PluginEngine.ICommand.OnCreate(IApplication hook)
{
if (hook != null)
{
this.hk = hook;
cmd= new NBGIS.CalculateVolume.CV() as ESRI.ArcGIS.SystemUI.ICommand;
cmd.OnCreate(this.hk.MapControl);
}
}
}
cmd.OnCreate(this.hk.MapControl);老是过不去,其中NBGIS.CalculateVolume是我自己做的一个DLL
我想问的是:
怎么才能在一个菜单或是Toolbar里建立一个命令,该命令不用AE中的命令,而是自己定义的,而且点击该命令能产生一个窗口,这个命令还要是插件形式的。急切盼望您的回答,谢谢了!呵呵
cmd.OnCreate(this.hk.MapControl);当然是过不去了,我之所以用这个语句,是因为例子中的cmd是AE提供的ICommand对象,它自己实现了OnCreate方法,而你做的NBGIS.CalculateVolume.CV,确实自定义的。要产生窗体非常简单,在OnClick方法中弹出一个即可,OnCreate不过是用来从宿主程序获得MapControl的。
batta 于 2009-4-10 14:22:23 回复已解决,呵呵,谢谢了啊
博主,我想问问书上那个框架在AE9.3下能不能用,电脑重装了,原来是9.2的,现在有9.3了,如果能用就装9.3,不能用还装9.2,年前把那个代码都敲出来实现了一遍,经典的东西不想让它闲着啊
蒋兄,我想问一个关于插件的问题:我想定义一个工具插件功能是实现加载数据,比如是TIN数据,我在插件生成了一个AddTINFrom,里面有一个方法是AddTIN,如下
AddTIN()
{
//打开文件夹
······
//获得图层
······
//打开工作空间并添加TIN文件
······
//建立TIN图层
······
//增加TIN图层
}
在增加TIN图层时,应该向宿主程序的axMapControl控件里添加TIN数据,我是这样写的:
public partial class AddTINForm : Form
{
private IApplication hk;
public AddTINForm(IApplication m_hk)
{
InitializeComponent();
this.hk = m_hk;
}
AddTIN()
{
······
hk.MapControl.Map.AddLayer(pTinLayer as ILayer);
hk.MapControl.Refresh();
}
}
运行后,主程序里并没有加载TIN数据,AddTINFrom继承了你定义的ICommand接口,
public void OnClick()
{
this.Show();
}
public void OnCreate(IApplication hook)
{
if (hook != null)
{
this.hk = hook;
}
}
这是为什么啊?盼望您的解答,谢谢了啊
添加到代码放在onClick方法中
蒋老师:
我在添加 UITab这个插件的时候 找不到书上所说的Text属性,而且添加后只是空白不能实现选项卡的效果,:(
按照书上所说的一模一样输入,鸟瞰图还是显示不出来?是否是书上程序问题?
请见之前的blog文章
我跟这个人有同样的问题,请蒋兄指点下,这两个变量如何初始化,书上说很简单,我觉得一点都不简单,初学者,见笑了,其他的例子都实现了,就到这一步了。
LayerMenu是继承自BaseCommand,后者有个OnCreate方法,传入hook对象,这我明白。但是OnClick方法中并没有对m_App和m_tocControl进行定义和初始化。您把LayerMenu的代码给出来吧,我想这样更简洁明了。期待您的回答
fanfeilong 于 2009-4-24 1:36:44 回复实际上,作者贴代码并不能从根本上解决问题,这种问题最好通过自己思考解决,这样能学到更多.不知是否同意?
蒋老师,当我看到3.2.3节时,发现代码中UICommand这个类从来没有被定义过,通过阅读上下文感觉这个UICommand应该是ICommand和ITool的父接口吧,请问是这样吗?
jbttm 于 2009-5-12 23:13:55 回复完全不是这样
wsd 于 2009-5-12 23:27:45 回复那是什么样的呢?还请指点一下。
骥服盐车 于 2010-6-24 22:28:15 回复头文件调用 using Janus.Windows.UI.CommandBars;
蒋老师你好,急切地想请教个问题,在调试宿主程序时出现Error 2 The best overloaded method match for 'Janus.Windows.UI.CommandBars.UICommandCategoryCollection.Add(Janus.Windows.UI.CommandBars.UICommandCategory)' has some invalid arguments和
Error 12 The type or namespace name 'UICommand' could not be found (are you missing a using directive or an assembly reference?)时我该怎么办呢???UICommandCategory、UIPanel也是的呢。。。。宿主程序里的那些词都遇到这个问题了~~~
好想解决了呢~~~(*^__^*) 嘻嘻……
你好,蒋老师!P145中关于cAddData类的代码, IApplication接口AE9.2中没有吧?
蒋老师您好,请问按您的方法实现两种视图同步时,在点击版式选项卡时,两种视图会叠加显示呢,该如何解决这个问题呢?如何让地图视图不可见呢。。。
不明白你说的意思![]()
在插件式一书里,实现两视图同步时,在点击版图显示时,地图显示也还是在的,没有消失。。。怎么办呢?
不太可能吧,你是否缺少刷新?是TabPanel的刷新!
那个鸟瞰插件勾不上ItemAdded事件,导制不能显示底图的问题,有谁解决了,麻烦指导下小弟
原来加载数据库有时不会触发ItemAdded事件,加载lyr里会触发
3.2.3节中的UICommand是怎么回事,哪位知道的仁兄麻烦指点一下??
jbttm 于 2009-5-21 23:52:52 回复什么意思?有什么问题?
wsd 于 2009-5-24 19:01:32 回复我以前问过这个问题,但是没有得到解答。当我看到3.2.3节时,发现代码中UICommand这个类从来没有被定义过,通过阅读上下文感觉这个UICommand应该是ICommand和ITool的父接口吧,请问是这样吗?
HaHa 于 2010-5-4 14:14:49 回复这个问题还是尚未回答.....
蒋老师你好:
读过你的数获益匪浅,但遇到了一个小麻烦,是为toccontrol加右键的这一章,我希望为basecommand加一个图标,但是esri定义的却是一个int类型的,找遍了baidu也不知何因,希望蒋老师能贴出加载图标的代码,以解心中的疑惑。呵呵最后致歉,因为这点小问题还麻烦你。
你把图标的句柄值传给它应该就可以了
我按书上写的,添加cAddData功能,但是在PluginEngine.ICommand cmd = plugin as PluginEngine.ICommand;的时候cmd还是null。plugin带3个属性,caption,itemcount,name的,这是什么原因
UICommand .Click +=new CommandEventHandler(UICommand_Click);读3.2.3的时候这个地方提示UICommand_Click上下文中不存在 我是按提示 按住Tab 键 输入的啊 但编译还是提示 上下文中不存在错误
UITool.Click +=new CommandEventHandler(UITool_Click);也同样的错误
请指点
不是按住Tab键,而是写到这里智能提示出现时,单击两次Tab键即可。
请教蒋老师,ControlsSynchronizer::ReplaceMap()应该何时如何调用?谢谢!
关于加载Mxd文件后ItemAdded事件失效的问题,初步可以认为是MapControl的LoadMxFile方法中可能有移除ItemAdded事件响应函数的操作,因为我在LoadMxFile调用之后再用“+=”为该事件绑定一次响应函数,就可以在接下来的添加图层操作中响应该事件了。
究其原因,可能是因为LoadMxFile时可能会涉及比较多的图层添加,为了避免频繁的响应ItemAdded事件,所以干脆移除响应函数。另外要在鹰眼中显示LoadMxFile的地图,可以响应IMapControlEvents2中的OnMapReplaced事件。
谢谢你找出原因。![]()
我同样遇到鹰眼无法显示加载的图层问题,我添加的是shp文件而非MXD,有时能够激发ItemAdded事件,有时却不能够激发.
Leave a comment
Or, take a look at Archives and Categories
买了,第一天晚上看了过通宵.插件式GIS开发是我一直都在想的问题,这次终天实现了,书写得非常好!