QGIS 기반 공간통계

QGIS의 레이어를 이용한 분석

앞에서 실행해 본 PySAL의 Moran’s I 샘플은 내장된 예제 데이터를 이용해 훌륭히 자기상관관계를 분석하고 있지만, 우리가 아는 데이터도 아니고 자료가 지도로 보이는 것도 아니어서 좀 많이 답답하다.

QGIS에 불러와 시각적으로 보이는 데이터를 가지고 분석을 한다면, 그 의미도 명확히 이해 할 수 있고 분석 결과도 좀 더 시각적으로 잘 표현할 수 있다. 이제 QGIS와 PySAL을 결합하여 분석을 해 보자.

 

먼저 아래의 링크에서 샘플로 사용할 파일을 받자.

http://open.gaia3d.com/data/pysal/sample_dataset.zip

 

다운로드 받은 압축파일을 C:\QgisSpatialStat\data 폴더에 모두 압축 풀어주자.

이 중에서 ‘인구분포.shp’ 파일이 이번에 사용할 샘플 파일이다.

 

QGIS 로 돌아가 레이어-벡터 레이어 추가… 메뉴를 이용해  ‘인구분포.shp’ 파일을 불러보자.

[탐색] 버튼을 눌러 파일 선택용 대화상자를 열어 C:\QgisSpatialStat\data 에 있는 인구분포.shp 파일을 선택해 열어주면 된다.

좌표계 선택 화면에서는 필터에 5181 라고 입력하여 EPSG:5181인 Korea 2000: 중부원점 좌표계를 선택해 주면 된다.

 

그러면 다음과 같이 우리나라의 행정구역이 보이는 인구분포 데이터가 보인다.

 

상단 툴바 중 아래 그림에 있는 속성테이블 열기 버튼을 누르면 현재 선택된 레이어의 속성을 볼 수 있다.

 

속성테이블 열기 버튼으로 열린 테이블의 컬럼 중 ‘노인비율’ 컬럼이 우리가 공간자기상관관계 분석을 위해 사용할 컬럼이다.

 

이제 일단 아래의 코드를 PyCharm의 global_morans_i.py의 편집창에 복사해 붙여 넣어 보자.

# coding=utf-8

 

from pysal import W, Moran

import numpy as np

import qgis

from qgis.core import *

from qgis.gui import QgsMessageBar

from PyQt4.QtGui import QProgressBar

from PyQt4.QtCore import *

import matplotlib.pyplot as plt

 

 

# 전역변수 설정

TEST_DIST = 100000

NAME_FIELD = "SGG"

VALUE_FIELD = u"노인비율"

 

##########################

# 레이어에서 정보 추출

 

# 레이어 선택

oLayer = iface.activeLayer()

if not oLayer:

  raise UserWarning(u"레이어를 먼저 선택해야 합니다.")  # 종료

 

layerName = oLayer.name()

layerType = oLayer.geometryType()

crs = oLayer.crs()

 

# ID 리스트 확보

oIDs = oLayer.allFeatureIds()

 

# Progress 생성

progressMessageBar = iface.messageBar().createMessage(u"레이어 정보 수집중...")

progress = QProgressBar()

progress.setMaximum(len(oIDs))

progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)

progressMessageBar.layout().addWidget(progress)

iface.messageBar().pushWidget(progressMessageBar, iface.messageBar().INFO)

 

# centroid,value(y),name 모으기

centroidList = []

dataList = []

nameList = []

for i, oID in enumerate(oIDs):

  progress.setValue(i)

 

  iFeature = oLayer.getFeatures(QgsFeatureRequest(oID)).next()

  iGeom = iFeature.geometry().centroid()

  centroidList.append(iGeom)

  data = iFeature[VALUE_FIELD]

  dataList.append(data)

  name = iFeature[NAME_FIELD]

  nameList.append(name)

 

# 통계 대상 값 수집

y = np.array(dataList)

 

# Progress 제거

iface.messageBar().clearWidgets()

 

# Weight Matrix 계산 위한 정보 수집

neighbors = {}

weights = {}

for iID, iCent in zip(oIDs, centroidList):

  iRowNeighbors = []

  iRowWeights = []

  for jID, jCent in zip(oIDs, centroidList):

      # 동일 지역인 경우 제외

      if iID == jID:

          continue

      # 기준거리 이내인 경우 인접한 것으로 기록

      dist = iCent.distance(jCent)

      if dist <= TEST_DIST:

          iRowNeighbors.append(jID)

          iRowWeights.append(1)

  # iID 지역에 대한 인접 지역 및 가중치 기록

  neighbors[iID] = iRowNeighbors

  weights[iID] = iRowWeights

 

# 인접지역과 가중치를 기준으로 현재 testDist의 Weight Matrix 계산

w

댓글

댓글 본문
작성자
비밀번호
  1. FelixS
    안녕하세요, 작성해 주신 내용은 잘 읽었습니다.
    제가 가진 데이터로 테스트를 하는데, QProgressBar 클래스가 제거되었다고 나오네요.
    업데이트 하실 때 반영하시면 어떨까 합니다.
    감사합니다.
버전 관리
BJ Jang
현재 버전
선택 버전
graphittie 자세히 보기