目录

  • 1. 背景简介
  • 2. 开发环境配置
  • 2.1. 开发环境依赖
  • 2.2. 搭建 MFC 项目
  • 2.3. 配置 iObjects C++ 11i 组件开发环境依赖
  • 3. 功能实现
  • 3.1. 打开工作空间
  • 3.2. 另存工作空间
  • 3.3. 新建文件型数据源
  • 3.4. 打开文件型数据源
  • 3.5. 新建矢量数据集
  • 3.6. 新建栅格数据集
  • 3.7. 关闭数据集
  • 4. 总结


1. 背景简介

  SuperMap iObjects C++

  虽说 iObjects C++ 组件性能高,但 iObjects C++ 组件中提供的开发示例 DEMO 相比 iObjects .NET / Java 组件较少,基于 iObjects C++ 组件开发门槛较高且帮助文档关于 iObjects C++ API 接口说明较少,使之客户基于 iObjects C++ 组件开发难度较高,因此提供该教程和对应示例 DEMO 以供参考。

  该教程基于 SuperMap iObjects C++ 11i 组件实现 工作空间、数据源、数据集 管理功能,包括:工作空间新建、打开、保存、另存、关闭;数据源新建、打开、保存、关闭;点、线、面、三维点、三维线、三维面、CAD、模型、栅格、影像、属性表等数据集新建、关闭等功能。

  这些功能均属于 iObjects C++ 核心组件模块,因此仅需核心组件许可权限即可正常使用。iObjects C++ 组件许可模块详情如下:

Supermap 根据项目ID 查询项目范围 java示例 supermap iobjects_iObjects C++

2. 开发环境配置

2.1. 开发环境依赖

软件产品

版本

下载地址

备注

SuperMap iObjects C++

11i

SuperMap iObjects C++ 11i 下载地址

推荐使用 SuperMap iObjects C++ 11i 版本组件

Visual Studio

2022

Visual Studio 2022 社区版下载地址

在安装 Visual Studio 2022 时,需按照 C++ 库

2.2. 搭建 MFC 项目

  • Visual Studio 2022 社区版创建 MFC 应用
  • Supermap 根据项目ID 查询项目范围 java示例 supermap iobjects_iObjects C++_02

  • 创建 基于对话框MFC,选择 应用程序类型 后,直接点击 完成
  • Supermap 根据项目ID 查询项目范围 java示例 supermap iobjects_iObjects C++_03

  上述 2 步执行结束后,已成功创建最简单的 MFC 应用程序,接下来需要进一步对已创建的 MFC 应用程序配置 SuperMap iObjects C++ 11i 组件开发环境依赖。

2.3. 配置 iObjects C++ 11i 组件开发环境依赖

  • 配置 C/C++ 环境
  • iObjects C++ 目录\includeiObjects C++ 目录\include\private 目录添加到 C/C++》附加包含目录
  • Supermap 根据项目ID 查询项目范围 java示例 supermap iobjects_工作空间_04

  • _UGUNICODE 配置到 C/C++》预处理器定义
  • Supermap 根据项目ID 查询项目范围 java示例 supermap iobjects_数据源_05

  • C/C++》语言 项配置 WChar_t 视为内置类型
  • Supermap 根据项目ID 查询项目范围 java示例 supermap iobjects_iObjects_06

  • /bigobj 添加到 C/C++》命令行
  • Supermap 根据项目ID 查询项目范围 java示例 supermap iobjects_SuperMap_07

  • 配置 链接器 环境
  • iObjects C++ 目录\lib\lib_x64 添加到 链接器》附加库目录
  • Supermap 根据项目ID 查询项目范围 java示例 supermap iobjects_iObjects C++_08

  • 将下述库文件添加到 链接器》附加依赖项
