MAPX 学习笔记资料手册

sdshw 贡献于2014-03-14

作者 Administrators  创建于2012-09-29 08:14:00   修改者Administrator  修改于2012-09-29 08:14:00字数42854

文档摘要:MAPX学习使用笔记资料Mapxtreme下面应该有三种图层一种是固定图层当你新建一个固定图层的时候会生成*.tab等文件一种是临时图层不生成*.tab文件一种是用户绘制图层用户自己使用CDC(Graphics)进行绘图如果你想对多边形进行编辑至少你要响应Mapxtreme的鼠标事件通过鼠标事件来确定当前用户在进行何种操作。
关键词:

MAPX学习使用笔记 资料 Mapxtreme 下面应该有三种图层 一种是固定图层 当你新建一个固定图层的时候会生成*.tab等文件 一种是临时图层 不生成*.tab文件 一种是用户绘制图层 用户自己使用CDC(Graphics) 进行绘图 如果你想对多边形进行编辑 至少你要响应Mapxtreme的鼠标事件 通过鼠标事件来确定当前用户在进行何种操作。 一般的过程是这样的: 1.新建一个图层(建议临时图层或者用户绘制图层) 2.根据多边形的点的位置绘制图元或者用CDC绘制过变形 同时确定各个点在Mapxtreme地图窗口的位置 建立各个点的鼠标响应区域 3.通过鼠标落下的时候通过各个点的响应区域判断那个点被选中 鼠标移动 和抬起时要做响应的处理 来改变多边形选中点的位置 重重新给多边形的点赋值 如果使用临时图层 需要对临时图层里面的多边形图元的点参数进行更改 如果是CDC绘图的话只要更改CDC绘图即可 整个过程中需要考虑到地图坐标与Mapxtreme窗口坐标之间的转化。 {通过对象编辑工具,用户可以在地图图层中创建和修改图元。有四种标准的对象创建工具:“添加 点”、“添加线条”、“添加折线”和“添加区域”。 注:若要设置所使用的工具,请设置 Map.CurrentTool 属性。 对象编辑工具将新图元添加到在 Layers.InsertionLayer 属性中指定的任何图层中。只能有一个插入图 层,并且默认情况下是没有插入图层。在没有任何插入图层时将当前工具设置为对象创建工具将导致 错误。 MapX 还支持对现有地图图元的修改。若要编辑图元,则对于您要更改的任何图层,必须将 Layer.Editable 属性设置为真。然后,可以使用内置的“箭头”工具,在当前选择中移动图元或调整图 元的大小。若要移动选定图元,只需单击并在选} 代码名称:向已存在的图层中添加数据 作者/收集者:xyz2004 开发环境:MapX + Delphi 代码: procedure TForm1.Button2Click(Sender: TObject); var lyrnew:CMapxLayer; ds:  CMapxDataset; rvs: CMapxRowvalues; rv: CMapxRowvalue; ptNew: CMapXpoint; ftrNew: CmapXFeature; begin lyrNew := Map1.Layers.item(1); ds := Map1.Datasets.Add(miDataSetLayer, lyrNew,emptyparam,emptyparam,emptyparam,emptyparam,emptyparam,emptyparam); //rvs := ds.Rowvalues[1].Clone ; rv:= CoRowvalue.Create; rvs:=CoRowvalues.Create; rv.Dataset:=ds; rv.Field:=ds.Fields.Item(1); //假设mi表有两个字段,填充之 rv.value :='item1'; rvs.Add(rv); rv.Field:=ds.Fields.Item(2); rv.value :='item2'; rvs.Add(rv); ptNew:=CoPoint.Create; ptNew.Set_(map1.centerx, map1.centery); ftrNew := map1.FeatureFactory .CreateSymbol(ptNew,emptyparam); ftrNew := lyrNew.AddFeature(ftrNew, rvs); // 图元+属性,即feature+Rowvalues //ftrNew = lyrNew.AddFeature(ftrNew); //ftrNew.Update (True, rvs); end. 代码名称:在MapX中实现图元闪烁原码 作者/收集者:zlx 开发环境:Delphi + MapX 代码: MapX图元分三种类型:  1、线(Line),即miFeatureTypeLine  2、区域(Region),即miFeatureTypeRegion  3、点符号(Symbol),即miFeatureTypeSymbol  加入一个时钟控件,并在时钟控件中实现以下代码:  procedure  TMapFrm.tmFlashSelectTimer(Sender: TObject);  var  ft: CMapXFindFeature;  lyr: CMapXLayer;  bExist: Boolean;  i: Integer;  str: String;  ds: CMapXDataset;  begin  bExist := False;  for i := 1 to mapCity.Layers.Count do  begin  if mapCity.Layers.Item[i].Name = m_strSelLyr then  begin  bExist := True;  break;  end;  end;  if not bExist then  begin  tmFlashSelect.Enabled := False;  MsgFrm := TMsgFrm.Create(Self);  MsgFrm.m_strMsg := Format('图层[%s]信息不存在!',[m_strSelLyr]);  MsgFrm.ShowModal;  MsgFrm.Free;  Exit;  end;  lyr := mapCity.Layers._Item(m_strSelLyr);  ds := mapCity.Datasets.Add(miDataSetLayer, lyr ,EmptyParam, EmptyParam, EmptyParam, EmptyParam,  EmptyParam, EmptyParam);  lyr.Find.FindDataset := ds;  lyr.Find.FindField := ds.Fields.Item[1];  str := Format('%d',[m_nSelID]);  ft := lyr.Find.Search(str,EmptyParam);  if ft.FindRC mod 10 <> 1 then  begin  tmFlashSelect.Enabled := False;  MsgFrm := TMsgFrm.Create(Self);  MsgFrm.m_strMsg := Format('单位点[%s]信息不存在!',[m_strCorpName]);  MsgFrm.ShowModal;  MsgFrm.Free;  Exit;  end;   case ft.type_ of  miFeatureTypeLine:  begin  if ft.Style.LineColor = miColorWhite then  ft.Style.LineColor := miColorRed  else  ft.Style.LineColor := miColorWhite;  end;  miFeatureTypeRegion:  begin  if ft.Style.RegionColor = miColorGreen then  ft.Style.RegionColor := miColorRed  else  ft.Style.RegionColor := miColorGreen;  end;  miFeatureTypeSymbol:  begin  if not m_bFlashSel then  lyr.Selection.Replace(ft)  else  lyr.Selection.ClearSelection;  m_bFlashSel := not m_bFlashSel;  end;  end;  ft.Update(EmptyParam, EmptyParam);  if not m_bCenter then  begin  m_bCenter := True;  mapCity.CenterX := ft.CenterX;  mapCity.CenterY := ft.CenterY;  mapCity.Refresh;  end;  end;  我这里是把选中的图元实现闪烁,并把图元居中  实现图元闪烁的另一个方法:  假设图元原大小是20,改变后大小是15  if ft.Style.SymbolBitmapSize=20 then  ft.Style.SymbolBitmapSize:=15  else   ft.Style.SymbolBitmapSize:=20;  ft.Update(EmptyParam, EmptyParam);  ft是symbol类型的 代码名称:画多边形、直线代码名称:画多边形,画线 1,画多边形,画线 procedure TForm1.Map1PolyToolUsed(Sender: TObject; ToolNum: Smallint; Flags: Integer; const Points: IDispatch; bShift, bCtrl: WordBool; var EnableDefault: WordBool); var Style: CMapXStyle; f: CMapXFeature; begin case Flags of miPolyToolBegin: ;{ 某些用户开始使用 PolyTool.. } miPolyToolEnd: { 用户通过双击完成 PolyTool 的使用 } if ToolNum = MY_POLYGON_TOOL then begin { 它们使用 MY_POLYGON_TOOL!制作新的区域图元 并将其添加到第一个图层 } Style := Map1.DefaultStyle.Clone; Style.RegionPattern := miPatternSolid; Style.RegionColor := 255; Style.RegionBorderColor := 0; Style.RegionBorderWidth := 2; Style.RegionBorderStyle := 1; { 使用由事件为我提供的点。 MapX 自动关闭打开的多边形,因此我无 需担心! } f := Map1.FeatureFactory.CreateRegion(Points, Style); Map1.Layers.Item('Temp Layer').AddFeature(f, EmptyParam); end else if ToolNum = MY_POLYLINE_TOOL then begin { 它们使用 MY_ POLYLINE_TOOL!制作新的线图元 并将其添加到第一个图层 } Style := Map1.DefaultStyle.Clone; Style.LineStyle := 1; Style.LineColor := 255; Style.LineWidth := 2; { 使用由事件为我提供的点 } f := Map1.FeatureFactory.CreateLine(Points, Style); Map1.Layers.Item('Temp Layer').AddFeature(f, EmptyParam); end; miPolyToolEndEscaped: ; { 用户按下了 Esc 或退格键 删除所有节点... 不要再添加任何东西。 } end; end; ////////////////////////////// 2.画折线和多边形(并没有考虑属性数据的录入) procedure TForm1.Map1PolyToolUsed(Sender: TObject; ToolNum: Smallint; Flags: Integer; const Points: IDispatch; bShift, bCtrl: WordBool; var EnableDefault: WordBool); var Style: CMapXStyle; f: CMapXFeature; begin case Flags of miPolyToolBegin: ;{ 某些用户开始使用 PolyTool.. } miPolyToolEnd: { 用户通过双击完成 PolyTool 的使用 } if ToolNum = MY_POLYGON_TOOL then begin { 它们使用 MY_POLYGON_TOOL!制作新的区域图元 并将其添加到第一个图层 } Style := Map1.DefaultStyle.Clone; Style.RegionPattern := miPatternSolid; Style.RegionColor := 255; Style.RegionBorderColor := 0; Style.RegionBorderWidth := 2; Style.RegionBorderStyle := 1; { 使用由事件为我提供的点。 MapX 自动关闭打开的多边形,因此我无 需担心! } f := Map1.FeatureFactory.CreateRegion(Points, Style); Map1.Layers.Item('Temp Layer').AddFeature(f, EmptyParam); end else if ToolNum = MY_POLYLINE_TOOL then begin { 它们使用 MY_ POLYLINE_TOOL!制作新的线图元 并将其添加到第一个图层 } Style := Map1.DefaultStyle.Clone; Style.LineStyle := 1; Style.LineColor := 255; Style.LineWidth := 2; { 使用由事件为我提供的点 } f := Map1.FeatureFactory.CreateLine(Points, Style); Map1.Layers.Item('Temp Layer').AddFeature(f, EmptyParam); end; miPolyToolEndEscaped: ; { 用户按下了 Esc 或退格键 删除所有节点... 不要再添加任何东西。 } end; end; 用DELPHI开发”MapInfo MapX“ 分类:学习笔记 2007.11.13 15:41 作者:xboshi82 | 评论:0 | 阅读:2618 MapInfo MapX是一个用来做地图化工作的OCX控件, 首先是简介 是mapinfo4.0以后才有的  MapX是一个OCX组件,可以被快速集成到使用Visual Basic、PowerBuilder、Delphi、Visual C++或其他面向对象的语言的客户端应用程序以及使用Lotus Script的Lotus Notes (v4.5)中。开发人员可以在他们熟悉的环境中工作,最终用户可以通过他们熟悉的应用程序来访问地图数据。  MapX 的功能  MapX不仅仅是一个“地图浏览器”。通过MapX,可以分析并直观地显示业务数据,创建或编辑地图图元,并按地理位置显示数据结果。 1、专题制图 - 使用专题制图显现数据。联合数据和地图中的每个图元,并在地图中用颜色编码(或其他样式)来表示数据。可使用六种不同的样式来观察数据(色彩范围、点密度、独立值、等级符号、饼图、直方图)。 2、逐层细化制图 - 可以通过简单的定点和单击来浏览数据,在OLAP S环境下,可以允许用户通过定点和单击逐层细化地图的某个区域。 3、数据绑定 - 地图可合并来自嵌套OCX的容器、ODBC或DAO数据源(例如MSAccess)的数据。MapX提供多种不同类型数据的绑定,包括邮政编码级别的地理编码。 4、注释 - 可以提供定位、高亮显示特定数据的功能,通过添加文本、符号和标注来使您的地图信息变得更加丰富。 5、图层化 - 显示和控制地图图层的显示,让它只在地图的缩放比例符合事先调整的距离时才显示。还可以使用或创建无缝地图图层,它可以把一组基表看作一个整体。特殊图层类型可以支持特殊类型的应用,如动态图层(用于实时跟踪)和用户描绘图层(用于描绘特殊的地图元素,如地图上方的标志)。 6、栅格图像 - 用一幅放在底层的栅格图像作为地图背景,使您的地图更生动、更详细。目前,主要是配合卫星行片,使地图更加逼真 7、自动标注 - 自动向地图添加标注,同时控制其属性及显示。 8、选择 - 通过分组和组织数据,发挥MapX的分析特性。即在一个指定的半径、矩形区域或指定点的范围内选择地图图元。 图元工厂 - FeatureFactory对象使您得以创建、合并和缓冲区或擦除点、线和区域图元。 工具 - 用户可以通过单击和拖动直接与地图交互。通过MapX内置的导航、选择和标注工具或自定义工具来对地图进行操作。 地图编辑 - 可以让用户在地图上添加、修改或删除图元。 投影和坐标系 - MapX对地图坐标系和投影的完全支持使您可以更精确地调整地图的显示并在自己的坐标系中处理X-Y数据。 9、远程空间服务器连接 - 可以连接运行在Oracle8.0.5、Informix或其他所支持的数据库上的Oracle8i Spatial和MapInfo SpatialWare上存储的真实数据。为集中管理和安全起见,空间服务器允许公司在企业数据库中主持他们的地图数据。象SpatialWare和Oracle8i Spatial之类的空间服务器还提供高级查询处理功能,并增加了用于处理组织机构的空间数据的服务器性能。在一个RDBMS中存储空间数据对于需要进行大量地图编辑和处理大型数据集的应用程序也是必要的。 但需要说明的是,mapinfo公司有专门用于web的maoxtrem  安装 MapX 因为MapX是32位OCX,所以它需要一个32位版本的Windows (Windows 95/98或Windows NT 4.0)。MapX应用程序不能在Windows 3.1 中运行。 下面讲组织数据和地图 要使用 MapX,需要有您的记录和MapInfo地图文件。MapX 以 MapInfo 表的形式组织所有潜在信息。每个表都是一组用来在地图中创建图层的 MapInfo 文件。 文件如何组成表? 所有的 MapInfo 表都会拥有下列文件: <文件名>.tab:描述 MapInfo 表的结构。它是描述包含数据的文件的格式的小文本文件。 <文件名>.dat:(.mdb、.aid 或 .dbf):这些文件含有表格格式数据。 <文件名>.map:描述图形对象(如果表没有地图对象则不存在该文件)。 <文件名>.id:是链接对象和数据的交叉引用文件(如果表没有地图对象则不存在该文件)。 <文件名>.ind:索引文件。索引文件允许使用 Find 对象来查找地图对象。 不熟悉,就讲一下MapInfo 表和 MapX 图层 每个可用地图表示的 MapInfo 表都能在地图上作为图层显示。例如,您可以显示客户表、街道表以及县边界表。 图层是透明的,而每一层都包含了地图的不同部分。这些图层是一层层叠加,这样您就可以看到整个地图信息。    什么是 GeoSets? Geoset 保存了地图图层的集合以及一些对您来说简单易用的设置。其名称的由来是因为 Geosets 是由一些表示同一地理区域的以标准 MapInfo 格式出现的地图文件(.tab)组成的数据集。当您希望将多个图层作为示例地图使用时,会发现单独打开和显示多个图层是件多么费时的工作,Geoset 使您避免这样的情况。Geoset 的扩展名是 .gst。.gst 文件是文本文件,它包含若干用来告诉 MapX 显示什么表以及如何显示的元数据键值。 当打开 Geoset 时,它自动打开所有包括在 Geoset 中的文件并默认显示。开发者可以更改“默认显示”来迎合自己的需要。Geoset 设置包括投影、默认缩放值,对象的自动标注,缩放范围以及打开的表是否可见。MapX 也可以打开开发者指定的任意单个(.tab)地图文件。使用 Geoset 非常方便,无需 MapX 就能运行。MapX 将不会打开 MapInfo 工作空间(.wor 文件类型)。但在地图的组织上相当于MapInfo 工作空间 第三个概念:地图图元 以上是入门 下面讲的也是基础性的  Map 对象 下列图表是 MapX 对象体系的局部,您可以看到 Map 对象存在于最顶端。每个 MapX 的对象、属性和方法都衍生于 Map 对象。每个在 Map 对象之下的属性和方法都会对生成整个 Map 对象有所影响。主要是由 DataSets、Layers 和 Annotations 对象定义每一个 Map 对象。    下表显示了一些由数值表示的 Map 对象属性。可以在“设计时”改变这些属性,也可以在“运行时”使用以下代码示例来更改。 属性 描述 代码示例   Zoom 设置在地图中显示的英里(默认的距离单位)数。 Map1.Zoom = 500   Rotation 对地图旋转指定的度数 Map1.Rotation = 179   CenterX 设置 x 和 y 坐标,它们可能代表经纬度。这是由地图的投影来决定的。 Map1.CenterX = -79.4458   CenterY 设置 x 和 y 坐标,它们可能代表经纬度。这是由地图的投影来决定的。 Map1.CenterY = 44.9932  显示不正常  Zoom 设置在地图中显示的英里(默认的距离单位)数。 Map1.Zoom = 500   Rotation 对地图旋转指定的度数 Map1.Rotation = 179   CenterX 设置 x 和 y 坐标,它们可能代表经纬度。这是由地图的投影来决定的。 Map1.CenterX = -79.4458   CenterY 设置 x 和 y 坐标,它们可能代表经纬度。这是由地图的投影来决定的。 Map1.CenterY = 44.9932  用 Map 对象,可以通过操纵地图的几个方法和属性来控制地图如何来显示。有一些属性是由其他对象来表示的。例如,当您看到 MapX 地图时,也就是看到单独图层的集合,它是由 Layers 集合来表示的。Layers 集合是 Map 对象的属性。 现在让我们来看一看如何改变地图的属性。属性页允许我们操作 Map 对象的多个属性。    上面是属性页,可以直接修改,也可以在程序里修改  下面讲图层 每一幅单独的地图是一个图层,MapX 把地图存储为图层的集合。  区域地图   图层集合还有很多,以后再详细讲 下面是GeoSets  GeoSet 是地图图层及其设置的集合。可以在“设计时”指定GeoSet 。如果在“运行时”设置,则先要删除所有已加载的图层和数据集,然后加载新的 GeoSet。 如前所述,在运行时指定要加载的其他 GeoSet、给地图对象添加图层,或是操作图层的外观等操作都可以通过属性页来实现,或者可以通过与 MapX 一起装载的 MapX Geoset Manager 程序  来实现(此程序可以在 MapX 程序组中找到)。 可以利用GeoSetManager管理工具更改图层设置,当认为满意时,就可以保存地图。这将把 GeoSet 文件(*.GST)写到驱动器中。当打开该 GeoSet 文件时,将返回所有的地图图层和设置。Geoset Manager 使您可以修改图层、管理缩放等级、标注,以及其他属性。 下面是GeoDictionary,数据绑定的 你可以把图片打包,压缩传他 利用MapXz作数据绑定或创建专题地图时,可以用 GeoDictionary来匹配数据源与地图图层。GeoDictionary 是一个保存了关于哪个地图图层可以匹配、哪个字段可以用作匹配字段的信息文件(一般命名为 geodict.dct)。如果想运用自动匹配/自动绑定,则必须在 GeoDictionary 中注册文件。例如,如果拥有按州划分的销售额的数据,那么 GeoDictionary 就可以确定此数据和“USA”地图图层相匹配。 修改 GeoDictionary 如果在做数据绑定时要利用自动匹配,则在 GeoDictionary 里注册 MapInfo表是必要的。在 MapX GeoSet Manager 的工具菜单下有执行GeoDictionary 程序的选项。MapX GeoDictionary 程序允许把新的MapInfo 表注册到 GeoDictionary 中。同时,在 MapX GeoDictionary 中,单击注册表……按钮,然后选择要注册的表,设置表属性并为其输入描述。如果要想自动地把这张表加载到 GeoSet 中,请单击添加按钮然后选择要把表添加进的 GeoSet 。 下面是基础部分的第五个问题:DataSets  DataSets使您可以将数据绑定到地图。例如,如果您有一个按县划分的关于销售额的 MS Access 数据库和一幅县地图,您就可以把数据绑定在这幅县地图上,并可以发现这个按县划分的销售额趋势图,而以表格数据的形式则不容易突出显示该趋势。 如上所示,当 MapX 需要在数据和地图之间指定某个匹配时,该匹配是通过称为自动匹配/自动绑定的处理过程来确定的。如要利用自动匹配/自动绑定,首先必须在 GeoDictionary 中注册地图。一旦将数据和地图绑定,就可以看到相关的地理化信息。数据的直观表示使得专题地图的创建变得可行。专题就是以颜色划分的地图,以该方式来表现数据的变化趋势。我们将在以后章节中详细的讲解专题图的制作。  Annotations 集合是把文本和符号放在地图上的简单方法。注释放在所有其他图层的最顶端,并且不和任何数据链接。如果您熟悉 MapInfo,Annotations的概念在目的上与地图的装饰图层比较相似。 下表列出了 Annotations 集合对象的方法和属性: Annotations 集合方法  表格显示不正常,表格项依次是 方法 描述 代码示例  AddSymbol 向 Annotation 集合添加符号。使用默认样式(由 Map.DefaultStyle 指定)。 Map1.Annotations.AddSymbol  X, Y  AddText 向 Annotation 集合添加文本。第四个参数表示文本在指定坐标系中的初始位置。 Map1.Annotations.AddText _ “Developer Services”, _ 79.44, 46.8889, _ miPositionTL Remove 从集合中删除指定的 Annotation。 Map1.Annotations.Remove 1  RemoveAll 从集合中删除所有的 Annotation。 Map1. Annotations.RemoveAll  Annotation 集合属性    Editable 指定注释是否能够编辑。 Map1.Annotations.Editable _ = True  Type 指定 Annotation 对象类型。 If Map1.Annotations(2).Type_  Graphic 包含了拥有 Annotation 属性的 Graphic 对象。请参阅联机帮助中的 Graphic 对象描述。   请注意在注释对象中没有关于位置、符号样式或是注释的属性。注释的图形属性包含了该信息的图形对象。要修改注释,可修改注释的图形对象。 下列代码在指定位置添加符号: 'Add a symbol at location Map1.Annotations.AddSymbol(X1, Y1);   第七个问题:创建对象 在 MapX 对象模型中,可以使用下列对象类来创建独立对象。  BindLayer  ODBCQueryInfo   BitmapSymbols  点集的集合   Feature  Point   Fields  Points   NotesQueryInfo  Rectangle   NotesViewInfo  Style  Delphi 示例 Var    s : variant; begin      s := CreateOleObject('MapX.Style.4');      s.PickRegion;      MapObject.Layers.Item(1).Style := s; End 一、加载地图数据 1、 TAB的数据分为两种数据:地图数据(Layers)、属性数据(Datasets)。关系:不可分割的一个数据集的两部分. 2、 数据加载:GST文件由GeosetManager40.exe程序生成。在程序使用gsT文件:Map1.Geoset=Filepath+FileName 3、 问题:GST文件加载后,只是默认将地图数据加载,属性数据另外需要使用单独的命令进行加载,否则对属性数据的操作全部非法。加载:Map1.Datasets.ADD 属性数据集名称   4、 另一种加载方式:使用LayerInfo 对象,这种方式下加载地图数据源的地图集和属性集均可直接使用。示例: dim LayerInfo as MapXLib.LayerInfo dim Lyr as Mpxlib.layer                                                                                            LayerInfo.Type = miLayerInfoTypeTab    ‘加载表的类型 LayerInfo.AddParameter FileSpec, FilePath + LayerName + .TAB      ‘加载表 的全路径名 LayerInfo.AddParameter NAME, LayerName   ‘地图集的别名 LayerInfo.AddParameter AutoCreateDataset, 1    ‘是否加载属性数据集 LayerInfo.AddParameter datasetname, LayerName   ‘属性数据集别名   MainMap.Layers.Add LayerInfo    ‘加载到指定的MapX对象中,立即可直接使用   5、 第三种加载数据方式:GST文件+ LayerInfo方式。示例:      使用两个MapX对象:MainMap、TempMap TempMap.Geoset=GST文件 MainMap.geoset=”” TempMap.Refresh   For I=1 to TempMap.Layers.Count FileName=TempMap.Layers.Item(I).Filespec ‘直接引用LayerInfo方式加载地图数据到MainMap Next   二、创建地图对象   必要:创建地图对象,必须使用FeatureFactory对象 1、 创建一个点对象 点对象有一个坐标点(X,Y),点对象变量是Point类型,点对象的样式(Style)是符号 样式。 Dim Pnt AS MapXLib.Point Dim FeaFac AS MapXLib.FeatureFactory Dim Lyr AS MapXLib.Layer Dim Ftr AS MapXLib.Feature Dim NewStyle AS MapXLib.Style   ‘绑定 SET Lyr=MainMap.Layers.Item(LayerName) SET FeaFac=mainmap.featurefactory ‘设置点对象样式 With NewStyle     .SymbolType = miSymbolTypeBitmap     .SymbolBitmapSize = 24     .SymbolBitmapTransparent = False     .SymbolBitmapName = YIEL2-32.BMP End With Mainmap.AutoRedraw=False     ‘禁止自动刷新 Lyr.Editable=True              ‘置当前图层为可写状态 ‘创建点对象 pnt.set X1,Y1 ‘添加进当前图层 Set Ftr=FeaFac. CreateSymbol (Pnt,Newstyle)   ‘创建符号 ‘Set Ftr=FeaFac. CreateSymbol (Pnt,MainMap.DefaultStyle) ‘添加 Lyr.AddFeature Ftr Lyr.Refresh Mainmap.AutoRedraw=True Lyr.Editable=False ‘释放 SET Pnt = Nothing SET FeaFac  = Nothing SET Lyr  = Nothing SET Ftr  = Nothing ‘以上代码放在MapX的ToolUsed事件下   单独修改某个图元的样式:SET Ftr.Style=NewStyle,再用Update 即可 2、 创建一个线矩形 Dim Pnts AS MapXLib.Points   With NewStyle     .LineColor=Rgb(0, 0,255) End With ‘第一个点 Pnt.Set X1,Y1 Pnts.add Pnt ‘第二个点 Pnt.Set X2,Y1 Pnts.add Pnt ‘第三个点 Pnt.Set X2,Y2 Pnts.add Pnt ‘第四个点 Pnt.Set X1,Y2 Pnts.add Pnt ‘第五个点 Pnt.Set X1,Y1 Pnts.add Pnt   ‘创建线矩形 SET Ftr=FeaFac.CreateLine(Pnts,NewStyle) Lyr.AddFeature Ftr Lyr.Refresh   3、 上面创建对象中存在的问题:并未对其数据数据进行赋值 创建对象的同时创建其数据集合 Dim Pnt AS MapXLib.Point Dim FeaFac AS MapXLib.FeatureFactory Dim Lyr AS MapXLib.Layer Dim Ftr AS MapXLib.Feature Dim NewStyle AS MapXLib.Style Dim ds AS MapXLib.Dataset Dim Flds AS MapXLib.Fields    ‘绑定 SET Lyr=MainMap.Layers.Item(LayerName) SET ds=Lyr.Datasets.Item(1) Set Flds=ds.Fields SET FeaFac=mainmap.featurefactory ‘设置点对象样式 With NewStyle     .SymbolType = miSymbolTypeBitmap     .SymbolBitmapSize = 24     .SymbolBitmapTransparent = False     .SymbolBitmapName = YIEL2-32.BMP End With Mainmap.AutoRedraw=False     ‘禁止自动刷新 Lyr.Editable=True              ‘置当前图层为可写状态 ‘创建点对象 pnt.set X1,Y1 ‘创建图形 Set Ftr=FeaFac. CreateSymbol (Pnt,Newstyle)   ‘创建符号 ‘Set Ftr=FeaFac. CreateSymbol (Pnt,MainMap.DefaultStyle) ‘设置属性 For I=1 to Flds.Count Lyr.KeyFields=Flds.Item(i).Name Ftr.KeyValue=ValueStr(I)   ‘这里并没有对字段类型进行判断 Next ‘另外一种方法:使用RowValues和RowValue对象 ‘添加 Lyr.AddFeature Ftr Lyr.Refresh Mainmap.AutoRedraw=True Lyr.Editable=False ‘释放 SET Pnt = Nothing SET FeaFac  = Nothing SET Lyr  = Nothing SET Ftr  = Nothing   SET ds = Nothing SET Flds  = Nothing 4、 创建表 (1) 临时表: A、用MainMap.Layers.CreateLayer方法创建临时表。但这个临时表只有一个字段:GeoNa me( Char 24)。程序运行过程中该表存放位置为系统临时文件夹下 B、使用LayerInfo对象创建临时表,可以指定字段。示例:     Dim Lyr As MapXLib.Layer   Dim LayerInfo As New MapXLib.LayerInfo   Dim Flds As New MapXLib.Fields    ‘字段定义   Flds.AddStringField ID, 12   Flds.AddStringField Name, 50   Flds.AddNumericField Deptch, 12, 2   Flds.AddIntegerField Length      ´   LayerInfo.Type = miLayerInfoTypeTemp   LayerInfo.AddParameter FileSpec, FileName   LayerInfo.AddParameter NAME, LayerName   LayerInfo.AddParameter Fields, Flds      Set Lyr = MainMap.Layers.Add(LayerInfo, 1)      Set Lyr = Nothing   Set LayerInfo = Nothing   (2) 创建永久表   Dim Lyr As MapXLib.Layer   Dim LayerInfo As New MapXLib.LayerInfo   Dim Flds As New MapXLib.Fields      Flds.AddStringField ID, 12   Flds.AddStringField Name, 50   Flds.AddNumericField Deptch, 12, 2   Flds.AddIntegerField Length      ´   LayerInfo.Type = miLayerInfoTypeNewTable   LayerInfo.AddParameter FileSpec, FilePath + + FileName   LayerInfo.AddParameter NAME, LayerName   LayerInfo.AddParameter Fields, Flds      Set Lyr = MainMap.Layers.Add(LayerInfo, 1)      Set Lyr = Nothing   Set LayerInfo = Nothing   5、 创建工具句柄 系统已经定义工具句柄都以整数(包括16进制)常数存在,句柄号大于1000和小于12基本都为系统使用。 A. 定义常数:必须为全局变量 Global Const CreateSymbolTool = 13   ´创建节点 Global Const CreateLineTool = 15     ´创建管线 Global Const InfoTipTool = 16        ´信息工具 Global Const MoveFeature = 17        ´移动地图 Global Const ScaleDistanceTool = 18  ´测量两点间的距离   B. 使用CreateCustomTool创建新的工具句柄: MainMap.CreateCustomTool CreateSymbolTool, miToolTypePoint, miSymbolCursor MainMap.CreateCustomTool CreateLineTool, miToolTypeLine, miCrossCursor MainMap.CreateCustomTool InfoTipTool, miToolTypePoint, miCrossCursor MainMap.CreateCustomTool MoveFeature, miToolTypeLine, miPanCursor MainMap.CreateCustomTool ScaleDistanceTool, miToolTypeLine, miPanCursor C. 如何使用?  在Map对象的ToolUsed事件的ToolNum参数为当前所激活的工具使当前操作指向某行为:MainMap.CurrentTool=工具句柄号,如放大:MainMap.CurrentTool=miZoomInTool,移动图元:MainMap.CurrentTool=MoveFeature 操作具体的工具句柄时,执行该捕捉到的工具句柄的代码: 在ToolUsed事件中:   Select Case ToolNum    Case MoveFeature       ‘执行代码 End Select   删除图元:Lyr.DeleteFeature Ftr   三、查询   1、 属性查找。Find、Search方法:注意的是Find方法只支持TAB表文件,不支持空间数据表。 Find :与FoxPro中Locate定位命令想类似。 Search:支持SQL语句。写法:仅指SQL语句的WHERE 部分,且From语句中只能有一个表——仅对单表进行操作: Select * from LayerName WHERE ID LIKE “%北京%” 示例: A、查找 Dim Ftrs AS MapXlib.Features     ‘图元集合   SET Ftrs=Lyr.Search(“ID LIKE ““%北京%”””) For I=1 to Ftrs.Count    ‘执行语句 Next B、高亮显示 Lyr.Selection.Replace Ftrs    ‘将当前查询所得的结果集全部高亮显示(隐含执行:Lyr.ClearSelection语句)——加入selection集合闪烁:不能用Selection,否则会对整个屏幕进行整个刷新(抖动)。使用更新Style的方法进行选定图元的闪烁。 记载图元的老样式:S et Oldsytle=Ftr.Style   Lyr.Selection.Add Ftrs    ‘将当前查询所得的结果集添加到已有的结果集中,再全部高亮显示 C、对查询的结果集进行属性修改 示例程序:完成的是Professional中信息工具功能 Dim ds AS MapXlib.Dataset Dim Flds AS MapXlib.Fields Dim Ftr AS MapXlib.Feature   Set Lyr=MainMap.Layers.Item(LayerName) Set ds=Lyr.Datasets.item(1) Set Flds=ds.Fields ‘查找 SET Ftrs=Lyr.Search(“ID LIKE ““%北京%”””) If Ftrs.count=0 then exit sub   ‘读取属性值 For I=1 to Ftrs.Count    Set Ftr=Ftrs.Item(I)    For j=1 to Flds.count FldsName(J)=Flds.Item(J).Name    ‘字段列表 Lyr.KeyField=FldsName(J)   ValueStr(I,J)=Ftr.KeyValue        ‘值列表    Next Next   ‘修改属性 MainMap.AuyoRedraw=False Lyr.Editable=True   For j=1 to Flds.count Lyr.KeyField= Flds.Item(J).Name Ftrs.Item(j).KeyValue =ValueStr(J)     ‘更新值列表 Ftrs.Item(j).Update True Next   Lyr.Refresh Lyr.Editable=False MainMap.AuyoRedraw=True   ‘修改样式 Dim NewStyle AS MapXlib.Style   With NewStyle ‘设置样式 End With   MainMap.AuyoRedraw=False Lyr.Editable=True   For i=1 to Ftrs.count Set Ftr =Ftrs.Item(I) SET Ftr.Style=NewStyle        ‘更新样式 Ftr.Update True Next   Lyr.Refresh Lyr.Editable=False MainMap.AuyoRedraw=True   2、 空间查找 ² 点查找:SearchAtPoint,结果集为Features类型 Dim Pnt AS MapXlib.Point   Pnt.Set X,Y Set Ftrs=Lyr.SearchAtPoint(Pnt,miSearchResultAll) For I=1 to Ftrs.Count    ‘执行语句 Next 注意:点查找时,一般情况下结果集在一个以上的图层都存在。所以取值时应分别提取   ² 园查找:在临时图层上画一个不保存的圆,然后查找被这个圆所包含的所有图层的图元对象。 Dim Pnt AS MapXlib.Point Dim TempCir AS MapXlib.Feature Dim FeaFac AS MapXLIB.featurefactory   Pnt.Set X,Y Set tempcir=FeaFac.CreateCircularRegion(miCircleTypeMap ,Pnt,1, MainMap.MapUni t,,)   ‘miSearchTypeCentroidWithin :中心点包含 ‘miSearchTypePartiallyWithin :部分包含 ‘miSearchTypeEntirelyWithin :全部包含   Set Ftrs=Lyr.SearchWithinFeature (TempCir, miSearchTypePartiallyWithin)   For I=1 to Ftrs.Count    ‘执行语句 Next   SET Pnt =Nothing set TempCir =Nothing set FeaFac =Nothing   3、 相交 判断两个图元是否有交点以及交点坐标信息。 (1)判断是否相交 IF Lyr.IntersectionTest( ftr1, ftr2, miIntersectFeature ) THEN    ‘交点 END IF   (2)获取相交点坐标信息 ‘交点 Dim Ftr AS MapXlib.Feature   SET Ftr=MainMap.FeatureFactory. IntersectFeatures(Ftr1,Ftr2) ‘交点坐标信息 For J=1 to Ftr.parts.item(1).count     X1= Ftr.parts.item(1).Item(J).X     Y1= Ftr.parts.item(1).Item(J).Y Next   4、 测距 使用Map对象的Distance方法。如何测量任意多边形的周长? 使用累加的方法,还要使用图元节点集合。 DistanceValue=0 ‘第一个点 Pnt.Set Ftr.Parts.Item(1).Item(1).X, Ftr.Parts.Item(1).Item(1).Y For j=2 TO Ftr.Parts.Item(1).Count    ‘累加    X1= Ftr.Parts.Item(1).Item(j-1).X    Y1= Ftr.Parts.Item(1).Item(j-1).Y    X2= Ftr.Parts.Item(1).Item(j).X Y2= Ftr.Parts.Item(1).Item(j).Y    DistanceValue = DistanceValue +MainMap.Distance(X1, Y1, X2, Y2) Next ‘多边形周长 Msgbox DistanceValue+” ”+MainMap.MapUnit   四、对象编辑   (1)、对属性的编辑 主要使用Fields对象。示例: Dim Flds AS MapXlIB.Fields   ‘修改当前图层的每一个字段 For J=1 to Flds.Count Lyr.KeyField= Flds.Item(j).Name ‘使当前图层指向J字段   ‘更新当前图元的J字段值   Ftr.KeyValue=NewValueStr(J)   Ftr.Update True    ‘并未写入硬盘 Next Lyr.Refresh      ‘保存修改到硬盘   (2)、移动地图 首先创建一个移动工具句柄 MainMap.CreateCustomTool MoveFeature, miToolTypeLine, miPanCursor 在Map对象的ToolUsed事件的ToolNum参数为当前所激活的工具捕捉MoveFeature工具句柄‘传过来的参数:X1,Y1,X2,Y2 Select case ToolNum    ……..    Case  MoveFeature Dim Lyr AS MapXlib.Layer Dim Ftr AS MapXlib.Feature Dim Ftrs AS MapXlib.Features   Dim Xe,Ye AS Double     ‘坐标偏移量   Xe=X2-X1 Ye=Y2-Y1   Set Lyr=Mainmap.Layers.Item(LayerName) Set Ftrs=Lyr.Selection.Clone      ‘将当前图层中选定的集合复制到Ftrs变量中 MainMap.AutoRedraw=False Lyr.Editable=True For J=1 to Ftrs.Count    Set Ftr=Ftrs.Item(J)    Ftr.Offset Xe,Ye    Ftr.Update True Next Lyr.Refresh Lyr.Editable=False MainMap.AutoRedraw=True   SET lyr=Nothing SET Ftr=Nothing End Select (3)、样式更新  Dim NewStyle AS MapXLib.Style   ‘初始赋值 Set Lyr=MainMap.Layers.Item(LayerName) Set Ftrs=Lyr.AllFeatures Set NewStyle=Ftrs.Item(1).Style ‘设置样式 With NewStyle     .SymbolType = miSymbolTypeBitmap     .SymbolBitmapSize = 24     .SymbolBitmapTransparent = False     .SymbolBitmapName = YIEL2-32.BMP End With ‘更新 MainMap.AutoRedraw=False Lyr.Editable=True SET Ftr.Style=NewStyle Ftr.Update True Lyr.Refresh Lyr.Editable=False MainMap.AutoRedraw=True   五、输出   1、属性的输出   输出到EXCEL表: For I=1 to Flds.Count Lyr.KeyFields=Flds.Item(i).Name Excel(1,I).Cell=Ftr.KeyValue Next 2、复制、粘贴 Global CopyFtrs AS MapXlib.Features   Set lyr=mainmap.Layers.item(LayerName) Set Ftrs=Lyr.Selection.Clone      ‘复制选中集合 ‘复制 For I=1 to Ftrs.Count CopyFtrs.add Ftrs.Item(I) Next   ‘粘贴(图形) Set lyr_1=mainmap.Layers.item(LayerName_1) Mainmap.AutoRedraw=False Lyr_1.Editabled=True For J=1 to CopyFtrs.Count    Lyr_1.AddFeature CopyFtrs.Item(J) Next Lyr_1.Refresh Mainmap.AutoRedraw=True Lyr_1.Editabled=False   3、地图的打印   Dim iScaleMode As Integer     iScaleMode = MainMap.Container.ScaleMode   MainMap.Container.ScaleMode = 6     On Error GoTo PrinterError      Printer.Print   Printer.CurrentX = 0   Printer.CurrentY = 0   MainMap.PrintMap Printer.hDC, 0, 0, MainMap.Width * 100, MainMap.Height * 10 0   Printer.NewPage   Printer.EndDoc   MainMap.Container.ScaleMode = iScaleMode   Exit Sub    PrinterError:   If Err.Number = 482 Then      On Error Resume Next      CommonDialog1.Flags = &H40      CommonDialog1.ShowPrinter   Else      MsgBox     打印机存在错误,请更正后重试。错误号: + (Str(Err.Number)), , 失败   End If      4、另存为图片文件 MainMap.ExportMap(App.Path+”Images”, miFormatJPEG)   ‘输出当前地图窗口 参数设置:MainMap.ExportSelection=True   ‘将选中部分以不同于其他未选中地图部分 形式输出   六、专题图   6种专题图:除独立值专题图绑定的字段类型可以是字符的以外,都必须是数字类型。与其 他数据源绑定时,使用ODBC 调用ThemeDlg对话框可以让用户自己定义专题图。示例: For Each ftr In lyr.Selection  ' The children of the layer are the individual  ' features    Set ftrNode = QueryTree.Nodes.Add(lyrNode, tvwChild,lyr.Name _    & ftr.Name & Str$(ftr.FeatureID), ftr.Name)    For Each fld In ds.Fields     ' Each feature has data attached to it; add  this data as a child of the feature     lyr.KeyField = fld.Name     QueryTree.Nodes.Add ftrNode, tvwChild, , lyr.KeyField _     & : & ftr.KeyValue    Next   Next   七、在MapX下紧缩表   在Professional里面,紧缩表用 Pack Table 语句完成。而在MapX中则需要使用临时图层 ,并用复制技术来完成。示例: ‘紧缩当前Map对象中的所有图层    Dim LayerInfo As New MapXLib.LayerInfo    Dim Lyr As MapXLib.Layer    Dim LyrTemp As MapXLib.Layer    Dim Flds As MapXLib.Fields    Dim Ds As MapXLib.Dataset        Dim I As Integer    Dim LayerName, FilePath As String        On Error Resume Next        For I = MainMap.Layers.Count To 1 Step -1       ´复制源表数据到临时表       Set Lyr = MainMap.Layers.Item(I)       Set Ds = Lyr.Datasets.Item(1)       Set Flds = Ds.Fields              LayerName = Lyr.Name              LayerInfo.Type = miLayerInfoTypeTemp       LayerInfo.AddParameter FileSpec, LayerName       LayerInfo.AddParameter NAME, LayerName      LayerInfo.AddParameter Features, Lyr.AllFeatures‘复制所有有效图元       LayerInfo.AddParameter Fields, Flds    ’复制字段列表              LayerInfo.AddParameter AutoCreateDataset, 1       LayerInfo.AddParameter datasetname, LayerName Set LyrTemp = MapTemp.Layers.Add(LayerInfo, 1)    ‘复制到另外Map对象              ´删除源表       Set Lyr = Nothing       FilePath = MainMap.Layers.Item(I).Filespec       LayerName = Mid(FilePath, InStr(1, FilePath, Maps) + 6, Len(FilePath) - InStr(1, FilePath, Maps))       FilePath = Mid(FilePath, 1, InStr(1, FilePath, Maps) + 5)       LayerName = Mid(LayerName, 1, Len(LayerName) - 4)              MainMap.Layers.Remove (I)       MainMap.Refresh              Kill FilePath + LayerName + .TAB              ´复制临时表数据到源表       Set LyrTemp = MapTemp.Layers.Item(LayerName)         LayerInfo.Type = miLayerInfoTypeNewTable       LayerInfo.AddParameter FileSpec, FilePath + LayerName + .TAB       LayerInfo.AddParameter NAME, LayerName       LayerInfo.AddParameter Features, LyrTemp.AllFeatures       LayerInfo.AddParameter Fields, Flds                LayerInfo.AddParameter AutoCreateDataset, 1       LayerInfo.AddParameter datasetname, LayerName       Set Lyr = MainMap.Layers.Add(LayerInfo, 1)              ´删除临时表       MapTemp.Layers.Remove (MapTemp.Layers.Count)       MapTemp.Refresh    Next           Set Lyr = Nothing    Set Ds = Nothing    Set Flds = Nothing    Set LayerInfo = Nothing   八、如何和大型数据库关联   系统是混合结构:对地图的访问使用的是文件访问方式,对属性数据的访问使用的是大型数据库形式使用ID关联:在TAB表和数据库中有ID字段,两个字段作为唯一值关联字段。(一对一的关系)。示例:   Lyr.KeyField=”ID” Set Ftr=Ftrs.Item(J)   ‘SQL语句查找对应的属性信息 SampleAdo.RecordSource =”Select a.id as id,b.name as name from Table1 a, Tabl e2 b WHERE (a.id=b.id) AND ( a.id LIKE ‘%“ +Ftr.KeyValue+“%’)”   九、空间数据库   ’空间数据库中的索引技术用的是R_Tree技术,而不是原来一般意义上的B_Tree索引技术。 ’空间数据在Spatial中以地理属性信息形式存放。 ’在Oracle的版本中有如下需要注意事项: a) Oracle 8.1.5这个版本中,首次引入Spatial组件。使用上非常不好:图形的样式非常单一,且为黑白的而非彩色,上载地图数据时,数据丢失非常严重。存取数据时非常慢。在Spatial中自动创建prinx字段作为地图索引主关键字段 b) Oracle 8.1.6版本:图形为彩色的,增加了样式的支持,但不支持同一图层下的多样式(主要指点对象)。创建地图数据时,地图的坐标常发生偏移。属性数据更新时,需要两次刷新才能完整提交;地图数据数据提交时,其坐标发生偏移:向原点偏移,需要认为地单独将其移动到其初始创建位置。存取速度上还是比较慢,离实用尚有一定距离。在Spatial中自动创建mi_prinx字段作为地图索引主关键字段 ² Oracle 8.1.7版本:支持多样式,数据上载丢失非常小(只有文本对象存在丢失的记录)。在地图数据存取不是很大的时候,速度上可以被用户接受。 ² 如何将MapInfo 的TAB表内容上传到Oracle 中? a) 免费工具:easyloader6.7(Oracle 8.1.7),下载322555现场开奖,香港马会开奖结果直播:www.mapinfo.com.cn b) 如何上载?注意:上载之前对Tab表进行紧缩。 c) 在程序中如何使用空间数据库中的地图数据? d) 添加地图时,必须指定字段mi_prinx的明确值,且该值不能为表中已存在的值。写入地图数据时,应将其全部NOT NULL 字段值赋给,否则保存失败。 e) 示例:Tab表+空间数据表 的数据分布形式。   十、GIS应用的分发   1、 制作你自己的系统的安装盘:可执行文件、必要系统文件、运行库文件、其他数据文件。 2、 单独的MapX安装盘:MapInfo MapX Runtime安装程序,实际上是MapX控件安装程序(存在于MapX sdk包) 3、 注册:安装完成以后,运行GeosetManager40.exe程序获得硬件ID号,然后通过EMAIL的形式将该ID号发送到MapX产品供应商申请正式的许可文件(mapx40.lic)。获得后覆盖原mapx40.lic文件即可。注意:硬盘格式化后该ID号失效。   十一、构造一个GIS应用系统   需求:鹰眼功能、拓扑关系、不同图形不同颜色表现、数据绑定、系统性能。   结构分析:做基于TAB文件的GIS系统 1、 鹰眼功能 (1) 建立两个Form对象,将两个Map对象分别放在这两个窗口对象中。 (2) 一个小窗口作为鹰眼窗口,大 窗口作为主地图窗口。鹰眼窗口中的Map对象的视野应很大,而主地图窗口的视野根据需要设置。 (3) 两个窗口中加载不同的GST文件。需要的是主地图窗口的显示范围应为鹰眼窗口中某个矩形所包含的地图对象范围。 (4) A、在鹰眼窗口中画一个矩形(Rect为矩形对象),B、主地图窗口执行 Set MainMap.Bounds = Rect (5) 需要注意的是:鹰眼窗口与主地图窗口两者间的坐标投影系统应完全一致。   2、 拓扑关系 实际上就是图元与图元的空间关系。说历史:原来建立拓扑关系使用的是属性关联。 点查询、圆查询、矩形查询、多边形查询等这些是属于简单空间关系的对比。而对拓扑关系的查询多数情况下使用Parts对象来解决。 Ftr1与另一个Ftr2的空间关联:先找到Ftr1的其止节点,然后以这个节点为中心画一个非常小的圆,在这个圆范围内的某个设备可认为与该Ftr1相连。 判断某个图元在指定图层上的相交对象集合: Set Ftrs=Lyr.SearchWithinFeature (SearchFtr, miSearchTypePartiallyWithin)   3、 不同图形不同颜色表现 (1)更新样式   再结合临时图层就可以很好解决(使用图层刷新)。而且刷新时不会引起整个Map对象的刷新(屏幕抖动) (2)专题图   存在更新属性值后不能实时刷新专题图的问题。 4、 数据绑定 对未绑定的属性集合使用 MainMap.Datasets.ADD 地图集合和属性集合为一个数据集合的不可分割的两个部分 5、 系统性能 速度是否为用户所接受、系统是否稳定(界面要求)、修改数据数据的时候是否存在数据一致性维护问题、造价是否合理。 (1)速度:使用数据分布可以较好地解决:地图数据:地形图数据以文件形式存放,业务地图数据存放在空间数据库中;属性数据:全部存放在大型数据库中。   (2)系统是否稳定(界面要求):A、字段全部用英文,B、地图拓扑关系在进入系统以前进行必要的验证,C、文件地图数据中字段数减少到最小,可使访问属性频率大大减少,可有效保证其他用户访问时不会大量出现访问拒绝的现象;D、数据提交时尽可能采用事务机制:事务开始:  Lyr.BeginAccess,事务结束:Lyr.EndAccess;E、数据修改提交时尽可能采用批量提交。至于界面要求,应主要满足从地图对象获取相关的要求。   (3)数据一致维护:遵循图元优先的原则。图形对象必须首先存在,其他相关信息在此基础上建立。注意: ² 修改时应先修改地图对象,后提交属性信息 ² 删除时应先删除其他信息,最后删除图形信息 (4)造价  这里主要指平台费用。A、现有数据格式,B、功能要求:空间分析是否复杂、地图图层是否分散、系统中地图输出的质量要求、系统中统计分析复杂程度是否较繁琐、直接的平台使用用户数(并发数)。 MapX快速开发教程 文章来源: 文章作者: 2006-07-08  字体:[大 中 小]  我要投稿! 一、加载地图数据 1、 TAB的数据分为两种数据:地图数据(Layers)、属性数据(Datasets)。关系:不可分割的一个数据集的两部分. 2、 数据加载:GST文件由GeosetManager40.exe程序生成。在程序使用gsT文件:Map1.Geoset=Filepath+FileName 3、 问题:GST文件加载后,只是默认将地图数据加载,属性数据另外需要使用单独的命令进行加载,否则对属性数据的请注意作全部非法。加载:Map1.Datasets.ADD 属性数据集名称 4、 另一种加载方式:使用LayerInfo 对象,这种方式下加载地图数据源的地图集和属性集均可直接使用。示例: dim LayerInfo as MapXLib.LayerInfo dim Lyr as Mpxlib.layer LayerInfo.Type = miLayerInfoTypeTab ‘加载表的类型 LayerInfo.AddParameter "FileSpec", FilePath + LayerName + ".TAB" ‘加载表 的全路径名 LayerInfo.AddParameter "NAME", LayerName ‘地图集的别名 LayerInfo.AddParameter "AutoCreateDataset", 1 ‘是否加载属性数据集 LayerInfo.AddParameter "datasetname", LayerName ‘属性数据集别名 字串1 MainMap.Layers.Add LayerInfo ‘加载到指定的MapX对象中,立即可直接使用 5、 第三种加载数据方式:GST文件+ LayerInfo方式。示例: 使用两个MapX对象:MainMap、TempMap TempMap.Geoset=GST文件 MainMap.geoset=”” TempMap.Refresh For I=1 to TempMap.Layers.Count FileName=TempMap.Layers.Item(I).Filespec ‘直接引用LayerInfo方式加载地图数据到MainMap Next 二、创建地图对象 必要:创建地图对象,必须使用FeatureFactory对象 1、 创建一个点对象 点对象有一个坐标点(X,Y),点对象变量是Point类型,点对象的样式(Style)是符号 样式。 Dim Pnt AS MapXLib.Point Dim FeaFac AS MapXLib.FeatureFactory Dim Lyr AS MapXLib.Layer Dim Ftr AS MapXLib.Feature Dim NewStyle AS MapXLib.Style ‘绑定 SET Lyr=MainMap.Layers.Item(LayerName) SET FeaFac=mainmap.featurefactory ‘设置点对象样式 字串8 With NewStyle .SymbolType = miSymbolTypeBitmap .SymbolBitmapSize = 24 .SymbolBitmapTransparent = False .SymbolBitmapName = "YIEL2-32.BMP" End With Mainmap.AutoRedraw=False ‘禁止自动刷新 Lyr.Editable=True ‘置当前图层为可写状态 ‘创建点对象 pnt.set X1,Y1 ‘添加进当前图层 Set Ftr=FeaFac. CreateSymbol (Pnt,Newstyle) ‘创建符号 ‘Set Ftr=FeaFac. CreateSymbol (Pnt,MainMap.DefaultStyle) ‘添加 Lyr.AddFeature Ftr Lyr.Refresh Mainmap.AutoRedraw=True Lyr.Editable=False ‘释放 SET Pnt = Nothing SET FeaFac = Nothing SET Lyr = Nothing SET Ftr = Nothing ‘以上代码放在MapX的ToolUsed事件下 单独修改某个图元的样式:SET Ftr.Style=NewStyle,再用Update 即可 2、 创建一个线矩形 Dim Pnts AS MapXLib.Points With NewStyle .LineColor=Rgb(0, 0,255) End With ‘第一个点 字串1 Pnt.Set X1,Y1 Pnts.add Pnt ‘第二个点 Pnt.Set X2,Y1 Pnts.add Pnt ‘第三个点 Pnt.Set X2,Y2 Pnts.add Pnt ‘第四个点 Pnt.Set X1,Y2 Pnts.add Pnt ‘第五个点 Pnt.Set X1,Y1 Pnts.add Pnt ‘创建线矩形 SET Ftr=FeaFac.CreateLine(Pnts,NewStyle) Lyr.AddFeature Ftr Lyr.Refresh 3、 上面创建对象中存在的问题:并未对其数据数据进行赋值 创建对象的同时创建其数据集合 Dim Pnt AS MapXLib.Point Dim FeaFac AS MapXLib.FeatureFactory Dim Lyr AS MapXLib.Layer Dim Ftr AS MapXLib.Feature Dim NewStyle AS MapXLib.Style Dim ds AS MapXLib.Dataset Dim Flds AS MapXLib.Fields ‘绑定 SET Lyr=MainMap.Layers.Item(LayerName) SET ds=Lyr.Datasets.Item(1) Set Flds=ds.Fields SET FeaFac=mainmap.featurefactory ‘设置点对象样式 With NewStyle .SymbolType = miSymbolTypeBitmap 字串9 .SymbolBitmapSize = 24 .SymbolBitmapTransparent = False .SymbolBitmapName = "YIEL2-32.BMP" End With Mainmap.AutoRedraw=False ‘禁止自动刷新 Lyr.Editable=True ‘置当前图层为可写状态 ‘创建点对象 pnt.set X1,Y1 ‘创建图形 Set Ftr=FeaFac. CreateSymbol (Pnt,Newstyle) ‘创建符号 ‘Set Ftr=FeaFac. CreateSymbol (Pnt,MainMap.DefaultStyle) ‘设置属性 For I=1 to Flds.Count Lyr.KeyFields=Flds.Item(i).Name Ftr.KeyValue=ValueStr(I) ‘这里并没有对字段类型进行判断 Next ‘另外一种方法:使用RowValues和RowValue对象 ‘添加 Lyr.AddFeature Ftr Lyr.Refresh Mainmap.AutoRedraw=True Lyr.Editable=False ‘释放 SET Pnt = Nothing SET FeaFac = Nothing SET Lyr = Nothing SET Ftr = Nothing SET ds = Nothing SET Flds = Nothing 4、 创建表 (1) 临时表: A、用MainMap.Layers.CreateLayer方法创建临时表。但这个临时表只有一个字段:GeoNa 字串4 me( Char 24)。程序运行过程中该表存放位置为系统临时文件夹下 B、使用LayerInfo对象创建临时表,可以指定字段。示例: Dim Lyr As MapXLib.Layer Dim LayerInfo As New MapXLib.LayerInfo Dim Flds As New MapXLib.Fields ‘字段定义 Flds.AddStringField "ID", 12 Flds.AddStringField "Name", 50 Flds.AddNumericField "Deptch", 12, 2 Flds.AddIntegerField "Length" ´ LayerInfo.Type = miLayerInfoTypeTemp LayerInfo.AddParameter "FileSpec", FileName LayerInfo.AddParameter "NAME", LayerName LayerInfo.AddParameter "Fields", Flds Set Lyr = MainMap.Layers.Add(LayerInfo, 1) Set Lyr = Nothing Set LayerInfo = Nothing (2) 创建永久表 Dim Lyr As MapXLib.Layer Dim LayerInfo As New MapXLib.LayerInfo Dim Flds As New MapXLib.Fields Flds.AddStringField "ID", 12 字串8 Flds.AddStringField "Name", 50 Flds.AddNumericField "Deptch", 12, 2 Flds.AddIntegerField "Length" ´ LayerInfo.Type = miLayerInfoTypeNewTable LayerInfo.AddParameter "FileSpec", FilePath + "" + FileName LayerInfo.AddParameter "NAME", LayerName LayerInfo.AddParameter "Fields", Flds Set Lyr = MainMap.Layers.Add(LayerInfo, 1) Set Lyr = Nothing Set LayerInfo = Nothing 5、 创建工具句柄 系统已经定义工具句柄都以整数(包括16进制)常数存在,句柄号大于1000和小于12基本都为系统使用。 A. 定义常数:必须为全局变量 Global Const CreateSymbolTool = 13 ´创建节点 Global Const CreateLineTool = 15 ´创建管线 Global Const InfoTipTool = 16 ´信息工具 Global Const MoveFeature = 17 ´移动地图 Global Const ScaleDistanceTool = 18 ´测量两点间的距离 B. 使用CreateCustomTool创建新的工具句柄: 字串9 MainMap.CreateCustomTool CreateSymbolTool, miToolTypePoint, miSymbolCursor MainMap.CreateCustomTool CreateLineTool, miToolTypeLine, miCrossCursor MainMap.CreateCustomTool InfoTipTool, miToolTypePoint, miCrossCursor MainMap.CreateCustomTool MoveFeature, miToolTypeLine, miPanCursor MainMap.CreateCustomTool ScaleDistanceTool, miToolTypeLine, miPanCursor C. 如何使用? 在Map对象的ToolUsed事件的ToolNum参数为当前所激活的工具使当前请注意作指向某行为:MainMap.CurrentTool=工具句柄号,如放大:MainMap.CurrentTool=miZoomInTool,移动图元:MainMap.CurrentTool=MoveFeature 请注意作具体的工具句柄时,执行该捕捉到的工具句柄的代码: 在ToolUsed事件中: Select Case ToolNum Case MoveFeature ‘执行代码 End Select 删除图元:Lyr.DeleteFeature Ftr 三、查询 1、 属性查找。Find、Search方法:注意的是Find方法只支持TAB表文件,不支持空间数据表。 Find :与FoxPro中Locate定位命令想类似。 字串5 Search:支持SQL语句。写法:仅指SQL语句的WHERE 部分,且From语句中只能有一个表——仅对单表进行请注意作: Select * from LayerName WHERE ID LIKE “%北京%” 示例: A、查找 Dim Ftrs AS MapXlib.Features ‘图元集合 SET Ftrs=Lyr.Search(“ID LIKE ““%北京%”””) For I=1 to Ftrs.Count ‘执行语句 Next B、高亮显示 Lyr.Selection.Replace Ftrs ‘将当前查询所得的结果集全部高亮显示(隐含执行:Lyr.ClearSelection语句)——加入selection集合闪烁:不能用Selection,否则会对整个屏幕进行整个刷新(抖动)。使用更新Style的方法进行选定图元的闪烁。 记载图元的老样式:Set Oldsytle=Ftr.Style Lyr.Selection.Add Ftrs ‘将当前查询所得的结果集添加到已有的结果集中,再全部高亮显示 C、对查询的结果集进行属性修改 示例程序:完成的是Professional中信息工具功能 Dim ds AS MapXlib.Dataset Dim Flds AS MapXlib.Fields Dim Ftr AS MapXlib.Feature 字串3 Set Lyr=MainMap.Layers.Item(LayerName) Set ds=Lyr.Datasets.item(1) Set Flds=ds.Fields ‘查找 SET Ftrs=Lyr.Search(“ID LIKE ““%北京%”””) If Ftrs.count=0 then exit sub ‘读取属性值 For I=1 to Ftrs.Count Set Ftr=Ftrs.Item(I) For j=1 to Flds.count FldsName(J)=Flds.Item(J).Name ‘字段列表 Lyr.KeyField=FldsName(J) ValueStr(I,J)=Ftr.KeyValue ‘值列表 Next Next ‘修改属性 MainMap.AuyoRedraw=False Lyr.Editable=True For j=1 to Flds.count Lyr.KeyField= Flds.Item(J).Name Ftrs.Item(j).KeyValue =ValueStr(J) ‘更新值列表 Ftrs.Item(j).Update True Next Lyr.Refresh Lyr.Editable=False MainMap.AuyoRedraw=True ‘修改样式 Dim NewStyle AS MapXlib.Style With NewStyle ‘设置样式 字串9 End With MainMap.AuyoRedraw=False Lyr.Editable=True For i=1 to Ftrs.count Set Ftr =Ftrs.Item(I) SET Ftr.Style=NewStyle ‘更新样式 Ftr.Update True Next Lyr.Refresh Lyr.Editable=False MainMap.AuyoRedraw=True 2、 空间查找 ² 点查找:SearchAtPoint,结果集为Features类型 Dim Pnt AS MapXlib.Point Pnt.Set X,Y Set Ftrs=Lyr.SearchAtPoint(Pnt,miSearchResultAll) For I=1 to Ftrs.Count ‘执行语句 Next 注意:点查找时,一般情况下结果集在一个以上的图层都存在。所以取值时应分别提取 ² 园查找:在临时图层上画一个不保存的圆,然后查找被这个圆所包含的所有图层的图元对象。 Dim Pnt AS MapXlib.Point Dim TempCir AS MapXlib.Feature Dim FeaFac AS MapXLIB.featurefactory Pnt.Set X,Y Set tempcir=FeaFac.CreateCircularRegion(miCircleTypeMap ,Pnt,1, MainMap.MapUni 字串2 t,,) ‘miSearchTypeCentroidWithin :中心点包含 ‘miSearchTypePartiallyWithin :部分包含 ‘miSearchTypeEntirelyWithin :全部包含 Set Ftrs=Lyr.SearchWithinFeature (TempCir, miSearchTypePartiallyWithin) For I=1 to Ftrs.Count ‘执行语句 Next SET Pnt =Nothing set TempCir =Nothing set FeaFac =Nothing 3、 相交 判断两个图元是否有交点以及交点坐标信息。 (1)判断是否相交 IF Lyr.IntersectionTest( ftr1, ftr2, miIntersectFeature ) THEN ‘交点 END IF (2)获取相交点坐标信息 ‘交点 Dim Ftr AS MapXlib.Feature SET Ftr=MainMap.FeatureFactory. IntersectFeatures(Ftr1,Ftr2) ‘交点坐标信息 For J=1 to Ftr.parts.item(1).count X1= Ftr.parts.item(1).Item(J).X Y1= Ftr.parts.item(1).Item(J).Y Next 4、 测距 字串5 使用Map对象的Distance方法。如何测量任意多边形的周长? 使用累加的方法,还要使用图元节点集合。 DistanceValue=0 ‘第一个点 Pnt.Set Ftr.Parts.Item(1).Item(1).X, Ftr.Parts.Item(1).Item(1).Y For j=2 TO Ftr.Parts.Item(1).Count ‘累加 X1= Ftr.Parts.Item(1).Item(j-1).X Y1= Ftr.Parts.Item(1).Item(j-1).Y X2= Ftr.Parts.Item(1).Item(j).X Y2= Ftr.Parts.Item(1).Item(j).Y DistanceValue = DistanceValue +MainMap.Distance(X1, Y1, X2, Y2) Next ‘多边形周长 Msgbox DistanceValue+” ”+MainMap.MapUnit 四、对象编辑 (1)、对属性的编辑 主要使用Fields对象。示例: Dim Flds AS MapXlIB.Fields ‘修改当前图层的每一个字段 For J=1 to Flds.Count Lyr.KeyField= Flds.Item(j).Name ‘使当前图层指向J字段 ‘更新当前图元的J字段值 Ftr.KeyValue=NewValueStr(J) Ftr.Update True ‘并未写入硬盘 Next Lyr.Refresh ‘保存修改到硬盘 字串1 (2)、移动地图 首先创建一个移动工具句柄 MainMap.CreateCustomTool MoveFeature, miToolTypeLine, miPanCursor 在Map对象的ToolUsed事件的ToolNum参数为当前所激活的工具捕捉MoveFeature工具句柄‘传过来的参数:X1,Y1,X2,Y2 Select case ToolNum …….. Case MoveFeature Dim Lyr AS MapXlib.Layer Dim Ftr AS MapXlib.Feature Dim Ftrs AS MapXlib.Features Dim Xe,Ye AS Double ‘坐标偏移量 Xe=X2-X1 Ye=Y2-Y1 Set Lyr=Mainmap.Layers.Item(LayerName) Set Ftrs=Lyr.Selection.Clone ‘将当前图层中选定的集合复制到Ftrs变量中 MainMap.AutoRedraw=False Lyr.Editable=True For J=1 to Ftrs.Count Set Ftr=Ftrs.Item(J) Ftr.Offset Xe,Ye Ftr.Update True Next Lyr.Refresh Lyr.Editable=False MainMap.AutoRedraw=True SET lyr=Nothing SET Ftr=Nothing End Select (3)、样式更新 字串5 Dim NewStyle AS MapXLib.Style ‘初始赋值 Set Lyr=MainMap.Layers.Item(LayerName) Set Ftrs=Lyr.AllFeatures Set NewStyle=Ftrs.Item(1).Style ‘设置样式 With NewStyle .SymbolType = miSymbolTypeBitmap .SymbolBitmapSize = 24 .SymbolBitmapTransparent = False .SymbolBitmapName = "YIEL2-32.BMP" End With ‘更新 MainMap.AutoRedraw=False Lyr.Editable=True SET Ftr.Style=NewStyle Ftr.Update True Lyr.Refresh Lyr.Editable=False MainMap.AutoRedraw=True 如何在在MapX中画线的代码(Visual C++) 收藏 CMapXPoints  Pnts;          //点集对象  CMapXFeatureFactory FeaFac;   CMapXLayer   Layer;  CMapXFeature Feature;  CMapXStyle   Style;  double centerX,centerY;    //得到地图的中心  centerX=m_ctrlMapX.GetCenterX();  centerY=m_ctrlMapX.GetCenterY();  Pnts.CreateDispatch(Pnts.GetClsid());  // 判断是否存在tempLayer图层  CMapXLayers layers=m_ctrlMapX.GetLayers();  BOOL Flag=false;  for(int i=0;iAddRef();  Feature=FeaFac.CreateLine(vtPoints); //按照点集画线  Style=Feature.GetStyle();  Style.SetLineColor(miColorRed); //线条颜色  Style.SetLineWidth(2);          //线条宽度  Feature.SetStyle(Style.m_lpDispatch);  Layer.AddFeature(Feature);  //加入Feature  Layer.Refresh();            //更新图层 ------------------------------ 简单说明,tempLayer是画线的图层,首先判断是否存在。如果不存在就新建,并且使它为动态图层。 点的加入顺序不同,画出来的线条也是不一样的,大家可以测试一下,就明白了。 再用放射线法来判断点是否在多边形内的时候,请问该如何判断放射线与某条边是否相交呢? 可以用矢量叉乘的方法,比如,2条线段AB和CD如果他们相交,那么     ((A-C)*(D-C))*((B-C)*(D-C))<0 经过该点的任意方向的射线,和n条边的相交点的数目     奇数在内,偶数在外     需要处理几种特殊情况,相交在线段的端点,和线段重合的情况   C语言中实现 点在多边形内 算法 首先定义点结构如下: 以下是引用片段:   /* Vertex structure */   typedef struct   {   double x, y;   } vertex_t;   本算法里所指的多边形,是指由一系列点序列组成的封闭简单多边形。它的首尾点可以是或不是同一个点(不强制要求首尾点是同一个点)。这样的多边形可以是任意形状的,包括多条边在一条绝对直线上。因此,定义多边形结构如下: 以下是引用片段:   /* Vertex list structure – polygon */   typedef struct   {   int num_vertices; /* Number of vertices in list */   vertex_t *vertex; /* Vertex array pointer */   } vertexlist_t;   为加快判别速度,首先计算多边形的外包矩形(rect_t),判断点是否落在外包矩形内,只有满足落在外包矩形内的条件的点,才进入下一步的计算。为此,引入外包矩形结构rect_t和求点集合的外包矩形内的方法vertices_get_extent,代码如下: 以下是引用片段:   /* bounding rectangle type */   typedef struct   {   double min_x, min_y, max_x, max_y;   } rect_t;   /* gets extent of vertices */   void vertices_get_extent (const vertex_t* vl, int np, /* in vertices */   rect_t* rc /* out extent*/ )   {   int i;   if (np > 0){   rc->min_x = rc->max_x = vl[0].x; rc->min_y = rc->max_y = vl[0].y;   }else{   rc->min_x = rc->min_y = rc->max_x = rc->max_y = 0; /* =0 ? no vertices at all */   }   for(i=1; i    {   if(vl[i].x < rc->min_x) rc->min_x = vl[i].x;   if(vl[i].y < rc->min_y) rc->min_y = vl[i].y;   if(vl[i].x > rc->max_x) rc->max_x = vl[i].x;   if(vl[i].y > rc->max_y) rc->max_y = vl[i].y;   }   }   当点满足落在多边形外包矩形内的条件,要进一步判断点(v)是否在多边形(vl:np)内。本程序采用射线法,由待测试点(v)水平引出一条射线B(v,w),计算B与vl边线的交点数目,记为c,根据奇内偶外原则(c为奇数说明v在vl内,否则v不在vl内)判断点是否在多边形内。   具体原理就不多说。为计算线段间是否存在交点,引入下面的函数:   (1)is_same判断2(p、q)个点是(1)否(0)在直线l(l_start,l_end)的同侧;   (2)is_intersect用来判断2条线段(不是直线)s1、s2是(1)否(0)相交; 以下是引用片段:   /* p, q is on the same of line l */   static int is_same(const vertex_t* l_start, const vertex_t* l_end, /* line l */   const vertex_t* p,   const vertex_t* q)   {   double dx = l_end->x - l_start->x;   double dy = l_end->y - l_start->y;   double dx1= p->x - l_start->x;   double dy1= p->y - l_start->y;   double dx2= q->x - l_end->x;   double dy2= q->y - l_end->y;   return ((dx*dy1-dy*dx1)*(dx*dy2-dy*dx2) > 0? 1 : 0);   }   /* 2 line segments (s1, s2) are intersect? */   static int is_intersect(const vertex_t* s1_start, const vertex_t* s1_end,   const vertex_t* s2_start, const vertex_t* s2_end)   {   return (is_same(s1_start, s1_end, s2_start, s2_end)==0 &&   is_same(s2_start, s2_end, s1_start, s1_end)==0)? 1: 0;   }   下面的函数pt_in_poly就是判断点(v)是(1)否(0)在多边形(vl:np)内的程序: 以下是引用片段:   int pt_in_poly ( const vertex_t* vl, int np, /* polygon vl with np vertices */   const vertex_t* v)   {   int i, j, k1, k2, c;   rect_t rc;   vertex_t w;   if (np < 3)   return 0;   vertices_get_extent(vl, np, &rc);   if (v->x < rc.min_x || v->x > rc.max_x || v->y < rc.min_y || v->y > rc.max_y)   return 0;   /* Set a horizontal beam l(*v, w) from v to the ultra right */   w.x = rc.max_x + DBL_EPSILON;   w.y = v->y;   c = 0; /* Intersection points counter */   for(i=0; i    {   j = (i+1) % np;   if(is_intersect(vl+i, vl+j, v, &w))   {   c++;   }   else if(vl[i].y==w.y)   {   k1 = (np+i-1)%np;   while(k1!=i && vl[k1].y==w.y)   k1 = (np+k1-1)%np;   k2 = (i+1)%np;   while(k2!=i && vl[k2].y==w.y)   k2 = (k2+1)%np;   if(k1 != k2 && is_same(v, &w, vl+k1, vl+k2)==0)   c++;   if(k2 <= i)   break;   i = k2;   }   }   return c%2;   } 106.6593401 29.551350 106.684689|29.589831,106.594038|29.563551,106.669063|29.484711,106.729498|29.539145,106.722470|29.586083 106.663411 29.541549 一个小例子,希望对你有帮助!   (该方法适用于屏幕坐标,不能用于经度纬度)   procedure   TForm1.Button1Click(Sender:   TObject);     var         rgn   :   HRGN;         rgnPoints   :   array   of   TPoint;         hbr   :   HBRUSH;         point   :   TPoint;     begin         setlength(rgnPoints,4);         rgnPoints[0].X   :=   0;         rgnPoints[0].Y   :=   0;         rgnPoints[1].X   :=   100;         rgnPoints[1].Y   :=   0;         rgnPoints[2].X   :=   100;         rgnPoints[2].Y   :=   100;         rgnPoints[3].X   :=   0;         rgnPoints[3].Y   :=   100;         point.X   :=   50;         point.Y   :=   50;         rgn   :=   CreatePolygonRgn(rgnPoints[0],4,WINDING);         if   rgn<>0   then         begin                     hbr   :=   CreateSolidBrush(clRed);                     if   (Ptinregion(rgn,point.X,point.Y)=True)   then                         FillRgn(Form1.Canvas.Handle,rgn,hbr);                     deleteObject(rgn);                     DeleteObject(hbr);         end;     end; 通过经纬度坐标来计算地表上两点间的距离   Post By:2008-6-7 13:55:00 现在许多地图的坐标系统用的是WGS1984坐标系,其坐标单位为经纬度,那么如何通过用经纬度坐标计算地表上两点间的距离呢?这里不需要涉及到坐标投影,直接用经纬度坐标求解圆弧的长度是计算地表上两点间距离的精确方法。 如果考虑地表的高程变化,使用经纬度结合DEM数据来计算两点之间的地表距离,那是比较复杂的,至少我自己现在不会算。在项目应用中,由于要求不是那么精确,我采用两种思路根据经纬度来计算两点的地表距离。 1.完全把地球假设成一个半径为6378.137公里的正球体,下面给出C#的示例代码。 Class PtDistance { private const double EARTH_RADIUS = 6378.137; private static double rad(double d) { return d * Math.PI / 180.0; } public static double GetDistance(double lat1, double lng1, double lat2, double lng2) { double radLat1 = rad(lat1); double radLat2 = rad(lat2); double a = radLat1 - radLat2; double b = rad(lng1) - rad(lng2); double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2),2) + Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Pow(Math.Sin(b/2),2))); s = s * EARTH_RADIUS; s = Math.Round(s * 10000) / 10000; return s; } } 2.如果你想更精确一点,可以按照地球的长短轴把他假设为一个规则的椭球体,下面给出C++(开发环境VC6.0)示例: ————–CJWD.h————– #ifndef __JWD_AND_HELPER_20051005 #define __JWD_AND_HELPER_20051005 #include “stdafx.h” #include #include using namespace std; #ifndef PI #define PI 3.14159265; #endif static double Rc = 6378137; // 赤道半径 static double Rj = 6356725; // 极半径 namespace CDYW{ class JWD { public: double m_LoDeg, m_LoMin, m_LoSec; // longtitude 经度 double m_LaDeg, m_LaMin, m_LaSec; double m_Longitude, m_Latitude; double m_RadLo, m_RadLa; double Ec; double Ed; public: // 构造函数, 经度: loDeg 度, loMin 分, loSec 秒; 纬度: laDeg 度, laMin 分, laSec秒 JWD(double loDeg, double loMin, double loSec, double laDeg, double laMin, double laSec) { m_LoDeg=loDeg; m_LoMin=loMin; m_LoSec=loSec; m_LaDeg=laDeg; m_LaMin=laMin; m_LaSec=laSec; m_Longitude = m_LoDeg + m_LoMin / 60 + m_LoSec / 3600; m_Latitude = m_LaDeg + m_LaMin / 60 + m_LaSec / 3600; m_RadLo = m_Longitude * PI / 180.; m_RadLa = m_Latitude * PI / 180.; Ec = Rj + (Rc - Rj) * (90.- m_Latitude) / 90.; Ed = Ec * cos(m_RadLa); } //! JWD(double longitude, double latitude) { m_LoDeg = int(longitude); m_LoMin = int((longitude - m_LoDeg)*60); m_LoSec = (longitude - m_LoDeg - m_LoMin/60.)*3600; m_LaDeg = int(latitude); m_LaMin = int((latitude - m_LaDeg)*60); m_LaSec = (latitude - m_LaDeg - m_LaMin/60.)*3600; m_Longitude = longitude; m_Latitude = latitude; m_RadLo = longitude * PI/180.; m_RadLa = latitude * PI/180.; Ec = Rj + (Rc - Rj) * (90.-m_Latitude) / 90.; Ed = Ec * cos(m_RadLa); } }; class CJWDHelper { public: CJWDHelper() {}; ~CJWDHelper() {}; //! 计算点A 和 点B的经纬度,求他们的距离和点B相对于点A的方位 /*! * \param A A点经纬度 * \param B B点经纬度 * \param angle B相对于A的方位, 不需要返回该值,则将其设为空 * \return A点B点的距离 */ static double distance(JWD A, JWD B, double *angle) { double dx = (B.m_RadLo - A.m_RadLo) * A.Ed; double dy = (B.m_RadLa - A.m_RadLa) * A.Ec; double out = sqrt(dx * dx + dy * dy); if( angle != NULL) { *angle = atan(fabs(dx/dy))*180./PI; // 判断象限 double dLo = B.m_Longitude - A.m_Longitude; double dLa = B.m_Latitude - A.m_Latitude; if(dLo > 0 && dLa <= 0) { *angle = (90. - *angle) + 90.; } else if(dLo <= 0 && dLa < 0) { *angle = *angle + 180.; } else if(dLo < 0 && dLa >= 0) { *angle = (90. - *angle) + 270; } } return out/1000; } //! 计算点A 和 点B的经纬度,求他们的距离和点B相对于点A的方位 /*! * \param longitude1 A点经度 * \param latitude1 A点纬度 * \param longitude2 B点经度 * \param latitude2 B点纬度 * \param angle B相对于A的方位, 不需要返回该值,则将其设为空 * \return A点B点的距离 */ static double distance( double longitude1, double latitude1, double longitude2, double latitude2, double *angle) { JWD A(longitude1,latitude1); JWD B(longitude2,latitude2); return distance(A, B, angle); } //! 已知点A经纬度,根据B点据A点的距离,和方位,求B点的经纬度 /*! * \param A 已知点A * \param distance B点到A点的距离 * \param angle B点相对于A点的方位 * \return B点的经纬度坐标 */ static JWD GetJWDB(JWD A, double distance, double angle) { double dx = distance*1000 * sin(angle * PI /180.); double dy = distance*1000 * cos(angle * PI /180.); //double dx = (B.m_RadLo - A.m_RadLo) * A.Ed; //double dy = (B.m_RadLa - A.m_RadLa) * A.Ec; double BJD = (dx/A.Ed + A.m_RadLo) * 180./PI; double BWD = (dy/A.Ec + A.m_RadLa) * 180./PI; JWD B(BJD, BWD); return B; } //! 已知点A经纬度,根据B点据A点的距离,和方位,求B点的经纬度 /*! * \param longitude 已知点A经度 * \param latitude 已知点A纬度 * \param distance B点到A点的距离 * \param angle B点相对于A点的方位 * \return B点的经纬度坐标 */ static JWD GetJWDB(double longitude, double latitude, double distance, double angle) { JWD A(longitude,latitude); return GetJWDB(A, distance, angle); } }; } #endif =========== 测试程序========== #include “stdafx.h” #include #include #include “CJWD.h” using namespace std;using namespace CDYW; double Rc = 6378137; // 赤道半径 double Rj = 6356725; // 极半径// 绵阳 double jd1 = 104.740999999; double wd1 = 31.4337;// 成都 double jd2 = 104.01; double wd2 = 30.40; int main(int argc, char* argv[]) { double angle = 0; cout << “A(绵阳): JD = ” << jd1 << ” WD = ” << wd1 << endl; cout << “B(成都): JD = ” << jd2 << ” WD = ” << wd2 << endl; cout << “——————–” << endl; cout << D_jw(wd1,jd1,wd2,jd2, angle) << endl; cout << “angle: ” << angle < cout << “==============” < JWD A(jd1,wd1),B(jd2,wd2); double distance = CJWDHelper::distance(jd1,wd1,jd2,wd2, &angle); //cout << CJWDHelper::distance(A,B, &angle) << endl; cout << distance << endl; cout << “angle: ” << angle < cout << “==============” < JWD C = CJWDHelper::GetJWDB(A, distance, angle); cout << “JD = ” << C.m_Longitude << ” WD = ” << C.m_Latitude << endl; cout << “==============” < cout << A.m_LoDeg << ” ” << A.m_LoMin << ” ” << A.m_LoSec << endl; return 0; } 希望上述代码能给大家的算法设计有所帮助,在实际应用中再加以改进吧!

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享文档获得金币 ] 4 人已下载

下载文档