OpenLayersはポイントフィーチャーレイヤーの集約表示方法を実現します

OpenLayersはポイントフィーチャーレイヤーの集約表示方法を実現します

1. はじめに

多くの場合、ポイント フィーチャ レイヤー内のフィーチャの数は数百または数千になります。これらのフィーチャを処理せずにマップに直接ロードすると、ユーザーの視覚的エクスペリエンスが低下するだけでなく、マップ インターフェースがフリーズする原因にもなります。次のコードは、表示用に1000ランダム ポイントを作成します。

<!DOCTYPE html>
<html>
<ヘッド>
    <meta http-equiv="コンテンツタイプ" コンテンツ="text/html; charset=utf-8" />
    <メタ文字セット="utf-8" />
    <title>OpenLayers</title>
    <スタイル>
        html、本文、#map {
            幅: 100%;
            高さ: 100%;
            マージン: 0;
            パディング: 0;
        }
    </スタイル>
    <link href="libs/ol/ol.css" rel="スタイルシート" />
    <script src="libs/ol/ol.js"></script>
</head>
<本文>
    <div id="マップ"></div>

    <スクリプト>
        // 1000 個のランダムな特徴を作成します。var source = new ol.source.Vector();
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.00 + Math.random(), 30.00 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.01 + Math.random(), 30.01 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.02 + Math.random(), 30.02 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.03 + Math.random(), 30.03 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.04 + Math.random(), 30.04 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }

        // レイヤーを作成する var layer = new ol.layer.Vector({
            出典: 出典、
            スタイル: 関数 (機能、解像度) {
                var style = new ol.style.Style({
                    画像: 新しい ol.style.Icon({
                        ソース: 'img/location.png'
                    })
                })
                戻りスタイル;
            }
        });

        // マップを作成する var map = new ol.Map({
            ターゲット: 'マップ',
            レイヤー:
                新しい ol.layer.Tile({
                    ソース: 新しい ol.source.OSM()
                })、
                層
            ]、
            ビュー: 新しい ol.View({
                投影: 'EPSG:4326',
                中央: [120, 30],
                ズーム: 10,
                最小ズーム: 5,
                最大ズーム: 14
            })
        });
    </スクリプト>
</本文>
</html>

実行結果は下の図に示されています。

ここに画像の説明を挿入

たくさんのポイントが密集しているのを見ると気持ち悪いと思いませんか?一般的に、ポイント フィーチャ レイヤーに多数のポイントがある場合は、圖層聚合によって処理します。ただし、圖層聚合只對點要素圖層有效,對線和面圖層無效注意してください。

2. ポイントフィーチャーレイヤーの集約

openlayersでは、レイヤー集約の一般的な手順は次のとおりです。

  • フィーチャを作成する
  • データソースを作成して機能を追加する
  • 集計データソースを作成し、集計距離を設定する
  • レイヤーを作成し、データソースを集計データソースに設定します
  • マップを作成し、集計レイヤーを追加する

レイヤー集約コードは次のとおりです。

<!DOCTYPE html>
<html>
<ヘッド>
    <meta http-equiv="コンテンツタイプ" コンテンツ="text/html; charset=utf-8" />
    <メタ文字セット="utf-8" />
    <title>OpenLayers</title>
    <スタイル>
        html、本文、#map {
            幅: 100%;
            高さ: 100%;
            マージン: 0;
            パディング: 0;
        }
    </スタイル>
    <link href="libs/ol/ol.css" rel="スタイルシート" />
    <script src="libs/ol/ol.js"></script>
