地理空間データを操作するための node.js ライブラリを探しています。データベースに地理タグ付きデータの大規模なセットがあります。
必要な機能は次のとおりです。
- ジオコーディングとリバース ジオコーディング
- 近くのアイテムを探す
- 地理的境界内のアイテムを見つける
RoR の GeoCoder gem に相当するノードのようなものです。
GeoCoding とリバース部分については、https://github.com/wyattdanger/geocoderを使用できます。
npm install geocoder
検索部分については、地理操作をサポートしている場合は、データベース システムを使用するのが最善の方法です。
そうでない場合は、データベースを別のデータベースに複製しますか (geo 操作を使用)? ギガバイトのデータで作業する必要がある場合、メモリにすべてをロードするのは非常に簡単ではありません。そのためのデータベースが存在します:)。
アプリケーションが何であるかに応じて、直接の Geocoding / rev-Geocoding API に由来しないものをインデックス化する場合、何らかの形式の Geohashing が役立つ場合があります。
Geohash の 1 つのタイプはGoogle の S2 です。これは、64 ビット整数を使用して、地球の表面に指先までの精度で領域にインデックスを付けることができます。
これは、検索時に O(1) ランタイムを使用してノード S2 ライブラリとの境界に何かがあるかどうかを検出する例です。この場合、誰かがブルックリンのウィリアムズバーグにいるかどうかを確認しています。
const s2 = require('@radarlabs/s2');
const williamsburgLongLats = [
[-73.95841598510742, 40.72423412682422],
[-73.96957397460938, 40.71226430831242],
[-73.9683723449707, 40.70497727808752],
[-73.96184921264648, 40.69951148213175],
[-73.95923137664795, 40.70852329864894],
[-73.94775152206421, 40.70391994183744],
[-73.94163608551025, 40.71145106322093],
[-73.94335269927979, 40.71834706657437],
[-73.9469575881958, 40.719778223045275],
[-73.94970417022705, 40.722217623379684],
[-73.95056247711182, 40.721892375167045],
[-73.95193576812744, 40.72335597960796],
[-73.95425319671631, 40.72312830991985],
];
const lls = williamsburgLongLats.map((lnglat) => {
const [lng, lat] = lnglat;
return new s2.LatLng(lat, lng);
});
const s2Level = 14; // ~0.32 km^2
const neighborhoodS2Cells =
new Set(s2.RegionCoverer.getCoveringTokens(
lls,
{ min: s2Level, max: s2Level }
));
const user1LongLat = [-73.95429611206055, 40.71369559554873]; // in williamsburg
const user2LongLat = [-73.9266586303711, 40.71616774648679]; // not in williamsburg
const user1S2 = new s2.CellId(new s2.LatLng(user1LongLat[1], user1LongLat[0])).parent(14); // level 14 to ensure 1:1 mapping to cover
const user2S2 = new s2.CellId(new s2.LatLng(user2LongLat[1], user2LongLat[0])).parent(14); // level 14 to ensure 1:1 mapping to cover
console.log(neighborhoodS2Cells.has(user1S2.token())); // true - O(1)
console.log(neighborhoodS2Cells.has(user2S2.token())); // false - O(1)