一目でわかる!Mapbox GLで農地センサー実装状況を「見える化」

はじめに

広大な農地におけるセンサーの導入状況、全体像を把握するのに苦労していませんか? どのエリアで導入が進んでいるのか、遅れているのかが一目で分かれば、今後のDX戦略も立てやすくなるはず。本記事では、地理空間情報プラットフォームMapbox GLを活用し、農地センサーの実装率をヒートマップで可視化する具体的な手順を解説します。直感的で分かりやすいヒートマップで、データに基づいたスマートな農業経営を実現しましょう。

Mapbox GLで可視化する意義

農業におけるデータ活用は、精密農業の推進や収量向上に不可欠です。特に、農地センサーの導入状況は、今後のDX戦略を左右する重要な指標となります。しかし、点在するセンサーのデータを単に数値で管理するだけでは、全体像の把握が難しく、地域ごとの進捗度合いや課題を特定しにくいという課題があります。Mapbox GLを活用することで、これらのセンサーデータを地理情報と紐付け、直感的なヒートマップとして可視化することが可能になります。ヒートマップは、実装率の高いエリアを濃い色で、低いエリアを薄い色で表示するため、一目で状況を把握できます。例えば、特定の地域でセンサー導入が進んでいない場合、その原因を分析し、集中的なサポートを行うなどの対策を講じることが可能になります。また、過去のデータと比較することで、導入の進捗状況を経時的に把握し、効果測定や目標設定に役立てることもできます。

ヒートマップ作成のステップ

データ準備

CSV形式で入力データを用意

以下のような列を持つ sensors.csv を用意します。

id,latitude,longitude,installed_count,total_count
001,35.6895,139.6917,30,50
002,34.6937,135.5023,10,40
…

GeoJSON化(クライアント側で動的に)

ブラウザ上で PapaParse を使い、CSV→GeoJSON に変換します。各ポイントには実装率 rate = installed_count / total_count をプロパティとして持たせます。

HTML+ライブラリ読み込み

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>農地センサー実装率ヒートマップ</title>
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <!-- Mapbox GL JS -->
  <link href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css" rel="stylesheet" />
  <script src="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js"></script>
  <!-- PapaParse (CSV パース用) -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.2/papaparse.min.js"></script>
  <style>
    body, html { margin: 0; padding: 0; height: 100%; }
    #map { width: 100%; height: 100%; }
  </style>
</head>
<body>
  <div id="map"></div>
  <script>
    // ここにステップ3以降のコードを記述
  </script>
</body>
</html>

Mapbox 初期化

mapboxgl.accessToken = '<YOUR_MAPBOX_ACCESS_TOKEN>';
const map = new mapboxgl.Map({
  container: 'map',
  style: 'mapbox://styles/mapbox/light-v10',
  center: [135.0, 35.0],  // 日本付近の中心座標
  zoom: 5
});

CSV の読み込み&GeoJSON 生成

map.on('load', () => {
  fetch('data/sensors.csv')
    .then(res => res.text())
    .then(csvText => {
      const geojson = { type: 'FeatureCollection', features: [] };
      Papa.parse(csvText, {
        header: true,
        skipEmptyLines: true,
        complete: results => {
          results.data.forEach(row => {
            const lat = parseFloat(row.latitude);
            const lon = parseFloat(row.longitude);
            const installed = parseInt(row.installed_count, 10);
            const total    = parseInt(row.total_count, 10);
            const rate     = total > 0 ? installed / total : 0;
            geojson.features.push({
              type: 'Feature',
              geometry: { type: 'Point', coordinates: [lon, lat] },
              properties: { rate }
            });
          });
          addHeatmapLayer(geojson);
        }
      });
    });
});

ヒートマップレイヤーの追加

