OpenSky REST API

FlightRadarやFlightAwareにあるような飛行機のライブマップを作ることになり、無償または安価なAPIをさがしてましたところ見つけましたので使ってます。

ドキュメントURL : https://opensky-network.org/apidoc/rest.html

個人利用、非営利目的利用は自由ですが、広告掲載には同意が必要です。

関連FAQリンク : https://opensky-network.org/about/faq#q6

Androidアプリで広告入れて使いたいので、質問したところ、OKの回答をいただいてます。
PlayStoreリンク

[ メリット ]
1) 無償で使える
2) ライブマップはほぼリアルタイム
3) ライブマップの範囲を四角いバウンダリで指定できるので地図に最適(他で見つけたのが半径なので、面倒なのでやめる)
4) ライブマップは範囲指定の他、ICAO24指定で単機のステータスもわかる

[ デメリット ]
1) レスポンス時間が長い場合があり、タイムアウトも多い
2) 研究目的なデータなので、フライトナンバー、ルートはわからない
3) 過去データの航跡追跡は現在休止中
4) カバー出来てない地域(上海北京周辺、北北海道、アフリカ)、飛行中機がまばらな地域(東南アジア)がある
5) 各飛行機のADS-Bの運用上の問題かも知れないが、着陸前空中にいる状況で途切れ、アプローチ中消えてる場合が多い

WebArena Indigo がうれしい点

サイズの大きいMySQLのデータベースを運用する必要があり、16GB以上で低価格なVPSを探してましたところ、見つけましたので利用中です。

メモリ32GBで月額 11,193円で、他の1/3で使えます。

ひとつのアカウントで10インスタンスまで作成可能、従量制課金なので、ちょっと試してすぐに停止するとさほど課金されないので、開発、テスト用としても最適かと思います。

HomePage : https://web.arena.ne.jp/indigo/?utm_source=google&utm_medium=cpc&utm_campaign=indigo&argument=vUrp7v4z&dmai=g_210113_102

[ メリット ]
1) 価格が安い
2) NTTなので安心
3) 従量制課金
4) 設定がシンプルでかんたん
5) スナップショットがとれる
6) SSDの容量が大きい

[ デメリット ]
1) CPUがXEON E3で少し遅い
2) IPアドレスが1個しかとれない
3) スナップショットはとったインスタンスでのみ利用可(コピーしてスケール出来るわけではない)
4) メンテナンス停止が多く連絡が間際な場合がある(らしい)

ダッシュボード

 

VPS比較2021年版リンク : https://vpshikaku.com/webarena-indigo/

AeroDataBox Aviation API

飛行機のフライトライブ地図、パストトラックなど扱うアプリのデータとして使ってます。

他と比べて安価です。

だいたいのデータは揃ってます。OpenSkyの飛行機コードがICAO24, CallSignなので、それらからフライト番号を参照したり、エアライン、出発、到着、時刻を参照したりしてます。

Home : https://www.aerodatabox.com/

 

API ドキュメント : https://doc.aerodatabox.com/

Airport flights, departures and arrivals (FIDS) by airport ICAO code で、出発空港発の各到着ルート数、そのエアラインとかがわかります。

[ 利用画面例 ]

10日に1回履歴でためてるので、コロナの影響減便、修復状況などがよくわかります。

 

 

ブログ復旧のご連絡

最近、2カ月ほど、ご訪問されましてもSSL証明書の不備により見苦しく、使いにくくなってました。
昨日、新規にSSL証明書を配置、テーマの変更などを行いまして復旧に至っています。
今後とも、よろしくお願い致します。

MySQL5.7でダンプしたfunctionがMySQL8にレストア出来ない問題の解消

MySQL5.7でダンプしたfunctionが、MySQL8にレストア時にエラーでレストア出来ないので調べてましたところ、my.cnfに以下の設定を入れることで解決しました。

[ my.cnf に追加した設定 ]

