2010년 2월 7일 일요일

[Tips]Simplifying a geomtery

Simplify는 Geometry(이하 지오메트리)가 Topologically Legal(Correct, Consistency)한 상태를 만드는 과정이며, 일반적으로 ITopologicalOperator 인터페이스의 Simplify 메쏘드를 사용한다.

Simplify는 지도학에서의 일반화(Generalization)와는 전혀 다른 의미로 사용되며, 일반화는 IPolycurve 인터페이스의 Generalize(Douglas-Peucker simplification algorithm) 메쏘드를 사용할 수 있다.

여기에서는 Simplify의 개념과 Point, MultiPoint, Polyline, Polygon에서의 Simplify 적용 과정을 개략적으로 살펴본다.

1. When do I need to simplify a geometry?
* 원문출처 : http://resources.esri.com/help/9.3/ArcGISEngine/dotnet/0dfbaef2-4bb0-4ccb-b0d4-ee9b59b272d9.htm

About simplifying a geometry
Simplify는 입력 지오메트리를 영구적으로 변형하므로, 지오메트리 유형에 따른 Topologically Legal(Correct, Consistency)한 정의를 잘 고려해서 사용해야 한다.

* 참고 : ArcSDE Shape Verification Rules


Simplify 메쏘드를 사용하는 방법 및 사전에 필요한 정보는 아래 [2. What do I need to know before calling Simplify?] 섹션을 참고한다.
 
Simplify and points
Point 자체는 어떤 제약사항도 없기 때문에 Point 지오메트리에 대해서 Simplify를 적용하지 않는다.
 
Simplify and multipoints
Multipoint에 대해서
Simplify는 지오메트리의 spatial reference grid에 모든 x, y, z, m 좌표의 snap을 가하며, 중복(동일한) 포인트는 제거한다.

*
IGeometry의 SnapToSpatialReference 메쏘드 참고
: SnapToSpatialReference는 지오메트리의 공간좌표체계에 정의된 해상도(resolution)에 모든 좌표값을 맞춘다. 이는 지오메트리를 지오데이터베이스(*.mdb or ArcSDE)에 저장하는 방식과 비슷한 효과를 가진다.

포인트간에 X, Y 좌표가 같으면(Snapping 후에) 두 포인트는 동일하며 aware 속성이 있을 경우 aware 속성을 확인한다. 예를 들어, 두 포인트가 Z-aware라면 Z값까지 동일한지 확인한다.

○ Multipoint
Simplify 예:

Simplify and polylines
Polyline의 Simplify는
Planar와 Nonplanar의 2가지 유형이 있다.

Planar Simplify
기본적으로 m-aware가 아닌 Polyline의 경우에는 planar 방식으로 처리한다.
 - 모든 중복(overlapping) Segment는 단일 Segment로 변경되며 Segment는 교차점에서 분할(split)된다.
 - Output paths는 순차적으로 연결된 Segment로 생성된다.
 - 입력 Segment의 방향은 가능하면 유지되지만 Path의 Interior Segment는 필요할 경우 방향을 바꾼다(reoriented).

○  Nonplanar Simplify
M-aware를 사용하는 Polyline은 다음의 nonplanar simplify 방식으로 처리한다:
 - Overlaps과 self-intersections은 유지되나, 
zero-length Segment는 제거된다.
 -
Segment 방향은 조정되어Segment I의 끝점은 Segment I+1의 시작점과 같게 맞춘다.
 -
Segmen간에 연결되지 않는 곳은 새로운 path가 생성된다.
 - Segment 끝점이 만나는 2개의 path에 대해서는 2개의 path가 merge된다.
 
Polyline Simplify 예:
Simplify and polygons
Simplify는 폴리곤의 interior 및 exterior Ring을 식별하고 이에 맞춰 일관성을 유지하면서 폴리곤의 구조를 변경한다.

Interior 및 exterior Ring을 식별하는 기본적인 방법은 다음과 같다:
 -
Segment의 모든 Dangling(dangling sequences) 제거한다.
 - 기존 폴리곤에서 가장 큰
Ring(legal rings)을 식별한 후 새로 생성한 폴리곤에 추가하고 기존 링을 삭제한다.
 - 위 과정을 반복한다.
 - 만약 너무 많은
