1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Web GIS のズーム・レベルとタイル・キャッシュの設計

Last updated at Posted at 2025-04-28

1. ズーム・レベル

ズーム・レベルの設計の良し悪しは、Web GIS の使い心地を大きく左右します。

ズーム・レベルの設計が良くないと、目的の地物を適切な大きさで表示することが出来ません。ひどいときには、ズームインやズームアウトをした拍子に地物を見失ったりもします。

ストレス無く Web GIS を使えるようにするためには、ユーザ・フレンドリーなズーム・レベルを設計する必要があります。特に難しいことはありませんが、いくつか要点があります。

1-1. 上限と下限を適切に決める

最初にズーム・レベルの上限と下限を決めます。

上限および下限としてどのような値が適切かは表示する地図によってさまざまです。QGIS 等の Desktop GIS で表示を確認しながら、適切な上限と下限を決めてください。

どっちが上限でどっちが下限?

  • 縮小して広い範囲を表示 = 縮尺の分母が大きい = 小縮尺
  • 拡大して狭い範囲を表示 = 縮尺の分母が小さい = 大縮尺

というのが一般的な用語です。従って、小縮尺側を下限、大縮尺側を上限とします。

とりあえずは、下限だけを決めても構いません。すなわち、これ以上表示範囲を広くすると私の地図が小さくなりすぎて意味が無くなる、というあたりの縮尺を下限として決めます。

上限の方は、たいてい、やっていくうちに自ずと決ります。

1-2. 比率を 1:√2 にする

経験上、各ズーム・レベルの間の比率を 1:2 ではなく、1:√2 にするのがお奨めです。

つまり、ズーム・ボタンを一回押すと縮尺が倍になる、というのではなく、一回で 1.41421356 倍になり、二回で倍になる、という具合にします。

1:2 の比率では間隔が広すぎて気持ちが落ち着かないけれど、1:√2 の比率にすると安心してズームイン、ズームアウトの操作ができます ... 少なくとも私はそうです。

1-3. Excel でズーム・レベル表を作成する

下のような表を Excel で作成します。

Level 基準縮尺(の分母) UI 縮尺(の分母) 画素値(m/d)
0 1024000 1000000 264.583333333333
1 724077.343935025 750000 198.4375
2 512000 500000 132.291666666667
3 362038.671967512 350000 92.6041666666667
4 256000 250000 66.1458333333333
5 181019.335983756 180000 47.625
6 128000 125000 33.0729166666667
7 90509.667991878 90000 23.8125
8 64000 65000 17.1979166666667
9 45254.833995939 45000 11.90625
10 32000 30000 7.9375
11 22627.4169979695 20000 5.29166666666667
12 16000 15000 3.96875
13 11313.7084989847 10000 2.64583333333333
14 7999.99999999999 8000 2.11666666666667
15 5656.85424949237 5500 1.45520833333333
16 3999.99999999999 4000 1.05833333333333
17 2828.42712474619 3000 0.79375
18 2000 2000 0.529166666666667
19 1414.21356237309 1500 0.396875
20 999.999999999998 1000 0.264583333333333
21 707.106781186546 700 0.185208333333333
22 499.999999999999 500 0.132291666666667
23 353.553390593273 350 0.0926041666666667
24 250 250 0.0661458333333333
  • 上記では、レベル 0 から 24 まで、25 段階のズームを定義
  • 基準縮尺(の分母)の列は自動計算
    • =B1/sqrt(2) のような式を埋め込んで、比率を 1:√2 で変化させる
    • 1024000 のような 計算上 切りの良い値から始めるとよい
  • UI 縮尺(の分母)の列は手入力
    • 基準縮尺の値を参照しながら、人間にとって 切りの良い数値にする
  • 画素値の列は自動計算
    • 「画素値」は meter/dot すなわち 1 画素あたりのメーター数を示す値
    • 画素値 = 縮尺の分母 / 3779.527559 で計算
    • この数値を見れば、ズームの上限をどこに置くかを判断しやすい
    • この値は、後でタイル・キャッシュの設計でも用いる

