GIS

QGIS 파이썬 콘솔: Gemma 3 LLM과 지도로 대화하기

유병혁 2025. 6. 1. 04:35

안녕하세요. 이번 글에서는 QGIS 파이썬 콘솔에서 Gemma 3 LLM과 지도를 활용한 대화형 코드를 소개해 보겠습니다. 이전 글에서 다룬 코드를 확장하여, QGIS 맵 캔버스 이미지와 텍스트를 함께 처리할 수 있는 방식으로 구성하였습니다. 이전 글은 아래 링크를 참고하시면 됩니다.

 

QGIS 파이썬 콘솔: Gemma 3 LLM과 대화하기

안녕하세요? 이번 글에서는 QGIS 파이썬 콘솔에서 Gemma 3 LLM과 대화하는 코드를 소개해 보겠습니다. Gemma 3 LLM 설치 방법은 앞서 작성한 아래 글을 참고하시면 됩니다. Ollama(올라마): 로컬에서 LLM(Gem

foss4g.tistory.com

아래 코드는 QGIS에서 현재 보고 있는 지도 화면(맵 캔버스)을 이미지로 저장한 다음, 그 이미지를 Gemma 3 LLM 모델에게 보내서 질문(prompt)에 대한 답변을 받아오는 기능을 하는 파이썬 스크립트입니다.

import requests 
import json
import sys
import threading
import base64
from qgis.utils import iface

def ask_gemma_with_image(prompt, image_path = "C:/Users/bhyu/Desktop/map.png"):
    def _worker():
        try:
            # QGIS 맵 캔버스 이미지 저장
            canvas = iface.mapCanvas()
            canvas.saveAsImage(image_path)
            print(f"[✔] 지도 저장 완료: {image_path}")

            # 이미지 base64 인코딩
            with open(image_path, "rb") as f:
                image_base64 = base64.b64encode(f.read()).decode("utf-8")

            # Gemma API 요청 payload
            payload = {
                "model": "gemma3:4b",
                "prompt": prompt,
                "images": [image_base64],
                "stream": True
            }

            url = "http://localhost:11434/api/generate"

            # 스트리밍 요청 처리
            with requests.post(url, json=payload, stream=True, timeout=120) as response:
                response.raise_for_status()
                buffer = b""

                for chunk in response.iter_content(chunk_size=512):
                    if not chunk:
                        continue
                    buffer += chunk

                    while b"\n" in buffer:
                        line, buffer = buffer.split(b"\n", 1)
                        if not line.strip():
                            continue
                        try:
                            data = json.loads(line.decode("utf-8"))
                            text = data.get("response", "")
                            if text:
                                sys.stdout.write(text)
                                sys.stdout.flush()
                        except json.JSONDecodeError:
                            continue

        except requests.exceptions.RequestException as e:
            print(f"[연결 오류] {e}")
        except Exception as e:
            print(f"[예외 발생] {e}")

    threading.Thread(target=_worker, daemon=True).start()

 

사용 예시는 다음과 같습니다.

ask_gemma_with_image("이 지도에 보이는 섬에 대해 설명해줘.")