【上海】コロナ感染者マップを自作する(百度地図API、高德地図API)

f:id:denim012:20220323151316p:plain

現在上海では新規コロナ感染者の居住地を毎朝公表しています。今回は、この公表された住所を地図上にマークして、コロナ感染者マップを自作してみます。

地図アプリAPIを利用するために

中国で主に利用されている地図アプリは「百度地図」「高德地図」の2つです。

共にAPIを利用するためには開発者登録が必要となります。ただ、身分証の無い外国人は個人開発者として登録することが出来ません。そこで今回は登録なしでも無料で使えるdemo画面を利用する事にします。

百度地図デモ画面

今回作成したいのは、複数の住所をマーキングした地図です。

「百度地图开放平台示列中心」→「其他LBS服务」→「正/逆地址解析」→「地址批量解析」に複数住所情報を一括でマーキングするプログラムのサンプルがあります。

地图JS API示例 | 百度地图开放平台 (baidu.com)

「正地址解析」は住所から緯度経度情報を取得する関数で、「逆地址解析」は緯度経度情報から住所を取得します。

ちなみに、中国では同じ住所でもアプリごとに緯度経度の数値が異なります。「百度地図の緯度経度情報」を「高德地図」で表示しても別の場所を指すので、変換関数を呼び出す必要があります。

坐标转换-API文档-开发指南-Web服务 API | 高德地图API

コロナ感染者マップを自作

サンプルは「合肥市」の情報なので、住所を上海の新規感染者居住地に置き換えます。※Wechatの「上海发布」公众号からコピペ。

f:id:denim012:20220323151519p:plain

「源代码编辑器」を編集し「运行」を押すことで反映されます。

f:id:denim012:20220323151648p:plain

▼修正後javascript。住所情報の後ろに()で発生日が追加されていますが、問題なく検索できています。

var map = new BMapGL.Map('container');
        map.centerAndZoom(new BMapGL.Point(121.43185415104254,31.22332785607418), 13);
        map.enableScrollWheelZoom(true);
        var myGeo = new BMapGL.Geocoder();
        var adds = [
            "玉屏南路725号(3/22)",
            "愚园路1240弄(3/22)",
            "娄山关路988号(3/22)",
            "新华路569弄106支弄(3/22)",
            "天山西路350弄(3/22)",
            "绥宁路628号(3/22)",
            "华山路1615号(3/22)",
            "金钟路333弄(3/22)",
            "昭化路518弄(3/22)",
            "金钟路255弄(3/22)",
            "新华路84弄(3/22)",
            "古北路181弄(3/22)",
            "金钟路68弄(3/22)",
            "东诸安浜路103号(3/22)",
            "哈密路398弄(3/21)",
            "剑河路409弄(3/21)",
            "宣化路299弄(3/21)",
            "江苏路495弄(3/21)",
            "绥宁路628号(3/21)",
            "宣化路113弄(3/21)",
            "华山路1520弄(3/21)",
            "古北路181弄(3/21)",
            "泉口路225弄(3/21)",
            "水城路728弄(3/21)",
            "金钟路255弄(3/21)",
            "天山西路350弄(3/21)",
            "镇宁路405弄(3/21)",
            "仙霞西路885弄(3/21)",
            "幸福路381弄(3/21)",
            "北翟路980弄(3/21)",
            "定西路615弄(3/21)",
            "汇川路88弄(3/21)",
            "中山西路1231号(3/21)",
            "长宁路491弄(3/21)"
        ];
        var index = 0;
        function bdGEO(){
            if (index < adds.length) {
                var add = adds[index];
                geocodeSearch(add);
                index++;
            }
        }
        function geocodeSearch(add){
            if(index < adds.length){
                setTimeout(window.bdGEO,400);
            } 
            myGeo.getPoint(add, function(point){
                if (point) {
                    var address = new BMapGL.Point(point.lng, point.lat);
                    addMarker(address,new BMapGL.Label(index+":"+add,{offset:new BMapGL.Size(10,-10)}));
                }
            }, "上海市");
        }
    // 编写自定义函数,创建标注
    function addMarker(point,label){
        var marker = new BMapGL.Marker(point);
        map.addOverlay(marker);
        marker.setLabel(label);
    }

※コロナ感染者地図は、自作しなくても支付宝(高德地図)で「疫情场所地图」と検索すると表示できます。

ただ、「疫情场所地图」は何故か上海市が公表している場所より少ないので、すべての場所を表示したい場合は自作地図の方が役に立ちます。

コロナ隔離地区マップ

今度は、コロナで隔離対象となっている「街道」「镇」を地図上に表示します。

コロナ隔離対象地区は、Wechatの「上海本地宝」公众号→「上海疫情」→「上海封闭管理小区」で確認できます。

f:id:denim012:20220323152157j:plain

3/23現在長寧区では「新泾镇」と「江苏路街道」が全小区封鎖されています。ただ、普段「街道」は意識しないので、これらが具体的にどこの場所かは分かりません。この「街道」「镇」を地図上にマークする方法を探してみます

「百度地図」では行政区(長寧区、普陀区・・)単位でしかマークする方法がありません。「高德地図」の方を見てみました。

高德地図デモ画面

「高德地图开放平台JS API示列」→「其他LBS服务」→「行政区划查询」→「行政区边界查询」に区の境界を取得するAPIがあります。

行政区边界查询-行政区划查询-示例中心-JS API 示例 | 高德地图API (amap.com)

例えば「长宁区」で検索すると、区の境界情報を取得して、区内領域に背景色を設定できます。

f:id:denim012:20220323152342p:plain

しかし、区の下の行政単位取得処理「下属行政区查询」では、「街道」の境界情報は取得できませんでした。

f:id:denim012:20220323152446p:plain

「下属行政区查询」では「长宁区」の下の行政単位の名称(周家桥街道、江苏路街道・・)と、各街道の中心座標が取得できるだけです。

という訳で、現在隔離対象エリア(街道、镇)情報を地図上に表示することは出来ませんでした。

まとめ

上海市が公表している新規コロナ感染者の居住地からコロナ感染者マップを自作してみました。

住所をピンポイントで表示するだけなら簡単に作成できますが、「街道」「镇」単位のエリア情報をマークするのは現在提供されているAPIだけでは無理そうでした。