log_bin_trust_function_creators = 1

ここで教えていただきました。https://hiroasake.blogspot.com/2019/03/mysql.html

Leaflet Javascript のベースレイヤーでMapboxのレイヤーを使う

[ コード例 ]

レイヤー定義クラス



/**
 * Leaflet地図レイヤークラス
 * @type type
 */
class MapLayers {

  constructor() {
  }

  /**
   * 明暗種別取得
   * @param {type} label
   * @returns 
   */
  getLDType(label) {

    const mpl = new MapLayers();
    const ary = mpl.getLeafletBaseMapLayerArray();
    for (let j = 0; j < ary.length; j++) {
      if (label === ary[j]["label"]) {
        return ary[j]["ldtp"];
      }
    }

  }

  /**
   * ベースレイヤー
   * @returns {Array}
   */
  getLeafletBaseMapLayerArray() {
    const LEAFLET_LAYERS = [
      {
        label: '国土地理院標準',
        url: 'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png',
        attr: {attribution: "地理院標準"},
        ldtp: "L"
      },
      {
        label: '国土地理院淡色',
        url: 'http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png',
        attr: {attribution: "地理院淡色"},
        ldtp: "L"
      },
      {
        label: 'オープンストリートマップ',
        url: 'http://tile.openstreetmap.jp/{z}/{x}/{y}.png',
        attr: {attribution: "OpenStreetMap contributors"},
        ldtp: "L"
      },
      {
        label: 'グーグル衛星',
        url: 'http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}',
        attr: {
          maxZoom: 20,
          subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
        },
        ldtp: "D"
      },

      // 2021-04-11 //
      {
        label: 'USGS 衛星 Topo',
        url: 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile/{z}/{y}/{x}',
        attr: {
          attribution: "Tiles courtesy of the U.S. Geological Survey"},
        ldtp: "D"
      },

      {
        label: 'Esri 衛星',
        url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
        attr: {
          attribution: "Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"},
        ldtp: "D"
      },

      {
        label: 'Stadia Maps Dark',
        url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png',
        attr: {
          attribution: "Stadia Maps"},
        ldtp: "D"
      },
      // 2021-04-11 終わり //

      // 2021-04-12 //
      {
        label: 'CartoDB DarkMatter',
        url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',
        attr: {
          attribution:
                  '© OpenStreetMap contributors © CARTO'
        },
        ldtp: "D"
      },

      {
        label: '白地図',
        url: 'http://cyberjapandata.gsi.go.jp/xyz/blank/{z}/{x}/{y}.png',
        attr: {id: 'blankmap', attribution: "地理院白地図"},
        ldtp: "L"
      },
      {
        label: 'Stamen Toner-Background',
        url: 'http://{s}.tile.stamen.com/{variant}/{z}/{x}/{y}.png',
        attr: {
          attribution: 'Map tiles by Stamen Design, ',
          variant: 'toner-background'
        },
        ldtp: "D"
      },

      {
        label: 'Stamen Toner-Lite',
        url: 'http://{s}.tile.stamen.com/{variant}/{z}/{x}/{y}.png',
        attr: {
          attribution: 'Map tiles by Stamen Design, ',
          variant: 'toner-lite'
        },
        ldtp: "L"
      },
      {
        label: 'Stamen Watercolor',
        url: 'http://{s}.tile.stamen.com/{variant}/{z}/{x}/{y}.png',
        attr: {
          attribution: 'Map tiles by Stamen Design, ',
          variant: 'watercolor'
        },
        ldtp: "L"
      },
      {
        label: 'Esri World Topo Map',
        url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
        attr: {
          attribution: 'Tiles ©  Esri Japan '
        },
        ldtp: "L"
      },
      {
        label: 'Esri Ocean Base Map',
        url: 'http://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}',
        attr: {
          maxZoom: 13,
          attribution: 'Tiles by  Esri Japan '
        },
        ldtp: "L"
      },
      
      // From mapbox //
      {
        label: 'Mapbox dark',
        url: 'https://api.mapbox.com/styles/v1/mapbox/dark-v9/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "D"
      },
      {
        label: 'Mapbox satellite',
        url: 'https://api.mapbox.com/styles/v1/mapbox/satellite-v9/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "D"
      },
      {
        label: 'Mapbox satellite streets',
        url: 'https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v11/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "D"
      },
      {
        label: 'Mapbox night traffic',
        url: 'https://api.mapbox.com/styles/v1/mapbox/traffic-night-v2/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "D"
      },
      {
        label: 'Mapbox day traffic',
        url: 'https://api.mapbox.com/styles/v1/mapbox/traffic-day-v2/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "L"
      },
      
      {
        label: 'Mapbox outdoor',
        url: 'https://api.mapbox.com/styles/v1/mapbox/outdoors-v11/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "L"
      },
      
      {
        label: 'Mapbox light',
        url: 'https://api.mapbox.com/styles/v1/mapbox/light-v10/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "L"
      },
      
      /* {
        label: 'Mapbox decimal',
        url: 'https://api.mapbox.com/styles/hisashitanaka/ckj2fjsoj0alp19pqqtcvfk0i/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "D"
      },*/
      
    ];
    return LEAFLET_LAYERS;
  }
  