Segment가 제거되거나 할 경우, IPolygon4.SimplifyEx 메쏘드의 XOR 파라미터 사용을 고려해야 한다.
 
Polygon Simplify 예:
Polyline와 Polygon의 Simplify 과정에서 지오메트리 SpatialReference의 x,y tolerance 속성을 사용한다.

2. What do I need to know before calling Simplify?
* 원문출처: http://resources.esri.com/help/9.3/ArcGISEngine/dotnet/9df45774-c95a-4ae4-9a0d-3eedcf58c5c0.htm

About the Simplify method
Simplify 메쏘드는 High-level 지오메트리에만 적용할 수 있으며, High-level 지오메트리에는 Point, Multipoint, Polyline, Polygon이 있다.

이 메쏘드를 Low-level 지오메트리(segments-line, circular arc, elliptic arc, bezier curve, paths, rings 등)에 적용하기 위해서는 반드시 High-level 지오메트리로 변환해서 사용해야 한다.


다음 코드는 low-level(Line segment) 지오메트리를 High-level(Polyline) 지오메트리로 변환하는 예이다.

[code c#]
//Assume a line (line1 as ILine) is already created.
ILine line1 = new LineClass();

ISpatialReference spatialRef = null;
object obj = Type.Missing;
ISegmentCollection segCollection = new PolylineClass()as ISegmentCollection;
segCollection.AddSegment((ISegment)line1, ref obj, ref obj);

//Set the spatial reference on the new polyline.
//The spatial reference is not transferred automatically from the segments.
IGeometry geom = segCollection as IGeometry;
geom.SpatialReference = spatialRef;

//Can now be used with ITopologicalOperator methods.
ITopologicalOperator topoOpt = geom as ITopologicalOperator topoOpt;
IGeometry bufferedGeom = topoOpt.Buffer(500);
[/code]
Determining if the geometry is simple
위에서 말한대로 Simplify는 지오메트리를 영구적으로 변형(삭제, 생성, 구조변경 등)하므로 Simplify를 호출하기 전에 지오메트리가 Simple한지 판단해야 한다.

다음의 지오메트리는 일반적으로 Simple Geometry로 간주한다.
 : Empty 지오메트리, 피쳐클래스로부터 직접 불러온 지오메트리,
ITopologicalOperator의 메쏘드 결과로 생성된 지오메트리

다음의 지오메트리는 일반적으로 Not-Simple Geometry로 간주한다.
 : 일반적인 방법으로 지오메트리를 추가하여 생성한 Not
Empty Geometry
 : 다음의 메쏘드를 사용한 결과 지오메트리
  - P
rojection(IGeometry.Project)
  - Generalization(IPolycurve.Generalize)
  - Smoothing(IPolycurve.Smooth)

사용자는 IsKnownSimple 속성을 false로 설정하여 명시적으로 Simple하지 않다고 설정할 수 있으며, IsSimple 속성의 호출은 지오메트리의 IsSimple 상태를 알려준다.

다음의 코드처럼 IsKnownSimple 상태를 false로 설정했기 때문에 IsSimple의 리턴값은 false이다.

[code c#]
topoOp2.IsKnownSimple_2 = false;
bool bIsSimple = topoOp2.IsSimple;
[/code]
IsSimple 속성처럼 Simplify 메쏘드 역시 처리 전에 ITopologicalOperator.IsKnownSimple 플래그를 가장 먼저 체크한다.

만약 플래그가 true이면 Simplify 메쏘드는 지오메트리가 Simple한 것으로 간주하고 처리를 중단하며, 플래그가 false이면 지오메트리 일관성을 체크한 후 필요하면 지오메트리를 갱신한다. Simplify 메쏘드 호출 후 IsKnownSimple 플래그는 true로 설정된다.

다음은 지오메트리의
IsKnownSimple 플래그를 false로 설정하여 Simplify를 수행하는 예이다.
[code c#]
topoOp2.IsKnownSimple_2 = false;
topoOp2.Simplify();
[/code]
경험상 응용프로그램 개발할 때 IDisplayFeedback(Polyline, Polygon 등) 등을 사용하여 MapControl로부터 지오메트리를 생성했을 경우에도 반드시 Simplify를 수행해야 한다.