SuAllocation.lib
SuAnalyst3D.lib
SuAnimation.lib
SuBase.lib
SuBase3D.lib
SuBGDataCompiler.lib
SuBPlusTree.lib
SuCacheBuilder.lib
SuCacheBuilder3D.lib
SuCacheFile.lib
SuChartBase.lib
SuChartToolkit.lib
SuCompactFile.lib
SuCVToolkit.lib
SuDataCheck.lib
SuDataExchange.lib
SuDB2CI.lib
SuDCPackager.lib
SuDCToolkits.lib
SuDrawing.lib
SuDrawing3D.lib
SuDrawingLayout.lib
SuElement.lib
SuEngine.lib
SuEngineBaiduMaps.lib
SuEngineBingMaps.lib
SuEngineDB2.lib
SuEngineES.lib
SuEngineExtendFile.lib
SuEngineGanos.lib
SuEngineGaoDeMaps.lib
SuEngineGBase.lib
SuEngineGoogleMaps.lib
SuEngineImagePlugin.lib
SuEngineMapWorldMaps.lib
SuEngineMySQL.lib
SuEngineODBC.lib
SuEngineOGC.lib
SuEngineOGDC.lib
SuEngineOpenStreetMaps.lib
SuEngineOracle.lib
SuEnginePG.lib
SuEnginePGis.lib
SuEngineRest.lib
SuEngineSCV.lib
SuEngineSMCloud.lib
SuEngineSpatialite.lib
SuEngineSQLPLUS.lib
SuEngineSsp.lib
SuEngineUDB.lib
SuEngineXYZTile.lib
SuFileParser.lib
SuFileParser3DModel.lib
SuFileParser3ds.lib
SuFileParserAcad.lib
SuFileParserBitMap.lib
SuFileParserCSV.lib
SuFileParserDEM.lib
SuFileParserE00.lib
SuFileParserENC.lib
SuFileParserFME.lib
SuFileParserGDAL.lib
SuFileParserKML.lib
SuFileParserLidar.lib
SuFileParserMAPGIS.lib
SuFileParserMitab.lib
SuFileParserNetCDF.lib
SuFileParserOGR.lib
SuFileParserPointCloud.lib
SuFileParserRAW.lib
SuFileParserS3MB.lib
SuFileParserSCV.lib
SuFileParserSGM.lib
SuFileParserTEMS.lib
SuFMELicense.lib
SuGeneralization.lib
SuGeoCode.lib
SuGeometricNetwork.lib
SuGeometry.lib
SuGeometry3D.lib
SuGeometryCAD.lib
SuGeometryConverter.lib
SuGeometryLayout.lib
SuGeometryPlot.lib
SuGeoOperation.lib
SuGeoOperation3D.lib
SuGraphics.lib
SuGraphics3D.lib
SuGraphics3DGameEngine.lib
SuGraphics3DOGRE.lib
SuGraphicsPDF.lib
SuGraphicsPS.lib
SuGraphicsW.lib
SuGridAnalyst.lib
SuGridAnalystOpenCL.lib
SuGridModeling.lib
SuLayer3DDataset.lib
SuLayer3DDatasetModel.lib
SuLayer3DFile.lib
SuLayer3DMap.lib
SuLayer3DTree.lib
SuLayoutEditor.lib
SuLinearReference.lib
SuLogistics.lib
SuMap.lib
SuMapEditor.lib
SuMapMatching.lib
SuMapServiceStub.lib
SuMGAnimationExp.lib
SuMGAuxiliaryPlotting.lib
SuMGCommon.lib
SuMGMapData.lib
SuMGMovingTarget.lib
SuMGObjects.lib
SuMGSituation.lib
SuMGSituationMonitor.lib
SuMGSituationSimulation.lib
SuMongoCI.lib
SuMosaic.lib
SuMosaicOpenCV.lib
SuMySQLCI.lib
SuNetToolkit.lib
SuNetworkBuilder.lib
SuNetworkEnvironment.lib
SuNTopoDataCompiler.lib
SuNTopoIndexTree.lib
SuODBCCI.lib
SuOGCParser.lib
SuOGDC.lib
SuOracleCI.lib
SuOverlay.lib
SuParticleSystem.lib
SuPathAnalyst.lib
SuPathAnalystCH.lib
SuPathNavi.lib
SuPluginCommon.lib
SuPluginGECache.lib
SuPluginGlobalCache.lib
SuPluginGridCache.lib
SuPluginMapCache.lib
SuPluginMapCache50.lib
SuPluginWebCache.lib
SuPostgreSQLCI.lib
SuProjection.lib
SuProjectionProj.lib
SuProjectionWKT.lib
SuProximity.lib
SuPublicTransport.lib
SuRasterData.lib
SuRectify.lib
SuRender.lib
SuRepresentation.lib
SuRStarTree.lib
SuScene.lib
SuSceneEditor.lib
SuSpatialIndex.lib
SuSpatialQuery.lib
SuSQLiteCI.lib
SuStream.lib
SuSymbol.lib
SuSymbolAlgo1.lib
SuSymbolAlgo2.lib
SuSymbolAlgo3.lib
SuSymbolAlgo4.lib
SuSymbolAlgo5.lib
SuSymbolAlgo6.lib
SuSymbolAlgo7.lib
SuSymbolExchange.lib
SuSymbolMarker3D.lib
SuTheme3DBase.lib
SuTileStorage.lib
SuToolkit.lib
SuToolkit3D.lib
SuToolkitPointCloud.lib
SuToolkitVDB.lib
SuTopoBase.lib
SuTopoBuilder.lib
SuVRDevices.lib
SuWorkspace.lib
SuWrapc.lib
SuAlgorithm.lib
SuAlgorithm3D.lib