  // mapboxgl.accessToken = "pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ";
  
  /**
   * OpenWeatherMap気象レイヤー Ver 1
   * @returns {Array}
   */
  getLeafletWeatherMapLayerArray() {

    const WEATHER_LAYERS = [
      {
        label: "Precipitation",
        url: 'http://{s}.tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}.png?appid=8af427e393a1da34767ec02a4ba117e1',
        attr: {attribution: '降水',
          opacity: 0.9
        }
      },

      {
        label: "Clouds",
        url: 'http://{s}.tile.openweathermap.org/map/clouds_new/{z}/{x}/{y}.png?appid=8af427e393a1da34767ec02a4ba117e1',
        attr: {attribution: '',
          opacity: 0.9
        }
      },

      {
        label: "Pressure",
        url: 'http://{s}.tile.openweathermap.org/map/pressure_new/{z}/{x}/{y}.png?appid=8af427e393a1da34767ec02a4ba117e1',
        attr: {
          attribution: '気圧',
          opacity: 0.9
        }
      },

      {
        label: "Wind",
        url: 'http://{s}.tile.openweathermap.org/map/wind_new/{z}/{x}/{y}.png?appid=8af427e393a1da34767ec02a4ba117e1',
        attr: {
          attribution: '風速',
          opacity: 0.9
        }
      },
      
      {
        label: "Temperture",
        url: 'http://{s}.tile.openweathermap.org/map/temp_new/{z}/{x}/{y}.png?appid=8af427e393a1da34767ec02a4ba117e1',
        attr: {
          attribution: '気温',
          opacity: 0.9
        }
      }
    ];
    return WEATHER_LAYERS;

  }
  
  /**
   * OpenWeatherMap気象レイヤー Ver 2
   * Freeライセンスでは利用不可
   * @returns {Array}
   */
  getLeafletWeatherMapLayerArrayV2() {

    const WEATHER_LAYERS = [
      {
        label: "Precipitation",
        url: 'https://maps.openweathermap.org/maps/2.0/weather/TA2/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de&fill_bound=true',
        attr: {attribution: '降水',
          opacity: 0.9
        }
      },

      {
        label: "Clouds",
        url: 'https://maps.openweathermap.org/maps/2.0/weather/CL/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de&fill_bound=true',
        attr: {attribution: '',
          opacity: 0.9
        }
      },

      {
        label: "Pressure",
        url: 'https://{s}.tile.openweathermap.org/map/pressure_new/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de',
        attr: {
          attribution: '気圧',
          opacity: 0.9
        }
      },

      {
        label: "Wind",
        url: 'https://{s}.tile.openweathermap.org/map/wind_new/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de',
        attr: {
          attribution: '風速',
          opacity: 0.9
        }
      },
      
      {
        label: "Wind with direction",
        url: 'https://maps.openweathermap.org/maps/2.0/weather/WND/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de',
        attr: {
          attribution: '風速風向',
          opacity: 0.9
        }
      },
      
      {
        label: "Temparture",
        url: 'https://maps.openweathermap.org/maps/2.0/weather/TA2/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de',
        attr: {
          attribution: '気温',
          opacity: 0.9
        }
      }
    ];


    return WEATHER_LAYERS;

  }

}

