FingerEyes-Xr에서 속성값으로 도형 심벌 및 라벨문자열 설정하기

여러 개의 속성값으로 라벨 문자열을 조립하여 실제 표시되는 라벨을 결정하는 코드의 예입니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
CustomLabelFormatter = Xr.Class({
name: "CustomLabelFormatter",
extend: Xr.label.ProgrammableLabelFormatter,
requires: [Xr.label.ILabelFormatter],
construct: function (layer) {
this.superclass(layer);
this._MGN_CD = -1;
this._MGN_DT = -1;
this._codeValues = {
'C01': '시설A',
'C02': '시설B',
'P01': '시설C',
'P03': '시설D',
'R03': '시설E',
'T01': '시설F'
};
},
methods: {
value: function (shapeRow, fieldSet, attributeRow) {
if (this._EQMT_FIXPLC_RGN_SE_CD == -1) {
this._EQMT_FIXPLC_RGN_SE_CD = fieldSet.fieldIndex("MGN_CD");
}
if (this._FST_REGI_TSP == -1) {
this._FST_REGI_TSP = fieldSet.fieldIndex("_MGN_DT");
}
let code = attributeRow.valueAsString(this._MGN_CD);
// 필드 2개의 값(_MGN_CD 필드의 코드값 + _MGN_DT 의 값)을 조합한 라벨 표시, 예: 시설B(2020-07-27 14:32:32)
return this._codeValues[code] + "(" + attributeRow.valueAsString(this._MGN_DT) + ")";
}
}
});
var lyr = new Xr.layers.ShapeMapLayer("lyr", ...);
let label = lyr.label();
label.enable(true);
let formatter = new CustomLabelFormatter(lyr);
label.formatter(formatter);
lm.add(lyr);
CustomLabelFormatter = Xr.Class({ name: "CustomLabelFormatter", extend: Xr.label.ProgrammableLabelFormatter, requires: [Xr.label.ILabelFormatter], construct: function (layer) { this.superclass(layer); this._MGN_CD = -1; this._MGN_DT = -1; this._codeValues = { 'C01': '시설A', 'C02': '시설B', 'P01': '시설C', 'P03': '시설D', 'R03': '시설E', 'T01': '시설F' }; }, methods: { value: function (shapeRow, fieldSet, attributeRow) { if (this._EQMT_FIXPLC_RGN_SE_CD == -1) { this._EQMT_FIXPLC_RGN_SE_CD = fieldSet.fieldIndex("MGN_CD"); } if (this._FST_REGI_TSP == -1) { this._FST_REGI_TSP = fieldSet.fieldIndex("_MGN_DT"); } let code = attributeRow.valueAsString(this._MGN_CD); // 필드 2개의 값(_MGN_CD 필드의 코드값 + _MGN_DT 의 값)을 조합한 라벨 표시, 예: 시설B(2020-07-27 14:32:32) return this._codeValues[code] + "(" + attributeRow.valueAsString(this._MGN_DT) + ")"; } } }); var lyr = new Xr.layers.ShapeMapLayer("lyr", ...); let label = lyr.label(); label.enable(true); let formatter = new CustomLabelFormatter(lyr); label.formatter(formatter); lm.add(lyr);
CustomLabelFormatter = Xr.Class({
    name: "CustomLabelFormatter",
    extend: Xr.label.ProgrammableLabelFormatter,
    requires: [Xr.label.ILabelFormatter],
    construct: function (layer) {
        this.superclass(layer);
        this._MGN_CD = -1;
        this._MGN_DT = -1;
        this._codeValues = {
            'C01': '시설A',
            'C02': '시설B',
            'P01': '시설C',
            'P03': '시설D',
            'R03': '시설E',
            'T01': '시설F'
        };
    },
    methods: {
        value: function (shapeRow, fieldSet, attributeRow) {
            if (this._EQMT_FIXPLC_RGN_SE_CD == -1) {
                this._EQMT_FIXPLC_RGN_SE_CD = fieldSet.fieldIndex("MGN_CD");
            }

            if (this._FST_REGI_TSP == -1) {
                this._FST_REGI_TSP = fieldSet.fieldIndex("_MGN_DT");
            }

            let code = attributeRow.valueAsString(this._MGN_CD);

            // 필드 2개의 값(_MGN_CD 필드의 코드값 + _MGN_DT 의 값)을 조합한 라벨 표시, 예: 시설B(2020-07-27 14:32:32)
            return this._codeValues[code] + "(" + attributeRow.valueAsString(this._MGN_DT) + ")";
        }
    }
});

var lyr = new Xr.layers.ShapeMapLayer("lyr", ...);
let label = lyr.label();
label.enable(true);

let formatter = new CustomLabelFormatter(lyr);
label.formatter(formatter);

lm.add(lyr);

다음은 속성값으로 도형의 스타일 심벌을 지정하는 코드의 예입니다.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
CustomLayerTheme = Xr.Class({
name: "CustomLayerTheme",
extend: Xr.theme.ProgrammableShapeDrawTheme,
requires: [Xr.theme.IShapeDrawTheme],
construct: function (/* ShapeMapLayer */ layer) {
this.superclass(layer);
this._fieldIndex = -1;
let codes = ['R01', 'P02', 'R03', 'P01', 'P02', 'T01', 'T02', 'C01', 'C02'];
let colors = ['#f1c40f', '#f39c12', '#e67e22', '#e74c3c', '#c0392b', '#ff0000', '#00ff00', '#0000ff', '#ff00ff'];
let symbols = [];
let cntCodes = codes.length;
for (let i = 0; i < cntCodes; i++) {
let SDS = new Xr.symbol.ShapeDrawSymbol();
SDS.brushSymbol().color(colors[i]).opacity(0.5);
SDS.penSymbol().color(colors[i]).width(2);
let symbol = {
code: codes[i],
symbol: SDS
};
symbols[i] = symbol;
}
this._symbols = symbols;
},
methods: {
/* ShapeDrawSymbol */ symbol: function (/* ShapeRow */ shapeRow, /* FieldSet */ fieldSet, /* AttributeRow */ attributeRow) {
if (this._fieldIndex === -1) {
this._fieldIndex = fieldSet.fieldIndex("MGN_CD");
}
let value = attributeRow.valueAsString(this._fieldIndex);
let symbols = this._symbols;
let symbol = undefined;
let cntSymbols = symbols.length;
for (var i = 0; i < cntSymbols; i++) {
symbol = symbols[i];
if (value === symbol.code) {
break;
}
}
return symbol.symbol;
},
/* boolean */ needAttribute: function () {
return true;
}
}
});
var lyr = new Xr.layers.ShapeMapLayer("lyr", ...);
var newTheme = new CustomLayerTheme(lyr)
lyr.theme(newTheme);
lm.add(lyr);
CustomLayerTheme = Xr.Class({ name: "CustomLayerTheme", extend: Xr.theme.ProgrammableShapeDrawTheme, requires: [Xr.theme.IShapeDrawTheme], construct: function (/* ShapeMapLayer */ layer) { this.superclass(layer); this._fieldIndex = -1; let codes = ['R01', 'P02', 'R03', 'P01', 'P02', 'T01', 'T02', 'C01', 'C02']; let colors = ['#f1c40f', '#f39c12', '#e67e22', '#e74c3c', '#c0392b', '#ff0000', '#00ff00', '#0000ff', '#ff00ff']; let symbols = []; let cntCodes = codes.length; for (let i = 0; i < cntCodes; i++) { let SDS = new Xr.symbol.ShapeDrawSymbol(); SDS.brushSymbol().color(colors[i]).opacity(0.5); SDS.penSymbol().color(colors[i]).width(2); let symbol = { code: codes[i], symbol: SDS }; symbols[i] = symbol; } this._symbols = symbols; }, methods: { /* ShapeDrawSymbol */ symbol: function (/* ShapeRow */ shapeRow, /* FieldSet */ fieldSet, /* AttributeRow */ attributeRow) { if (this._fieldIndex === -1) { this._fieldIndex = fieldSet.fieldIndex("MGN_CD"); } let value = attributeRow.valueAsString(this._fieldIndex); let symbols = this._symbols; let symbol = undefined; let cntSymbols = symbols.length; for (var i = 0; i < cntSymbols; i++) { symbol = symbols[i]; if (value === symbol.code) { break; } } return symbol.symbol; }, /* boolean */ needAttribute: function () { return true; } } }); var lyr = new Xr.layers.ShapeMapLayer("lyr", ...); var newTheme = new CustomLayerTheme(lyr) lyr.theme(newTheme); lm.add(lyr);
CustomLayerTheme = Xr.Class({
    name: "CustomLayerTheme",
    extend: Xr.theme.ProgrammableShapeDrawTheme,
    requires: [Xr.theme.IShapeDrawTheme],
    construct: function (/* ShapeMapLayer */ layer) {
        this.superclass(layer);
        this._fieldIndex = -1;
        let codes = ['R01', 'P02', 'R03', 'P01', 'P02', 'T01', 'T02', 'C01', 'C02'];
        let colors = ['#f1c40f', '#f39c12', '#e67e22', '#e74c3c', '#c0392b', '#ff0000', '#00ff00', '#0000ff', '#ff00ff'];
        let symbols = [];
        let cntCodes = codes.length;
        for (let i = 0; i < cntCodes; i++) {
            let SDS = new Xr.symbol.ShapeDrawSymbol();
            SDS.brushSymbol().color(colors[i]).opacity(0.5);
            SDS.penSymbol().color(colors[i]).width(2);

            let symbol = {
                code: codes[i],
                symbol: SDS
            };

            symbols[i] = symbol;
        }

        this._symbols = symbols;
    },
    methods: {
/* ShapeDrawSymbol */ symbol: function (/* ShapeRow */ shapeRow, /* FieldSet */ fieldSet, /* AttributeRow */ attributeRow) {
            if (this._fieldIndex === -1) {
                this._fieldIndex = fieldSet.fieldIndex("MGN_CD");
            }

            let value = attributeRow.valueAsString(this._fieldIndex);
            let symbols = this._symbols;
            let symbol = undefined;
            let cntSymbols = symbols.length;
            for (var i = 0; i < cntSymbols; i++) {
                symbol = symbols[i];
                if (value === symbol.code) {
                    break;
                }
            }
            return symbol.symbol;
        },

/* boolean */ needAttribute: function () {
            return true;
        }
    }
});


var lyr = new Xr.layers.ShapeMapLayer("lyr", ...);

var newTheme = new CustomLayerTheme(lyr)
lyr.theme(newTheme);

lm.add(lyr);

NexGen, 공간 데이터의 분포경향 분석을 위한 밀도맵 기능

공간 분석 중, 밀도맵은 위치 데이터가 공간 상에 분포하는 경향을 매우 효과적으로 시각화할 수 있는 의사결정 지원 도구입니다. 위치 데이터의 공간 상의 위치 분포 뿐만 아니라 각 위치 데이터가 갖는 가중치값을 밀도 분석에 반영할 수 있어 위치 데이터와 통계 데이터를 조합할 수 있습니다.

밀도맵 기능의 소개를 위해 서울시의 인구 통계 데이터를 담고 있는 SHP 파일을 NexGen에 바로 불러와 밀도맵을 작성했습니다. 아래의 표는 사용한 인구 SHP 파일의 속성값에 대한 구조입니다. 통계청의 집계구 데이터를 받아 SHP 파일로 가공하였습니다.

이 데이터는 아래의 URL을 통해 다운로드 받으실 수 있습니다. 통계청에서 다운로드 받은 폴리곤 타입의 SHP 파일인 집계구 데이터와 TXT 파일인 2017년도 인구 데이터를 이용해 포인트 타입의 단일 SHP 파일로 직접 가공한 것입니다. 좌표계는 EPSG:5181입니다.



아래의 시연 동영상은 위의 인구 데이터를 활용한 NexGen의 밀도맵 기능에 대한 소개입니다.

웹 기반의 GIS 솔루션인 NexGen의 밀도맵 기능은 히트맵(HeatMap) 방식이 아닌 정규분포 방식의 알고리즘을 활용하여 고품질의 밀도맵을 작성할 수 있습니다.