LoginSignup
0
0

PyQGISでタイルレイヤのURLを取得したい

Posted at

はじめに

この記事は、
「タイルのURL取得なんて余裕だと思ってたのに、なぜかできない。。。」
と謎にハマってしまった人(数日前の自分)に向けた記事です。

image.png

予想される検索ワード

以下、この記事を求めているであろう方が入力しそうな
(というか実際に私が必死で検索した)検索ワードです。

QGIS, PyQGIS, タイル, URL, 取得

実行環境

  • Windows11
  • QGIS 3.28

忙しい人向けの結論

QGISでタイルレイヤを選択している状態で、Pythonコンソールで以下を実行すれば取得できます。

Pythonコンソール
# アクティブレイヤ
layer = iface.activeLayer()

# レイヤのソースを取得
src = layer.source()

# ソースを"&"で分けてリスト化
src_list = src.split("&")

# "url="で始まる要素を取得
url = [s for s in src_list if s.startswith('url=')][0]

# 先頭の"url="という文字は不要なので削除
url = url.lstrip("url=")

# URLデコード
url = url.replace("%7B", "{").replace("%7D", "}")

print(url)

タイルのURLを取得するために

取得方法自体は上述の通りなので、
ここからは「なんで上記のコードで取得できるの?」について書いていきます。

layer.source()とは

私が混乱した諸悪の根源です。
というか、そもそもPyQGISのドキュメントに"layer.source()"って載ってないですよね?
「アンタは一体何なんだ!」って感じです。

とりあえず、素直にQGISに質問(ただのhelp)してみると以下のように返してくれます。

>>> help(qgis._core.QgsRasterLayer.source)

Help on built-in function source:

source(...)
    source(self) -> str
    Returns the source for the layer. This source may contain usernames, passwords
    and other sensitive information.
    
    .. seealso:: :py:func:`publicSource`

ふむふむ。なんだかレイヤのソース(URL)を返してくれそうですね。

layer.source()を試してみる

さて、みんな大好き地理院タイルで確認してみましょう。
(きっとタイルのURLを返してくれるに違いない!)

image.png

 
$\huge{「...いや、欲しいのはそっちじゃないんや。」}$
 

世の中、そう甘くはないですね。

ちなみに、私はここから 「きっと、素直にURLを返す関数があるに違いない!」
関数探しの旅に出(て帰ってこれなくなり)ました。

layer.source()の戻り値

関数探しの旅に出ると帰って来れなくなる恐れがあるので
素直にlayer.source()の戻り値と向き合います。

指定レイヤがWebマップタイルだった場合
layer.source()の戻り値は基本的に、

key1=value1&key2=value2&key3=value3&...

という構造のようです。
(指定レイヤがWebマップタイルでない場合は、この限りでは無いです)

今回返ってきた値を分解してみると

type=xyz # xyzタイル形式だよ
&
url=https://cyberjapandata.gsi.go.jp/xyz/pale/%7Bz%7D/%7Bx%7D/%7By%7D.png # urlはここだよ
&
zmax=18&zmin=0 # ズームレベル0~18だよ
&
http-header:referer= # HTTPリファラは無いよ

ということを示しています。

URLの取得

layer.source()の戻り値を見てみたところ、
"url="に割り当てられている値がそれっぽいので、取得してみましょう。

Pythonコンソール
# アクティブレイヤ
layer = iface.activeLayer()

# レイヤのソースを取得
src = layer.source()

# ソースを"&"で分けてリスト化
src_list = src.split("&")

# "url="で始まる要素を取得
url = [s for s in src_list if s.startswith('url=')][0]

# 先頭の"url="という文字は不要なので削除
url = url.lstrip("url=")

print(url)
# => https://cyberjapandata.gsi.go.jp/xyz/pale/%7Bz%7D/%7Bx%7D/%7By%7D.png

それっぽい値が取得できましたね。
あとは"%7B"とか"%7D"をどうにかすれば良さそうです。

URLエンコード

"%7B"とか"%7D"は
URLエンコードによって "{" とか "}" が変換された値です。

URLエンコード、とは、URLとして使用できない文字を扱う際に、利用可能な文字に変換(エンコード)する事を言います。パーセントエンコーディング、とも言います。

引用元:https://www.en-pc.jp/tech/urlencode.php

そのため、"%7B"とか"%7D"をデコード(元に戻す)すれば良いです。

Pythonコンソール
# URLデコード
url = url.replace("%7B", "{").replace("%7D", "}")

print(url)
# => https://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png

上手く取得することができました。めでたしめでたし。

おわりに

「タイルのURL取得なんてQGISのプロパティでサクッと見られるんだから余裕でしょ」
と思っていたのですが、意外にも手間取ってしまいました。(主に関数探しのせい)

皆様も関数探しの旅は、ほどほどに。。。

 
...あ、urlを一発で取得できる関数を知っている方がいれば、教えてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0