地図描画クラス

    // -- ベースレイヤー設定 -- //
    // -C
    const layersclass = new MapLayers();
    let leyers = layersclass.getLeafletBaseMapLayerArray();
    //alert(leyers.length);

    let baseMaps = {};
    let curkey = "";
    let objlayer;
    $.each(leyers, function (j, itm) {
      curkey = itm["label"];
      objlayer = L.tileLayer(itm["url"], itm["attr"]);
      baseMaps[curkey] = objlayer;

      //console.log("curkey:" + curkey);
      //console.log("LDTP:" + itm["ldtp"]);
    });

    // -- OpenWeatherMap設定 -- //
    // -C
    leyers = layersclass.getLeafletWeatherMapLayerArray();
    let weatherMaps = [];

    $.each(leyers, function (j, itm) {
      curkey = itm["label"];
      objlayer = L.tileLayer(itm["url"], itm["attr"]);
      weatherMaps[curkey] = objlayer;
    });


    // 天気選択を加えたレイヤーコントロール //
    L.control.layers(baseMaps, weatherMaps, /*{collapsed: false}*/).addTo(lmap);
    // ベースマップを乗せる //
    let baseadd = baseMaps[layerkey].addTo(lmap);

[ 画面例 ]

Mapbox Night Traffic

Leaflet Javascript に OpenWeatherMap の天気レイヤーを重ねる

ここで教えていただきました。
https://blog.kazu634.com/labs/leaflet-js-mapbox-js/001-leaflet-js-tutorial/

[ コード例 ]


   
/**
 * Leaflet地図レイヤークラス
 * @type type
 */
class MapLayers {

  constructor() {
  }

  /**
   * 明暗種別取得
   * @param {type} label
   * @returns 
   */
  getLDType(label) {

    const mpl = new MapLayers();
    const ary = mpl.getLeafletBaseMapLayerArray();
    for (let j = 0; j < ary.length; j++) {
      if (label === ary[j]["label"]) {
        return ary[j]["ldtp"];
      }
    }

  }

