读取一个shapefile文件的所有属性值[AO开发教程]

// AOConsoleTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "iostream.h"
#include "atlbase.h"
#include "comdef.h"

#pragma warning(push)
#pragma warning(disable : 4192) /* Ignore warnings for types that are duplicated in win32 header files */
#pragma warning(disable : 4146) /* Ignore warnings for use of minus on unsigned types */

#import "esriSystem.olb" /* Type library to generate C++ wrappers */ /
  raw_interfaces_only,                             /* Don't add raw_ to method names        */ /
  raw_native_types,                                /* Don't map to DTC smart types          */ /
  no_namespace,                                    /* Don't wrap with C++ name space        */ /
  named_guids,                                     /* Named guids and declspecs             */ /
  exclude("OLE_COLOR", "OLE_HANDLE", "VARTYPE")    /* Exclude conflicting types             */
#import "esriGeometry.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids          
#import "esriDataSourcesFile.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids
#import "esriGeoDatabase.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids


#pragma warning(pop)


//CString VariantToString1(VARIANT * va);

int main(int argc, char* argv[])
{
 ::CoInitialize(NULL);

 IWorkspaceFactoryPtr pWSFactory(CLSID_ShapefileWorkspaceFactory);
 IWorkspacePtr pWS;
// BSTR path;
// path = ::SysAllocString(L"C://test");
 HRESULT hr = pWSFactory->OpenFromFile(CComBSTR(L"C://test//bj"),0,&pWS);
 
 if (FAILED(hr) || pWS==NULL)
 {
  cerr<<"Failed to open the destination folder."<<endl;
  return 1;
 }

 IFeatureWorkspacePtr pFWS(pWS);
 IFeatureClassPtr pFClass;
 pFWS->OpenFeatureClass (CComBSTR(L"bj_est1"),&pFClass);

 IFeatureCursorPtr pFCursor;
 pFClass->Search (NULL,VARIANT_TRUE,&pFCursor);

 long lngFieldCount ;
 IFieldsPtr pFields;
 IFieldPtr pField;
 pFCursor->get_Fields (&pFields);
 pFields->get_FieldCount (&lngFieldCount);

 IFeaturePtr pFeature;
 pFCursor->NextFeature (&pFeature);

 USES_CONVERSION;

 long t;
   CComBSTR bsValues;
   CComVariant varValue;
   esriFieldType esriFldType;
 while (pFeature)
 {
  bsValues = CComBSTR(L"  ");
  for (t =0; t < lngFieldCount ; t++)
  {
         pFields->get_Field(t, &pField);
      pField->get_Type(&esriFldType);
      switch (esriFldType)
      {
      case (esriFieldTypeGeometry):
     bsValues += CComBSTR(L"Shape  ");
     break;
      default:
     pFeature->get_Value(t, &varValue);
     if (varValue.vt != VT_BSTR)
       varValue.ChangeType(VT_BSTR);
     bsValues += varValue.bstrVal;
     bsValues += CComBSTR(L"  ");
     break;
      }
  }

//  _bstr_t outString(bsValues,FALSE); //方法1:为控制台输出作准备
//  cout << outString<<endl;
                         //方法2:也可以用OLE2A来进行转化, 
                                  //当然需要加上 USES_CONVERSION;
  cout << OLE2A(bsValues)<< endl;
  pFCursor->NextFeature (&pFeature);
 }

 pWSFactory=NULL;
 pWS=NULL;
 pFWS=NULL;
 pFClass=NULL;
 pFCursor=NULL;
 pFields=NULL;
 pField=NULL;

 ::CoUninitialize();

 return 0;
}

需要注意的地方:
--------------------------------------------
1、程序最开始要初始化COM库,即::CoInitialize(NULL);,这个一般可以在程序最开始的地方(确切的说只要在开始使用COM组件之前就行吧),如果是做组件我想放在构造的时候是个不错的选择。
2、既然初始化了,最后就要卸载COM库(暂且这么说吧),即::CoUninitialize();。它一般在程序的最后(程序退出之前就行)。当然不要它,似乎也能运行,但还是规范点好。这里有个问题,就是程序中用到的变量置空的问题。如果在卸载COM库之前,不将这些变量的置空(释放掉对象的引用),那么在卸载的时候会得到烦人的错误。我就被这个错误困扰了好一阵子(毕竟在VB里COM库的初始化和卸载不要我来做)。当然在一个子过程中,我想不一定需要置空(过程结束,这些变量也就撤销了),但作为一个好习惯,我想还是自己来做一下这个事免得出错。
3、在Import的时候,这些库有先后顺序。比如这里的esriGeometry.olb要放在前面,否则你会得到一个基类未定义的错误,因为这个基类是在esriGeometry.olb这个库里定义的:(
4、下面的问题全集中在字符串的处理上了。COM里用到了BSTR和VARIANT,目的COM原理的书里都有。这两种数据类型会出现在很多地方,搞清楚这两种数据类型很重要。它们的使用有一些麻烦,为了方便我们使用ATL封装的两个类CComBSTR和CComVariant。程序在最后读取属性的时候可以看到,读取的属性值的类型很多,但我们为了在Console中输出,需要做一些处理。
[a]具体是:如果它是Geometry,那么就直接用“Shape”来表示,如果它是其它的类型就把它转化成BSTR,当然本身是BSTR就不用转化了。(注意里面用到的L"",When working with CComBSTR, use the text mapping L"" to declare constant OLECHAR strings. )
[b]对BSTR本身来说无法直接链接两个BSTR,要连接需要转换(如用_bstr_t类)。但CComBSTR重载了+=,真是幸福的事,呵呵。
[c]最后一步在console中输出,cout不支持BSTR,无疑又要用到转换了。方法有两个:第一是用_bstr_t类,将BSTR转换成_bstr_t类型,然后输出;第二个是使用ATL提供的宏,OLE2A,这里需要在程序中添加USES_CONVERSION; 程序中只要添加一次就行了。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值