0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Leaflet.PixiOverlay その2many-markers

Last updated at Posted at 2018-05-30

その1:Leaflet.PixiOverlay その1マーカーの表示 - Qiita
その2:Leaflet.PixiOverlay その2many-markers - Qiita

はじめに

LeafletとWebGLのライブラリであるPixi.jsの橋渡しをするLeaflet.PixiOverlayを使って、many-markersをやってみます。

Leaflet.PixiOverlay

image
拡大するとこんな沢山のマーカーでした。
image

many-markers

Githubに置いてあるmany-markers.htmlをやってみます。

関連JSのインストール

  • bezier-easing
    many-markersを動かすにはbezier-easingが必要なようです。gre/bezier-easing

以下のコマンドでインストールします。
> npm i bezier-easing --save

  • MarkerContainer.js
    Githubリポジトリのdocs/js/MarkerContainer.jsも必要になるのでプロジェクトにコピーし配置します。

index.html

index.htmlを以下の内容にしました。

index.html
<html>
<head>
    <title>Leaflet</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="./node_modules/leaflet/dist/leaflet.css" />
</head>
<body style="height: 100%; margin: 0; overflow: hidden;">
    <div id="map" style="height: 100%; width: 100%;"></div>
</body>

<script src="./node_modules/leaflet/dist/leaflet.js"></script>
<script src="./node_modules/pixi.js/dist/pixi.min.js"></script>
<script src="./node_modules/leaflet-pixi-overlay/L.PixiOverlay.min.js"></script>
<script src="./node_modules/bezier-easing/dist/bezier-easing.min.js"></script>
<script src="./js/MarkerContainer.js"></script>

<script src="./js/many-markers.js"></script>
<script src="./js/index.js"></script>

</html>

JS部分

function manyMarker() {
    var map = L.map('map').setView([48.838565, 2.449264526367], 13);
    L.tileLayer('//stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png', {
        subdomains: 'abcd',
        attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">ODbL</a>.',
        minZoom: 4,
        maxZoom: 18
    }).addTo(map);

    //マーカー最大個数
    var markersLength = 1000000;


    function getRandom(min, max) {
        return min + Math.random() * (max - min);
    }

    //Draw a marker
    var loader = new PIXI.loaders.Loader();
    loader.add('marker', '../img/marker-icon.png'); //リソースにmarkerという名で'img/marker-icon.png'を登録
    loader.load(function (loader, resources) {  //リソース(marker)をロードする
        var texture = resources.marker.texture;

        var pixiContainer = new PIXI.Container();
        var innerContainer = new PIXI.particles.ParticleContainer(markersLength, { vertices: true });
        innerContainer.texture = texture;
        innerContainer.baseTexture = texture.baseTexture;
        innerContainer.anchor = { x: 0.5, y: 1 };
        pixiContainer.addChild(innerContainer);

        var firstDraw = true;
        var prevZoom;
        var initialScale;

        var pixiOverlay = L.pixiOverlay(function (utils) { //Leafletでズームやパンを行う度にコールされます。ドラッグ中はコールされない
            var zoom = utils.getMap().getZoom(); //Leafletのズーム率  ex. 0~18
            var container = utils.getContainer();
            var renderer = utils.getRenderer();
            var project = utils.latLngToLayerPoint; //Leaflet座標系LatLngからオーバーレイの座標系に投影されたL.Pointを返す。
            var scale = utils.getScale();
            var invScale = 1 / scale;

            if (firstDraw) {
                var origin = project([(48.7 + 49) / 2, (2.2 + 2.8) / 2]);
                innerContainer.x = origin.x;
                innerContainer.y = origin.y;
                initialScale = invScale / 8;
                innerContainer.localScale = initialScale;
                for (var i = 0; i < markersLength; i++) {
                    var coords = project([getRandom(48.7, 49), getRandom(2.2, 2.8)]);
                    // our patched particleContainer accepts simple {x: ..., y: ...} objects as children:
                    innerContainer.addChild({
                        x: coords.x - origin.x,
                        y: coords.y - origin.y
                    });
                }
            }

            if (firstDraw || prevZoom !== zoom) {
                innerContainer.localScale = zoom < 8 ? 0.1 : initialScale;// 1 / scale;
            }

            firstDraw = false;
            prevZoom = zoom;
            renderer.render(container); //オーバーレイ上にあるオブジェクトの再描画する。
        }, pixiContainer);

        pixiOverlay.addTo(map);
    });
}

コード解説

Loader

Loader部分はその1とあまり変わりません。
唯一、documentのDOMContentLoadedイベント発火後にloader.loadが実行されるようになっています。(この意図はいまいちわからず)

       map.attributionControl.setPosition('bottomleft');
       map.zoomControl.setPosition('bottomright');

zoomControlとLeaflet表記の位置が変更されています。

ParticleContainer

たくさんのマーカーを扱う為にParticleContainerを使っています。

公式ヘルプ#ParticleContainerには以下の記述があります。

The ParticleContainer class is a really fast version of the Container built solely for speed, so use when you need a lot of sprites or particles. The tradeoff of the ParticleContainer is that most advanced functionality will not work. ParticleContainer implements the basic object transform (position, scale, rotation) and some advanced functionality like tint (as of v4.5.6). Other more advanced functionality like masking, children, filters, etc will not work on sprites in this batch.
ParticleContainerクラスは、スピード専用に作成されたコンテナの高速バージョンです。スプライトやパーティクルがたくさん必要な場合に使用します。 ParticleContainerのトレードオフは、最も高度な機能が動作しないことです。 ParticleContainerは、基本オブジェクトの変換(位置、スケール、回転)と色調のような高度な機能を実装しています(v4.5.6以降)。 マスキング、子供、フィルタなどのその他の高度な機能は、このバッチのスプライトでは機能しません。

L.pixiOverlay

var pixiLayer = (function () {
中略
return L.pixiOverlay(function (utils, event) {
})();

その1でpixiOverlayで作成したレイヤーをpixiOverlayに格納していましたが、
これと書き方が違いますが、これと同様の事を行っています。pixiOverlayをpixiLayerに代入。

var pixiOverlay = L.pixiOverlay(function (utils) {
中略
}, pixiContainer);

違いはズーム時の微妙な挙動を付けているところです。

PIXI.ticker.Ticker

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?