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개입니다.
'조그만 기술로 세상을 이롭게 > 고속도로어때' 카테고리의 다른 글
| Syncfusion MAUI는? (0) | 2026.05.12 |
|---|---|
| 구글플레이 신규 앱을 공식 출시하려면 (0) | 2026.05.12 |
| ITS Open API 종류 및 활용 그리고 C# 예제 (0) | 2026.05.12 |
| ITS 국가교통정보센터 소개 및 OPEN API 활용 (0) | 2026.05.12 |
| 고속도로어때 개발은? (0) | 2026.05.12 |