• 在C#中如何实现MapX图层操作


    IT168 技术文档】在C#中实现MapX从数据库读取数据形成新图层分为两个问题:

      1. MapX从数据库读取数据形成新图层;

      2. 将DataTable转换为ADO的Recordset。这里的第二个问题是由第一个问题引起的,因为MapX是一个COM控件,而且它只支持ADO的数据访问方式,而C#编程时一般会使用ADO.NET方式,为此需要在两种方式之间做一下转换。(当然也可以在C#中使用ADO方式)

      DataTable转换为ADO的Recordset的操作代码如下所示。

     /// <summary>
      
    /// 在.net中用ADO.NET取代了ADO实现对数据的访问,但一些COM控件只支持ADO并不支持ADO.NET。
      
    /// 为了使用这类控件,只能将ADO.NET中的数据对象,比如转换DataTable为ADO中的Recordset
      
    /// (DataSet对象本质上是DataTable的集合,因此本文只讲述DataTable对象的转换)。
      
    /// <summary>
      public sealed class ADONETtoADO
      {
      
    /// <summary>
      
    /// 将DataTable对象转换为Recordeset对象
      
    /// <summary>
      
    /// DataTable对象
      
    /// 转换后得到的Recordeset对象
      public static Recordset ConvertDataTableToRecordset(DataTable table)
      {
      
    //思路:
      
    // 1. 创建Recordset对象后,在其中对应DataTable的Column创建Field,为此需要将ADO.NET的数据类型转换为ADO的数据类型;
      
    // 2. 打开Recordset对象,对应DataTable对象中的每一行,在Recordset对象中新建一条记录,并对每个字段赋值。
      Recordset rs = new RecordsetClass();
      
    foreach (DataColumn dc in table.Columns)
      {
      rs.Fields.Append(dc.ColumnName, GetDataType(dc.DataType), 
    -1, FieldAttributeEnum.adFldIsNullable, Missing.Value);
      }
      rs.Open(Missing.Value, Missing.Value, CursorTypeEnum.adOpenUnspecified, LockTypeEnum.adLockUnspecified, 
    -1);
      
    foreach (DataRow dr in table.Rows)
      {
      rs.AddNew(Missing.Value, Missing.Value); 
    object o;
      
    for (int i = 0; i < table.Columns.Count; i++)
      {
      rs.Fields[i].Value 
    = dr[i];
      o 
    = rs.Fields[i].Value;
      }
      }
      
    return rs;
      }
      
    /// <summary>
      
    /// 将ADO.NET的数据类型转换为ADO的数据类型
      
    /// <summary>
      
    /// ADO.NET的数据类型
      
    /// ADO的数据类型
      private static DataTypeEnum GetDataType(Type dataType)
      {
      
    switch (dataType.ToString())
      {
      
    case "System.Boolean": return DataTypeEnum.adBoolean;
      
    case "System.Byte": return DataTypeEnum.adUnsignedTinyInt;
      
    case "System.Char": return DataTypeEnum.adChar;
      
    case "System.DateTime": return DataTypeEnum.adDate;
      
    case "System.Decimal": return DataTypeEnum.adDecimal;
      
    case "System.Double": return DataTypeEnum.adDouble;
      
    case "System.Int16": return DataTypeEnum.adSmallInt;
      
    case "System.Int32": return DataTypeEnum.adInteger;
      
    case "System.Int64": return DataTypeEnum.adBigInt;
      
    case "System.SByte": return DataTypeEnum.adTinyInt;
      
    case "System.Single": return DataTypeEnum.adSingle;
      
    case "System.String": return DataTypeEnum.adVarChar;
      
    //case "TimeSpan":return DataTypeEnum.
      case "System.UInt16": return DataTypeEnum.adUnsignedSmallInt;
      
    case "System.UInt32": return DataTypeEnum.adUnsignedInt;
      
    case "System.UInt64": return DataTypeEnum.adUnsignedBigInt;
      
    default: throw (new Exception("没有对应的数据类型"));
      }
      }
      }

    在得到了Recordset对象后,如何解决第一个问题。步骤如下:

      1. 创建CMapXFields对象,并对应数据库中字段添加字段;

      2. 创建CMapXBindLayer对象,指定其坐标值字段的序号;

      3. 向map.DataSets中添加数据集,从而生成新的图层;

      4. 指定新图层中要素的显示风格,本文采用显示位图的方式,为此需要将要显示的位图放入MapX安装目录的CUSTSYMB文件夹下。

      具体的操作代码如下所示:

      /// <summary>
      
    /// 删除所有的图层数据
      
    /// <summary>
      
    /// <param name="layerName"></param>
      private void DeleteLayerByName(string layerName)
      {
      
    //Layer的序号是从1开始
      int count = axMap1.Layers.Count;
      
    for (int i = 1; i < count; i++)
      {
      
    if (axMap1.Layers[i].Name == layerName)
      {
      axMap1.Layers.Remove(i);
      }
      }
      }
      
    /// <summary>
      
    /// 创建新的图层信息
      
    /// <summary>
      
    /// <param name="layerName"></param>
      
    /// <param name="rsNoPass"></param>
      private void CreatNewLayerfromDB(string layerName, ADODB.Recordset rsNoPass)
      {
      DeleteLayerByName(layerName); 
    //将原有层删除
      CMapXFields flds = new FieldsClass();
      
    // Describe the structure of the Unbound dataset
      flds.Add("stationid", "theid", AggregationFunctionConstants.miAggregationIndividual,
      FieldTypeConstants.miTypeString);
      flds.Add(
    "address", "address", AggregationFunctionConstants.miAggregationIndividual,
      FieldTypeConstants.miTypeString);
      flds.Add(
    "longitude", "longitude", AggregationFunctionConstants.miAggregationSum,
      FieldTypeConstants.miTypeNumeric);  
    //经度
      flds.Add("latitude", "latitude", AggregationFunctionConstants.miAggregationSum,
      FieldTypeConstants.miTypeNumeric);  
    //纬度
      CMapXBindLayer bindLayerObject = new BindLayerClass();
      bindLayerObject.LayerName 
    = layerName;
      bindLayerObject.RefColumn1 
    = 3;
      bindLayerObject.RefColumn2 
    = 4;
      bindLayerObject.LayerType 
    = BindLayerTypeConstants.miBindLayerTypeXY;
      CMapXDataset dataSet 
    = axMap1.DataSets.Add(DatasetTypeConstants.miDataSetADO, rsNoPass, layerName, "stationid", "address", bindLayerObject, flds, false);
      CMapXLayer layer 
    = axMap1.Layers._Item(layerName);
      layer.OverrideStyle 
    = true;
      
    string picName = "icon.BMP";
      
    if (layer.Style.SupportsBitmapSymbols == true)
      {
      layer.Style.SymbolType 
    = SymbolTypeConstants.miSymbolTypeBitmap;
      layer.Style.SymbolBitmapSize 
    = 60;
      layer.Style.SymbolBitmapTransparent 
    = true;
      layer.Style.SymbolBitmapName 
    = picName;
      }
      }
    来自:http://tech.it168.com/a2009/1210/822/000000822545_1.shtml
  • 相关阅读:
    qt自定义的串口类判断断开
    ubuntu16.04永久修改有线接口名称(enp0s3->eth0)
    记录一下读过的书
    Qt 主界面卡死
    Mysql5.7及版本以上导入sql提示Incorrect date value: '0000-00-00' for column
    webpack打包css
    ant-design-vue中的a-directory-tree更换图标
    解决php-fpm占用内存过高问题
    centos,解压源代码安装,没有configure文件
    OSS存储上遇到The difference between the request time and the current time is too large
  • 原文地址:https://www.cnblogs.com/gisoracle/p/1640357.html
Copyright © 2020-2023  润新知