크리깅(Kriging) 공간분석

공간 상에 분포된 값 기반의 보간 방식 중 하나인 크리깅을 기능 단위로 만든 코드를 정리한 글입니다. GIS 엔진은 웹 GIS 컴포넌트인 FingerEyes-Xr를 사용했습니다. 크리깅 알고리즘은 오픈소스 라이브러리인 kriging.js를 사용하였으므로 Leaflet이나 OpenLayers에 대한 API에 익숙한 개발자라면 해당 GIS 컴포넌트로도 크리깅 결과에 대한 효과적인 시각화를 구현할 수 있을 것입니다. 웹 기반에서 수행되지만 별도의 서버가 필요하지 않습니다. 지도는 VWorld의 배경지도를 그대로 이용할 것이며 크리깅을 위한 입력 데이터는 실행시 동적으로 생성할 것이기 때문입니다.

결과를 이미지로 먼저 살펴보면 아래와 같습니다.

0~100까지의 값을 가지는 총 35개의 지점이 있고 특정 영역 안에서 크리깅 분석을 수행해 그 결과를 그라디언트 색상으로 표현하는 것인데요. 먼저 특정 영역에 대한 좌표를 지정하고 지도에 표시하는 코드는 다음과 같습니다.

let psd = new Xr.data.PolygonShapeData([[
    new Xr.PointD(14289447.80, 4437166.67),
    new Xr.PointD(14289920.87, 4437347.65),
    new Xr.PointD(14289963.20, 4437210.07),
    new Xr.PointD(14290033.05, 4437198.42),
    new Xr.PointD(14289981.19, 4436636.45),
    new Xr.PointD(14289942.04, 4436488.28),
    new Xr.PointD(14289879.60, 4436349.64),
    new Xr.PointD(14289733.55, 4436420.55),
    new Xr.PointD(14289717.67, 4436438.54)
]]);

let psr = new Xr.data.PolygonGraphicRow(0, psd);

psr.brushSymbol().opacity(0);
psr.penSymbol().color('#ff0000');

gl.rowSet().add(psr);

0~100까지 난수로 부여된 값을 가지는 총 35개의 지점을 지도에 표시하는 코드는 다음과 같구요.

const x = [
    14289539.88, 14289633.01, 14289713.44, 14289812.93, 14289912.41,
    14289598.08, 14289698.63, 14289809.75, 14289883.83, 14289952.62,
    14289747.31, 14289760.01, 14289779.06, 14289793.88, 14289815.04,
    14289836.21, 14289864.78, 14289920.87, 14289698.63, 14289665.82,
    14289758.95, 14289697.57, 14289771.65, 14289732.49, 14289804.46,
    14289828.8, 14289839.38, 14289853.14, 14289885.95, 14289853.14,
    14289878.54, 14289876.42, 14289942.04, 14289929.34, 14289912.41
];

const y = [
    4437041.79, 4437076.72, 4437109.52, 4437148.68, 4437185.72,
    4436892.57, 4436923.26, 4436970.88, 4436999.46, 4436999.46,
    4436877.75, 4436834.36, 4436785.67, 4436736.99, 4436681.96,
    4436626.92, 4436563.42, 4436512.62, 4436824.83, 4436761.33,
    4436740.17, 4436667.14, 4436638.57, 4436577.18, 4436553.90,
    4436927.49, 4436879.87, 4436834.36, 4436790.97, 4436723.23,
    4436687.25, 4436629.04, 4436890.45, 4436744.40, 4436600.47
];

const t = [];

for (let i = 0; i < x.length; i++) {
    t[i] = Math.random() * 100.0;

    let p = new Xr.PointD(x[i], y[i]);
    let tsd = new Xr.data.TextShapeData({ x: x[i], y: y[i], text: t[i] >> 0 });
    let pgr = new Xr.data.TextGraphicRow(i + 1, tsd);

    gl.rowSet().remove(i + 1);
    gl.rowSet().add(pgr);
}

크리깅을 위한 입력값이 준비되어 있으므로 크리깅 분석을 아래의 코드처럼 수행합니다.

const variogram = kriging.train(t, x, y, "spherical", 0, 100);

이제 크리깅 분석 결과를 지도에 표시하기 위해 GridLayer를 사용하게 되는데, 크리깅 분석 결과 모델을 토대로 모르는 지점에 대한 값도 예측할 수 있으며 이 값들을 토대로 적절하게 색상을 배합하면 됩니다. 이러한 코드는 다음과 같습니다.

gridLyr.reset();

const minX = psr.MBR().minX;
const maxX = psr.MBR().maxX;
const minY = psr.MBR().minY;
const maxY = psr.MBR().maxY;

for (let x = minX; x < maxX; x += cellRes) {
    for (let y = minY; y < maxY; y += cellRes) {
        const v = kriging.predict(x, y, variogram);
        gridLyr.value(x, y, v);
    }
}

let clrTbl = new Xr.ColorTable(6);
                    
clrTbl.set(5, 225, 228, 177, 230);
clrTbl.set(4, 190, 208, 122, 230);
clrTbl.set(3, 152, 193, 99, 230);
clrTbl.set(2, 97, 168, 93, 230);
clrTbl.set(1, 46, 146, 85, 230);
clrTbl.set(0, 20, 102, 59, 230);

if (clrTbl.build()) {
    gridLyr.updateByColorTable(clrTbl, psd);
    map.update();
}

GridLayer에 대한 변수는 gridLyr이며 크리깅 보간을 통해 gridLayer 내부의 전체 셀값들이 업데이트됩니다. updateByColorTable 함수를 통해 표현할 색상과 원하는 경계 이외의 셀은 투명하게 잘리게 됩니다. 원하는 경계는 psd라는 변수로 지정하고 있는데 이 psd는 앞서 생성한 특정 영역에 대한 그래픽 요소 객체입니다. 참고로 gridLyr 객체의 생성 코드는 다음과 같습니다.

let cellRes = 1;
let gridLyr = new Xr.layers.GridLayer("grid",
    {
        mbr: psr.MBR(),
        resolution: cellRes
    }
);

이상으로 잘 만들어진 크리깅 라이브러리를 이용하여 웹 상에서 크리깅 분석을 수행하고 그 분석 결과를 시각화하는 코드에 대해 살펴 보았습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다