「画素値」という用語は一般に流通している言葉ではありません。「1 画素あたりのメーター数」を示す適当な用語が見当たらないので、この文書ではそれを「画素値」と呼ぶことにします。

画素値の計算の根拠

  • 1 画素の大きさは、通常のモニターで、1/96 inch(96 DPI)
  • 1 inch = 0.0254 m
  • 従って、1 m あたりの画素数は、96 / 0.0254 = 3779.527559
  • 縮尺の分母の値 = 地図上の 1m の実際の m 数
  • 従って、画素値 = 縮尺の分母 / 3779.527559

要するに、1:√2 で変化する基準縮尺を参考にしながら、人間が読み取りやすい縮尺値をおおむね 1:√2 で変化させよう、ということです。基準縮尺は目安に過ぎないと考えて構いません。

また、地図によっては、部分的に縮尺の間隔を広げたり狭めたりする方が使い勝手が良いかも知れません。

1-4. ビューワのズーム・レベルを設定する

qwc-services / QWC2 の場合は、themesConfig.jsondefaultScales またはテーマごとの scales に上記の UI 縮尺のリストを設定します。

themesConfig.json
{
    "defaultScales": [
        1000000,
        750000,
        500000,
        350000,
        250000,
        180000,
        125000,
        90000,
        65000,
        45000,
        30000,
        20000,
        15000,
        10000,
        8000,
        5500,
        4000,
        3000,
        2000,
        1500,
        1000,
        700,
        500,
        350,
        250
    ],
    ...

2. タイル・キャッシュの設計

タイル・キャッシュは、ビューワのズーム・レベルに合せた形で設計するのが合理的です。

タイル・キャッシュはビューワから要求された縮尺に最も近い縮尺のタイル画像を返します。縮尺に違いがある場合は、ビューワ側での拡大・縮小が必要になりますので、出来れば要求通りの縮尺で画像を返したいものです。

ただし、タイル・キャッシュはディスク・リソースを大量に消費しますので、節約できるところは節約する工夫が必要です。

なお、以下では MapCache を例として話を進めます。と言うのは、筆者が MapCache しか使ったことが無いからです。しかし、基本的な考え方は他の地図画像キャッシュ・アプリでも同じであろうと思いますので、参考にしてください。

要点は、

  • ベクタ・レイヤ用とラスタ・レイヤ用で異なるグリッドを使う
  • ラスタ・レイヤ用のグリッドでは、足切りと間引きを行う

です。

2-1. ベクタ用グリッドは画素値のリストに従う

下記が、筆者が使用しているベクタ・レイヤ用のグリッドです。

mapcache.xml
    <grid name="GV">
        <metadata>
            <title>Grid for Vector Layers</title>
        </metadata>
        <srs>EPSG:3857</srs> <!--  WGS 84 / Pseudo-Mercator -->
        <units>m</units>
        <extent>
            15002000.0
             4156000.0
            15060000.0
             4207000.0
        </extent>
        <resolutions>
            <!-- m/dot      level scale(縮尺) -->
            264.5833333  <!-- 0 : 1/1,00,000 -->
            198.4375     <!-- 1 : 1/750,000 -->
            132.2916667  <!-- 2 : 1/500,000 -->
            92.60416667  <!-- 3 : 1/350,000 -->
            66.14583333  <!-- 4 : 1/250,000 -->
            47.625       <!-- 5 : 1/180,000 -->
            33.07291667  <!-- 6 : 1/125,000 -->
            23.8125      <!-- 7 : 1/90,000 -->
            17.19791667  <!-- 8 : 1/65,000 -->
            11.90625     <!-- 9 : 1/45,000 -->
            7.9375       <!-- 10: 1/30,000 -->
            5.291666667  <!-- 11: 1/20,000 -->
            3.96875      <!-- 12: 1/15,000 -->
            2.645833333  <!-- 13: 1/10,000 -->
            2.116666667  <!-- 14: 1/8,000 -->
            1.455208333  <!-- 15: 1/5,500 -->
            1.058333333  <!-- 16: 1/4,000 -->
            0.79375      <!-- 17: 1/3,000 -->
            0.529166667  <!-- 18: 1/2,000 -->
            0.396875     <!-- 19: 1/1,500 -->
            0.264583333  <!-- 20: 1/1,000 -->
            0.185208333  <!-- 21: 1/700 -->
            0.132291667  <!-- 22: 1/500 -->
            0.092604167  <!-- 23: 1/350 -->
        </resolutions>
        <size>256 256</size>
        <read-only>false</read-only>
    </grid>
  • extent (対象領域)については後述
  • resolutions のリストに、Excel ズーム・レベル表の画素値の値を設定
  • ただし、Level 24 は省略

Level が 1 つ上がるとタイル数は 2 倍

縮尺が √2 倍になると、タイル数は √2 x √2 で 2 倍になります。タイル数は幾何級数的に増えますので、ある程度の所で止めないと、あっと言う間にディスクがいっぱいになります。

逆に、小縮尺側はかなり贅沢にしてもディスクをほとんど消費しません。

2-2. ラスタ用グリッドでは足切りと間引きをする

下記が、筆者が使用しているラスタ・レイヤ用のグリッドです。

mapcache.xml
    <grid name="GR">
        <metadata>
            <title>Grid for Raster Layers</title>
        </metadata>
        <srs>EPSG:3857</srs> <!--  WGS 84 / Pseudo-Mercator -->
        <units>m</units>
        <extent>
            15002000.0
            4156000.0
            15060000.0
            4207000.0
        </extent>
        <resolutions>
            <!-- m/dot      level scale(縮尺) -->
            264.5833333  <!-- 0 : 1/1,00,000 -->
            198.4375     <!-- 1 : 1/750,000 -->
            132.2916667  <!-- 2 : 1/500,000 -->
            92.60416667  <!-- 3 : 1/350,000 -->
            66.14583333  <!-- 4 : 1/250,000 -->
            47.625       <!-- 5 : 1/180,000 -->
            33.07291667  <!-- 6 : 1/125,000 -->
            23.8125      <!-- 7 : 1/90,000 -->
            17.19791667  <!-- 8 : 1/65,000 -->
            11.90625     <!-- 9 : 1/45,000 -->
            7.9375       <!-- 10: 1/30,000 -->
            5.291666667  <!-- 11: 1/20,000 -->
            3.96875      <!-- 12: 1/15,000 -->
            <!-- 2.645833333  XX: 1/10,000 -->
            2.116666667  <!-- 13: 1/8,000 -->
            <!-- 1.455208333  XX: 1/5,500 -->
            1.058333333  <!-- 14: 1/4,000 -->
            <!-- 0.79375      XX: 1/3,000 -->
            0.529166667  <!-- 15: 1/2,000 -->
        </resolutions>
        <size>256 256</size>
        <read-only>false</read-only>
    </grid>
  • resolutions のリストに、Excel ズーム・レベル表の画素値の値を設定
  • ただし、画素値 0.529166667 のところで終了し、残りは割愛する
  • また、大縮尺でいくつかレベルを間引きする

2-2-1. 足切りの根拠

筆者が扱うラスタ・レイヤのソースで最も解像度の高いデータは、兵庫県が提供している高精度3次元地理空間データ、すなわち、50cm メッシュの DEM や DSM または CS 立体図です。つまり、0.5 meter/dot のデータです。

このデータについて、0.5 meter/dot より縮尺の大きなタイル・キャッシュを用意することは可能ですが、あまり意味がありません。キャッシュされるのは拡大された画像に過ぎず、ビューワでも細かい四角形が目立つぼやけた画像になります。

ソース・データの縮尺で足切りをすろと、それを超える縮尺の地図を表示するためにはビューワ側で拡大処理をする必要が生じるのですが、昨今の PC であれば、そのための CPU 負荷は体感できるほど大きくはありません。

それよりも、Level が 1 つ上がると 2 倍 になるタイル数を節約できるメリットが非常に大きいことが、この足切りを正当化する最大の理由になります。

2-2-2. 間引きの根拠

ベクタ・データに比べると、ラスタ・データの拡大・縮小に伴う画像の荒れは、特に大縮尺側において、あまり目立たない傾向があります。

ここでも、ディスク領域の節約のために、ラスタ・データについては大縮尺側でいくつかのグリッド・レベルを間引くことにします。

ベクタ・レイヤでは、足切りと間引きを避けること

ベクタ・レイヤの画像キャッシュは、ベクタをラスタ化した結果の画像ですので、拡大・縮小すると、ギザギザになったり、線が途切れたりと、何かと荒れが目立ちます。従って、可能な限り、ビューワが要求する縮尺のタイルを返すようにするべきです。

また、ベクタ・レイヤでは、足切りや間引きによるディスク容量節約効果がラスタ・レイヤに比べると非常に小さなものになります。理由は:

  • 色数が少ないため圧縮が良く効いて、1 枚のタイルのサイズが小さくなる
    • ラスタ・レイヤの 256 x 256 のタイルは、数十KB
    • ベクタ・レイヤのそれは、約十分の一(数KB)
  • 離散的なデータであったり、空白(透明)部分があったりするので、超軽量な NoData タイルが多くなる

以上の理由から、ベクタ・レイヤでは、足切りと間引きはなるべく避ける方が賢明です。

2-3. グリッドの領域を設定する

mapcache.xml
        <extent>
            15002000.0
            4156000.0
            15060000.0
            4207000.0
        </extent>

上記は、mapcache.xml でグリッドの対象領域を設定している部分です。順に、min_x(西)、min_y(南)、max_x(東)、そして、max_y(北)の ESPG:3857 による座標値で指定しています。

この領域は、将来を見越して、思い切って広めに取っておくことをお奨めします。

MapCache では、キャッシュするレイヤごとに、グリッド内の使用領域を限定することが出来ますので、その機能を利用します。

mapcache.xml
    <tileset name="tanada">
        <source>tanada</source>
        <cache>disk</cache>
        <grid restricted_extent="15015288 4180523 15015951 4181927"
              tolerance="0" minzoom="10">GV</grid>
        <format>PNG</format>
        <metatile>5 5</metatile>
        <metabuffer>10</metabuffer>
    </tileset>

minzoom および maxzoom による使用ズーム・レベルの限定も可能です。

このようにすれば、将来、レイヤの領域を変更したり、別のレイヤを追加したりするときに、既存のグリッドを使い続けることが可能になります。グリッドの定義から修正しなければならないとなると、それまでにシーディングされてきたキャッシュ・データを全て破棄しなければならなくなりますので、グリッドの定義はなるべく変更する必要がないようにしておきたいのです。

なお、実際にディスク領域の消費量を決定するのは、レイヤごとの限定された領域とズーム・レベルです。グリッド自体が定義する領域とズーム・レベルは、どんなに贅沢な仕様になっていても、それだけではディスク領域を全く消費しません。

ラベルを表示するレイヤの領域設定

ベクタ・レイヤで地名や建物名などのラベルを表示するものは、次の点に注意が必要です。

  • metabuffer を大きく取らないと、タイル境界上でラベルが途切れることがある
  • Point のレイヤ、または、外部にラベルを表示する Polygon のレイヤでは、領域自体もレイヤの BBox より広めに取る必要がある

レイヤごとのグリッド設定も Excel の表にして記録するのがお奨めです。そうしないと、すぐに忘れて、何が何だか分らなくなります ... 少なくとも私は。

1
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?