ホームページ > ウェブフロントエンド > jsチュートリアル > 地理空間インデックス作成サンプラー

地理空間インデックス作成サンプラー

Barbara Streisand
リリース: 2024-12-30 09:48:22
オリジナル
819 人が閲覧しました

Geospatial Indexing Sampler

私は最近、ミニマリストのふりをしながらアプリを構築する練習をしました。そのためには、実績のある友人である PostGIS を使用せずに GPS ポイントをフィルタリングできる必要がありました。

空間データにインデックスを付ける最も一般的な 3 つの方法、Geohash、H3、S2 について簡単に説明しました。

これら 3 つのツールはすべて、ズームインするにつれて地球をより小さな単位に細分化する形状にスライスすることで機能します。

  • GeoHash は長方形を使用します
  • H3 は六角形を使用します
  • S2 はワイルドであり、空間充填曲線を使用します

これらの種類のインデックスがどのように機能するかを調べるための優れた方法は、https://geohash.softeng.co/ です。各セルをクリックすると拡大表示され、より深いレベルが表示されます。世界で私のお気に入りの場所の 1 つは、GeoHash ddk6p5

です。

これらを使用して GPS データに「インデックス」を付けることは、関心のあるレベルごとにテキスト列を追加するだけで簡単です。たとえば、次のようなテーブルを作成できます。

CREATE TABLE IF NOT EXISTS places (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT,
    latitude REAL,
    longitude REAL,
    geohash_level_2 TEXT,
    geohash_level_4 TEXT
);

INSERT INTO places (name,latitude,longitude,geohash_level_2,geohash_level_4)
VALUES('mt shavano', 38.618840, -106.239364, '9w', '9wu7');

INSERT INTO places (name,latitude,longitude,geohash_level_2,geohash_level_4)
VALUES('blanca peak', 37.578047, -105.485796, '9w', '9wsv');

INSERT INTO places (name,latitude,longitude,geohash_level_2,geohash_level_4)
VALUES('mt princeton', 38.749148, -106.242578, '9w', '9wuk');

INSERT INTO places (name,latitude,longitude,geohash_level_2,geohash_level_4)
VALUES('la soufriere', 13.336299, -61.177146, 'dd', 'ddk7');
ログイン後にコピー

Sqlime は、これらのクエリを試すのに最適な場所です。

次に、コロラド州南部の場所を見つけるために、地図の「9w」の部分をカバーするハッシュを見つけます。

SELECT * FROM places WHERE geohash_level_2 = '9w';
ログイン後にコピー

カリブ海南部の場所を見つけるには、以下を使用できます:

SELECT * FROM places WHERE geohash_level_2 = 'dd';
ログイン後にコピー

このアプローチでは、データベースにどのレベルのインデックスを保持する必要があるかを事前に計画する必要があります。 それ以外の場合は、特定のエリアまたはマップ ビューポートでどのオブジェクトが見つかったかをすばやく見つける必要がある単純なアプリケーションに最適です。

LIKE クエリをサポートするデータベースを使用すると、複数の列の使用を減らすことができます。また、H3 セル番号は完全に重複していないため、「で始まる」タイプのクエリは H3 では機能しないことにも注意してください。

最後に、これらのインデックスの優れた特徴は、セル番号が優れたリアルタイム イベント トピックになることです。 したがって、上記の例では、コロラド州南部に対して「9w」というイベント トピックを作成できます。その後、新しい場所が追加されると、新しい場所ごとに「9w」トピックでイベントを発行します。

これらの各インデックス タイプのサンプル JavaScript (deno) コードを次に示します。

GeoJSON 出力はここで表示できることに注意してください: https://geojson.io/

ジオハッシュ

import { geocoordinateToGeohash } from 'npm:geocoordinate-to-geohash'
import { geohashToPolygonFeature } from 'npm:geohash-to-geojson'

import geohash from 'npm:ngeohash'
const lat = 38.618840
const lng = -106.239364
const hash2 = geohash.encode(lat, lng, 2)
console.log('mt shavano hash at level 2', hash2)
const feat2 = geohashToPolygonFeature(hash2)
console.log('mt shavano hash at level 2 bounds', JSON.stringify(feat2))

// About a city block in size in CO (size changes as you head towards poles)
const hash7 = geohash.encode(lat, lng, 7)
console.log('mt shavano hash at level 4', hash7)
const feat7 = geohashToPolygonFeature(hash7)
console.log('mt shavano hash at level 4 bounds', JSON.stringify(feat7))
ログイン後にコピー

H3

import h3 from 'npm:h3-js'
import geojson2h3 from "npm:geojson2h3"

const lat = 38.618840
const lng = -106.239364

// Level 2 (~1/3 Colorado Size)
const h3IndexL2 = h3.latLngToCell(lat, lng, 2);
console.log('mt shavano cell at level 2', h3IndexL2)
const featureL2 = geojson2h3.h3ToFeature(h3IndexL2)
console.log('mt shavano cell at level 2 bounds', JSON.stringify(featureL2))

// Level 4 (~City of Salida Size)
const h3IndexL4 = h3.latLngToCell(lat, lng, 4);
console.log('mt shavano cell at level 4', h3IndexL4)
const featureL4 = geojson2h3.h3ToFeature(h3IndexL4)
console.log('mt shavano cell at level 4 bounds', JSON.stringify(featureL4))
ログイン後にコピー

S2

// This might be a better choice : https://www.npmjs.com/package/@radarlabs/s2
import s2 from 'npm:s2-geometry'
const S2 = s2.S2
const lat = 38.618840
const lng = -106.239364

const key2 = S2.latLngToKey(lat, lng, 2)
const id2 = S2.keyToId(key2)
const feature2 = cellCornersToFeatureCollection(lat, lng, 2)
console.log('mt shavano key at level 2', key2)
console.log('mt shavano cell id at level 2', id2)
console.log('mt shavano cell at level 2 corners', JSON.stringify(feature2))

const key4 = S2.latLngToKey(lat, lng, 4)
const id4 = S2.keyToId(key4)
const feature4 = cellCornersToFeatureCollection(lat, lng, 4)
console.log('mt shavano key at level 4', key4)
console.log('mt shavano cell id at level 4', id4)
console.log('mt shavano cell at level 4 corners', JSON.stringify(feature4))

function cellCornersToFeatureCollection(lat, lng, level) {

    const ll = S2.L.LatLng(lat, lng)
    const cell = S2.S2Cell.FromLatLng(ll, level)
    const corners = cell.getCornerLatLngs()
    const coordinates = corners.map((pair) => {
        return [pair.lng, pair.lat]
    })

    return {
        "type": "FeatureCollection",
        "features": [
          {
            "type": "Feature",
            "geometry": {
              "type": "Polygon",
              "coordinates": [coordinates]
            },
            "properties": {}
          }
        ]
      }
}
ログイン後にコピー

以上が地理空間インデックス作成サンプラーの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート