关于shape can,t have z values的问题解决方法

我碰到此问题是在做将“CAD数据导入到SDE数据库”时发现的,当时其主要原因是由于由于mutipatch数据形式的存在,问题已经解决,现拿出解决方法和大家分享。

                    IFeatureClass pLineFeatureClass = GetFeatureClassbyName(pLineFeatureName);
                    IPolyline pPolyline = PointCollection as IPolyline;


                    IFeature newLineFeature = pLineFeatureClass.CreateFeature();
                    try
                    {
                        newLineFeature.Shape = pPolyline;
                    }
                    catch
                    {
                        IGeometry pGeo = pPolyline;
                        IZAware pZAware = pGeo as IZAware;
                        pZAware.ZAware = false;
                        newLineFeature.Shape = pGeo;


                    }
                   newLineFeature.Store();

这是我直接在项目中截取的一段代码,其中红色部分为解决的主要方法,大家可以举一反三,其中点、线、面的数据格式都是一样的,我试验过了~~~



管线和其附属物的坐标数据都是带有Z值的

而且有些情况下,一个管段的两个端点的x,y值一模一样(垂直的管段)

这样的线,在直接生成shape图层的时候,就会产生问题,特别是

使用ArcSDE的C API直接创建到表中的时候你会发现,这样的数据是生成不了的

 

解决的方法就是为图层添加Z值,一个图层是否带有高程值,可以在ArcMap中通过查看

图层的属性表得知,带有Z值的图元,在Shape字段中,其类型后面会有个ZM字样

比如point ZM,Polyline ZM

带高程值的图元Shape字段显示状态

创建带高程Z值的图层时,只设置Point的Z属性是没有用的,默认情况下

ArcEngine会忽略Z值,

两步走,解决问题:

第一步:创建Shape图层,使用IFeatureWorkspace.CreateFeatureClass

此函数的第二个参数是IFields,字段定义,在字段定义中对Shape字段的类型

使用IGeometryDefEdit.HasZ_2 = true指定其包含Z值,

[c-sharp]  view plain  copy
  1. IGeometryDef pGeometryDef = new GeometryDef(); // 为esriFieldTypeGeometry类型的字段创建几何定义,包括类型和空间参照   
  2.                     IGeometryDefEdit pGeometryDefEdit = pGeometryDef as IGeometryDefEdit;  
  3.                     pGeometryDefEdit.GeometryType_2 = geometryType;  
  4.                     pGeometryDefEdit.HasZ_2 = true;//图层是有高程值的  
  5.                     pGeometryDefEdit.SpatialReference_2 = axmapcontrol.SpatialReference;                      
  6.                     pFieldEdit.GeometryDef_2 = pGeometryDef;  

第二步:添加图元,需要使用IZAware接口指定其ZAware为true

[c-sharp]  view plain  copy
  1. IPoint pFromPoint = new PointClass();  
  2. pFromPoint.PutCoords(fromX, fromY);                                                             
  3.                                 pFromPoint.Z = formZ;  
  4.                                 IZAware fromZAware = pFromPoint as IZAware;  
  5.                                 fromZAware.ZAware = true;  
  6.                                 //IZ iFromZ = (IZ)pFromPoint;  
  7.                                 IPoint pToPoint = new PointClass();  
  8.                                 pToPoint.PutCoords(toX, toY);                                  
  9.                                 pToPoint.Z = toZ;  
  10.                                 IZAware toZAware = pToPoint as IZAware;  
  11.                                 toZAware.ZAware = true;  
  12.                                 //IZ iToZ = (IZ)pToPoint;  
  13.                                   
  14.                                   
  15.                                 IPolyline pPolyline = new PolylineClass();  
  16.                                 IZAware iPolylineAware = (IZAware)pPolyline;  
  17.                                 iPolylineAware.ZAware = true;  
  18.                                 pPolyline.FromPoint = pFromPoint;  
  19.                                 pPolyline.ToPoint = pToPoint;  

顺便提一下ArcSDE C API中的此种问题,

一开始我以为比较简单,使用SE_layerinfo_set_3D就能解决问题,

但老有几条记录导入不了,使用field calculator查看一下图元的Z值才发现,

高程都变成整数了,我可以确定传入的数据是double型的,但是调用

SE_shape_generate_point和SE_shape_generate_line之后,生成的数据就是高程为整数

查了查,网上有代码说使用SE_coordref_set_precision设置坐标为高精度的,

我在创建layerinfo和插入shape的时候都进行了设置,却没有任何效果,只好暂时作罢.


20100723更新:

上面高程精度丢失问题解决了,

本来以为很简单,直接生成shape再用ArcCatalog导入到ArcSDE中,

用的时候发现,有几个图层死活导入不了,

提示错误是 ORA-01426: numeric overflow ,

于是还是得写代码直接导入,今天折腾了将近一天,想法是用C++直接调用SDE的C API来做,试试看值传入的有没有问题,

搞到下午,折腾的差不多了的时候,突然发现这个函数SE_coordref_set_z_by_range

使用高程的最大值最小值加0.001后传入这个函数,效果是立竿见影啊,立即搞定了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值