Include HTML

GIS는 하나의 페이지에서 다양한 기능을 구현하는 경우가 대부분이다. 그러다보니 새로운 컨텐츠를 표시하기 위해 현재 표시되는 페이지(html)에 새로운 Tag를 생성해야 한다. 만약 ASP나 JSP와 같은 서버측 페이지 기술을 사용하지 않고 오로지 Javascript만을 사용하는 경우라면 Javascript 코드로 Tag 생성을 위해 매우 긴 문자열을 기술했을 것이다. 늘 이부분이 걸려왔는데.. 이번에 진행하는 프로젝트에서는 Javascript의 문자열을 통한 Tag의 생성이 아닌 HTML 파일을 원하는 곳에 Include ! 하는 방식을 적용해 본다.

그중 한가지 방법으로 W3School에서 제공하는 방식인데, 약간의 커스터마이징을 거친 버전을 정리해 본다. 예를들어 하나의 메인 페이지가 다음의 DOM 요소로 구성되어 있다고 하자.

위의 containerA에는 A.html을, containerB에는 B.html을 Include해 보고자 하는 것인데.. 먼저 A.html 파일의 내용은 다음과 같다.


  1. 안녕하세요!
  2. Hello!

B.html 파일의 내용은 다음과 같다.


  • 사과
  • 포도

이제 위의 2개의 html 리소스(파일)을 원하는 DIV 요소에 Include 하는 코드는 아래와 같다.

includeHTML(document.querySelector('#containerA'), 'A.html');
includeHTML(document.querySelector('#containerB'), 'B.html');

includeHTML라는 함수는 아래와 같다.

function includeHTML(divContainer, urlHTML) {
        let xhttp = new XMLHttpRequest();

        xhttp.onreadystatechange = function () {
        if (this.readyState == 4) {
            if (this.status == 200) { divContainer.innerHTML = this.responseText; }
            if (this.status == 404) { divContainer.innerHTML = "Page not found."; }
        }
    }

    xhttp.open("GET", urlHTML, true);
    xhttp.send();
}

결과는 아래와 같다.

Python과 OpenCV – 1 : 이미지를 가지고 시작하기

원문은 https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_image_display/py_image_display.html#display-image 입니다.

OpenCV는 단일 이미지나 동영상의 이미지를 원하는 결과를 분석 및 추출하기 위한 API입니다. OpenCV는 C/C++ 언어로 개발되었고, 이 API를 사용할 수 있는 언어는 C/C++, Java, Python 등입니다. 그리고 활용할 수 있는 플랫폼은 Windows, Linix, Android, iOS 등입니다. 이 글은 OpenCV를 Python 언어를 이용해 학습하면서 정리할 필요가 있다고 판단되는 핵심내용을 꼼꼼이 기록하기 위한 목적을 갖습니다. 각 글에 대한 원문은 글의 서문에 언급해 두고 있으니, 참고하시기 바랍니다. 아울리 이 글은 필자가 원문의 내용을 통해 학습하고 필자 나름대로 재해석하여 글을 작성하고 있습니다. 이 글과 이후의 Python과 OpenCV 관련글은 모두 이와 같습니다.

OpenCV와 Python의 설치 방법은 생략합니다. 검색을 통해 각자 자신에 맞는 환경에 설치하기 바랍니다.

OpenCV는 이미지를 대상으로 어떤 처리를 수행하므로 이미지를 읽고 화면에 표시하는 것은 매우 중요하고 기초적인 내용입니다. 이 글은 바로 이미지를 읽어 화면에 표시하는 내용에 대한 글입니다. 가장 먼저 작성된 코드는 다음과 같습니다.

import numpy as np
import cv2

img = cv2.imread('./data/quark-particle-flavors.jpg', cv2.IMREAD_GRAYSCALE)

cv2.imshow('image', img)

k = cv2.waitKey()

if k == ord('s'):
    cv2.imwrite('d:/z.jpg', img)