function addHeatmapLayer(data) {
  // 1) GeoJSON ソースを追加
  map.addSource('sensors', { type: 'geojson', data });

  // 2) ヒートマップレイヤーを追加
  map.addLayer({
    id: 'sensor-heatmap',
    type: 'heatmap',
    source: 'sensors',
    maxzoom: 15,
    paint: {
      // 実装率を重みとして使う
      'heatmap-weight': ['get', 'rate'],
      // ズームに応じて強度を調整
      'heatmap-intensity': [
        'interpolate', ['linear'], ['zoom'],
        5, 1,
        15, 3
      ],
      // 密度に応じたカラーグラデーション
      'heatmap-color': [
        'interpolate',
        ['linear'],
        ['heatmap-density'],
        0,   'rgba(0, 0, 255, 0)',
        0.2, 'royalblue',
        0.4, 'cyan',
        0.6, 'lime',
        0.8, 'yellow',
        1,   'red'
      ],
      // 半径(ピクセル単位)をズームで変更
      'heatmap-radius': [
        'interpolate', ['linear'], ['zoom'],
        5, 20,
        15, 50
      ],
      // ズーム 7 以上で徐々に透明に(ポイントレイヤーに切り替え)
      'heatmap-opacity': [
        'interpolate', ['linear'], ['zoom'],
        7, 0.6,
        15, 0
      ]
    }
  });

  // 3) 拡大時ポイントを表示するサークルレイヤー
  map.addLayer({
    id: 'sensor-point',
    type: 'circle',
    source: 'sensors',
    minzoom: 12,
    paint: {
      'circle-radius': 4,
      'circle-color': 'white',
      'circle-stroke-color': 'black',
      'circle-stroke-width': 1
    }
  });
}

インタラクション(マウスオーバーで実装率を表示)

// ポイントレイヤーにだけカーソルを反応させる
map.on('mousemove', 'sensor-point', e => {
  const props = e.features[0].properties;
  const rate = (props.rate * 100).toFixed(1);
  // ポップアップ表示
  new mapboxgl.Popup({
    closeButton: false,
    closeOnClick: false
  })
    .setLngLat(e.lngLat)
    .setHTML(`実装率: ${rate}%`)
    .addTo(map);
});
// レイヤー外に移動するとポップアップを消す
map.on('mouseleave', 'sensor-point', () => map.getCanvas().style.cursor = '' );

運用・拡張ポイント

  • 定期更新
    バックエンドで GeoJSON を生成して同じ URL に置くと、地図をリロードするだけで最新データ反映可能。
  • ポリゴン単位でのヒートマップ
    ポイントではなく区画ポリゴンごとに実装率を持たせる場合は、type:'fill' レイヤーでカラー階層(Choropleth)としても可。
  • モバイル対応
    HTML/CSS を調整し、フォームやパン・ズーム操作をタッチフレンドリーに。

以上が、Mapbox GL JS を用いた「農地センサー実装率ヒートマップ」のフルコード例と手順です。

実装率データ活用の未来

農地センサーの実装率をヒートマップで可視化することは、現状把握に留まらず、今後の農業DXを推進するための重要な一歩となります。例えば、ヒートマップと気象データや土壌データを重ね合わせることで、センサー導入と収量との関連性を分析し、より効果的なセンサー配置戦略を立てることが可能になります。また、過去のヒートマップを比較することで、地域ごとの導入傾向を把握し、今後の普及活動のターゲットエリアを特定することもできます。さらに、得られた実装率データは、自治体や農業協同組合といった関係機関との情報共有にも役立ち、地域全体のスマート農業推進に向けた連携を強化することができます。将来的には、AI技術と組み合わせることで、ヒートマップから自動的に課題や改善点を抽出し、具体的なアクションプランを提案するような高度な活用も期待されます。

まとめ

本記事では、Mapbox GLを活用して農地センサーの実装率をヒートマップで可視化する手順と、その意義、今後の活用について解説しました。直感的なヒートマップは、データに基づいた意思決定を支援し、農業DXの加速に貢献します。

コメント

タイトルとURLをコピーしました