GeoJson 뷰어 (QML)
GeoJson 뷰어 예제는 MapItem을 조작하고, 사용자 입력을 처리하며, GeoJson 파일과의 입출력을 처리하는 방법을 보여줍니다.

이 예제는 다양한 MapItem이 포함된 지도를 표시합니다. MapItem은 QtLocation 의 GeoJsonData API를 사용하여 GeoJson 파일에서 가져오거나, TapHandlers 를 사용하여 사용자가 직접 그릴 수 있습니다.
GeoJSON 파일의 예제는 예제 디렉터리 내의 data 디렉터리에서 확인할 수 있습니다.
MapItem을 그리려면 지도의 빈 공간을 마우스 오른쪽 버튼으로 클릭한 후 나타나는 메뉴에서 원하는 항목 유형을 선택하십시오. 이후 클릭을 통해 선택한 항목을 정의하게 됩니다. 이 예제에서는 MapCircles, MapRectangles, MapPolygons 및 MapPolylines 을 그릴 수 있습니다. 두 점으로 완전히 정의되는 항목, 즉 원과 사각형은 마우스 왼쪽 버튼을 두 번 클릭하여 그릴 수 있습니다. 여러 점으로 정의되는 도형(예: 다각형 및 폴리라인)은 마우스 왼쪽 버튼을 원하는 횟수만큼 클릭하여 생성한 후, 마우스 오른쪽 버튼으로 완료합니다. 이 방식으로 그려진 도형은 GeoJSON 사양에 부합하도록 점, 다각형 및 폴리라인으로 저장됩니다. 자세한 내용은 https://geojson.org/을 참조하십시오.
예제 실행
다음 경로에서 예제를 실행할 수 있습니다.
- Qt Creator
Welcome 모드를 열고 Examples 에서 예제를 선택하십시오. 자세한 내용은 Qt Creator 의 ‘튜토리얼: 빌드 및 실행’을 참조하십시오.
- Qt Extension for Visual Studio Code
Command Palette 에서 Qt: Open Qt examples 명령을 실행하고 목록에서 예제를 선택합니다. 자세한 내용은 Qt Extension for Visual Studio Code: 튜토리얼: 빌드 및 실행을 참조하십시오.
MapView 생성
먼저 모든 항목을 배치할 수 있는 기본 지도를 생성합니다. 기본 Map 에 입력 처리 기능(마우스 휠, 드래그 등)을 결합한 MapView 요소를 활용합니다. 기본이 되는 Map 에는 map 속성을 통해 접근할 수 있습니다. MapView 에서 원하는 속성을 찾을 수 없는 경우, 대부분 MapView.map 를 통해 접근할 수 있습니다.
MapView {
id: view
anchors.fill: parent
map.plugin: Plugin { name: "osm" }
map.zoomLevel: 4
map.center: QtPositioning.coordinate(3, 8)
}GeoJSON 모델 설정 / MapItems 표시
지도에 파일 내용을 표시하기 위해 모델/뷰(Model/View) 프로그래밍이라는 디자인 패턴을 사용할 것입니다. 먼저 적절한 뷰를 설정해야 하는데, 이 예제에서는 MapItemView 요소를 사용합니다. 이 요소의 부모는 MapView 의 기본 지도로 설정되어야만 그 안에 배치된 모든 항목이 올바르게 표시됩니다.
MapItemView {
id: miv
parent: view.map
}다음으로, GeoJSON 문서를 나타내는 적절한 모델이 필요합니다. 이를 위해 QtLocation 은 GeoJSON 파일을 읽고 쓸 수 있는 GeoJsonData 요소를 제공합니다. 이 요소는 쉽게 인스턴스화할 수 있으며
GeoJsonData {
id: geoDatabase
sourceUrl: ":/data/11-full.json"
}MapItemView 에 할당할 수 있습니다.
model: geoDatabase.model11-full.json 파일은 예제로서 시작 시 자동으로 로드됩니다.
마지막으로, 모델 데이터를 항목 표현으로 변환하여 MapItemView 을 채우는 delegate 이 필요합니다.
delegate: GeoJsonDelegate {}GeoJsonDelegate 요소는 GeoJsonDelegate.qml 파일에 선언되어 있습니다. 이는 서로 다른 지오메트리 유형의 다양한 속성을 고려하기 위한 DelegateChooser 요소입니다.
DelegateChooser {
id: dc
role: "type"
}DelegateChooser 에는 GeoJSON 파일에서 찾을 수 있는 각 지오메트리 유형에 대한 DelegateChoice 가 포함되어 있습니다. role 속성은 DelegateChoice.roleValue 와 매칭되어 올바른 델리게이트를 결정합니다.
예를 들어, GeoJson에서 "type":"Point" 로 기술된 점은 MapItemView 에 있는 MapCircle 로 표현됩니다:
DelegateChoice {
roleValue: "Point"
delegate: MapCircle {
property string geojsonType: "Point"
property var props: modelData.properties
geoShape: modelData.data
radius: (props && props.radius) || 20*1000
border.width: 2
border.color: hh.hovered ? "magenta" : Qt.darker(color)
opacity: dc.defaultOpacity
color: (props && props.color) || (parent && parent.props && parent.props.color) || dc.defaultColor
}
}MapCircle 의 속성(예: color 또는 radius )은 modelData 속성 형태로 제공되는 GeoJSON 파일에서 읽으려고 시도됩니다. 그러나 이는 GeoJSON의 엄격한 표준은 아니며, 모든 속성에 대해 대체 값이 설정되어 있습니다.
MapItems를 GeoJSON에 쓰기
MapItems를 GeoJson 파일에 기록하려면 지정된 파일 이름을 사용하여 GeoJsonData::saveAs 함수를 호출하기만 하면 됩니다. 이렇게 하면 현재 모델에 있는 모든 항목이 지정된 파일에 기록됩니다. 파일에 기록해야 할 다른 항목이 있다면, 먼저 GeoJsonData::addItem 또는 GeoJsonData::setModelToMapContents 함수를 사용하여 모델에 추가해야 합니다.
geoDatabase.saveAs(fileWriteDialog.selectedFile)MapItems를 통한 사용자 상호작용
사용자 상호작용을 처리하기 위해 PointHandlers 을 사용합니다. 이 함수는 항상 정사각형 모양을 덮는 MouseArea 과 달리, 기본 항목의 정확한 모양을 따르기 때문에 이 작업에 특히 적합합니다. GeoJson 파일에서 가져온 MapItems는 델리게이트 내에서 직접 HoverHandler 및 TapHandler 을 갖게 됩니다:
TapHandler {
onTapped: {
if (props !== undefined)
console.log(props.name)
else if (parent.parent.geojsonType == "MultiPoint")
console.log(parent.parent.props.name)
else
console.log("NO NAME!", props)
}
}
HoverHandler {
id: hh
}TapHandler 는 항목을 탭했을 때 콘솔에 해당 항목에 대한 정보를 출력하는 데 사용됩니다. HoverHandler 는 마우스 포인터 아래에 있는 항목을 강조 표시하는 데 사용됩니다. 이는 HoverHandler 의 속성/상태인 hovered 에 따라 border.color 속성을 정의함으로써 구현됩니다.
새 항목 추가
MapView 에 대한 HoverHandler 과 TapHandler 을 조합하면 사용자의 마우스 움직임과 클릭에 반응할 수 있습니다.
TapHandler 이 singleTapped 신호를 발생시키면, LeftButton 에서 새로운 MapItem을 생성하거나 수정하고, RightButton 에서 해당 MapItem을 완료합니다. 완료할 항목이 없으면 RightButton 에서 메뉴를 표시합니다.
onSingleTapped: (eventPoint, button) => {
lastCoordinate = view.map.toCoordinate(tapHandler.point.position)
if (button === Qt.RightButton) {
if (view.unfinishedItem !== undefined) {
view.finishGeoItem()
} else
mapPopupMenu.show(lastCoordinate)
} else if (button === Qt.LeftButton) {
if (view.unfinishedItem !== undefined) {
if (view.unfinishedItem.addGeometry(view.map.toCoordinate(tapHandler.point.position), false)) {
view.finishGeoItem()
}
}
}
}pointChanged 신호는 MapItem을 일시적으로 업데이트하여 사용자에게 미리보기를 제공하는 데 사용됩니다.
HoverHandler {
id: hoverHandler
property variant currentCoordinate
grabPermissions: PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType
onPointChanged: {
currentCoordinate = view.map.toCoordinate(hoverHandler.point.position)
if (view.unfinishedItem !== undefined)
view.unfinishedItem.addGeometry(view.map.toCoordinate(hoverHandler.point.position), true)
}
}MapItem은 별도의 qml 파일에 정의된 프로토타입에서 생성됩니다. 이 항목들은 createComponent 함수를 사용하여 생성되며, addMapItem 를 통해 지도에 추가됩니다. 사용자가 나중에 조작할 수 있도록 새 항목에 대한 참조가 저장됩니다.
function addGeoItem(item)
{
var co = Qt.createComponent('mapitems/'+item+'.qml')
if (co.status === Component.Ready) {
unfinishedItem = co.createObject(map)
unfinishedItem.setGeometry(tapHandler.lastCoordinate)
unfinishedItem.addGeometry(hoverHandler.currentCoordinate, false)
view.map.addMapItem(unfinishedItem)
} else {
console.log(item + " is not supported right now, please call us later.")
}
}Map 에 항목을 추가하는 것만으로도 항목을 표시할 수 있습니다. 하지만 항목을 추가로 활용하려면(예: 파일에 저장하기 위해), 해당 항목을 모델에 추가해야 합니다. 이는 편집이 완료된 후에 수행됩니다:
function finishGeoItem()
{
unfinishedItem.finishAddGeometry()
geoDatabase.addItem(unfinishedItem)
map.removeMapItem(unfinishedItem)
unfinishedItem = undefined
}항목 제거
맵에서 모든 항목을 제거하려면 GeoJsonData 객체의 reset 함수를 호출하기만 하면 됩니다.
function clearAllItems()
{
geoDatabase.clear();
}© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.