[GIS] GeoService-Xr, PostGIS으로부터 Geometry 읽기 오류 Fix

GeoService-Xr은 DuraMap-Xr, FingerEyes-Xr, BlackPoint-Xr을 통해 공간 데이터를 서비스하는 공간 데이터 서버입니다. GeoService-Xr은 ArcSDE, MySQL 그리고 PostgreSQL을 통해 공간 데이터를 읽고 쓸 수 있습니다.

PostgreSQL은 PostGIS을 통해 공간 데이터를 질의하고 있으며 GeoService-Xr 역시 PostGIS를 사용합니다. 이러한 PostGIS을 통해 지오메트리를 읽는 GeoService-Xr의 기능 중 Multi-Polygon에 대해 옳바르게 도형을 표현하지 못하는 문제점이 있어서 이에 대한 버그를 해결하였습니다.

버그 대상이 되는 폴리곤은 Ring을 여러개 가지는 폴리곤으로써.. 예를 들어 구멍이 뚫린 폴리곤의 경우입니다. 아래의 그림은 버그가 해결된 상태에서 PostGIS를 통해 공간 데이터를 가져와 FingerEyes에서 표출한 화면입니다. 클릭하면 원본 크기로 볼 수 있습니다.


해결된 부분에 대한 GeoService-Xr의 소스 코드 부분은 다음과 같습니다. 문제의 근본적인 원인은 PostGIS에서 폴리곤에 대한 Geometry Type에 대한 제 스스로에 대한 이해 부족입니다. 혹… PostGIS를 통해 공간 데이터를 쿼리하고 결과를 받아 좌표를 뽑아 낼때 아래의 코드가 조금이나마 도움이 되시길 바랍니다.

} else if(geometryType_ == Geometry.MULTIPOLYGON) {
    while(row.next()) {
        PGgeometry geom = (PGgeometry)row.getObject(shapeFieldIndex);
        ComposedGeom shp = (ComposedGeom)geom.getGeometry();
        
        // 멀티폴리곤을 구성하는 Ring의 개수 구하기  
        short cntPart = 0; // Ring의 개수!
        int cntGeoms = shp.numGeoms();
        for(int iGeom=0; iGeom        Polygon polygon = (Polygon)shp.getSubGeometry(iGeom);
            cntPart += polygon.numRings();
        }
  
        // 각 Ring을 구성하는 정점(Vertex) 구하기
        for(int iGeom=0; iGeom            Polygon polygon = (Polygon)shp.getSubGeometry(iGeom);
            int numRings = polygon.numRings();
            for(int iRing=0; iRing                LinearRing ring = polygon.getRing(iRing);
                int numPts = ring.numPoints();
                for(int iPt=0; iPt                    Point vtx = ring.getPoint(iPt); // 정점!
                }
            }
        }
    }
}

주의 할점은 멀티폴리곤은 Polygon으로 구성되며 Polygon은 다시 LinearRing으로 구성된다는 점입니다. Polygon이 다시 LinearRing으로 구성되는 이유는 구멍이 뚫린 폴리곤 등을 나타내기 위함입니다.