web-dev-qa-db-ja.com

数百万ポイントのヒートマップレイヤーを生成する

Googleマップのヒートマップレイヤーを使用してヒートマップを表示していますが、ポイントが多すぎて、ブラウザーで処理できなくなったため、機能しなくなりました。私はそれらがFusionTablesを提供していることを発見しましたが、それらも制限されています:100k行に制限されています。これは低すぎます。数百万またはそれ以上のポイントのヒートマップをレンダリングする必要があります。サーバーにPHPスクリプトを使用して、たとえば1日に1回ヒートマップをレンダリングできるとしたら、完璧です。その後、jsのクライアントは、プリロードされたヒートマップを(マップ上に)ダウンロードするだけです。グーグルマップのようですが、異なるマップかもしれません)これはいくつかの既存のテクノロジーで可能ですか(商用にすることができます)?

13
Makalele

必要なのは、ポイントをより少ない数のポイントに事前にクラスター化し、元のポイントであるかのようにこれらのグループをGoogleマップに渡すことです。したがって、値3、5、および10の近くに3つのポイントがある場合、それらの座標の加重平均で値18の1つのポイントを作成します。すべてのデータセットに対してそれを行うと、3分の1に削減されます。データセットをさらに減らすには、3を適切な値に変更します。

データをクラスター化する簡単な方法は、ジオハッシュ[1]を使用することです。これがPHP用のNiceジオハッシュライブラリです[2]。追加するときに、ポイントごとに異なる精度のジオハッシュのセットを1回だけ計算し、必要な精度を使用して、単純なGROUP BYを使用してデータセットを減らすことができます。例(メタ):

use Lvht\GeoHash;

class DataPoint extends ActiveRecord {
    public geo_hash_precision4, geo_hash_precision5, geo_hash_precision6;
    public function save() {
        $this->geo_hash_precision4 = GeoHash::encode($this->lat,$this->lon, 0.0001);
        $this->geo_hash_precision5 = GeoHash::encode($this->lat,$this->lon, 0.00001);
        $this->geo_hash_precision6 = GeoHash::encode($this->lat,$this->lon, 0.000001);
        parent::save();
    }
}

class DataSet extends ActiveQuery {
    /**
     * @param int $p Desired precision
     */
    public function getValues($p = 6) {
        $data = $this->rawQuery("SELECT geo_hash_precision{$p}, SUM(value) FROM {$this->table} GROUP BY geo_hash_precision{$p}");
        // Add bounding box WHERE to reduce set for map size
        foreach ($data as $row) {
            list($minLon, $maxLon, $minLat, $maxLat) = GeoHash::decode($row["geo_hash_precision{$p}"]);
            $row['lat'] = ($maxLat - $minLat) / 2;
            $row['lon'] = ($maxLon - $minLon) / 2;
            unset($row["geo_hash_precision{$p}"]);
        }
    }
}
  1. https://en.wikipedia.org/wiki/Geohash
  2. https://github.com/lvht/geohash
7
SergeAx

視覚化には heatmap.js を使用します。それは本当に速く、たくさんのポイントを処理することができます。 1.5ミルポイントが機能するかどうかはわかりませんが。

私が想像できるのは、node.jsでJavascriptソリューションの1つを使用して事前レンダリングすることです。 'heatmap js nodejs prerender'に関する簡単なグーグル検索で、これが見つかりました https://github.com/substack/node-heatmap そしてこれ https://mango-is.com/ blog/Engineering/pre-render-d3-js-charts-at-server-side /

3
Danmoreng