상위 목록: 하위 목록: 작성 날짜: 읽는 데 21 분 소요

GeoJSON

GeoJSON은 위치 정보를 갖는 점을 기반으로 체계적으로 지형을 표현하기 위해 설계된 개방형 공개 표준 형식입니다.

지도에 특정 구역 별로 나누어 표시하거나, 기하학적 도형을 포함하고자 할때 사용합니다.

GeoJSON은 다음과 같은 형태를 같습니다.

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "prop0": "value0",
                "prop1": "value1",
                ...
            },
            "geometry": {
                "type": "MultiPolygon",
                "coordinates": [
                    [
                        [
                            [
                                128.994033813476562,
                                34.981803894042969
                            ],
                            [
                                128.994033813476562,
                                34.981529235840128
                            ],
                            ...
                        ]
                    ]
                ]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "prop0": "value0",
                "prop1": "value1",
                ...
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            128.69171142578125,
                            35.965698242187557
                        ],
                        [
                            128.699508666992642,
                            35.963829040527457
                        ],
                        ...
                    ]
                ]
            }
        }
    ]
}

GeoJSON 형식에는 properties, geometry 등에 주요한 정보가 담겨 있습니다.

properties국가, 도시, 토지 등에 대한 정보가 담겨 있습니다.

geometry는 메타 데이터의 형식과 좌표가 담겨 있습니다.

메타 데이터 형식에는 Point, LineString, Polygon 등이 있으며, Multi 속성으로도 구현될 수 있습니다.

Multi으로 작성된 경우, 1개 이상의 지리 데이터가 담겨있습니다.



클래스 코드

using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using GMap.NET;
using GMap.NET.MapProviders;
using GMap.NET.WindowsForms;
using Newtonsoft.Json.Linq;

namespace Project
{
    class Map
    {
        public GMapControl App;
        public GMapOverlay KoreaOverlay = new GMapOverlay("korea");

        public Map(GMapControl app)
        {
            // App Connection
            this.App = app;
            this.App.MapProvider = GMapProviders.GoogleMap;
            this.App.Overlays.Add(KoreaOverlay);

            // Default Zoom Level
            this.App.Zoom = 16;
            this.App.MaxZoom = 25;
            this.App.MinZoom = 5;

            // Default Position
            this.App.Position = new PointLatLng(37.497872, 127.0275142);

            // GeoJSON
            // https://raw.githubusercontent.com/southkorea/southkorea-maps/master/gadm/json/skorea-provinces-geo.json
            string file = File.ReadAllText("skorea-provinces-geo.json");
            JObject json = JObject.Parse(file);

            foreach (var features in json["features"])
            {
                string name = features["properties"]["NAME_1"].ToString();

                if (features["geometry"]["type"].ToString() == "Polygon")
                {
                    foreach (var coordinates in features["geometry"]["coordinates"])
                    {
                        GMapPolygon polygon = AddPolygon(coordinates, name);
                        KoreaOverlay.Polygons.Add(polygon);
                    }
                }
                else
                {
                    foreach (var coordinates in features["geometry"]["coordinates"])
                    {
                        foreach (var coord in coordinates)
                        {
                            GMapPolygon polygon = AddPolygon(coord, name);
                            KoreaOverlay.Polygons.Add(polygon);
                        }
                    }
                }
            }
        }

        public GMapPolygon AddPolygon(JToken coordinates, string name)
        {
            List<PointLatLng> points = new List<PointLatLng>();
            foreach (var coord in coordinates)
            {
                points.Add(new PointLatLng((double)coord[1], (double)coord[0]));
            }
            GMapPolygon polygon = new GMapPolygon(points, name);
            polygon.Fill = new SolidBrush(Color.FromArgb(50, Color.Black));
            polygon.Stroke = new Pen(Color.Red, 2);

            return polygon;
        }
    }
}


세부 코드

GeoJSON

// GeoJSON
// https://raw.githubusercontent.com/southkorea/southkorea-maps/master/gadm/json/skorea-provinces-geo.json
string file = File.ReadAllText("skorea-provinces-geo.json");
JObject json = JObject.Parse(file);

GeoJSON을 적용하기 위해 skorea-provinces-geo.json 파일을 읽어 JSON Object 형식으로 변경합니다.

파일 형태가 아닌, WebRequest 형태로도 JSON Object 형식으로 가져올 수 있습니다.

GeoJSON 다운로드

South Korea Github


foreach (var features in json["features"])
{
    string name = features["properties"]["NAME_1"].ToString();
    ...
}

foreach 문을 활용하여 features 속성에 있는 데이터를 가져옵니다.

다각형(Polygon)의 이름은 properties 속성의 NAME_1 으로 사용합니다.


if (features["geometry"]["type"].ToString() == "Polygon")
{
    ...
}
else
{
    ...
}

geometry 속성의 type을 확인하여 분기 처리를 진행합니다.

Polygon기본 형태(Geometry primitives)의 구조를 가지며, MultiPolygon복잡한 형태(Multipart geometries)의 구조를 가집니다.

기본 형태(Geometry primitives)는 객체 하나만 가지고 있으며, 복잡한 형태(Multipart geometries)는 두 개 이상의 객체를 가지고 있습니다.

그러므로, 복잡한 형태(Multipart geometries)깊이(Depth)가 하나 더 깊습니다.


기본 형태(Geometry primitives)

foreach (var coordinates in features["geometry"]["coordinates"])
{
    GMapPolygon polygon = AddPolygon(coordinates, name);
    KoreaOverlay.Polygons.Add(polygon);
}

기본 형태(Geometry primitives) 데이터를 반복하여 coordinates 데이터를 통해 다각형(Polygon)을 그립니다.

구멍(hole)이 있는 다각형도 기본 형태(Geometry primitives) 데이터이며, 구멍의 판단 유/무는 배열의 길이로 확인할 수 있습니다.

구멍이 있는 다각형을 그리고자 한다면, 8강의 강좌의 코드를 활용합니다.


복잡한 형태(Multipart geometries)

foreach (var coordinates in features["geometry"]["coordinates"])
{
    foreach (var coord in coordinates)
    {
        GMapPolygon polygon = AddPolygon(coord, name);
        KoreaOverlay.Polygons.Add(polygon);
    }
}

복잡한 형태(Multipart geometries) 데이터를 반복하여 coordinates 데이터를 가져옵니다.

복잡한 형태의 데이터는 깊이가 하나 더 깊으므로, 한 번 더 반복하여 동일한 데이터 형식으로 변경합니다.

이 데이터 형식은 구멍이 있는 다각형이 여러 개 있을 수 있습니다.


AddPolygon

public GMapPolygon AddPolygon(JToken coordinates, string name)
{
    List<PointLatLng> points = new List<PointLatLng>();
    foreach (var coord in coordinates)
    {
        points.Add(new PointLatLng((double)coord[1], (double)coord[0]));
    }
    GMapPolygon polygon = new GMapPolygon(points, name);
    polygon.Fill = new SolidBrush(Color.FromArgb(50, Color.Black));
    polygon.Stroke = new Pen(Color.Red, 2);

    return polygon;
}

기존 다각형 그리기와 동일한 방식으로 등록합니다.

coordinates의 좌표계는 위도 / 경도의 순서로 나열되어 있습니다.

PointLatLng경도 / 위도의 순서로 입력받으므로, 색인 순서를 반대로 입력합니다.

구멍이 있는 다각형을 그리고자 한다면, features[“geometry”][“coordinates”] 배열의 길이를 확인하여 분리해 적용합니다.



출력 결과

댓글 남기기