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

推薦する

Linux\Nginx 環境での仮想ドメイン名の設定とテスト検証

Nginx 仮想ドメイン名設定を使用すると、ドメイン名を購入せずに特定のドメイン名を介してローカル ...

MySQL マスタースレーブレプリケーションプロセスの詳細な説明

1. マスタースレーブレプリケーションとは何ですか?マスター データベースの DDL および DML...

MySQLスローログクエリの詳細な説明

遅いログクエリ機能スロー ログ クエリの主な機能は、設定された時間しきい値を超える SQL ステート...

Docker /var/lib/docker/aufs/mnt ディレクトリのクリーニング方法

会社のサービスはdockerを使用しており、ディスクマンが見つかりました。その後、次のコマンドを実行...

Node.js コード実行をバイパスするためのヒントのまとめ

目次1. 子プロセス2. nodejsでのコマンド実行2.1 16進数エンコード2.2 ユニコードエ...

MySQLでユーザーを作成し、権限を管理する方法

1. ユーザーとパスワードの作成方法1. MySQLデータベースに入る mysql> mysq...

知っておくべき JS 配列削減の高度な使い方 25 選

序文Reduce は ES5 で追加された新しい従来の配列メソッドの 1 つです。forEach、f...

Linux で測位バックグラウンド サービスが時々クラッシュする問題の解決方法

問題の説明最近のバックグラウンドサービスでは、特定の命令の要求データをディスクに保存する新しい機能が...

CentOS7におけるKVM仮想化の基本管理の詳しい説明

1. kvm仮想化をインストールする : : : : : : : : : : : : : : : :...

jconsole を使用してリモート Tomcat サービスを監視する方法

JConsoleとはJConsole は Java 5 で導入されました。 JConsole は、コ...

Docker の NFS-Ganesha イメージを使用して NFS サーバーを構築する詳細なプロセス

目次1. NFS-Ganeshaの紹介2. NFS-Ganeshaの設定3. NFS-Ganesha...

Windows および Linux で tomcat9 を介して war パッケージを手動で展開する方法

Windows 環境と Linux 環境では結果が異なります。ウィンドウズステップ 1: Maven...

JavaScriptでポインターの位置を取得する方法を教えます

JavaScript でポインターの位置を取得する方法は、イベント オブジェクトの pageX と ...

MySQLの基礎知識学習ノート

データベースを表示show databases;データベースを作成するDATABASE データベース...

Alibaba Cloud Server Ubuntu 上の Workbench が MySQL に接続できない問題の解決策 (テスト済み)

過去 2 日間、ワークベンチが Alibaba Cloud Server に接続できない問題を解決す...