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

推薦する

CSS3 を使用したテキスト折り紙効果のサンプルコード

序文この記事では主に、CSS3 を使用してテキスト折り紙効果を実現する例を紹介します。これは、参考と...

axios でリクエストをキャンセルし、重複リクエストを防ぐ方法について簡単に説明します。

目次序文コア - キャンセルトークン実用的なアプリケーションとパッケージングいくつかの小さな詳細序文...

Node.jsはexpress-fileuploadミドルウェアを使用してファイルをアップロードします

目次プロジェクトを初期化するサーバーの作成クライアントを初期化するコンポーネントの記述ファイルアップ...

Vue で jsx 構文を正しく使用する方法

目次序文仮想DOM仮想DOMとは仮想DOMの利点レンダリング関数とは何ですか? jsx Vue3 で...

Vue は Websocket カスタマー サービス チャット機能を実装します

この記事では主に基本的なチャットの実装方法を紹介します。今後は絵文字や写真のアップロードなどの機能も...

js はマウスによる画像の切り替えを実装します (タイマーなし)

この記事の例では、マウス切り替え画像を実現するためのjsの具体的なコードを参考までに共有しています。...

MySQLのユーザー管理とPostgreSQLのユーザー管理の違い

1. MySQL ユーザー管理[例1.1] ローカルMySQLサーバーのテストデータベースにroot...

HTML におけるメタの役割について (インターネットから収集および分類)

W3Cschoolではこのように説明しています<meta> 要素は、検索エンジン向けの説...

MySQLのストレージエンジンについてお話しましょう

基礎リレーショナル データベースでは、各データ テーブルはファイルに相当し、異なるストレージ エンジ...

HTML フォーム コントロールの無効な属性の読み取り専用と無効の概要

HTML でフォームの送信を無効にする方法は 2 つあります。 1. コントロールタグにreadon...

alpineをベースにdockerfileで作成したtomcatイメージの実装

1.アルパインイメージをダウンロードする [root@docker43 ~]# docker pul...

TypeScript で時間を費やした場所の概要

TS で時間を過ごした場所をいくつか記録します。 (まず、文句を言わせてください。stackover...

dockerコマンドの使用にはsudoは必要ありません

docker デーモンは通常の TCP ポートではなくホストの Unix ソケットにバインドする必要...

React Native JSIはRNとネイティブ通信のサンプルコードを実装します

目次JSIとはJSIの違いiOS で JSI を使用するiOS 設定RN側の構成jsはパラメータ付き...

5 分で vue-cli3 を使用してプロジェクトを作成する方法を説明します (初心者向けガイド)

目次1. Vue環境を構築する2. Vue スキャフォールディングツール3. プロジェクトを作成する...