Supermap 根据项目ID 查询项目范围 java示例 supermap iobjects_工作空间_09

  此处是为了方便,便直接将 SuperMap iObjects C++ 的全部 依赖项 都直接添加到 MFC 应用程序依赖项。若觉得 SuperMap iObjects C++ 的全部 依赖项 太多,则可以适当添加需要的使用的部分 依赖项

3. 功能实现

  接下来是关于工作空间、数据源、数据集管理的核心功能调用接口以及实现逻辑,具体代码实现可直接参考下述实现代码。

3.1. 打开工作空间

  打开工作空间的操作主要包括 2 步:1. 构建工作空间连接信息(工作空间路径、版本、类型和名称);2. 根据构建的工作空间连接信息打开指向的工作空间。详细编码可参考以下实现:

// 构建工作空间连接信息
UGWorkspaceConnection workspaceConnection = UGWorkspaceConnection();
workspaceConnection.m_strServer = workspaceFilePath;
workspaceConnection.m_nVersion = UG_WORKSPACE_VERSION_20120328;
workspaceConnection.m_nWorkspaceType = GetWorkspaceType(workspaceFileExt);
workspaceConnection.m_bFailIfExists = false;
workspaceConnection.m_strWorkspaceName = workspaceFileName;

// 打开工作空间
m_workspace = new UGWorkspace();
if (m_workspace->Open(workspaceConnection))
{
    m_workspace->SetName(workspaceConnection.m_strWorkspaceName);
    m_workspace->SetCaption(workspaceConnection.m_strWorkspaceName);
}

3.2. 另存工作空间

  另存工作空间的操作流程与打开工作空间一样,详细编码可参考以下实现:

// 构建工作空间连接信息
UGWorkspaceConnection workspaceConnection = UGWorkspaceConnection();
workspaceConnection.m_strServer = workspaceFilePath;
workspaceConnection.m_nVersion = UG_WORKSPACE_VERSION_20120328;
workspaceConnection.m_nWorkspaceType = GetWorkspaceType(workspaceFileExt);
workspaceConnection.m_bFailIfExists = false;
workspaceConnection.m_strWorkspaceName = workspaceFileName;

m_workspace->SetName(workspaceConnection.m_strWorkspaceName);
m_workspace->SetCaption(workspaceConnection.m_strWorkspaceName);

// 另存工作空间
if (m_workspace->SaveAs(workspaceConnection)) {}

3.3. 新建文件型数据源

  新建文件型数据源需要指定文件路径、文件别名以及数据源类型,其中 UGEngineType::Spatialite 对应 UDBX 文件型数据源,UGEngineType::UDB 对应 UDB 文件型数据源,建议根据实际需求设置适合的数据源类型。

注意:

// 构建数据源信息
UGDataSource* datasource = UGDataSourceManager::CreateDataSource(UGEngineType::Spatialite);
UGDsConnection& dsConn = datasource->GetConnectionInfo();
dsConn.m_strServer = filePath;
dsConn.m_strAlias = fileTitle;
dsConn.m_nType = UGEngineType::Spatialite;

// 新建数据源
if (!datasource->Create())
{
  datasource->Close();
  delete datasource;
}
else
{
  // 数据源新建成功,添加到当前工作空间中
  if (!m_workspace->m_DataSources.Insert(dsConn.m_strAlias, datasource) || !m_workspace->Save()) {}
}

