본문 바로가기
조그만 기술로 세상을 이롭게/고속도로어때

돌발상황정보 API 활용 및 개발

by eplus 2026. 5. 12.

C# 예시는 이렇게 정리하면 됩니다.

1. 기본 구조

  • HttpClient로 ITS API 호출
  • JSON/XML 응답 수신
  • 모델 객체로 변환
  • Grid/WebView에 표시

2. 주요 클래스

  • ItsCctvInfo
    CCTV명, URL, X, Y 좌표
  • ItsTrafficInfo
    도로명, 링크ID, 속도, 통행시간

3. 핵심 서비스

  • GetCctvAsync(lat, lng)
    주변 CCTV 조회
  • GetTrafficInfoAsync(minX, maxX, minY, maxY)
    교통소통정보 조회

4. 주요 기술

  • HttpClient
  • System.Text.Json
  • XDocument
  • async/await

5. 거리 계산

  • 사용자 위치와 CCTV 좌표 거리 계산
  • 가까운 순으로 정렬
  • 보통 상위 20건 표시

6. MAUI 화면 흐름

  • 앱 실행
  • GPS 위치 취득
  • CCTV 조회
  • Grid 목록 표시
  • 선택 시 WebView에 영상 표시

7. 실무 필수 처리

  • 타임아웃
  • 권한 오류 처리
  • GPS 꺼짐 처리
  • JSON 숫자/문자 혼합 대응
  • URL 유효성 검사

8. 권장 폴더 구조

  • Models
  • Services
  • Pages
  • Platforms/Android

한 줄 요약
C#에서는
HttpClient + JSON/XML 파싱 + 거리계산 + MAUI UI 바인딩 구조로 ITS API를 구현하면 됩니다.

------------------------------------------------------------------------------

ITS 국가교통정보센터의 돌발상황정보 API는 apiKey, type, eventType, minX/maxX/minY/maxY, getType를 받으며, 출력값으로 eventType, eventDetailType, startDate, coordX, coordY, linkId, roadName, roadNo, roadDrcType, lanesBlockType, lanesBlocked, message, endDate 등을 제공합니다. type은 all/ex/its/loc/sgg/etc, eventType은 all/cor/acc/wea/ete/dis/etc를 씁니다.

1. 모델 클래스

 
public class ItsEventInfo
{
    public string Type { get; set; } = "";
    public string EventType { get; set; } = "";
    public string EventDetailType { get; set; } = "";
    public string StartDate { get; set; } = "";
    public string EndDate { get; set; } = "";
    public string RoadName { get; set; } = "";
    public string RoadNo { get; set; } = "";
    public string RoadDrcType { get; set; } = "";
    public string LanesBlockType { get; set; } = "";
    public string LanesBlocked { get; set; } = "";
    public string LinkId { get; set; } = "";
    public string Message { get; set; } = "";
    public double CoordX { get; set; }
    public double CoordY { get; set; }
}
 

2. 서비스 클래스

 
using System.Globalization;
using System.Text.Json;

public class ItsEventService
{
    private readonly HttpClient _http = new HttpClient
    {
        Timeout = TimeSpan.FromSeconds(15)
    };

    private const string ApiKey = "여기에_발급받은_APIKEY";

