환경계측데이터에 대한 보간 및 TMS 가공

환경과 관련된 계측 데이터에는 풍속, 풍향, 온도, 미세먼지, 오존농도 등이 있습니다. 이러한 계측 데이터는 일정한 시간 주기로 측정되고 측정된 값은 관련된 시스템의 서버에 저장되어, 이를 필요로 하는 곳에서 활용할 수 있도록 다양한 방식으로 제공되는데요. 제공되는 방식은 파일 기반으로 다운로드 받을 수 있거나 OpenAPI 형태로 효과적으로 서비스 받을 수 있습니다.

계측 데이터는 공간 상에 특정한 위치에 계측기를 설치하여 측정되는데요. 측정되지 못하는 지점에 대한 계측값은 이미 계측된 다른 가까운 지점들을 이용하여 보간(Interpolation)됩니다. 공간에 대한 보간 알고리즘은 Spline, Kernel Density, IDW, Kriging 등이 있고 각 보간 알고리즘마다 하나의 좋은 주제로써 추후 시간을 내어 연구해 볼만합니다.

이 글은 이러한 환경과 관련된 계측 데이터를 보간하고, 보간된 결과를 웹에서 누구나 쉽게 조회할 수 있도록 지도로 서비스할 수 있는 TMS 형태로 가공하여 OpenLayer나 Leaflet와 같은 가장 많이 사용하는 오픈소스 기반의 클라이언트 지도 엔진에서 활용하는 것에 대한 내용을 정리해 보았는데요. 각 처리 과정에서 활용한 툴은 자체적으로 개발된 엔진을 이용하여 보다 빠르게 처리할 수 있었습니다.

최종적으로 웹 기반의 지도로 서비스될 계측 데이터는 ‘온도’로 하였습니다. 전세계의 온도 데이터는 다양한 경로를 통해 다운로드받을 수 있습니다. 아래의 그림은 전세계의 위경도에 대해 1도마다 측정된 온도 데이터를 보다 쉽게 보간할 수 있도록 SHP 파일 형태로 변환하는 내용입니다.

온도에 대한 계측 지점에 대한 온도값 속성으로 단위가 켈빈인 K 값을 담고 있습니다.

이제 이 계측값에 대한 SHP 파일을 보간을 통해 모든 지점에 대한 계측값을 계산할 수 있는데요. 아래의 그림은 보간 방법 중 IDW 알고리즘을 사용한 것으로, 그 결과에 대해 의미있는 색상을 적용해 표현한 것입니다.

보간된 데이터는 그리드(Grid) 형태입니다. 이를 TMS 형태의 격자로 가공하기 위해 아래의 화면과 같이 Mr.Tiler-Xr이라는 타일맵 가공툴을 이용해 가공합니다.

이렇게 가공된 TMS 형식의 타일맵에 약간의 투명도를 주어 OpenLayers를 이용해 OpenStreetMap을 배경지도 상에 정확히 중첩되는지 확인한 화면은 아래와 같습니다.

추후 이러한 일련된 과정을 자동화하여 주기적으로 들어오는 계측값을 자동으로 TMS 형식의 타일맵으로 가공해 서버측에 저장해 두는 기능을 고려하고 있습니다.

DuraMap-Xr에서 마우스 Wheel로 지도 확대, 축소하기

DuraMap-Xr의 Mouse Wheel 이벤트를 이용해 지도를 확대 축소하는 이벤트에 대한 글을 정리합니다. 배경지도는 TMS 형식으로 활용할 수 있는 VWorld를 이용합니다. 먼저 VWorld의 배경지도에 대한 Layer는 아래처럼 추가할 수 있는데요. 저는 아래의 코드를 폼(Form)이 Shown 이벤트에 추가하였습니다.

XrMapLib.ValueList URLs = new XrMapLib.ValueList();
URLs.AddValueByString(VWORLD_TMS_URL);

XrMapLib.Extent MaxMBR = new XrMapLib.Extent();
MaxMBR.MinX = -20037508.342789244;
MaxMBR.MinY = -20037508.342789244;
MaxMBR.MaxX = 20037508.342789244;
MaxMBR.MaxY = 20037508.342789244;

