🕌

座標点群配列から、各点の近傍(半径100m以内)の点群数を数えて、座標点群配列に追加する

2024/08/31に公開

本記事の分類

  • 学習ノート

機能

  • 舗装修繕箇所(ポットホールの修繕箇所)の座標データから定量的に舗装修繕回数が多い範囲(部分)を評価する

想定シーン

  • 舗装修繕箇所の優先順位付けの参考資料を作成する

仕様

  • 各舗装補修箇所の近傍(半径100m以内)の補修箇所数を数える。
  • 各点の座標データと補修箇所数を要素とする新しい配列を作成する。
  • ラフな精度でも問題ないため地球を球体として計算している。

参考

Code

  • 以下のとおり
createStaffTable
latArrIndex = 0;
lonArrIndex = 1;

function fetchPoints() {
  const range = SpreadsheetApp.getActiveRange();
  let points = range.getValues();
  return points;
}

// 地球の半径 (キロメートル)
const R = 6371;

// 緯度と経度をラジアンに変換する関数
function toRadians(degrees) {
    return degrees * (Math.PI / 180);
}

// 2地点間の距離を計算する関数
function calculateDistance(lat1, lon1, lat2, lon2) {
    // 緯度と経度をラジアンに変換
    const φ1 = toRadians(lat1);
    const φ2 = toRadians(lat2);
    const λ1 = toRadians(lon1);
    const λ2 = toRadians(lon2);

    // 内積からθを求める
    const cosθ = Math.cos(φ1) * Math.cos(φ2) * Math.cos(λ1 - λ2) + Math.sin(φ1) * Math.sin(φ2);

    // θ = arccos(cosθ)
    const θ = Math.acos(cosθ);

    // 距離を計算
    const distance = R * θ;
    return distance;
}

const radius = 0.1; //0.1km
function countAndAddNearbyPointsToCoordinate(points) {
    return points.map((point, currentIndex) => {
        const lat1 = point[latArrIndex];
        const lon1 = point[lonArrIndex];
        
        const nearbyCount = points.filter((point, anotherIndex) => {
            if (currentIndex === anotherIndex) return false; // 同じポイントは除外
            const lat2 = point[latArrIndex];
            const lon2 = point[lonArrIndex];
            const distance = calculateDistance(lat1, lon1, lat2, lon2);
            return distance <= radius;
        }).length;

        return [nearbyCount,point[latArrIndex],point[lonArrIndex]];
        point[countNearbyPointsArrIndex] = nearbyCount;
        point[countNearbyPointsArrIndex+1] = 'test';
        
    });
}

function setResultToSheetResult(arr) {
  const resultSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('result'); 
  if (resultSheet) resultSheet.clear();
  if (!resultSheet) resultSheet = spreadsheet.insertSheet('result');

  resultSheet.getRange(1,1,1,3).setValues([["近傍補修箇所数","緯度","経度"]]);
  resultSheet.getRange(2,1,arr.length,3).setValues(arr);
}

let points = fetchPoints();
const countsInRadiusAndCoodinates = countAndAddNearbyPointsToCoordinate(points);
setResultToSheetResult(countsInRadiusAndCoodinates);

使い方

  • googleSpreadSheetに座標値を入力(1列目は緯度、2列目は経度)
  • 座標値を範囲選択
  • ”拡張機能”→”Apps Script”を選択し上記codeを入力し実行をclick

参考にしたwebPage

Discussion