  /**
   * ベースレイヤー
   * @returns {Array}
   */
  getLeafletBaseMapLayerArray() {
    const LEAFLET_LAYERS = [
      {
        label: '国土地理院標準',
        url: 'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png',
        attr: {attribution: "地理院標準"},
        ldtp: "L"
      },
      {
        label: '国土地理院淡色',
        url: 'http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png',
        attr: {attribution: "地理院淡色"},
        ldtp: "L"
      },
      {
        label: 'オープンストリートマップ',
        url: 'http://tile.openstreetmap.jp/{z}/{x}/{y}.png',
        attr: {attribution: "OpenStreetMap contributors"},
        ldtp: "L"
      },
      {
        label: 'グーグル衛星',
        url: 'http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}',
        attr: {
          maxZoom: 20,
          subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
        },
        ldtp: "D"
      },

      // 2021-04-11 //
      {
        label: 'USGS 衛星 Topo',
        url: 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile/{z}/{y}/{x}',
        attr: {
          attribution: "Tiles courtesy of the U.S. Geological Survey"},
        ldtp: "D"
      },

      {
        label: 'Esri 衛星',
        url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
        attr: {
          attribution: "Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"},
        ldtp: "D"
      },

      {
        label: 'Stadia Maps Dark',
        url: 'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}{r}.png',
        attr: {
          attribution: "Stadia Maps"},
        ldtp: "D"
      },
      // 2021-04-11 終わり //

      // 2021-04-12 //
      {
        label: 'CartoDB DarkMatter',
        url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',
        attr: {
          attribution:
                  '© OpenStreetMap contributors © CARTO'
        },
        ldtp: "D"
      },

      {
        label: '白地図',
        url: 'http://cyberjapandata.gsi.go.jp/xyz/blank/{z}/{x}/{y}.png',
        attr: {id: 'blankmap', attribution: "地理院白地図"},
        ldtp: "L"
      },
      {
        label: 'Stamen Toner-Background',
        url: 'http://{s}.tile.stamen.com/{variant}/{z}/{x}/{y}.png',
        attr: {
          attribution: 'Map tiles by Stamen Design, ',
          variant: 'toner-background'
        },
        ldtp: "D"
      },

      {
        label: 'Stamen Toner-Lite',
        url: 'http://{s}.tile.stamen.com/{variant}/{z}/{x}/{y}.png',
        attr: {
          attribution: 'Map tiles by Stamen Design, ',
          variant: 'toner-lite'
        },
        ldtp: "L"
      },
      {
        label: 'Stamen Watercolor',
        url: 'http://{s}.tile.stamen.com/{variant}/{z}/{x}/{y}.png',
        attr: {
          attribution: 'Map tiles by Stamen Design, ',
          variant: 'watercolor'
        },
        ldtp: "L"
      },
      {
        label: 'Esri World Topo Map',
        url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
        attr: {
          attribution: 'Tiles ©  Esri Japan '
        },
        ldtp: "L"
      },
      {
        label: 'Esri Ocean Base Map',
        url: 'http://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}',
        attr: {
          maxZoom: 13,
          attribution: 'Tiles by  Esri Japan '
        },
        ldtp: "L"
      },
      
      // From mapbox //
      {
        label: 'Mapbox dark',
        url: 'https://api.mapbox.com/styles/v1/mapbox/dark-v9/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "D"
      },
      {
        label: 'Mapbox satellite',
        url: 'https://api.mapbox.com/styles/v1/mapbox/satellite-v9/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "D"
      },
      {
        label: 'Mapbox satellite streets',
        url: 'https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v11/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "D"
      },
      {
        label: 'Mapbox night traffic',
        url: 'https://api.mapbox.com/styles/v1/mapbox/traffic-night-v2/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "D"
      },
      {
        label: 'Mapbox day traffic',
        url: 'https://api.mapbox.com/styles/v1/mapbox/traffic-day-v2/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "L"
      },
      
      {
        label: 'Mapbox outdoor',
        url: 'https://api.mapbox.com/styles/v1/mapbox/outdoors-v11/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "L"
      },
      
      {
        label: 'Mapbox light',
        url: 'https://api.mapbox.com/styles/v1/mapbox/light-v10/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "L"
      },
      
      /* {
        label: 'Mapbox decimal',
        url: 'https://api.mapbox.com/styles/hisashitanaka/ckj2fjsoj0alp19pqqtcvfk0i/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ',
        attr: {
          maxZoom: 13,
          attribution: 'mapbox'
        },
        ldtp: "D"
      },*/
      
    ];
    return LEAFLET_LAYERS;
  }
  
  // mapboxgl.accessToken = "pk.eyJ1IjoiaGlzYXNoaXRhbmFrYSIsImEiOiJjazlnZ2J5dmMwbmpwM2xudnhreGRneDVwIn0.63ThZzKzusoMS5GGjJZ0tQ";
  
  /**
   * OpenWeatherMap気象レイヤー Ver 1
   * @returns {Array}
   */
  getLeafletWeatherMapLayerArray() {

    const WEATHER_LAYERS = [
      {
        label: "Precipitation",
        url: 'http://{s}.tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}.png?appid=8af427e393a1da34767ec02a4ba117e1',
        attr: {attribution: '降水',
          opacity: 0.9
        }
      },

      {
        label: "Clouds",
        url: 'http://{s}.tile.openweathermap.org/map/clouds_new/{z}/{x}/{y}.png?appid=8af427e393a1da34767ec02a4ba117e1',
        attr: {attribution: '',
          opacity: 0.9
        }
      },

      {
        label: "Pressure",
        url: 'http://{s}.tile.openweathermap.org/map/pressure_new/{z}/{x}/{y}.png?appid=8af427e393a1da34767ec02a4ba117e1',
        attr: {
          attribution: '気圧',
          opacity: 0.9
        }
      },

      {
        label: "Wind",
        url: 'http://{s}.tile.openweathermap.org/map/wind_new/{z}/{x}/{y}.png?appid=8af427e393a1da34767ec02a4ba117e1',
        attr: {
          attribution: '風速',
          opacity: 0.9
        }
      },
      
      {
        label: "Temperture",
        url: 'http://{s}.tile.openweathermap.org/map/temp_new/{z}/{x}/{y}.png?appid=8af427e393a1da34767ec02a4ba117e1',
        attr: {
          attribution: '気温',
          opacity: 0.9
        }
      }
    ];
    return WEATHER_LAYERS;

  }
  
  /**
   * OpenWeatherMap気象レイヤー Ver 2
   * Freeライセンスでは利用不可
   * @returns {Array}
   */
  getLeafletWeatherMapLayerArrayV2() {

    const WEATHER_LAYERS = [
      {
        label: "Precipitation",
        url: 'https://maps.openweathermap.org/maps/2.0/weather/TA2/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de&fill_bound=true',
        attr: {attribution: '降水',
          opacity: 0.9
        }
      },

      {
        label: "Clouds",
        url: 'https://maps.openweathermap.org/maps/2.0/weather/CL/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de&fill_bound=true',
        attr: {attribution: '',
          opacity: 0.9
        }
      },

      {
        label: "Pressure",
        url: 'https://{s}.tile.openweathermap.org/map/pressure_new/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de',
        attr: {
          attribution: '気圧',
          opacity: 0.9
        }
      },

      {
        label: "Wind",
        url: 'https://{s}.tile.openweathermap.org/map/wind_new/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de',
        attr: {
          attribution: '風速',
          opacity: 0.9
        }
      },
      
      {
        label: "Wind with direction",
        url: 'https://maps.openweathermap.org/maps/2.0/weather/WND/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de',
        attr: {
          attribution: '風速風向',
          opacity: 0.9
        }
      },
      
      {
        label: "Temparture",
        url: 'https://maps.openweathermap.org/maps/2.0/weather/TA2/{z}/{x}/{y}.png?appid=9792af345b029a9e82dc41ef143072de',
        attr: {
          attribution: '気温',
          opacity: 0.9
        }
      }
    ];


    return WEATHER_LAYERS;

  }

}

// ****** 描画用メソッド ****** //

    // -- ベースレイヤー設定 -- //
    // -C
    const layersclass = new MapLayers();
    let leyers = layersclass.getLeafletBaseMapLayerArray();
    //alert(leyers.length);

    let baseMaps = {};
    let curkey = "";
    let objlayer;
    $.each(leyers, function (j, itm) {
      curkey = itm["label"];
      objlayer = L.tileLayer(itm["url"], itm["attr"]);
      baseMaps[curkey] = objlayer;

      //console.log("curkey:" + curkey);
      //console.log("LDTP:" + itm["ldtp"]);
    });

    // -- OpenWeatherMap設定 -- //
    // -C
    leyers = layersclass.getLeafletWeatherMapLayerArray();
    let weatherMaps = [];

    $.each(leyers, function (j, itm) {
      curkey = itm["label"];
      objlayer = L.tileLayer(itm["url"], itm["attr"]);
      weatherMaps[curkey] = objlayer;
    });


    // 天気選択を加えたレイヤーコントロール //
    L.control.layers(baseMaps, weatherMaps, /*{collapsed: false}*/).addTo(lmap);
    // ベースマップを乗せる //
    let baseadd = baseMaps[layerkey].addTo(lmap);

 