double[] upps = {
    78000, 39000, 19600, 9800, 4900, 2400, //Dummy
    1222.9924523925781, 611.4962261962891, 305.74811309814453,
    152.87405654907226, 76.43702827453613, 38.218514137268066,
    19.109257068634033, 9.554628534317017, 4.777314267158508,
    2.388657133579254, 1.194328566789627, 0.5971642833948135, 0.5971642833948135/2 };

XrMapLib.ValueList UPPs = new XrMapLib.ValueList();

Scales.Clear();

for (int iUPP = 0; iUPP < upps.Length; ++iUPP)
{
    double UPP = upps[iUPP];
    double MapScale = axXr1.GetMapScaleFromUPP(UPP);

    UPPs.AddValueByFloat(UPP, 14);

    if (iUPP > 5) // upps 배열에서 0~4번째는 한국에서는 사용되지 않음
    {
        Scales.Add(MapScale);
    }
}

axXr1.Layers.AddTMSLayer("basemap", URLs, MaxMBR, UPPs, true);
axXr1.WaitForAllConnections();

XrMapLib.Coord MapPt = new XrMapLib.Coord();
MapPt.X = 14145315;
MapPt.Y = 4514689;
            
axXr1.MapCenter = MapPt;
axXr1.MapScale = Scales[0];
axXr1.Update();

axXr1.MouseMode = XrMapLib.XrMapViewModeEnum.XrPanMode;

참고로 듀라맵 지도 뷰어 컨트롤의 변수는 axXr1입니다. 위의 코드를 보면 Scales라는 전역 변수가 보입니다. 이 Scales는 다음처럼 정의되어 있습니다. Scales 컨터이너 변수는 각 지도 줌 단계에 대한 축척값을 담고 있습니다.

private List<double> Scales = new List<double>();

이제 지도 컨트롤의 마우스 휠 이벤트를 등록합니다. 아래의 코드는 듀라맵 지도 뷰 컨트롤의 휠 이벤트에 할당된 이벤트 함수입니다.

private void axXr1_OnMouseWheel(object sender, AxXrMapLib._IXrMapControlEvents_OnMouseWheelEvent e)
{
    double NewMapScale = axXr1.MapScale;

    // 현재 지도 축척값 중 가장 가까운 줌 레벨 얻기
    int cntLevels = Scales.Count;
    double Gap = Double.MaxValue;
    int CurrentLevel = -1;
    for (int i = 0; i < cntLevels; i++)
    {
        double ThatGap = Math.Abs(NewMapScale - Scales[i]);
        if (Gap > ThatGap)
        {
            Gap = ThatGap;
            CurrentLevel = i;
        }
    }

    if(e.delta == 120) // Wheel Up
    {
        int idx = CurrentLevel + 1;
        if (idx >= Scales.Count) idx = Scales.Count - 1;
        axXr1.MapScale = Scales[idx];
    }
    else  // Wheel Down
    {
        int idx = CurrentLevel - 1;
        if (idx < 0) idx = 0;
        axXr1.MapScale = Scales[idx];
    }

    axXr1.Update();
}

DuraMap-Xr 설치자(Installer)

GIS 엔진인 DuraMap-Xr을 쉽고 간단하게 설치할 수 있는 설치 프로그램입니다. 아래의 파일을 다운로드 받아 실행해 클릭만으로 간단히 DuraMap-Xr을 설치할 수 있습니다.



좀더 자세히 설명 드리면, 먼저 설치 프로그램을 실행하면 다음과 같은 프로그램이 표시됩니다.

처음 설치할 경우 Install 버튼을 클릭해 설치하면 되고, 버전업 등과 같은 업데이트는 Update 버튼을 클릭하면 됩니다. 그리고 깨끗히 제거 하기 위해서 Remove 버튼을 클릭하면 됩니다.

이 설치자는 Windows 10 64Bits에서 정상적인 작동을 확인하였습니다. 설치나 삭제 등에서 문제가 발생할 경우에 대한 기술지원은 댓글을 이용해 주시기 바랍니다.

GIS Server(GeoService-Xr)의 다중 DBMS Server 구성예

하나의 공간 서버(GeoService-Xr)에 대해 여러 개의 DBMS Server를 구성하는 경우에 대한 내용을 정리해 둡니다. 하드웨어적으로 다른 DBMS 서버는 물론이고, 동일한 서버에서 여러 개의 DBMS를 설치하거나, Port를 달리하거나 데이터베이스 명을 다르게 하여 분류해 사용하는 경우 모두 적용될 수 있습니다. 예를 들어 아래와 같은 구성 화면을 살펴보면..

