pyQGIS Tip

특정 Feature를 확대하기

아래의 코드는 선택된 Feature를 확대합니다.

canvas = iface.mapCanvas()
id = 0
#canvas.setSelectionColor(QColor("red"))
layer.select(id)
canvas.zoomToSelected(layer)

아래의 코드는 Feature를 선택하지 않고 FID가 0인 Feature를 확대합니다.

canvas = iface.mapCanvas()
id = 0
feat = layer.getFeature(id)
geom = feat.geometry()
bbox = geom.boundingBox()
canvas.setExtent(bbox)
canvas.refresh()

특정 Feature를 깜박이게 하기

canvas = iface.mapCanvas()
id = 0
canvas.flashFeatureIds(layer, [id])

화면 좌표와 지도 좌표 간의 변환

아래의 코드는 화면 좌표 (100, 20)을 지도 좌표로 변환하고 다시 변환된 지도 좌표를 화면 좌표로 변환하는 코드입니다.

ptView = QPoint(100, 20)
ptMap = canvas.getCoordinateTransform().toMapCoordinates(ptView)
print(ptMap.x(), ptMap.y())

ptMap2 = QgsMapTool(canvas).toCanvasCoordinates(ptMap)
print(ptMap2.x(), ptMap2.y())

다양한 형태의 지오메트리 생성

좌표를 지정해서 다양한 형태의 지오메트리를 생성하는 코드입니다.

geomPoint = QgsGeometry.fromPointXY(QgsPointXY(10000, 15000))

geomMultiPoint = QgsGeometry.fromMultiPointXY(
    [
        QgsPointXY(10000, 15000),
        QgsPointXY(11000, 16000),
    ]
)

geomPolyline = QgsGeometry.fromPolylineXY(
    [
        QgsPointXY(10000, 15000),
        QgsPointXY(11000, 16000),
        QgsPointXY(12000, 17000),
        QgsPointXY(13000, 18000),
    ]
)

geomPolyline = QgsGeometry.fromMultiPolylineXY(
    [
        [
            QgsPointXY(10000, 15000),
            QgsPointXY(11000, 16000),
            QgsPointXY(12000, 17000),
            QgsPointXY(13000, 18000),
        ]
    ]
)

pX = 971195
pY = 1841488

geomPolygon = QgsGeometry.fromPolygonXY(
    [
        [
            QgsPointXY(pX, pY),
            QgsPointXY(pX+1000, pY),
            QgsPointXY(pX+1000, pY+1000),
            QgsPointXY(pX, pY+1000),
        ],
        [
            QgsPointXY(pX+100, pY+100),
            QgsPointXY(pX+900, pY+100),
            QgsPointXY(pX+900, pY+900),
            QgsPointXY(pX+100, pY+900),
        ]
    ]
)

geomPolygon = QgsGeometry.fromMultiPolygonXY(
    [
        [
            [
                QgsPointXY(pX, pY),
                QgsPointXY(pX+1000, pY),
                QgsPointXY(pX+1000, pY+1000),
                QgsPointXY(pX, pY+1000),
            ],
            [
                QgsPointXY(pX+100, pY+100),
                QgsPointXY(pX+900, pY+100),
                QgsPointXY(pX+900, pY+900),
                QgsPointXY(pX+100, pY+900),
            ]
        ]
    ]
)

아래는 Python 언어의 특징을 이용한 효율적인 코드 작성입니다.

pts = [
    (583899.8, 8177297.19), 
    (583900.23, 8177262.52), 
    (583896.49, 8177262.47), 
    (583895.96, 8177297.29), 
    (583899.8, 8177297.19)
]

geomPolygon = QgsGeometry.fromPolygonXY( [[ QgsPointXY( xy[0], xy[1] ) for xy in pts ]] ) 

GeoService-Xr의 플러그인(PlugIn) 설정

GeoService-Xr을 기반으로 구축된 프로젝트마다 특화된 기능의 개발을 위해 PlugIn 방식으로 기능 확장을 하기 위한 설정입니다. 이 방식을 통해 GeoService-Xr의 유지보수 관리와 개별 프로젝트에 대한 특화된 기능에 대한 유지보수 관리가 효과적으로 완전히 분리됩니다.

기본적으로 GeoService-Xr의 설정 파일은 XrConfig.xml이며 아래의 예와 같습니다.


    ./SQL.json
    ./key.json
    ./session.json
    ./webHome
    ./geodata.xml
    777
    256
    10
    5485760
    0
    0
    ./plugin.json
    false

위의 설정 값 중 plugin 값으로 지정된 값인 plugin.json이 플러그인 기능에 대한 설정 파일입니다. 이 설정 파일을 보면 다음과 같습니다.

{
    "initializer": "kr.co.geoservice.geoserviceweb.PlugInInitializer",

    "services": [
        "kr.co.geoservice.geoserviceweb.request.ChangeProfile",
        "kr.co.geoservice.geoserviceweb.request.CheckAuthorizationCode",

        ....
    ],

    "schedulers": [
        "kr.co.geoservice.geoserviceweb.scheduler.NonauthorizedUserRemoverScheduler"

        ....
    ]
}

