フリーダムの日記

GIS(地理情報システム)を中心に技術的なことを書いています。

ArcGIS の OpenStreetMap (OSM) を使用してみた!

はじめに

以前は OpenStreetMap (OSM) の活動にも参加したり、イベントでも発表する機会がありました。最近はあまり活動にも参加してなく、情報のアップデートもしていない状況でした。

openstreetmap.jp

今回 EsriArcGIS API for JavaScript のリリース情報に OpenStreetMapOSM)についての情報があり、OpenStreetMapOSM)レイヤーを使用して、世界中で利用可能な 3D の建物や樹木を 3D での可視化が強化されたとのことで、久しぶりに色々と調べたり、実際に触ったりしましたので Esri の取り組み状況や API で使用した例を含めて紹介したいと思います。 developers.arcgis.com

以下は 2020年の記事ですが、EsriOpenStreetMap (OSM) との連携を積極的に取り組んでいます。OSM エディタでの ArcGIS データのサポートや ArcGIS のユーザー コミュニティを通じて高品質なデータを使用して OSM の強化を支援しているなどがあります。Esri の取り組みについて、詳しくは以下の記事を参照してください。

www.esri.com

記事の中では、例えば Meta (facebook) と Esri が Map with AI というサービスをリリースしているなど、OSM のマッパーがよく使用する地図データの修正ツールなどを提供しています。EsriOSM に貢献していることが分かります。

tech.fb.com

OpenStreetMap (OSM) のサービス

Esri が公開している OSM のサービスとして以下に情報がまとまっています。

OpenStreetMap (OSM)

EsriOpenStreetMap のサポーターであり、OpenStreetMap Foundation のゴールドコーポレート メンバーでもあります。

ArcGIS では、Esri がホストするベクトル ベースマップやフィーチャ レイヤーなど様々な方法で OSM データにアクセスでき、データの表示や検索、分析が可能になっています。また、データに関しても5分ごとに最新の編集内容で更新されます。

サイトは Esri によって管理され、Esri が公開した OSM データを掲載しています。OpenStreetMap Contributor に適切なライセンスと帰属表示を行えば、地図やアプリで自由に使用することができます。

OpenStreetMap (OSM) の例として、Esriクラウドサービスには OpenStreetMap (OSM) のデータを使用して 3D の建物と樹木のデータも公開されています。

OpenStreetMap 3D Buildings & Trees

ArcGIS で公開されている OpenStreetMap (OSM) ですが、世界中のデータが使用できるようになっています。以下の例ではアジア(Asia)で絞っており、日本のデータも確認することができます。

OpenStreetMap Layers

OpenStreetMap (OSM) は建物や道路、医療施設、観光名称など幾つかの種類のデータが使用できるようになっており、例えば アメニティ データデータとしても使用することもできるようになっています。

OpenStreetMap Amenities for Asia
OpenStreetMap Amenities for Asia

地図 API による OpenStreetMap (OSM) の表示

これまで紹介してきた OSM のデータを地図 API を使用して表示していきたいと思います。

下記では OpenStreetMap (OSM) の 3D 建物と樹木を ArcGIS Online の Scene Viewer で表示した例になります。こちらは ArcGIS API for JavaScript などの ArcGISAPI を使用して表示することも可能です。

OSM buildings and trees
OSM buildings and trees

また、下記の例では OpenStreetMap Amenities for Asia のデータを ArcGIS API for JavaScript を利用してクラスタリングした例になります。背景地図にも OSM を使用しています。

ArcGIS API for JavaScript のコードは以下になります。

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />

    <title>Point clustering - basic configuration</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.24/esri/themes/light/main.css" />
    <script src="https://js.arcgis.com/4.24/"></script>

    <style>
      html,
      body,
      #viewDiv {
        height: 100%;
        width: 100%;
        margin: 0;
        padding: 0;
        background-color: white;
      }
    </style>

    <script>
      require([
        "esri/config",
        "esri/Map",
        "esri/views/MapView",
        "esri/widgets/Home",
        "esri/layers/FeatureLayer"
      ], (
        esriConfig,
        Map,
        MapView,
        Home,
        FeatureLayer
      ) => {

        esriConfig.apiKey = "";

        const clusteredLayer = new FeatureLayer({
            url: "https://services-ap1.arcgis.com/iA7fZQOnjY9D67Zx/arcgis/rest/services/OSM_AS_Amenities/FeatureServer/0",
            popupTemplate: {
                title: "名前: {name}",
                content: [
                {
                    type: "fields",
                    fieldInfos: [
                        {
                            fieldName: "Amenity",
                            label: "Amenity"
                        },
                        {
                            fieldName: "addr_city",
                            label: "addr_city"
                        },
                        {
                            fieldName: "addr_country",
                            label: "addr_country"
                        },
                        {
                            fieldName: "addr_housenumber",
                            label: "addr_housenumber"
                        },                        
                        {
                            fieldName: "addr_postcode",
                            label: "addr_postcode"
                        },                        
                        {
                            fieldName: "addr_street",
                            label: "addr_street"
                        }
                    ]
                }]
            },
            renderer: {
              type: "simple",
              symbol: {
                type: "simple-marker",
                size: 10,
                color: "teal",
                outline: {
                  color: "white",
                  width: 0.5
                }
              }
            }
        });

        clusteredLayer.featureReduction = {
          type: "cluster",
          clusterMinSize: 16.5,
          // defines the label within each cluster
          labelingInfo: [
            {
              deconflictionStrategy: "none",
              labelExpressionInfo: {
                expression: "Text($feature.cluster_count, '#,###')"
              },
              symbol: {
                type: "text",
                color: "white",
                font: {
                  family: "MS ゴシック",
                  size: "12px"
                }
              },
              labelPlacement: "center-center"
            }
          ],
          // information to display when the user clicks a cluster
          popupTemplate: {
            title: "Cluster Summary",
            content: "This cluster represents <b>{cluster_count}</b> features.",
            fieldInfos: [{
              fieldName: "cluster_count",
              format: {
                places: 0,
                digitSeparator: true
              }
            }]
          }
        };

        const map = new Map({
            basemap: "osm-standard-relief",
            layers: [clusteredLayer]
        });

        const view = new MapView({
          container: "viewDiv",
          map,
          center: [139.69167, 35.68944],
          zoom: 15,
          popup: {
            dockEnabled: true,
            dockOptions: {
              breakpoint: false,
              position: "top-right"
            }
          },
          constraints: {
            snapToZoom: false
          }
        });

        view.ui.add(
          new Home({
            view: view
          }),
          "top-left"
        );

      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
  </body>
</html>

さいごに

OpenStreetMap (OSM) は設立は 2004 年 7月 (18年前)で、今でもサービスとしては多くのマッパーのユーザーを魅了している感じがします。マッパーのイベントだけでなく、FOSS4G などのオープンソースのイベントでも発表事例があったりとしていました。今ではEsri も貢献しているなどでサービスとしても成長しているのはうれしい限りです。

次回もOpenStreetMap (OSM) 関係で紹介できればと思います。

ja.wikipedia.org