作者:皇皇
问:如何将外部数据显示在标签专题图上?
答:第一种方法是使用soThemeLabel.ForeignValue属性,实现分两个步骤:(1)设置标签专题图的ForeignValue=2,表明使用外部数据;(2)关联外部数据,对标签专题图的ForeignValue属性进行设置,通过这个属性设置,可以将数据集中原有的属性与外部的其他属性关联到一起。第二种方法,对于数据库中的纯属性表,可以通过设置soQueryDef.RelTables关联表,将属性数据与空间数据关联起来再制作专题图,将属性表中的字段以标签的方式显示出来。
问:在地图上指定区域,仅对区域内的对象制作专题图,如何实现?
答:目前专题图对象还不支持过滤功能,可以考虑用两个图层,一个图层显示,另外一个图层用来制作专题图,对该图层设置过滤条件,仅显示指定区域内的对象。对于单值专题图对象还可以考虑AddItem的方法,将指定区域内的对象字段特征值添加到专题图对象中进行设置。
问:数据集保存在SDX+ for Oracle数据源中,对这样的图层用str(SMID) + str(SMID)表达式制作专题图,总是提示“表达式错误”,怎么回事?
答:Oracle中不支持str这样的函数操作,正确的表达式应该是:To_Char(SMID) || To_Char(SMID)。
问:怎样设置单值专题图中Item的可见或不可见?
答:soThemeUnique.ItemStyleEnabled可以设置图层显示时各单值类别是否使用专题风格。
问:如何使用专题图向导?如何移除专题图?
答:使用SuperLegend控件的ShowThemeWizard 方法可以调出专题图向导,soLayer.DeleteThematicMap()方法可以删除专题图。
问:如何对网络数据集的子数据集创建专题图?
答:将网络数据集添加到地图窗口后,通过soLayer对象的SubLayer属性获得网络图层的子图层对象,然后对这个子图层创建专题图。
问:如何实现反选功能?
答:假设选择了若干点对象的SMID分别为2、4、5、7、10,实现反选时设置查询条件为"smid not in (2,4,5,7,10)"。对此图层数据集查询出记录集,转换为选择集即可。
问:如何将选中的点的属性表显示出来?
答:选择对象后会触发SuperMap_GeometrySelected事件,在该事件中通过SuperMap.Selection得到选择集(soSelection),将选择集转换为记录集soSelection.ToRecordset,用SuperGridView关联记录集显示出属性信息。
问:怎样实现设置“线面选中风格设置”的功能?
答:通过设置soSelection.Style可以修改选中对象的高亮风格。
问:设置对象选中风格(soSelection.Style)和修改选中对象风格(SuperMap.ModifySelectedGeometry…)有什么区别?
答:(一)soSelection.Style。空间对象被选中后会以一种特定的显示风格来显示,以区别于没有被选中的对象。在SuperMap Objects中,这一风格由soSelection.Style决定。点、线、面和文本对象的选中风格都有自己的缺省值,也可以通过soSelection.Style来修改对象的选中风格。(二)SuperMap.ModifySelectedGeometry…:这一系列方法是实质性的修改对象的风格。一般而言,只有在这样的情况需要这一个功能:有多个具有各自风格的几何对象,现需要修改它们的某一个风格项(比如文本的颜色)、而其他风格都还保持每个几何对象自己的。由于只有在复合数据集和文本数据集中的几何对象才能存储风格,因此ModifySelectedGeometry…方法只适用于复合数据集和文本数据集,对其它数据集类型中的几何对象的风格设置无效。
问:用soSelection.FromRecordset方法或soSelection.Add向选择集中加入内容后为什么在SuperMap控件的选择集并未添加进去?
答:地图窗口中多个图层可以同时处于可选择状态,但是当前的被选择图层只能有一个,soSelection.Dataset这个接口是指定当前被选择的数据集,因此无论是通过FromRecordset或者通过Add方式添加到选择集中都要来自于同一个数据集中。上面的问题解决办法是先将待添加到选择集中的对象所在的Dataset设置给soSelection.Dataset。
问:如何实现跨图层选择的功能?
答:通过设置SuperMap.Action = scaSelect是不支持跨图层选择的,可以通过二次开发来实现这样的功能。将SuperMap.Action设置为scaTrackRectangle,在地图窗口上绘制要查询的区域,绘制结束后会触发SuperMap_Tracked事件,在该事件中通过SuperMap.TrackedGeometry获得矩形,用它对所有可选择图层循环进行查询,然后将查询到的对象添加到TrackingLayer上高亮显示即可。
问:进行选择操作后如何清除选中状态,刷新地图也不行。
答:使用选择集对象的RemoveAll方法来清除选中状态再刷新地图。
问:编辑图层时每修改一个对象都需要去刷新全部图层,如何提高性能避免每次都去访问数据库?
答:推荐使用soLayer.UserCache接口,设置编辑图层的该属性为True,那么编辑的时候,在编辑图层以下的所有图层不需要刷新,对背景图层数据量大的应用有明显的优化效果。
问:如何通过记录集返回图层名?
答:从选择集可以得到数据集soSelection.Dataset,再通过soDataset.DataSourceAlias获得数据集所在数据源的别名,图层名的命名规范是“数据集名称@数据源别名”,进而通过soLayers.Item得到对应的图层。
问:多张栅格图叠加显示时如何透视下面的图层?
答:多张栅格图叠加显示的时候,如果要透视下面的图层,可以对上面的图层设置不透明度,默认是100%不透明。
问:当捕捉到某一对象以后,能得到这个对象的属性吗?
答:这个功能可以通过二次开发来实现,鼠标在地图窗口上移动时会触发SuperMap_MouseMove事件,该事件会返回鼠标的当前位置,使用SuperMap.SnapPoint方法去判断是否当前捕捉到对象,该方法会在捕捉到对象时返回True,并且传入的点对象坐标被修改为捕捉到的位置坐标,可以通过该坐标到相应的图层中去HitTest,获得到哪个对象被捕捉到,并使用查询方法去获取对象属性。
问:如何获得当前图层中处于编辑状态的图层?
答:可以通过soLayers对象的GetEditableLayer方法来获得当前处于编辑状态的图层对象(soLayer)。
问:如何将线层中的某一特定的线显示为和其他对象不一样的风格?
答:两种办法:(1)通过专题图的方式来实现;(2)将该线添加在跟踪层上,设置不同的风格。
问:SuperMap.MaxScale与soLayer.VisibleScaleMax有何区别?
答:SuperMap.MaxScale是控制整个地图窗口的,在SuperMap控件中默认是可以无限放大的,但是一般情况下是放大到一定程度再放大就没有意义了,这时如果用户想要控制地图不再放大,可以通过这个接口来进行限制。而soLayer.VisibleScaleMax是控制指定图层的最大显示比例,比如城市地图中的学校标注信息,在全图的时候密密麻麻影响地图显示的美观度,因此会设置该图层在地图放大到一定程度才显示,就是通过这个属性来控制。
问:如何过滤图层中的数据,仅显示满足一定条件的对象?
答:使用soLayer.DisplayFilter接口可以过滤不符合条件的数据。DisplayFilter的用法是利用该图层所在的数据集的属性信息构造条件语句,作为一个字符串传给DisplayFilter,如objLayer.DisplayFilter=“SmID<100” 表示地图上只显示该图层上满足条件“SmID小于100”的对象。如果过滤条件需要根据比例尺的变化来设置,可以在SuperMap控件的BeforeMapDraw事件中动态地根据当前地图的比例尺来设置DisplayFilter。
问:怎样实现对图层中的不同几何对象设置不同的显示风格?
答:采用图层的风格设置可对同一图层的对象设置统一的风格(复合图层除外)。但是要对图层中的不同(种类)的对象设置不同的风格,就需要使用SuperMap控件的专题图功能(对复合图层)。具体可以采用单值专题图(soThemeRange )或者分段专题图(soThemeUnique )来实现。关于单值专题图和分段专题图的使用可以参考范例程序。
问:soLayer.Editable属性是只读的?那如何设置图层可编辑?
答:soLayer.Editable 是只读的,返回该图层当前是否为可编辑状态。设置图层可编辑是通过soLayers的SetEditableLayer(Index As VARIANT) 方法来设置的。
问:SuperMap Objects的GIS图层与复合图层有什么区别?
答:在SuperMap Objects的GIS图层上只能存储一种类型的对象,比如点数据集中只能保存点对象;这种图层上的空间对象不存储风格,需要通过设置图层风格或制作专题图来实现。GIS图层有利于统一数据结构,方便进行空间分析。复合图层上支持各种类型的对象,而且每一种对象都可以存储自己的显示风格。两种类型的图层各有特点,用户可根据不同的需求选择不同的方式。
问:如何根据地图的名字得到图层?
答:图层只有在地图打开后才能获取。打开地图后,从地图窗口得到图层集合soLayers,循环获取图层,继而得到相应属性。
问:自定义编辑的记录是否可以实现撤销/重做?
答:可以使用soEditHistory对象来实现,例如实现删除功能,在执行soRecordset.Delete之前,使用soEditHistory.SetEventInfo方法将要删除记录保存下来,然后就可以通过soEditHistory的Move方法实现撤销了。添加和修改的实现方式类似,详细信息可以参考《SuperMap Objects联机帮助》。
问:在SuperMap Objects中已知两个点的经纬度坐标,如何计算这两点之间的距离?
答:在经纬度坐标系下计算两点之间的距离,请使用soGeometrist.Geodesicdistance(objPoints As soPoints,[dPrimeAxis As Double],[dFlattening As Double]) 方法。
问:在SuperMap Objects中如何实现鹰眼导航的功能?
答:鹰眼导航的效果是,在主地图窗口上放大、缩小、漫游地图时,在缩略图上显示一个矩形来表示当前地图窗口的显示范围;实现该功能主要包括两个步骤:(一)在主地图窗口的SuperMap_AfterMapDraw事件中,取得SuperMap.ViewBounds,返回一个soRect;(二)通过这个soRect构建一个soGeoRegion对象,然后将这个soGeoRegion添加到缩略图的TrackingLayer上。注意,soGeoRegion对象的填充颜色可以设置成半透明,这样显示效果既醒目又美观。反过来,在缩略图上指定位置,主窗口也会显示相应位置的详细地图信息,实现思路是:在缩略图的SuperMap_MouseDown事件中,获得当前鼠标的位置,进行像素坐标到地理坐标的转换,并将这个点赋给主窗口的SuperMap.CenterPoint。具体的代码示范请参考SuperMap Objects的安装目录下VB范例程序库中的Location例子。
问:SuperMap Objects如何实现自动距离标注功能?
答:实现方法是这样的:(一)在线型库中创建一种两端带箭头的线型;(二)创建一个复合图层;(三)设置SuperMap.Action为scaTrackLinesect,在地图窗口上绘制一条线,在SuperMap_Tracked事件中可以通过SuperMap.TrackedGeometry获得刚刚绘制的线对象,计算线长度后创建文本对象保存,并将文本对象放置在线的中点上;(四)把线段和标注一起添加到复合图层上。
问:SuperMap控件如何使用自制的鼠标指针?
答:SuperMap控件可以支持自制的鼠标指针,方法如下:SuperMap.MouseIcon=“文件名”,这个文件名用您自制的鼠标指针的文件名即可。注意,只有当前SuperMap控件的Action为非SuperMap定义的Action时此设置才有效。
问:改变鼠标风格应该使用什么接口?
答:分两种情况说明:第一种情况:使用自定义鼠标样式。(1)设置SuperMap控件的FixedActionCursor属性为false;(2)设置SuperMap的ActionCursor属性,选择设置何种鼠标状态的风格,将ActionCursor设置为sccCursorUserDefine;(3)设置SuperMap的MouseIcon属性,指定鼠标风格的ico图片的全路径名。第二种情况:使用系统预定义的鼠标样式。(1)设置SuperMap的ActionCursor属性,选择设置何种鼠标状态的风格,将ActionCursor设置为系统预定义的鼠标样式。
问:用点串创建的面对象,不能设置填充颜色,为什么?
答:出现这种问题的原因一般是,构建面对象的点串中终点和起点不是同一个点。
问:如何计算线段上某一点离线段起点的距离?
答:可以用线段上的这个点,切割这条线,然后求出包含起点这条线段的长度。
问:如何分割一个复杂对象?
答:首先通过几何对象的PartCount得到复杂对象的子对象数,然后在一个循环中依次得到简单的子对象分别进行分割就可以了。
问:打断折线总是失败,是什么原因?
答:使用soGeoLine.Split方法打断折线失败的原因一般是容限导致的,soSetting.Epsilon默认的分析精度是很小的,可以根据数据情况适当扩大容限再去打断线。
问:可以实现把面分割成两块以上吗,可以把两个以上相邻的面合并吗?
答:用线对象或者面对象对面进行分割,使用soSpatialOperator.SplitRegion方法,可以分成多块;将两个以上相邻的面合并可以循环调用soSpatialOperator.Union方法来实现。
问:不使用Object提供的scaEditVertexAdd,如何实现输入坐标在一个面的某一个边界增加一个节点?
答:通过输入的坐标以及面对象原有坐标串,组织成一个新的点串对象(soPoints ),来生成新的面对象,替换原先面对象。
问:如何得到两直线的交点坐标?
答:使用soGeometrist.IntersectLine方法或者soGeoLine.GetCrossings方法。
问:如何给复合数据集中的几何对象设置风格?
答:由于复合数据集中的每个对象都可以有不同的风格,因此不能使用soLayer的Style属性进行设置,需要使用几何对象的Style属性来设置某一几何对象的风格,修改了风格属性的对象需要通过soRecordset.SetGeometry方法保存回数据集中去。
问:如何获取组成某个点、线、面对象的点(集)?
答:(一)点对象,通过soGeoPoint的X、Y属性获得点对象的坐标信息;(二)线对象,通过soGeoLine.GetPartAt(nIndex As Long)方法获得指定的子对象的点集soPoints;(三)面对象,通过soGeoRegion.GetPartAt(nIndex As Long)方法获得指定的子对象的点集soPoints。关于子对象的概念请参考《SuperMap Objects联机帮助》中GetPartAt接口的说明。
问:简单矩形对象soRect和矩形几何对象soGeoRect的用法有何区别?
答:简单矩形对象通常通过几何对象或地图窗口的范围(Bounds)获得。简单矩形对象主要用于确定矩形的位置,其接口有九个:Bottom、Left、Right、Top、BottomRight、CenterPoint、Height、TopLeft、Width。矩形几何对象(soGeoRect)则是几何对象(soGeometry)的子类,它可以和其他几何对象(soGeoLine、soGeoRegion等)互转,也可以被保存到矢量数据集中。
问:点几何对象soGeoPoint和简单点对象soPoint有何区别?
答:soGeoPoint是点几何对象,描述点状地物,是soGeometry的子类,继承soGeometry对象的所有接口。因此,可以赋予风格,并添加到跟踪层上显示,还能和其他对象进行空间运算和操作。soPoint只是简单点对象,是构成线、面几何对象控制点,不能用于表达点状地物,其主要接口有三个:soPoint.X、soPoint.Y、soPoint.OffSet,它只描述点的空间位置(地理坐标)。
问:soGeoCircle是面还是线,为什么有的是线状有的是面状呢?
答:soGeoCircle是不同于soGeoLine和soGeoRegion之外的一种特殊的参数化几何对象,只能存在于复合图层上。通过设置它的BrushStyle可以改变其风格,当BrushStyle=0时是填充的;当BrushStyle=1时是非填充的。在GIS图层上也可以通过soGeoCircle来构造圆(线或面),但是必须要先调用一下ConvertToLine或ConvertToRegion后生成相应的soGeoLine或soGeoRegion对象后才能保存到GIS数据集中。其它参数化对象也是类似的。
问:SuperMap Objects中很多几何对象都有AddPart、GetPartAt和SetPartAt等方法,请问这里的Part含义是什么?复杂对象和复合对象有何区别和联系?
答:SuperMap Objects中除了参数化几何对象外,有几种基本的GIS几何对象类型:点、线、面和文本。这些对象中,除了点对象不支持复杂对象外,其余三种对象都支持复杂对象。所谓复杂对象是指两个或两个以上同类“简单对象”组合而成的几何对象。那么什么是“简单对象”呢?对于线和面来说,简单对象就是简单线和简单面,它们由一个soPoints来表示;对于文本,简单对象就是一个文本子对象,它具有Text、X和Y三个基本属性。现实世界中复杂对象的例子比比皆是,比如海外拥有飞地的国家、被立交桥打断的街道等。复杂对象就是为了表示这种现象。为了数据结构的一致性考虑,所有支持复杂对象的几何对象都不单独提供仅支持简单对象类型的几何对象类型,而是统一用复杂几何对象来表达包括简单对象在内的对象。其做法就是每个复杂几何对象都至少拥有一个简单几何对象,通过AddPart、GetPartAt和SetPartAt三个方法可以为其增加、获取和修改几何对象中的简单对象。也就是说,Part指的是组成复杂对象的简单对象。与复杂对象对比的是复合对象soGeoCompound。这两者有一定的相似性,如都拥有上述三个方法。复合对象与复杂对象最关键的区别是:复杂对象只能是同类简单对象的组合而成,而复合对象则可以是任意类型的几何对象复合而成。所以,在复合对象中,每个Part的类型是soGeometry,而复杂对象的Part的类型只能是soPoints或soTextPart。所以,复合对象只能在复合数据集中存在,复杂对象则不但可以被复合数据集所接受,也可以被与其类型相同的普通数据集所接受。
问:点线面等几何对象的风格设置和文本对象的风格设置有什么不同?
答:点线面等几何对象的风格设置是通过soStyle进行的,而文本对象的风格是通过soTextStyle对象来设置的。点、线、面对象的风格包括对象的颜色、大小、符号形状等,而文本对象的风格包括文本的字体类型、字体颜色、大小、旋转角度等。
问:SuperMap Objects支持哪些参数化几何对象?这些对象在用法上和普通GIS几何对象有什么区别吗?
答:SuperMap Objects支持的参数化几何对象主要有soGeoArc(弧)、soGeoBSpline(B样条曲线)、soGeoCardinal(C样条曲线)、soGeoCircle( 圆)、soGeoCurve(曲线)、soGeoEllipse(椭圆)、soGeoEllipseOblique(斜椭圆)、soGeoEllipticArc(椭圆弧)等。这些对象和普通的GIS几何对象的不同点在于:参数化几何对象是用参数来表示的,是连续的;普通GIS几何对象是用组成该对象的关键点或点串的坐标来表示的,是离散的。举个例子,利用参数化对象soGeoCircle来表示一个圆时只需要根据圆心点的坐标和圆的半径就能够精确地表示该圆,而同样的圆要用普通的GIS几何对象如面对象来表示的话,需要将组成该圆的圆弧离散化取点,然后用这些点连成线后封闭成一个圆形面。由这个对比可知,一般参数化几何对象具有精确、连续、占用存储空间小等特点,适合于用来做图但不利于做GIS空间分析。而普通GIS几何对象则比较不精确,是离散的,占用存储空间也比较大。不过这种几何对象十分适合用于GIS空间分析。基于以上原因,使用SuperMap Objects的参数化几何对象应该注意一下几个问题:(一)参数化几何对象只能保存在复合数据集中;(二)参数化几何对象不能直接用于空间分析或操作函数中作为参数传入。如soDatasetVector.QueryEx(geometry As soGeometry,nSpatialQueryMode As seSpatialQueryMode,strFilter As String) 方法中不能直接用参数化几何对象作为geometry参数调用,否则不能返回正确的结果。正确的做法是先调用参数化几何对象自身的CovertToLine或CovertToRegion把参数化几何对象转换成普通的线对象soGeoLine或面对象soGeoRegion之后再进行调用。以上两点同样适用于soGeoCompound复合对象。
问:如何判断点在线的左边还是右边?
答:使用soGeoLine.Buffer2方法可以对线制作单边缓冲区(左/右缓冲区),用缓冲区面对点进行空间查询,进而判断点在哪边。
问:如何创建沿线文本对象?
答:可以通过交互式方法创建或通过代码来创建。使用前者的前提条件是SuerMap窗口中有一个文本数据集并且已经被设置为可编辑状态,然后将SuperMap控件的Action设置为37(scaEditCreateCurvedText);使用后者的思路是先创建好一个注记文本对象,然后调用soGeoText.Reshape方法将文本对象进行沿线分布处理。
问:如何计算一个点到距离它最近的线的交点?
答:分两步计算:(1)求距离点最近的线对象:用点对象对线数据集进行范围查询(soDatasetVector.QueryByDistance),比较出最近的线对象;(2)求点在线上最近的点(包括线节点或者点在线上的垂足):得到点到线对象的距离(soGeoPoint.DistanceTo),循环获取点跟线对象中的每个折线段的距离并跟点到线的距离进行比较,确定点到哪段折线段距离最短后,用点对此折线段求垂足soGeometrist.GetPerpendicularPosition,如果垂足不在折线段上,那么比较点到折线段端点的距离,求出距离最短的那个端点。
问:如何连接两条线?
答:使用soGeoLine.Joint方法,连接成功后这个soGeoLine对象被修改,如果要保存到数据集中去,那需要使用soRecordset.AddNew添加进去,或者使用soRecordset.SetGeometry来修改已有对象。
问:添加到跟踪层上的点使用符号表示,希望符号可以随图缩放,如何实现?
答:可以使用内存数据源来管理这些点对象,将点层添加到地图上后设置图层的符号可随图缩放属性。(soLayer.SymbolScalable = True)
问:使用scaTrackPolygon绘制一个面对象,绘制完对象就不见了。
答:使用scaTrack…系列动作绘制的对象不会添加到任何地方,是一个临时对象,可以通过映射SuperMap_Tracked事件,在该事件中通过SuperMap.TrackGeometry接口来获取到这个多边形来进行或许处理,比如放到跟踪层上临时显示,或者保存到已有图层上。
问:在跟踪层刷新时RefreshEx与Refresh方法有什么区别?
答:Refresh刷新整个跟踪层,也就是说整个跟踪层上的对象全部重新画一次。而RefreshEx只是刷新改变的部分,RefreshEx方法比Refresh方法更加智能,只是刷新需要刷新的地方,避免闪动。
问:保存地图和工作空间后,再打开原来的地图,原来的跟踪层上的东西都不见了?
答:跟踪层上的对象是临时保存在内存中的,地图关闭时跟踪层上的对象会被删除,所以通过保存地图的方法是不能保存跟踪层上的对象的。如果想要保存跟踪层上的对象,可在关闭地图窗口前将跟踪层上的所有对象都逐个取出然后保存到一个CAD数据集中,然后再保存地图并保存工作空间,这样下次再打开地图这些内容就不会丢失了。
问:为什么选不中TrackingLayer上的对象?
答:TrackingLayer与其他图层不同,不能通过设置图层可选择和设置SuperMap.Action来选中。实现对跟踪层上的对象的选择功能可以用TrackingLayer的HitTest方法,该方法通过传进去当前鼠标的位置和容限值,来获取鼠标周围的对象,然后通过改变该对象的颜色使其表现为选中状态。
问:SuperMap控件能打印TrackingLayer上的对象吗?
答:有两种打印方法,(一)直接调用SuperMap控件的PrintMap方法,这种方法可以打印TrackingLayer上的对象;(二)将地图窗口中的内容保存成地图然后在布局窗口中打印,由于TrackingLayer上的对象并不保存到地图中,所以需要先将跟踪层上的对象保存到一个复合图层上,然后到布局上使用SuperLayout.PrintLayout进行打印。
问:怎样在TrackingLayer上添加文本对象?
答:在TrackingLayer上添加文本对象与添加点、线、面对象一样,使用TrackingLayer.AddEvent方法。只不过由于文本对象本身包含风格信息,在添加时不用再设置风格,即AddEvent方法的第二个参数用Nothing(在VB中)即可。如果设置文本的风格,就要用soGeoText.TextStyle来设置。
问:一般什么使用需要使用TrackingLayer?
答:在有以下几种需求的时候可以使用跟踪层:(一)有一些临时对象,不想保存到图层中去,只是要临时显示一下,这时可以考虑将这些对象添加到跟踪层上去;(二)需要对目标进行动态跟踪的时候,如果把目标放到记录集中要实现动态跟踪就需要不断地刷新整个图层,这样不仅仅需要频繁的写数据源文件,而且要刷新整个地图窗口,效率不高,这时可以使用跟踪图层;(三)实现一些自定义的编辑效果时,可以将中间操作对象放到跟踪层上去显示,编辑结束才将对象真正保存到图层中去。
问:获得跟踪层上的对象后,如何获取跟踪层对象的属性信息?
答:跟踪层上的对象只保存了对象的图形信息和风格信息,而不保存属性信息。不过跟踪层上每个soGeoEvent对象都有自己的唯一索引值和标识符,可以通过这个标识符来关联外部的属性数据表来保存其属性信息。
问:地图窗口中没有图层的情况下是否可以使用TrackingLayer?
答:不能。
问:地图显示可以通过属性过滤条件来显示满足条件的对象,是否可以指定空间范围,在范围外的对象不显示?
答:可以通过SuperMap.ClipRegion接口,您可以任意设定一个地图显示的区域,该区域外的地图内容,将不会显示。可用于布局输出或地图打印输出,可以将设置保存到工作空间,但不会修改原数据。
问:如何调整栅格数据的亮度对比度?
答:调整亮度对比度等操作,可以通过soLayer的RasterBrightNess和RasterContrast接口来设置,这个是针对地图显示设置的,并没有真正修改栅格数据,修改的值会保存到工作空间中去;如果是使用soDatasetRaster的AdjustBrightness和AdjustContrast接口,那么是针对数据修改的。
问:一条线如何实现分段显示?比如一条10米的线,前5米显示为红色,后5米显示为蓝色,甚至线型也可能不一样。
答:可以考虑用动态分段功能实现,主要接口为soDatasetVector.CreateDynamicEvent,详细的使用说明请参考《SuperMap Objects联机帮助》。
问:SuperMap Objects可以实现换行文本标注吗?
答:可以通过标签专题图来实现,例如要标注的两个字段都是文本型字段,其字段名分别是aa和bb,通过表达式制作专题图,表达式的写法是:aa + chr(13) + chr(10) + bb。
如果使用文本图层的话,先新建两个soGeoText对象,分别加入一个soTextPart对象,这两个soTextPart对象的坐标一样,然后设置前一个soGeoText对象的soTextStyle的Align属性为bottomleft,underline为true,后一个文本的Align为topleft,underline为false,再将这两个soGeoText对象加入到数据集,完成显示。
问:如何将查询出的点集合居中并放大显示?
答:如果查询出点集合中的对象个数超过一个,可以使用SuperMap.EnsureVisibleRecordset方法,该方法的第二个参数是控制放大/缩小的倍数;如果点集合中的点对象个数是1,可以通过SuperMap.EnsureVisibleGeometry方法对点进行居中显示,但是第二个参数控制放大/缩小的无效,可以使用SuperMap.Zoom方法实现放大。
问:如何用鼠标中键实现缩放功能?
答:这个功能可以通过SuperMap的MouseWheel事件来实现,该事件的第二个参数zDelta(VB中)返回的就是滚动值,正为向前滚,负为向后滚,值的大小反映的是滚动的强度,在这个事件中调用SuperMap的Zoom(…)方法来实现中键缩放的功能,Zoom的参数可以根据事件的第二个参数来确定。
问:如何用图片来代替显示已有的点对象?
答:可以将需要的图片放到SuperMap的资源库中,在资源库中每个图片都对应一个ID号,将这个ID号赋值给soStyle对象的SymbolStyle属性,然后给点对象的Style赋值就可以了。
问:如何设置文本的大小使得文本显示时大小比较合适不至于太小了看不见?
答:文本大小有是否固定尺寸的设置,分别的设置办法是:(一)文本固定尺寸,即地图缩放时文本始终保持大小不变,通过soTextStyle.FixedSize =True来设置固定尺寸,通过soTextStyle.FixedTextSize来设置文本大小,逻辑单位;(二)文本不固定尺寸,通过soTextStyle.FontHeight来设置文本大小,单位与数据源的单位相同。
问:SuperMap Objects支持直接打开MicroStation和AutoCAD格式的数据,可是为什么打开后很多对象都不见了呢?
答:在CAD软件中地图的背景是黑色,而对象的颜色是白色的。而SuperMap控件窗口默认的地图背景色是白色,所以原来在CAD中为白色的对象就会看不见。解决的办法是把SuperMap控件的背景色改成黑色,修改的办法是对SuperMap.BackStyle进行设置。
问:打开数据集调用SuperMap.ViewEntire方法,为什么地图缩小成很小的一点?
答:这是由于图层的范围不正确导致的,解决这一问题的办法是对数据集的范围进行重新计算。涉及到的接口是soDatasetVector.ComputeBounds() 。
问:怎样设置文本对象和符号的大小随地图缩放而缩放?
答:(一)文本的大小是否随地图缩放而缩放,可通过设置soTextStyle.FixedSize属性控制文本对象的大小是否随地图一同缩放。如果设置为FixedSize = True,字体将固定显示大小,不随地图的缩放而缩放,此时文本对象的大小由soTextStyle.FixedTextSize属性决定,此属性是逻辑坐标。如果设置FixedSize = False,则文本的显示大小不固定,会随地图的缩放而缩放,此时文本对象的大小通过设置soTextStyle.FontHeight属性决定,此属性是地理坐标。FixedSize缺省为False。(二)符号大小是否随地图缩放而缩放,可以通过设置soLayer.SymbolScalable和soLayer.SymbolScaleDefinition等属性来实现。soLayer.SymbolScalable用于控制点状符号是否随地图缩放而缩放,设为False时表示符号固定大小,不随地图缩放而缩放;此时符号的大小由soStyle.SymbolSize决定。soLayer.SymbolScalable = True 时,表示符号随地图缩放;此时需要设置soLayer.SymbolScaleDefinition属性和SymbolSize属性。SymbolSize属性是符号的大小,逻辑单位,SymbolScaleDefinition属性是指当前所设置的符号的大小的基准地图比例尺,以后当地图比例尺发生变化后,符号的大小将由地图当前比例尺SuperMap.ViewScale与SymbolScaleDefinition、SymbolSize共同决定。他们之间的关系为:符号当前大小 = SuperMap.ViewScale / SymbolScaleDefinition * SymbolSize。
SymbolScalable属性缺省是False。soLayer.SymbolScalable和soLayer.SymbolScaleDefinition对线型宽度是否随地图缩放而缩放也同样有效。
问:打开数据集到地图窗口时普通GIS数据集都是以默认的风格显示,如何修改这种风格?
答:由于SuperMap Objects的GIS数据集(除文本数据集外)中的对象并不保存风格,所以这种数据集在地图窗口中打开显示时都是以缺省的风格显示的,这一风格实质上是该数据集对应的图层的风格,即soLayer.Style。因此,要想改变这一风格,修改该图层的soStyle即可。另外,推荐的解决办法是,在SuperMap Deskpro上设置好图层的风格或制作专题图,保存地图和工作空间,在二次开发的系统中直接使用地图,简单方便,而且效果最好。
问:在C# .NET中使用SuperMap.Bounds返回的坐标是屏幕坐标,为什么?
答:在C# .NET 2005开发环境中该接口变化为SuperMap.CtlBounds。
问:如何实现地图网格的制作?
答:根据设置的边界值和间隔距离,计算出创建线对象的相关坐标生成线对象,添加到相关数据集中。或者使用soMapMargin对象来自动生成标准图框。
问:如何将指定矩形区域内的地图打印出来?
答:可以使用SuperMap.OutputMapEx接口将矩形范围内的地图输出为影像数据集,导出为图片文件,然后再进行打印。
问:如何将指定区域内的地图输出到另外一个地图控件中显示?
答:使用SuperMap.OutputMapEx方法将指定区域的地图输出成一个内存数据源中的栅格数据集,然后在另一个地图控件中打开显示该数据集。
问:在Delphi中,用SuperMap.Cut、SuperMap.Copy和SuperMap.Paste时,出现“没有引用标示存在”的错误怎么解决?
答:在Delphi的选项卡system里面有一个ole控件,将其添加到窗体上可以解决这个问题。
问:SuperMap Objects中如何进行像素坐标与地理坐标的转换?
答:在目前的各编程语言中,经常会有涉及到屏幕坐标的处理,比如获得鼠标位置后进行某种操作。而在GIS软件里面经常使用的是地理坐标,不是屏幕坐标。这就需要对这两种不同的坐标进行相互转换。SuperMap Objects提供了接口来实现两种坐标的互转功能:把像素坐标转换成地理坐标,SuperMap Objects提供的接口是SuperMap.PixelToMapX(x As OLE_XPOS_PIXELS)、SuperMap.PixelToMapY(y As OLE_YPOS_PIXELS)。把地理坐标转换成像素坐标,SuperMap Objects提供的接口是SuperMap.MapToPixelX(x As Double)、SuperMap.MapToPixelY(y As Double)。需要说明的是,部分开发语言可以支持多种屏幕坐标,而且缺省的屏幕坐标不是像素坐标,这时需要首先把屏幕坐标转换为像素单位,再调用上述接口才能得到正确的结果。否则其结果必然是错误的。
问:如何选择地图窗口中的一部分内容并将其保存成地图?
答:可以使用SuperMap.TrackRectangle动作来绘制矩形范围,根据这个矩形范围对数据集进行裁剪,同时记录当前图层的风格。将裁剪之后的数据集打开到地图窗口同时赋于其相应的风格,最后保存地图就可以了。
问:怎样在VC中引入SuperMap Objects的常量?
答:在VC中使用SuperMap Objects不能像VB中那样可以直接使用常量名,而必须使用常量的值,如设置地图平移动作为SuperMap.SetAction(1),而不是SuperMap.SetAction(scaPan)。此外,也不能像在VB中那样可以直接用等号向变量赋值,而是使用相应的Get或 Set函数来赋值或取值。
问:打开WMS类型的WEB数据源,为什么只有第一个子图层可见?怎么设置其他子图层也可见?
答:默认情况下,WMS图层中只有索引为1的子图层可见,可以通过soLayer.SetWebSubLayerVisible()方法设置其他子图层可见。
问:为什么SqlServer数据源关联属性表查询的时候总是失败?
答:进行关联查询时,对于SQLPlus引擎的数据源,需要设置soQueryDef.CursorType = sctOpenStatic 或者3,即只读游标,或者静态游标。
问:Objects 打开WMS 网络数据源,能否在保存本地缓存?
答:通过设置Objects安装目录下bin目录中的supermap.ini文件中UseWMSCache = true,开启保存WMS的本地缓存。
问:SDB中CAD数据集存储的大量扇形对象,每秒修改对象形状和风格并在地图中显示,发现地图比较闪,刷新效率较低,尝试将扇形加到跟踪层效率也挺低,有什么优化的办法。
答:跟踪层只适合频繁添加删除少量的临时数据,对象多了会影响显示效率。对于比较频繁修改的大量数据,可以尝试创建内存数据源,比文件型的数据源更新效率高。
问:地图控件中BeforeGeometryDeleted事件为何不起作用,在事件中设置了取消仍能删除对象?
答:在BeforeGeometryDeleted事件中,需要设置e.bCancel为true,才会取消对象的删除操作。
问:如何设置当前地图中所有图层均不可以编辑?
答:使用soLayers.DisableEdit()方法可使当前地图中无可编辑图层。
问:服务器共享地图缓存文件,通过程序调用,此时打开地图缓存文件进行浏览操作效率较慢,何故?
答:通过共享文件的方式进行读取访问,与当前所处的网络带宽有较大关系,如果出现浏览操作效率较低可事先检查下当前局域网的带宽,如果带宽较小在读取下载对应的速度也较低,故此出现了通过共享文件方式打开地图缓存文件,浏览效率会出现相应降低
问:COM组件实现布局打印功能,地图中某个面图层设置了半透明,打印的结果,图斑都显示为黑块,如何解决。
答:COM组件不支持半透明图层的打印。要想实现半透明效果的打印有两种办法:一,将布局输出为图片,打印图片;二是用UGC 6R的组件完成布局打印模块。
问:怎么样使一幅地图显示裁剪区域的同时,特定图层不显示裁剪区域?
答:设置SuperMap.ClipRegionEnabled=false,特定的图层设置soLayer.ClipRegionEnabled=false即可实现效果。
问:使用soDatasetRaster.MaskRegion 对栅格数据集做掩膜,为什么掩膜后的栅格数据集打开后看不到掩膜的效果?
答:此问题是由于掩膜的时候栅格数据集打开的原因,因为只有在栅格数据集关闭的情况下进行掩膜,掩膜效果才能实现。
问:为什么在使用soSurfaceOperator.IsoRegionByValueEx方法生成等值面的过程中,返回的结果总是为空?
答:分析结果为空是由于工作空间控件和分析控件没有建立连接引起的,因此在使用网络分析、栅格代数运算、地形表面分析等常用和专业的分析功能时候,必须使工作空间控件与分析控件建立连接。
问:构造了一个多点对象,调用OgdcRecordset.AddNew方法,将其添加到点数据集中,添加失败。
答:多点(OgdcElemMultiPoint)对象需要添加到CAD数据集中,将其添加到简单点数据集中是不成功的。
问:选中某个对象之后,如何判断该对象的几何类型?
答:首先通过soSelection.ToRecordset()将选择的对象提取为记录集,然后soRecordset.GetGeometry() 获取当前记录对应的几何对象,最后soGeometry.Type返回几何对象的类型seGeometryType。
问:从2008低版本升级至538版本,报控件未注册是什么原因?
答:有可能因为当前操作系统注册了多个组件版本,以Visual Studio开发环境为例,建议如下操作:
1.反注册低版本;
2.注册538版本;
3.在VS中打开工程,删除已有的SuperMap引用;
4.在工具箱中重新添加SuperMap控件;
5.新建一Form窗体,从工具箱添加需要的控件;
6.删除第5步中新建窗体,重新编译工程即可。
问:Deskpro设置编辑锁定之后,在5.3.8版本Objects程序中去取消相应图层的编辑锁定无效。为什么?
答:5系列的Objects组件的图层对象不支持对编辑锁定的设置,建议将组件更新至6系列的,6系列组件图层对象中开放了编辑锁定接口,以更改当前图层编辑锁定状态
问:在Objects中用DeleteDataset方法删除数据集后,再次打开查看,该数据集仍然存在,在Deskpro软件中是可以直接删除的,怎么解决?
答:用soDataSource.DeleteDataset()方法删除数据集后,再调用soDataSource.Flush()方法刷新数据源中的数据集信息,这样就可以解决。
问:为什么使用SuperMap Objects在oracle数据源里生成TIN数据集失败?
答:因为基于SDX+的SQL Server 和 Oracle 数据源不支持 TIN 数据集。
问:COM组件中如何根据行列号获取当前行列号栅格的地理坐标值?
答:在Objects中没有直接根据行列号获取当前行列号栅格的地理坐标,不过可以通过获取当前栅格数据集的bounds,然后获取当当前bounds的左上点作为计算基准点,该点位于栅格数据集的第0行第0列的左上顶点;并且在DatasetGrid中提供了直接获取当前栅格的X、Y方向的分辨率接口,获取到相应的一个栅格在X、Y方向上的分辨率并且根据相应的行列数计算出当前栅格与获取的bounds左上基准点的相对距离,通过这个相对距离就可以计算出当前栅格中心点的坐标值。
问:用Query2 方法做关联查询,soQueryDef 中定义的各种查询条件和soRelQueryTableInfo 对象的关联信息均设置了,但最终查询出来的记录数目为0。
答:在进行soRelQueryTableInfo 对象的SearchCondition设置时,如果两个字段是文本型的则会出现这样的结果,在做关联查询时建议使用两个数值型字段进行关联。
问:使用FillSink方法对一个栅格数据集进行填充洼地计算,各个参数都设置正确,但跟踪发现定义的soDatasetRaster对象的实例并没有值,重新打开这个数据源后,发现结果数据集就在那里,怎么回事?
答:这个是相应控件没有关联的原因,在初始的时候:SuperAnalyst.Connect(SuperWorkspace.CtlHandle)就可以了。
问:VC的Objects工程,View类中无法实现控件拖放使用,那如何在View类中创建Objects控件?
答:VC工程中只有在Dialog中才能实现控件的直接拖拽使用View类中无法直接拖拽控件,不过Objects控件对应的各个类中均有Create方法,都可以直接通过Create方法将控件直接创建,创建方法可以参考工作空间的创建形式。
问:VC中使用Objects,通过强制转换,将获取的soDataset转换为soDatasetVector失败?
答:VC中soDataset转换为soDatasetVector需通过AttachDispatch方法,格式类似于soDatasetVector.AttachDispatch(soDataset,false)
问:在SuperMap Objects中怎么实现在SuperGridView只显示需要的字段的属性值?
答:在使用soDatasetVector.Query(strSQLFilter As String,bHasGeometry As Boolean,[objFields As soStrings],[strOptions As String]) 获取soRecordset的时候,对[objFields]参数设置需要显示的字段。
问:VC中有些对象例如CsoPoint直接实例化之后设置实例化对象的属性,运行到该实例对象处会出现attempt to call Invoke with NULL m_lpDispatch!警告,并且在使用该实例对象时候失败,为什么?
答:通过跟踪代码可以查看到CsoPoint的对象实例对应的m_lpDispatch为空。通常情况下,从COleDispatchDriver派生的类在实例化时,需要调用CreateDispatch方法。
实例化代码如下:
CsoPoint objPoint;objPoint=CreateDispatch(“SuperMap.sopoint”)
Project proMap_Output.exe raised exception class EAccessViolation with message ‘Access violation at address 00459F0C in module ‘proMap_Output.exe’. Read of address 00000008’. Process stopped. Use Step or Run to continue.
答:在soDataSources.RemoveAll或soDataSources.Remove前,如果调用过其中的数据源,需要逐个进行释放。示范代码如下:
for i := 1 to count do
begin
objDataSource := objDataSources.Item[i];
if objDataSource.ConnectionInfo.DataBase = ‘changchun’ then
begin
strDataSourceAlias := objDataSource.Alias;
EngineType := objDataSource.EngineType;
objDataSource := nil;
end;
end;
objDataSources.RemoveAll;
问:为什么SuperMap Objects 在sql数据源中新建文本型字段失败?
答:在sql数据源中,新建字段时需要设置soFieldInfo.Required=true和soFieldInfo.AllowZeroLength =true。