3.4. 打开文件型数据源

  打开文件型数据源的操作流程与新建文件型数据源一样,详细编码可参考以下实现:

// 构建数据源信息
UGDataSource* datasource = UGDataSourceManager::CreateDataSource(UGEngineType::Spatialite);
UGDsConnection& dsConn = datasource->GetConnectionInfo();
dsConn.m_strServer = filePath;
dsConn.m_strAlias = fileTitle;
dsConn.m_nType = UGEngineType::Spatialite;

// 打开数据源
if (!datasource->Open())
{
  datasource->Close();
  delete datasource;
}
else
{
  // 数据源打开成功,添加到当前工作空间中
  if (!m_workspace->m_DataSources.Insert(dsConn.m_strAlias, datasource) || !m_workspace->Save()) {}
}

3.5. 新建矢量数据集

  新建矢量数据集的操作流程都是一样的,唯有数据集类型不同,因此简单封装了以下接口用于复用新建不同类型的矢量数据集,包括:二维点(UGC::UGDataset::Point)、二维线(UGC::UGDataset::Line)、二维面(UGC::UGDataset::Region)、三维点(UGC::UGDataset::PointZ)、三维线(UGC::UGDataset::LineZ)、三维面(UGC::UGDataset::RegionZ)、模型(UGC::UGDataset::Model)、CAD(UGC::UGDataset::CAD)、属性表(UGC::UGDataset::Tabular)等。

/// <summary>
/// 创建矢量数据集
/// </summary>
/// <param name="workspace">工作空间</param>
/// <param name="datasetType">数据集类型</param>
/// <param name="datasetName">数据集名称</param>
/// <returns>是否创建成功</returns>
UGbool CWDDManagerDlg::CreateDefaultDatasetVector(UGWorkspace* workspace, UGDataset::DatasetType datasetType, std::string datasetName)
{
  UGbool isCreated = FALSE;
  int datasourcesCount = workspace->m_DataSources.GetCount();
  if (datasourcesCount > 0)
  {
    UGString datasourceAlias;
    UGDataSource* datasource;
    if (workspace->m_DataSources.GetAt(0, datasourceAlias, datasource) && datasource != nullptr)
    {
      // 获取可用的数据集名称
      UGString strName;
      strName = GetAvailableDatasetName(datasource, strName.FromStd(datasetName));

      // 构建矢量数据集信息
      UGDatasetVectorInfo datasetVectorInfo;
      datasetVectorInfo.m_strName = strName;
      datasetVectorInfo.m_strTableName = strName;
      datasetVectorInfo.m_nCodecType = UGDataCodec::CodecType::envNONE;
      datasetVectorInfo.m_nSmIDType = UGDataset::SmIDType::INT64;
      datasetVectorInfo.m_nType = datasetType;

      // 根据矢量数据集信息新建矢量数据集
      UGDatasetVectorPtr datasetVector = datasource->CreateDatasetVector(datasetVectorInfo);
      if (datasetVector == nullptr)
      {
        return isCreated;
      }
      else
      {
        isCreated = TRUE;
      }
    }
  }
  return isCreated;
}

3.6. 新建栅格数据集

  新建栅格数据集与新建矢量数据集类似,封装以下接口可用于构建简单的单波段栅格(UGC::UGDataset::Grid)、影像(UGC::UGDataset::Image)数据集。