[ 画面例 ]

turf.js で Bスプライン曲線

飛行機の航跡データをturf.jsでBスプライン曲線に変換して地図で描画してみました。

調べたところ、Bスプライン曲線は渡した実際の座標からはずれた座標にも線を引くので、業務用としては不向きかと思いますが、今回実装してみたアプリについては業務用途では使われないので、気にしなくてよいかと思います。

APIドキュメント

[ コード例 ]

ラッパークラスを使ってます。

GoogleMap 呼び出し側


const geojsonfnm = "geojson/SimpleLine.json";

$.getJSON(geojsonfnm, function (data) {

      const geomes = data["geometry"]["coordinates"];
      
      let applyData = data;

      // -- スプライン指定している場合、turf.jsでスプライン変換 -- //
      if (isSpline) {
        //console.log("--- Splined");
        // -C 自作ラッパークラス //
        const myturf = new MyTurf({resolution: 20000, sharpness: 2});
        applyData = myturf.getSplinedGeometries(geomes);
      }
      
      // GeoJSON を描画 //
      let lines = gmapS.data.addGeoJson(applyData);
});

ラッパークラス

/**
 * turf.js用ラッパークラス
 * @type type
 */
class MyTurf {

  /**
   * コンストラクタ
   * @param {type} optionmap オプション値
   * @returns {MyTurf}
   */
  constructor(optionmap) {
    this.optionmap = optionmap;
  }

  /**
   * Bスプライン曲線
   * @param {type} line Feature  [[lat,lon], [lat,lon], [lat,lon]]
   * @returns {undefined} Feature  - curved line
   */
  getSplinedGeometries(geomes) {
    let line = turf.lineString(geomes);
    return turf.bezierSpline(line, this.optionmap);
  }
  
  /**
   * 中心点取得
   * @param {type} geomes
   * @returns {unresolved}
   */
  getCenter (geomes) {
    let features = turf.points(geomes);
    return turf.center(features);
  }

  /**
   * 2点位置指定方向取得
   * @param {type} p1
   * @param {type} p2
   * @returns {unresolved}
   */
  getBeaing(p1, p2) {
    return turf.bearing(p1, p2);
  }
  
   /**
   * 方向角配列
   * @returns {Array|drawMapLAFlightSP.splinedBearingArray.barray}
   */
  getSplinedBearingArray(coordinates) {


    let barray = [];
    let prevll;
    let tmpbearing;

    const myturf = new MyTurf();
    const pushToArray = (ll, idx) => {

      if (idx > 0) {

        prevll = coordinates[idx - 1];
        // turf.jsで方向角を求める //
        tmpbearing = myturf.getBeaing(prevll, ll);
        // 時計式角度を航空式角度に変換 //
        tmpbearing = tmpbearing < 0 ? Number(tmpbearing) + Number(360) : tmpbearing; // アイコン用整数に四捨五入 // tmpbearing = Math.round(tmpbearing); barray.push(tmpbearing); } }; coordinates.forEach((ll, idx) => pushToArray(ll, idx));

    //console.log("--- barray");
    //console.log(barray);
    return barray;

  }

}

[ 利用例 ]

実はあまり変わり映えないばかりか、小半径な旋回が見受けられます。
アクチャル座標データが少ない曲線表現では有効かも知れませんが、多い場合、逆効果です。

スプライン未適用

スプライン適用