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使用仕様の共有

推薦する

MySQLのファジークエリのような遅い速度を解決する方法

質問: インデックスは作成されているのに、Like ファジー クエリがまだ遅いのはなぜですか?インデ...

MySQL 8.0.16 圧縮版のダウンロードと Win10 システムへのインストール チュートリアル

公式サイトからダウンロード: https://www.mysql.com MySQLの公式サイトにア...

CSS 画像アニメーション効果のサンプルコード(フォトフレーム)

この記事では、CSS 画像アニメーション効果(フォトフレーム)のサンプルコードを紹介し、皆さんと共有...

MySQL データベース トランザクション例のチュートリアル

目次1. トランザクションとは何ですか? 2. トランザクションに関連するステートメントは、挿入、削...

Linux でソースインストールされたパッケージを簡単に削除する方法

ステップ1: Stowをインストールするこの例では CentOS を使用しているため、拡張 EPEL...

vsftpd ユーザーが ssh 経由でログインすることを禁止する方法

序文vsftp は使いやすく安全な FTP サーバー ソフトウェアです。システムユーザーまたは仮想ユ...

要素 el-table テーブルの二次カプセル化 (テーブルの高さの調整付き)

序文会社でのインターンシップ中、フロントエンド開発にはvue+element-uiフレームワークを使...

mysql 5.7.11 winx64.zip インストールと設定方法のグラフィックチュートリアル

MySql データベース システムをインストールして構成します。 1. ダウンロード http://...

DockerでSpring Bootアプリケーションを実行する方法

ここ数日、dockerでSpring Bootアプリケーションを実行する方法を勉強してきました。以前...

Linuxシステムにおける重要なサブディレクトリの問題について話す

/etc/fstabパーティション/ディスクを自動的にマウントし、マウントするパーティション/デバイ...

mysql はインデックスを無効にしますか?

mysql の IN はインデックスを無効にしますか?しませんよ! 結果をご覧ください: mysq...

background-positionプロパティでのパーセンテージ値の使用法の検討

背景位置が背景画像の表示に与える影響この2日間のプロジェクトでホームページの写真を入れ替えていたとこ...

Vueシャトルボックスは上下の動きを実現します

この記事の例では、vueシャトルボックスを上下に動かすための具体的なコードを参考までに共有しています...

ウェブサイトのハイパーリンクを開く方法に関する議論

新しいウィンドウが開きます。 利点: ユーザーがリンクをクリックしても、現在閲覧しているコンテンツは...

MySQL 5.7.23 バージョンのインストールチュートリアルと設定方法

MySQL を自分でインストールするのに 3 時間かかりました。チュートリアルはたくさんあるにもかか...