initializer에 지정된 Java 클래스가 해당 플러그인에 대한 초기화를 시켜주며, services에 지정된 Java 클래스들이 각기 기능 단위들입니다. schedulers는 일정 시간마다 특정한 작업을 실행하는 Java 클래스들입니다.

아울러 GeoService-Xr에 대한 jar 파일을 생성할 때 manifest 파일에 플러그인에 대한 jar 파일을 포함해줘야 합니다.

모바일 현장지원 시스템, 넥스젠 모바일(NexGen Mobile)

넥스젠 모바일은 모바일 GIS 현장 업무 지원 솔루션입니다. 항공영상, 지형도와 같은 배경지와 다양한 수치지도를 활용한 모바일 지리정보 솔루션으로써 지도 중심의 현장 업무를 빠르고 효과적으로 수행할 수 있습니다.

아래의 그림은 넥스젠 모바일에서 활용할 수 있는 지도와 다양한 현장 업무 지원을 위한 기능에 대한 내용입니다.

넥스젠 모바일의 가장 핵심이 되는 기능은 아래의 그림처럼 크게 수치지도 조회, 현장 데이터 수집, 공간 데이터 편집입니다.

아래의 글은 앞서 언급해 드린 3가지 주요 기능에 대한 시연 동영상입니다.

모바일 넥스젠의 레이어 관리 및 속성 확인

모바일 넥스젠의 현장 데이터 수집

모바일 넥스젠의 공간 데이터 편집

넥스젠 모바일에 대한 사용자 메뉴얼은 아래의 다운로드 이미지를 클릭하여 살펴볼 수 있습니다.


지오코딩 서비스(GEOCODER-XR) 기능 개선

OpenAPI 형태의 서비스 단위로 제공되는 GEOCODER-XR이 고객의 요구사항에 맞춰 개선되었습니다. 다음과 같이 3가지 내용이 변경되었습니다.

  1. 지오코딩 결과에 대한 정좌표, 인근좌표, 대표좌표에 대한 구분(기존에는 인근좌표와 대표좌표의 구분이 없었음)
  2. 결과가 여러 개인 경우 정확도 순서에 따라 정렬해서 모든 결과를 다 제공하도록 변경
  3. 결과 형식을 JSON으로 변경(기존은 XML 형식였음)

예를들어 주소 중 “중앙동”으로 검색을 하기 위한 REST 방식의 OpenAPI는 다음과 같습니다.

http://localhost:8080/Gp?command=gc;addr=중앙동

위의 호출에 대한 결과는 다음과 같습니다.

[
   {
      "user-input":"중앙동",
      "full-address":"경기도 성남시 중원구 중앙동",
      "coordinate":[
         37.43959765091859,
         127.1505276103632
      ],
      "vicinity":true,
      "type":"대표좌표"
   },
   {
      "user-input":"중앙동",
      "full-address":"경상남도 통영시 중앙동",
      "coordinate":[
         34.84482143430977,
         128.42308057122085
      ],
      "vicinity":true,
      "type":"대표좌표"
   },
   {
      "user-input":"중앙동",
      "full-address":"경상남도 창원시 진해구 중앙동",
      "coordinate":[
         35.14902784720422,
         128.66126916577852
      ],
      "vicinity":true,
      "type":"대표좌표"
   },

   ...
]

JSON 형식이며 중앙동이라는 이름의 행정명칭은 우리나라에 여러 개이므로 복수의 결과를 모두 전달하고 vicinity가 true이므로 인근좌표이면서 type을 통해 “대표좌표”라는 것을 파악할 수 있습니다.

이번에는 “중앙로10″으로 호출하기 위해 다음 API를 사용합니다.

http://localhost:8080/Gp?command=gc;addr=중앙로10

결과는 다음과 같습니다.

[
   {
      "user-input":"중앙로10",
      "full-address":"경기도 가평군 중앙로 10 (가평읍)",
      "coordinate":[
         37.82638794989058,
         127.5132600931772
      ],
      "vicinity":false,
      "type":"도로명주소"
   },
   {
      "user-input":"중앙로10",
      "full-address":"강원도 영월군 중앙로 10 (영월읍)",
      "coordinate":[
         37.18337775533778,
         128.46505641724204
      ],
      "vicinity":false,
      "type":"도로명주소"
   },
   {
      "user-input":"중앙로10",
      "full-address":"강원도 원주시 중앙로 10 (인동)",
      "coordinate":[
         37.34571078558531,
         127.95473309264851
      ],
      "vicinity":false,
      "type":"도로명주소"
   },

   ...
]

vicinity 값이 false이므로 “정좌표”를 의미합니다.

마지막으로 정확히 1건으로 매칭되는 주소에 대한 경우입니다.

http://localhost:8080/Gp?command=gc;addr=아차산로7나길18

결과는 다음과 같습니다.

[
   {
      "user-input":"아차산로7나길18",
      "full-address":"서울특별시 성동구 아차산로7나길 18 (성수동2가)",
      "coordinate":[
         37.54770170889392,
         127.05746040023593
      ],
      "vicinity":false,
      "type":"도로명주소"
   }
]