cv2.destroyAllWindows()

1,2번 코드는 OpenCV API 사용을 위한 모듈을 불러들이는 코드입니다. OpenCV는 이미지 데이터를 numpy의 자료구조를 사용합니다. 그러므로 OpenCV의 사용에 있어 numpy 모듈은 항상 함께 합니다.

실제 이미지를 불러 들이는 코드는 4번의 cv2.imread 함수인데, 첫번째 인자는 불러드릴 이미지 파일명이며 두번째는 해당 이미지를 불러와 어떤 포맷으로 메모리에 적재해 numpy 자료 구조의 객체를 생성할 것인지입니다. 위의 코드에서는 cv.IMREAD_GRAYSCALE로써 비록 해당 원본 이미지가 RGB의 칼라 이미지이지만 Gray 색상으로 해석해 이미지 객체를 반환하라는 것입니다. cv.IMREAD_GRAYSCALE 이외에도 사용할 수 있는 값은 다음과 같습니다.

  • cv2.IMREAD_COLOR : 별도로 지정하지 않을 경우 사용되는 기본값이며 칼라 이미지로 읽어드림. 이미지의 투명도값은 무시된다.
  • cv2.IMREAD_GRAYSCALE : 이미지를 Grayscale로 읽는다
  • cv2.IMREAD_UNCHANGED : 투명도인 Alpha 채널을 포함하여 읽는다.

반환된 이미지는 img 변수에 담기며 img 변수의 type을 확인해 보면 ‘numpy.ndarray’라는 타입으로 표시됩니다. 이제 이 이미지를 표시하기 위해 6번의 코드인 cv2.imshow 함수가 사용되는데 첫번째 인수는 이미지가 표시되는 Window의 식별자인 이름이고 두번째가 표시되는 이미지 객체입니다. 표시되는 이미지 객체는 4번 코드에서 정의된 변수입니다.

8번 코드는 사용자가 키 입력을 기다리는 함수인 cv2.waitKey로 인자값이 없거나 0일 경우 시간 제한없이 사용자의 키 입력을 기다립니다. 인자가 지정되면 해당값의 시간만큼만 키 입력을 기다립니다.>/p>

10번 코드는 입력된 키값이 소문자 s일 경우 img 객체의 저장된 이미지를 또 다른 파일로 저장하라는 cv2.imwrite 함수입니다.

13번은 프로그램의 종료를 위해 표시된 모든 Window을 닫으라는 코드입니다. 실행해보면 다음 화면과 같습니다.

이미지의 표시는 OpenCV 방식만 있는것이라 아니고 Matplotlib를 사용할 수도 있습니다. 이미지 처리의 결과를 그래프를 통해 효과적으로 표시하기 위해 Matplotlib를 사용합니다. Matplotlib를 이용한 이미지 표시의 코드는 아래와 같습니다.

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('./data/quark-particle-flavors.jpg', 0)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])
plt.show()

실행 결과는 다음과 같습니다.

[OpenLayers] Geolocation을 이용한 내 위치 추적하기

HTML5에서도 Geolocation를 제공하지만, 이를 좀더 쉽게 사용할 수 있도록 랩핑 클래스로써 Geolocation를 제공합니다. ol의 Geolocation에 대한 API를 정리합니다. 먼저 html 코드는 아래와 같습니다.



    
        
        OpenLayers
        

    
      
        

Javascript 코드는 Geolocation 관련 코드가 들어가는데, 하나씩 살펴보겠습니다. 먼저 필요한 모듈을 import 합니다.

import 'ol/ol.css';

import Feature from 'ol/Feature.js';
import Geolocation from 'ol/Geolocation.js';
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import Point from 'ol/geom/Point.js';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer.js';
import {OSM, Vector as VectorSource} from 'ol/source.js';
import {Circle as CircleStyle, Fill, Stroke, Style} from 'ol/style.js';