</head>
<本文>
    <div id="マップ"></div>

    <スクリプト>
        // 1000 個のランダムな特徴を作成します。var source = new ol.source.Vector();
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.00 + Math.random(), 30.00 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.01 + Math.random(), 30.01 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.02 + Math.random(), 30.02 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.03 + Math.random(), 30.03 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.04 + Math.random(), 30.04 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }

        // 集計 var cluster = new ol.source.Cluster({
            出典: 出典、
            距離: 100
        })

        // レイヤーを作成する var layer = new ol.layer.Vector({
            出典: クラスター、
            スタイル: 関数 (機能、解像度) {
                var size = feature.get('features').length;
                var style = new ol.style.Style({
                    イメージ: 新しい ol.style.Circle({
                        半径: 30,
                        ストローク: 新しい ol.style.Stroke({
                            色: 「白」
                        })、
                        塗りつぶし: 新しい ol.style.Fill({
                            色: '青'
                        })
                    })、
                    テキスト: 新しい ol.style.Text({
                        テキスト: size.toString(),
                        塗りつぶし: 新しい ol.style.Fill({
                            色: 「白」
                        })
                    })
                })
                戻りスタイル;
            }
        });

        // マップを作成する var map = new ol.Map({
            ターゲット: 'マップ',
            レイヤー:
                新しい ol.layer.Tile({
                    ソース: 新しい ol.source.OSM()
                })、
                層
            ]、
            ビュー: 新しい ol.View({
                投影: 'EPSG:4326',
                中央: [120, 30],
                ズーム: 10,
                最小ズーム: 5,
                最大ズーム: 14
            })
        });
    </スクリプト>
</本文>
</html>

実行結果は下の図に示されています。

ここに画像の説明を挿入

3. 重合の特殊処理

上記のコードはポイント フィーチャ レイヤーの集約を実現しますが、実際には問題があります。次の図に示すように、地圖縮放層級最大時仍然保持著聚合效果

ここに画像の説明を挿入

一般的に言えば、當某處只有一個點時就應該取消聚合效果。 このとき、コールバック関数のstyle: function (feature, resolution)に変更する必要があります。 コードは次のとおりです。

<!DOCTYPE html>
<html>
<ヘッド>
    <meta http-equiv="コンテンツタイプ" コンテンツ="text/html; charset=utf-8" />
    <メタ文字セット="utf-8" />
    <title>OpenLayers</title>
    <スタイル>
        html、本文、#map {
            幅: 100%;
            高さ: 100%;
            マージン: 0;
            パディング: 0;
        }
    </スタイル>
    <link href="libs/ol/ol.css" rel="スタイルシート" />
    <script src="libs/ol/ol.js"></script>
</head>
<本文>
    <div id="マップ"></div>

    <スクリプト>
        // 1000 個のランダムな特徴を作成します。var source = new ol.source.Vector();
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.00 + Math.random(), 30.00 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.01 + Math.random(), 30.01 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.02 + Math.random(), 30.02 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.03 + Math.random(), 30.03 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.04 + Math.random(), 30.04 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }

        // 集計 var cluster = new ol.source.Cluster({
            出典: 出典、
            距離: 100
        })

        // レイヤーを作成する var layer = new ol.layer.Vector({
            出典: クラスター、
            スタイル: 関数 (機能、解像度) {
                var size = feature.get('features').length;
                (サイズ == 1)の場合{
                    新しい ol.style.Style({ を返します
                        画像: 新しい ol.style.Icon({
                            ソース: 'img/location.png'
                        })
                    })
                }
                それ以外 {
                    新しい ol.style.Style({ を返します
                        イメージ: 新しい ol.style.Circle({
                            半径: 30,
                            ストローク: 新しい ol.style.Stroke({
                                色: 「白」
                            })、
                            塗りつぶし: 新しい ol.style.Fill({
                                色: '青'
                            })
                        })、
                        テキスト: 新しい ol.style.Text({
                            テキスト: size.toString(),
                            塗りつぶし: 新しい ol.style.Fill({
                                色: 「白」
                            })
                        })
                    })
                }
            }
        });

        // マップを作成する var map = new ol.Map({
            ターゲット: 'マップ',
            レイヤー:
                新しい ol.layer.Tile({
                    ソース: 新しい ol.source.OSM()
                })、
                層
            ]、
            ビュー: 新しい ol.View({
                投影: 'EPSG:4326',
                中央: [120, 30],
                ズーム: 10,
                最小ズーム: 5,
                最大ズーム: 14
            })
        });
    </スクリプト>
