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

推薦する

PXEを使用してCentOS7.6を自動的にインストールする方法の詳細なチュートリアル

1. 需要ベースには 300 台の新しいサーバーがあり、CentOS7.6 オペレーティング システ...

vue+element で動的スキニングを実装するためのサンプルコード

プロジェクトのテーマがすべての人の美的感覚を満足できないこともあります。このとき、スキン変更機能は非...

Chrome をクラッシュさせる CSS コードの行

一般的な CSS コードでは、UI レイアウトや互換性に関して軽微な問題が発生するだけです。しかし、...

Tomcatのデフォルトプログラム公開パスの使用と変更についての説明

tomcat7 のデフォルトのプログラム公開パスは tomcat/webapps/ROOT/ です。...

WeChatアプレットが連携メニューを実現

最近はコース設計を実現するために、フロントエンドも少しやっています。今日はいくつかの機能を実現するた...

MySQL で戻り値ありと戻り値なしのストアド プロシージャを書く 2 つの方法

プロセス1: 戻り値あり: proc_addNum が存在する場合はプロシージャを削除します。 プロ...

Vmware での Ubuntu サーバーのインストール チュートリアル

この記事では、Ubuntuサーバーバージョンのインストールグラフィックチュートリアルを参考までに紹介...

HTML でのアンカータグの使用例の共有

アンカータグの使用法:同じドキュメント内の特定の場所にリンクすることをアンカー リンクと呼びます。ア...

AngularパイプラインPIPEの紹介と使い方

序文PIPE、パイプラインと翻訳されます。 Angular パイプは、HTML コンポーネントで宣言...

MySql でリモート接続を許可する方法

MySql でリモート接続を許可する方法この目標を達成するには、2つのことを行う必要がある。ユーザー...

HTML DOM入門_PowerNode Javaアカデミー

DOMとは何ですか? JavaScript を使用すると、HTML ドキュメント全体を再構築できます...

Vue グローバル フィルターの概念、注意事項、基本的な使用方法

目次1. フィルターの概念1. グローバルフィルターのフォーマットをカスタマイズする2. フィルター...

JavaScript によるダイナミッククリスマスツリーの詳細な説明

目次1. CSS のみを使用して作成したアニメーションのクリスマスツリー2. CSS のみを使用して...

MySQL マスタースレーブレプリケーションと読み取り書き込み分離の詳細な説明

目次序文1. 概要2. 読み取りと書き込みの分離3. MySQL マスタースレーブレプリケーションの...

VMware14 に CentOS 7 をインストールするグラフィック チュートリアル

CentOS の紹介CentOS は、Red Hat Linux が提供する無料で利用できるソースコ...