하드웨어적으로 분리된 2개의 DBMS Server가 있으며, 192.168.0.200의 Server는 동일한 DBMS에서 Database 명을 달리해 구분하도록 되어 있습니다.

위의 구성에 대한 Geodata 설정 파일을 아래와 같습니다.

<?xml version="1.0" encoding="euc-kr"?>
<XrGeoData>
    <Connections>
        <Connection 
            name="db_server1" 
            type="postgis" 
            driverName="org.postgresql.Driver" 
            url="jdbc:postgresql://192.168.0.100:5432/gis" 
            user="postgres" 
            password="@#$%^" 
            count="32" 
        />

        <Connection
            name="db_server2" 
            type="postgis" 
            driverName="org.postgresql.Driver" 
            url="jdbc:postgresql://192.168.0.200:5432/gis" 
            user="postgres" 
            password="@#$%^" 
            count="32" 
        />

        <Connection
            name="db_server2_2" 
            type="postgis" 
            driverName="org.postgresql.Driver" 
            url="jdbc:postgresql://192.168.0.200:5432/gis2" 
            user="postgres" 
            password="@#$%^" 
            count="32" 
        />
  </Connections>

    <GeoDataList>
        <GeoData>
            <Name>ecl_facility</Name>
            <ConnectionString>db_server1://public."ecl_facility"</ConnectionString>
            <EPSG>5179
        </GeoData>

        <GeoData>
            <Name>swl_facility</Name>
            <ConnectionString>db_server2://public."swl_facility"</ConnectionString>
            <EPSG>5179
        </GeoData>
    </GeoDataList>
</XrGeoData>

위의 geodata 설정 내용 중 Connection의 name은 생략될 수 있으며, 만약 생략될 경우 type의 값으로 name이 대체됩니다.

GDAL에서 제공하는 Command 정리

GDAL은 geotif 등과 같은 Raster 데이터에 대해 수행할 수 있는 다양한 Command를 제공합니다. Raster 파일에 대한 Extent와 좌표계 정보를 얻을 수 있는 gdalinfo.exe에서부터 영상에서 특정 영역만을 뽑아내 또 다른 영상 파일로 저장할 수도 있고, 좌표계에 대한 투영변환도 가능하며 GCP를 지정해 Georeferencing도 가능합니다. GIS 개발자에게 Raster 데이터를 저수준에서 처리하기 위해 GDAL는 매우 활용도가 높고 중요한 오픈소스 라이브러리입니다. (GDAL 라이브러리만 있다면 어떠한 GIS 데이터 포맷이든 모두 내 손 안에 있다규 !!)

GDAL에서 제공하는 Command 명령 중 실제 작업 중에 사용했던 것을 정리해 둡니다.

1. Raster 데이터의 정보 보기

Z:\> gdalinfo A.tif

위의 명령은 A.tif 파일에 대한 좌표계 및 Extents 등에 대한 정보를 얻기 위한 명령입니다.

2. geotif 영상에서 원하는 부분만을 잘라내 또다른 파일로 저장하기

Z:\> gdalwarp -te 197789.97 552829.04 199789.97 554829.04 G:\img\geotif\Seoul_10cm_GRS80.tif g:\a.tif

위의 명령은 Seoul_10cm_GRS80.tif 영상 파일에서 MBR(197789.97 552829.04 199789.97 554829.04)에 대한 부분을 a.tif 파일로 저장하기 위한 명령입니다.

3. GCP를 지정한 Georeferencing 하기

Z:\> gdal_translate -of GTiff -gcp 48.954 1298.304 219084 362071 -gcp 1174.042 348.95 219261 362144 -gcp 2610.376 5.8401 219418 362116 A.jpg B.tif
Z:\> gdalwarp -r lanczos B.tif C.tif

위의 연속적으로 실행되는 2개의 명령 중 첫번째는 GCP를 3개 사용해 입력 파일인 A.jpg 파일에 대해 Georeferencing 하여 B.tif 파일로 저장하라는 명령이고, 두번째는 저장된 B.tif를 Resizing 알고리즘 중 lanczos를 사용해 c.tif 파일로 저장하라는 명령입니다.