</本文>
</html>

実行結果は下の図に示されています。

ここに画像の説明を挿入

実際、このエフェクトの実装は非常に簡単です。コア コードは次のとおりです: var size = feature.get('features').length; size>1場合は集約スタイルを返し、それ以外の場合は画像スタイルを返します。

4. 重合の特殊処理 2

上記のコードでは、マップの最大ズーム レベルを14に設定しましたが、當地圖縮放到最大層級時,還有很多點保持著聚合效果問題が発生します。當地圖縮放到最大層級時,取消全部聚合效果要求する場合があります。この機能を実装するには、マップ イベントをリッスンする必要があります。コードは次のとおりです。

<!DOCTYPE html>
<html>
<ヘッド>
    <meta http-equiv="コンテンツタイプ" コンテンツ="text/html; charset=utf-8" />
    <メタ文字セット="utf-8" />
    <title>OpenLayers</title>
    <スタイル>
        html、本文、#map {
            幅: 100%;
            高さ: 100%;
            マージン: 0;
            パディング: 0;
        }
    </スタイル>
    <link href="libs/ol/ol.css" rel="スタイルシート" />
    <script src="libs/ol/ol.js"></script>
</head>
<本文>
    <div id="マップ"></div>

    <スクリプト>
        // 1000 個のランダムな特徴を作成します。var source = new ol.source.Vector();
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.00 + Math.random(), 30.00 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.01 + Math.random(), 30.01 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.02 + Math.random(), 30.02 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.03 + Math.random(), 30.03 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }
        (var i = 1; i <= 200; i++) の場合 {
            var 座標 = [120.04 + Math.random(), 30.04 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(座標));
            ソース.addFeature(機能);
        }

        // 集計 var cluster = new ol.source.Cluster({
            出典: 出典、
            距離: 100
        })

        // レイヤーを作成する var layer = new ol.layer.Vector({
            出典: クラスター、
            スタイル: 関数 (機能、解像度) {
                var size = feature.get('features').length;
                (サイズ == 1)の場合{
                    新しい ol.style.Style({ を返します
                        画像: 新しい ol.style.Icon({
                            ソース: 'img/location.png'
                        })
                    })
                }
                それ以外 {
                    新しい ol.style.Style({ を返します
                        イメージ: 新しい ol.style.Circle({
                            半径: 30,
                            ストローク: 新しい ol.style.Stroke({
                                色: 「白」
                            })、
                            塗りつぶし: 新しい ol.style.Fill({
                                色: '青'
                            })
                        })、
                        テキスト: 新しい ol.style.Text({
                            テキスト: size.toString(),
                            塗りつぶし: 新しい ol.style.Fill({
                                色: 「白」
                            })
                        })
                    })
                }
            }
        });

        // マップを作成する var map = new ol.Map({
            ターゲット: 'マップ',
            レイヤー:
                新しい ol.layer.Tile({
                    ソース: 新しい ol.source.OSM()
                })、
                層
            ]、
            ビュー: 新しい ol.View({
                投影: 'EPSG:4326',
                中央: [120, 30],
                ズーム: 10,
                最小ズーム: 5,
                最大ズーム: 14
            })
        });

        // マップ解像度の変更イベントをリッスンします。map.getView().on('change:resolution', function (event) {
            (map.getView().getZoom() == map.getView().getMaxZoom()) の場合 {
                クラスター.set距離(0);
            }
            それ以外 {
                クラスター.set距離(100);
            }
        })
    </スクリプト>
</本文>
</html>

実行結果は下の図に示されています。

ここに画像の説明を挿入

このエフェクトの実装も非常に簡単です。現在のマップの解像度変更イベントをリッスンするだけです。現在のズーム レベルがすでに最大レベルである場合は、集約距離を0に設定します。