/// <summary>
/// 创建栅格数据集
/// </summary>
/// <param name="workspace">工作空间</param>
/// <param name="datasetType">数据集类型</param>
/// <param name="datasetName">数据集名称</param>
/// <returns>是否创建成功</returns>
UGbool CWDDManagerDlg::CreateDefaultDatasetRaster(UGWorkspace* workspace, UGDataset::DatasetType datasetType, std::string datasetName)
{
  UGbool isCreated = FALSE;
  int datasourcesCount = workspace->m_DataSources.GetCount();
  if (datasourcesCount > 0)
  {
    UGString datasourceAlias;
    UGDataSource* datasource;
    if (workspace->m_DataSources.GetAt(0, datasourceAlias, datasource) && datasource != nullptr)
    {
      // 获取可用的数据集名称
      UGString strName;
      strName = GetAvailableDatasetName(datasource, strName.FromStd(datasetName));

      // 构建栅格数据集信息
      UGDatasetRasterInfo datasetRasterInfo;
      datasetRasterInfo.m_strName = strName;
      datasetRasterInfo.m_strTableName = strName;
      datasetRasterInfo.m_rc2Bounds = UGRect2D(-200.0, -200.0, 200.0, 200.0);
      datasetRasterInfo.m_eBlockSize = UGDatasetRasterInfo::IBSizeOption::IBS_64;
      datasetRasterInfo.m_nHeight = 800;
      datasetRasterInfo.m_nWidth = 800;
      datasetRasterInfo.m_nType = datasetType;
      datasetRasterInfo.SetPixelFormat(OGDC::PixelFormat::IPF_DOUBLE);
      datasetRasterInfo.SetNoValue(-9999.0);

      // 构建栅格波段信息
      UGBandInfo bandInfo;
      bandInfo.m_bAvail = TRUE;
      bandInfo.m_dMaxZ = 10000.0;
      bandInfo.m_dMinZ = -1000.0;
      bandInfo.m_nBandID = 1;
      bandInfo.m_nIndex = 1;
      bandInfo.m_nCodecType = UGDataCodec::CodecType::enrNONE;
      bandInfo.SetPixelFormat(OGDC::PixelFormat::IPF_DOUBLE);
      bandInfo.SetNoValue(-9999.0);
      datasetRasterInfo.Add(bandInfo);

      // 根据栅格数据集信息新建栅格数据集
      UGDatasetRasterPtr datasetRaster = datasource->CreateDatasetRaster(datasetRasterInfo);
      if (datasetRaster == nullptr)
      {
        return isCreated;
      }
      else
      {
        isCreated = TRUE;
      }
    }
  }
  return isCreated;
}

3.7. 关闭数据集

  关闭数据集的时候需要执行 2 步操作:1. 关闭数据集本身;2. 从需要被关闭的数据集所在数据源中移除该数据集。此 2 步骤执行结束后,即完整的关闭数据集。

注意:

/// <summary>
/// 关闭数据集
/// </summary>
/// <param name="workspace">工作空间</param>
/// <param name="datasetType">数据集类型</param>
/// <returns>是否关闭成功</returns>
UGbool CWDDManagerDlg::CloseDataset(UGWorkspace* workspace, UGDataset::DatasetType datasetType)
{
  if (IsExistedDataset(workspace, datasetType))
  {
    UGbool isDeleted = FALSE;
    UGint datasourcesCount = workspace->m_DataSources.GetCount();
    for (size_t i = 0; i < datasourcesCount; i++)
    {
      UGString datasourceAlias;
      UGDataSource* datasource;
      if (workspace->m_DataSources.GetAt(0, datasourceAlias, datasource) && datasource != nullptr)
      {
        UGint datasetCount = datasource->GetDatasetCount();
        OgdcUnicodeStringArray datasetNames = datasource->GetDatasetNames();
        for (size_t j = 0; j < datasetNames.GetSize(); j++)
        {
          UGDatasetPtr dataset = datasource->GetDataset(datasetNames.GetAt(j));
          if (dataset->GetType() == datasetType)
          {
            // 关闭数据集
            dataset->Close();
            
            // 从数据源中删除数据集
            if (!datasource->DeleteDataset(dataset->GetName()) || !datasource->SaveInfo() || !datasource->Compact(TRUE))
            {
              return isDeleted;
            }
            else
            {
              isDeleted = TRUE;
              break;
            }
          }
        }
      }
      if (isDeleted)
      {
        break;
      }
    }
    return isDeleted;
  }
}

4. 总结

  通过上述核心功能逻辑,即可非常轻松的基于 SuperMap iObjects C++ 11i 组件实现对工作空间、数据源、数据集的管理,以下是 Demo 演示:

Supermap 根据项目ID 查询项目范围 java示例 supermap iobjects_iObjects_10

  若仔细阅读上述流程以及实现逻辑后仍然感觉无从入手,不清楚究竟该如何基于这些核心逻辑实现代码应该如何在 MFC 窗口程序中组合使用,不用着急也不用担心,对于 C++ MFC 开发新手,特意提供了基于上述核心逻辑实现的 MFC 示例工程 《基于 iObjects C++ 11i 组件对工作空间、数据源、数据集管理》,可直接下载该开源示例,根据本篇博客对示例工程配置开发环境后即可轻松运行。