🕌
座標点群配列から、各点の近傍(半径100m以内)の点群数を数えて、座標点群配列に追加する
本記事の分類
- 学習ノート
機能
- 舗装修繕箇所(ポットホールの修繕箇所)の座標データから定量的に舗装修繕回数が多い範囲(部分)を評価する
想定シーン
- 舗装修繕箇所の優先順位付けの参考資料を作成する
仕様
- 各舗装補修箇所の近傍(半径100m以内)の補修箇所数を数える。
- 各点の座標データと補修箇所数を要素とする新しい配列を作成する。
- ラフな精度でも問題ないため地球を球体として計算している。
参考
- 高精度を求める場合は別の計算式が必要。https://qiita.com/Yuzu2yan/items/0f312954feeb3c83c70e
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
Discussion