2012년 2월 21일 화요일

[ArcObjects]두 FeatureClass의 XY Domain 범위 합치기..

 

> 두 개의 A, B FeatureClass를 Merge하여 하나의 FeatureClass로 만드는 과정에서..

> A의 Fields를 사용하여 새로운 FeatureClass를 만들고 A와 B의 FeatureClass의 Geometry를 Insert 하는 과정에서 A의 SpatialReference에 정의된 XY Domain의 범위에서 벗어난 Geometry가 B에 존재한다면 “The coordinates or measures are out of bounds.” 이라는 오류가 발생했다.

> 물런 IBasicGeoprocessor 인터페이스의 Merge 메소드를 사용하면 별 문제 없이 작업이 가능하겠지만 단순한 Merge 작업이 아닌 중간에 어떠한 프로세스가 들어간다면 어쩔 수없이 수동으로 Merge작업을 해야 한다.

> 위 오류는 ArcMap에서 Edit 작업 시에도 정의된 Domain 범위 이외의 지역에 새로운 Geometry를 저장하려 할 경우 같은 오류가 발생한다.

> END(ESRI Developer Network)에 따르면 XY Domain의 범위는 최초 FeatureClass가 생성될 때 지정되면 변경할 수가 없단다.. ㅜㅜ

> 결국 새로운 FeatureClass의 SpatialReference를 설정할 때 A, B 두 개의 XY Domain을 비교하여 넓은 범위의 XY Domain을 찾아서 설정한 후에 작업을 진행하면 된다.

> 아래 코드는 두 개의 FeatureClass의 XY Domain을 비교하여 새로운 XY Domain을 설정하는 코드이다.

   1: private void RecalculateDomain(IFeatureClass pFC1, IFeatureClass pFC2, IFields pFields)
   2: {
   3:     if (pFC1 == null) return;
   4:     if (pFC2 == null) return;
   5:     if (pFields == null) return;
   6:     if (pFields.FieldCount < 1) return;
   7:  
   8:     IField pField = null;
   9:  
  10:     for (int i = 0; i < pFields.FieldCount; i++)
  11:     {
  12:         pField = pFields.get_Field(i);
  13:  
  14:         if (pField.Type == esriFieldType.esriFieldTypeGeometry) break;
  15:  
  16:         pField = null;
  17:     }
  18:  
  19:     if (pField == null) return;
  20:  
  21:     ISpatialReference pDestSp = pField.GeometryDef.SpatialReference;
  22:  
  23:     double dXMin1 = 0;
  24:     double dXMax1 = 0;
  25:     double dYMin1 = 0;
  26:     double dYMax1 = 0;
  27:  
  28:     double dXMin2 = 0;
  29:     double dXMax2 = 0;
  30:     double dYMin2 = 0;
  31:     double dYMax2 = 0;
  32:  
  33:     double dXMinNew = 0;
  34:     double dXMaxNew = 0;
  35:     double dYMinNew = 0;
  36:     double dYMaxNew = 0;
  37:  
  38:     IGeoDataset pGeoDs = (IGeoDataset)pFC1;
  39:     pGeoDs.SpatialReference.GetDomain(out dXMin1, out dXMax1, out dYMin1, out dYMax1);
  40:  
  41:     pGeoDs = (IGeoDataset)pFC2;
  42:     pGeoDs.SpatialReference.GetDomain(out dXMin2, out dXMax2, out dYMin2, out dYMax2);
  43:  
  44:     dXMinNew = (dXMin1 < dXMin2) ? dXMin1 : dXMin2;
  45:     dXMaxNew = (dXMax1 > dXMax2) ? dXMax1 : dXMax2;
  46:     dYMinNew = (dYMin1 < dYMin2) ? dYMin1 : dYMin2;
  47:     dYMaxNew = (dYMax1 > dYMax2) ? dYMax1 : dYMax2;
  48:  
  49:     pDestSp.SetDomain(dXMinNew, dXMaxNew, dYMinNew, dYMaxNew);
  50: }