그리고 View와 Map 객체를 생성하는데 레이어로는 OpenStreetMap을 사용합니다.

var view = new View({
    center: [0, 0],
    zoom: 2
});

var map = new Map({
    layers: [
        new TileLayer({
            source: new OSM()
        })
    ],
    target: 'map',
    view: view
});

이제 이 글의 주인공인 Geolocation 객체를 생성합니다.

var geolocation = new Geolocation({
    trackingOptions: {
        enableHighAccuracy: true
    },
    projection: view.getProjection()
});

Geolocation은 좌표 단위는 WGS84 경위도 좌표인데, 이를 지도의 좌표계와 일치시켜주고 위해 projection 속성을 지도의 View 객체에 대한 projection 객체로 설정하고 있습니다. 그리고 바로 위치를 추적합니다.

geolocation.setTracking(true);

Geolocation은 위치의 변동, 추척 그리고 어떤 문제 발생을 이벤트 처리합니다. 아래와 같이 3개의 이벤트를 추가합니다.

geolocation.on('change', function() {
    console.log('accuracy = ' + geolocation.getAccuracy() + 'm ' +
        'altitude = ' + geolocation.getAltitude() + 'm ' +
        'altitudeAccuracy = ' +  geolocation.getAltitudeAccuracy() + 'm ' +
        'heading = ' + geolocation.getHeading() + 'rad ' +
        'speed = ' + geolocation.getSpeed() + 'm/s');
});

geolocation.on('error', function(error) {
    console.log('geolocation error: ' + error.message);
});

geolocation.on('change:position', function() {
    var coordinates = geolocation.getPosition();

    positionFeature.setGeometry(coordinates ? new Point(coordinates) : null);
});

위치에 대한 정확도, 고도, 고도에 대한 정확도, 방향각, 속도에 대한 변경이 발생할 경우 change 이벤트가 발생하고, 어떤 문제가 발생할 경우 error 이벤트가 발생합니다. 그리고 change:position를 통해 위치 변경시 이벤트가 발생됩니다. change:position 이벤트에서 지도 상에 현재의 위치를 표시하기 위해 positionFeature라는 이름의 객체에 위치를 지정하고 있는데, 이 positionFeature는 아래와 같습니다.

var positionFeature = new Feature();

positionFeature.setStyle(new Style({
    image: new CircleStyle({
        radius: 6,
        fill: new Fill({
            color: '#3399CC'
        }),
        stroke: new Stroke({
            color: '#fff',
            width: 2
        })
    })
}));

네, Feature입니다. Feature이므로 어떠한 모양으로 표시될지를 setStyle로 지정하고 있습니다. 또 Feature이므로 이를 지도와 함께 표시하기 위해 레이어가 필요합니다. 아래처럼요.

new VectorLayer({
    map: map,
    source: new VectorSource({
        features: [positionFeature]
    })
});

이제 실행하면, 위치 확인에 따른 사용자 확인을 묻고 사용자가 허락하면 사용자의 위치를 지도에 표시해 줍니다.

[OpenLayers] 지도를 원하는 위치와 Zoom으로 조정하기

Map 객체는 View 객체를 통해 화면에 지도의 어떤 위치를 표시할지를 결정할 수 있다. 먼저 MBR을 통해 조정하는코드의 예는 아래와 같다.

var mbr = vectorSource.getExtent();
map.getView().fit(mbr);

또한 원하는 지도의 위치로 화면을 이동하기 위해 필요한 코드는 아래와 같다.

var pt = [100000, 200000];
map.getView().setCenter(pt);

원하는 Zoom 레벨값으로 조저하는 코드는 아래와 같다.

map.getView().setZoom(10);

지도를 각도로 회전할 수 있는데 코드는 아래와 같다.

map.getView().setRotation(radianV);

지도를 해상도(Resolution)으로도 Zoom 할수 있는데 아래와 같다.

map.getView().setResolution(123.12344);