    public async Task<List<ItsEventInfo>> GetEventsAsync(
        string roadType = "all",
        string eventType = "all",
        double? minX = null,
        double? maxX = null,
        double? minY = null,
        double? maxY = null)
    {
        string url =
            "https://www.its.go.kr:9443/eventInfo?" +
            $"apiKey={ApiKey}" +
            $"&type={roadType}" +
            $"&eventType={eventType}" +
            "&getType=json";

        if (minX.HasValue) url += $"&minX={minX.Value.ToString(CultureInfo.InvariantCulture)}";
        if (maxX.HasValue) url += $"&maxX={maxX.Value.ToString(CultureInfo.InvariantCulture)}";
        if (minY.HasValue) url += $"&minY={minY.Value.ToString(CultureInfo.InvariantCulture)}";
        if (maxY.HasValue) url += $"&maxY={maxY.Value.ToString(CultureInfo.InvariantCulture)}";

        string json = await _http.GetStringAsync(url);
        using JsonDocument doc = JsonDocument.Parse(json);

        List<ItsEventInfo> list = new();

        if (!doc.RootElement.TryGetProperty("body", out JsonElement body))
            return list;

        if (!body.TryGetProperty("items", out JsonElement items) ||
            items.ValueKind != JsonValueKind.Array)
            return list;

        foreach (JsonElement item in items.EnumerateArray())
        {
            list.Add(new ItsEventInfo
            {
                Type = GetString(item, "type"),
                EventType = GetString(item, "eventType"),
                EventDetailType = GetString(item, "eventDetailType"),
                StartDate = GetString(item, "startDate"),
                EndDate = GetString(item, "endDate"),
                RoadName = GetString(item, "roadName"),
                RoadNo = GetString(item, "roadNo"),
                RoadDrcType = GetString(item, "roadDrcType"),
                LanesBlockType = GetString(item, "lanesBlockType"),
                LanesBlocked = GetString(item, "lanesBlocked"),
                LinkId = GetString(item, "linkId"),
                Message = GetString(item, "message"),
                CoordX = GetDouble(item, "coordX"),
                CoordY = GetDouble(item, "coordY")
            });
        }

        return list;
    }

    private static string GetString(JsonElement item, string name)
    {
        if (!item.TryGetProperty(name, out JsonElement el))
            return "";

        return el.ValueKind == JsonValueKind.String
            ? el.GetString() ?? ""
            : el.ToString();
    }

    private static double GetDouble(JsonElement item, string name)
    {
        if (!item.TryGetProperty(name, out JsonElement el))
            return 0;

        if (el.ValueKind == JsonValueKind.Number)
            return el.GetDouble();

        return double.TryParse(el.ToString(), out double v) ? v : 0;
    }
}
 

3. 사용 예시

전체 돌발 조회

 
ItsEventService service = new ItsEventService();

List<ItsEventInfo> events = await service.GetEventsAsync(
    roadType: "all",
    eventType: "all"
);
 

고속도로 사고만 조회

 
List<ItsEventInfo> accidents = await service.GetEventsAsync(
    roadType: "ex",
    eventType: "acc"
);
 

특정 좌표 범위 내 조회

 
double lat = 35.286526;
double lng = 128.604832;
double range = 1.0;

List<ItsEventInfo> nearby = await service.GetEventsAsync(
    roadType: "all",
    eventType: "all",
    minX: lng - range,
    maxX: lng + range,
    minY: lat - range,
    maxY: lat + range
);
 

4. 화면 표시 예시

 
private async Task LoadEventAsync()
{
    try
    {
        var service = new ItsEventService();

        var list = await service.GetEventsAsync(
            roadType: "ex",
            eventType: "all"
        );

        gridEvent.ItemsSource = list;
        lblStatus.Text = $"{list.Count}건 조회됨";
    }
    catch (HttpRequestException ex)
    {
        lblStatus.Text = "통신 오류: " + ex.Message;
    }
    catch (TaskCanceledException)
    {
        lblStatus.Text = "요청 시간 초과";
    }
    catch (Exception ex)
    {
        lblStatus.Text = "오류: " + ex.Message;
    }
}
 

5. 자주 쓰는 값

  • roadType
    • all: 전체
    • ex: 고속도로
    • its: 국도
    • loc: 지방도
    • sgg: 시군도
  • eventType
    • all: 전체
    • cor: 공사
    • acc: 사고
    • wea: 기상
    • ete: 기타돌발
    • dis: 재난
    • etc: 기타

6. 실무 팁

좌표 범위를 안 넣으면 전체 조회가 될 수 있어 응답량이 커질 수 있습니다. 그래서 모바일 앱은 현재 위치 기준 minX/maxX/minY/maxY를 함께 주는 방식이 안전합니다. 공식 문서도 범위 좌표는 type=all 또는 eventType=all에서 사용할 수 있다고 안내합니다.

한 줄 요약:
돌발상황정보 C# 구현은
HttpClient + JSON 파싱 + 이벤트 모델 바인딩 구조로 하면 됩니다. 요청 핵심은 type, eventType, 좌표 범위 4개입니다.

728x90
반응형