5. 結論

要素の数が多い場合は、それらを集約することを検討する必要があります。これにより、ユーザー エクスペリエンスが向上するだけでなく、インターフェイスのフリーズも回避できます。実際、上記のコードでは、 change:resolutionイベントをリッスンしていました。これを別のイベント、 moveendに変更することもできます。コードは次のとおりです。

map.on('moveend', 関数(イベント) {
    (map.getView().getZoom() == map.getView().getMaxZoom()) の場合 {
        クラスター.set距離(0);
    }
    それ以外 {
        クラスター.set距離(100);
    }
});

moveendイベントをリッスンすることで同じ効果を実現できます。このイベントは、マップがズームされているかパンされているかに関係なくトリガーされるためです。

OpenLayers でポイント フィーチャ レイヤーの集約表示を実装する方法についての記事はこれで終わりです。OpenLayers でポイント フィーチャ レイヤーの集約表示に関する詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Openlayers+EasyUI Treeはレイヤーコントロールを動的に実現します
  • OpenLayers3はレイヤー制御機能を実装する
  • OpenLayersはレイヤー切り替え制御を実装します

<<:  Ubuntu 20.04 Firefox でビデオを再生できない (Flash プラグインがない) 場合の解決策

>>:  超詳細なMySQL使用仕様の共有

推薦する

JS はデータ URL をどのように理解するのでしょうか?

目次概要データ URL の使用を開始するデータURL構文複数言語の文字列のBase64エンコードとデ...

MySQL データベースの Binlog 使用法の概要 (必読)

MySQL データベースにとって binlog バイナリ ログがどれほど重要であるかについては詳し...

Linux で ARM 開発ボード用のファイルシステムを作成する

1. Busyboxのソースコードをオンラインでダウンロードしてください。コンパイル方法については、...

HarborをベースにしたDocker専用倉庫の構築方法

目次1. ハーバーの紹介1. ハーバーが民間倉庫を建設3. 港湾の維持管理4. Harborユーザー...

WeChatミニプログラムにナビゲーション機能を実装する方法

1. レンダリング2. 操作手順1. テンセントマップキーを申請する - 住所2. ミニプログラムの...

MySQL データベースのエンコーディングを utf8mb4 に変更する方法

utf8mb4 エンコーディングは utf8 エンコーディングのスーパーセットであり、utf8 と互...

JavaScriptのループの違いについての詳細な説明

目次序文列挙可能なプロパティ反復可能なオブジェクトforEachメソッドとmapメソッドチェーン呼び...

JavaScript を使用してテーブル情報を追加および削除する

JavaScript 入門JavaScript は軽量なインタープリタ型の Web 開発言語です。言...

vue+tp5はシンプルなログイン機能を実現

この記事では、参考までに、簡単なログイン機能を実装するためのvue+tp5の具体的なコードを紹介しま...

MySQLデータベースインデックスの詳細な説明

目次1. MySQLインデックスの紹介2. MySQLの5種類のインデックスの詳しい説明1. 総合索...

シェルスクリプトはNginxのaccess.logのPVを定期的にカウントし、APIに送信してデータベースに保存します。

1. PVとIPの統計一日のPV(ページビュー)をカウントする cat access.log | ...

フロントエンドの上級者向けコースでは、JavaScript のストレージ機能の使い方を学習します。

目次序文背景実施計画の考え方js ストレージ機能ソリューション設計やっと要約する序文どの SaaS ...

Reactを使用する際の7つの落とし穴のまとめ

目次1. コンポーネントの肥大化2. 状態を直接変更する3. プロパティは数値を渡す必要があるが文字...

keepalived+nginx の高可用性を実装する方法の例

1. keepalived の紹介Keepalived は、もともと LVS クラスタ システム内の...

画像比較を実現するjQueryプラグイン

この記事の例では、画像比較を実現するためのjQueryプラグインの具体的なコードを参考までに共有して...