【QGIS】フィルタを使ってGISデータを抽出する

## はじめに
この記事は#30DayMapChallenge2022 11日目の記事です。
テーマはColour Friday: Redです。
QGISを使って「赤」が入った駅名データを抽出して、MapLibre GL JSで地図上に表示してみます。

![image](https://raw.githubusercontent.com/tjukanovt/30DayMapChallenge/main/images/flyers/30dmc-2022.png)

https://30daymapchallenge.com/

## QGISとは
フリーでオープンソースの地理情報システム
ほとんどのUnixプラットフォーム、Windows、macOS上で動作する

## 事前準備

既にインストール済みのQGIS（バージョン3.22.3）を使います。
QGISを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/13c801a9-4ba2-7996-cb45-16f32c999cd1.png)

## GISデータから欲しいデータを抽出
[国土数値情報の鉄道データ](https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N02-v2_3.html)を利用します。
駅のデータはポイントデータがよかったのですがラインデータでした。。

Line to Point処理済の駅のポイントデータを頂いたので、今回はそれを使いました。
Thanks! @bordoray


駅のポイントデータをドラッグ&ドロップで読み込みます。
レイヤを右クリックして、「フィルタ」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/0ee8121e-f517-e234-d7b6-b70648ed7fe9.png)

フィルタの条件を入力します。
今回は、駅名に「赤」が入ったデータを抽出したいので、LIKEを使って文字列の部分一致検索をしました。
「テスト」をクリックすると、データが何件返ってくるか確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/6080ddd6-9d0c-9067-7c90-18e4392a3e8e.png)

OKをクリックすると、フィルタされたデータが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/806f169a-2e3f-fb9d-7dc6-4833baa2a57c.png)

フィルタされた状態のGISデータを出力するには、レイヤを右クリックして、「エクスポート」＞「新規ファイルに地物を保存」をクリックします。

## MapLibre GL JSで抽出したデータを表示
鉄道の路線と「赤」がつく駅をMapLibre GL JSで表示してみます。
路線はオレンジっぽい色で、駅は赤色にしてみました。

初期表示時は日本全体が移るようにして、ジャンプボタンを押すと東京にズームするようにしてみました。
ズームレベルに応じて、駅のデータをサークル（丸）からアイコンに変化するようにしてみました。

'text-field' オプションを使って、駅のアイコンの下に駅名が出るようにしました。

```index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8" />
        <title>サンプル</title>
        <meta name="description" content="サンプルです" />
        <link href="style.css" rel="stylesheet" />
        <!-- MapLibre -->
        <script src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
        <link href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css" rel="stylesheet" />
    </head>
    <body>
        <div id="map"></div>
        <button id="fly">東京へジャンプ！</button>
        <script src="main.js"></script>
    </body>
</html>
```

```style.css
body {
    margin: 0;
    padding: 0;
}
#map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
}

#fly {
    display: block;
    position: relative;
    margin: 30px auto;
    width: 15%;
    height: 50px;
    padding: 10px;
    border: none;
    border-radius: 50px;
    font-size: 20px;
    text-align: center;
    color: #fff;
    background: red;
    cursor: pointer;
}
#fly:hover {
    transform: scale(1.1, 1.1);
}
```

```main.js
const tokyo_location = [139.74019, 35.6642];
const start_location = [136.29, 38.84];

var map = new maplibregl.Map({
    container: 'map',
    style: 'https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json', // 地図のスタイル
    center: start_location, // 中心座標
    zoom: 5, // ズームレベル
    pitch: 0, // 傾き
});

map.on('load', function () {
    map.addSource('railroad', {
        type: 'geojson',
        data: './data/railroad.geojson',
    });
    map.addLayer({
        id: 'railroad',
        type: 'line',
        source: 'railroad',
        minzoom: 0,
        layout: {
            'line-join': 'round',
            'line-cap': 'round',
        },
        paint: {
            'line-color': '#ee7800',
            'line-opacity': 0.7,
            'line-width': 1.5,
        },
    });
    map.loadImage('./data/station.png', function (error, image) {
        if (error) throw error;
        map.addImage('station_icon', image);
    });
    map.addSource('red_station', {
        type: 'geojson',
        data: './data/red_station.geojson',
        attribution: '国土数値情報（鉄道データ）',
    });
    map.addLayer({
        id: 'red_station',
        type: 'symbol',
        source: 'red_station',
        minzoom: 6,
        layout: {
            'icon-image': 'station_icon',
            'icon-size': 0.15,
            'text-field': ['get', 'station'],
            'text-font': ['Open Sans Semibold', 'Arial Unicode MS Bold'],
            'text-offset': [0, 1.2],
            'text-anchor': 'top',
        },
        paint: {
            'text-color': '#ffffff',
        },
    });
    map.addLayer({
        id: 'red_station_circle',
        source: 'red_station',
        maxzoom: 6,
        type: 'circle',
        paint: {
            'circle-radius': 4,
            'circle-color': 'red',
        },
    });
});

document.getElementById('fly').addEventListener('click', function () {
    map.flyTo({
        center: tokyo_location,
        zoom: 14,
        bearing: 0,
        speed: 1.1,
        curve: 1.42,
        easing: function (t) {
            return t;
        },
        essential: true,
    });
});
```


![fly.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/fd740a0c-399b-736a-3b56-5b19175e6ae6.gif)

赤っぽい地図になりましたね～

## 参考文献
https://maplibre.org/maplibre-gl-js-docs/example/flyto/

https://maplibre.org/maplibre-gl-js-docs/example/geojson-line/

https://maplibre.org/maplibre-gl-js-docs/example/geojson-markers/