Leaflet 플러그인 > L.PixiOverlay를 TypeScript 환경에서 사용



처음에



TS+React에서 Leaflet을 사용하는 프로젝트에서 L.PixiOverlay 플러그인을 사용해 보았습니다.

TypeScript 사용? 사용하지 않고 기분이 흔들리고 있는 가운데 트라이 해 보았습니다만, 시행착오가 힘들었습니다.

이 작업을 플러그인을 추가할 때마다 수행하는 것이 올바른지 여부를 확인할 수 없습니다.

그렇다고는 해도 공수를 생각하면, Leafet와 Leaflet 플러그인을 건간 시험하면서 사용해 피드백을 내어 가는 프로젝트에서는, TypeScript를 사용하지 않는 것이 좋을까라고 하는 것이 솔직한 곳입니다.

이 엔은 이하의 「TypeScript를 사용하지 않는 편이 좋은 케이스」에 들어맞는 것일까라고 생각하고 있습니다.
TypeScript를 사용하는 것이 좋은 경우란? |POSTD

ASP.NET Core 2 React.js Template with ES6 (not TypeScript)

Why isn't typescript used more in the react community? : reactjs

처리 흐름



패키지 추가



package.json에 다음을 추가

package.json
    "leaflet-pixi-overlay": "^1.5.1",
    "pixi.js": "^4.8.0",
    "@types/pixi.js": "4.7.4",

typeScript용 d.ts 파일 만들기



소스 폴더에 leaflet-pixi-overlay.d.ts를 만듭니다.
내용을 다음과 같이 했습니다.

leaflet-pixi-overlay.d.ts
import * as L from 'leaflet'
import * as PIXI from 'pixi.js';

declare module 'leaflet' {
    interface pixiOverlay {
        new(callback: (utils: L.pixiOverlayUtils) => void,
            pixiContainer: PIXI.Container,
            options?: PixiOverlayOptions): any;
        addTo(map: L.Map): pixiOverlay;
    }

    interface pixiOverlayUtils {
        latLngToLayerPoint(_wgsOrigin: L.LatLng): any;
        layerPointToLatLng(): any;
        getScale(): any;
        getRenderer(): PIXI.WebGLRenderer;
        getContainer(): PIXI.Container;
        getMap(): L.Map;
    }

    interface PixiOverlayOptions {
    }

    function pixiOverlay(callback: (utils: L.pixiOverlayUtils) => void,
        pixiContainer: PIXI.Container,
        options?: PixiOverlayOptions): pixiOverlay;

}

manubb/Leaflet.PixiOverlay 의 Examples>Draw a marker를 움직이는 최소한의 기술로 하고 있습니다.

src 폴더라도 좋고,
node_modules/@types/아래에 leaflet-pixi-overlay 폴더를 만들고 index.d.ts 파일로 만들 수 있지만 관리가 번거롭다고 생각합니다.

내가 만든 일을 잊어버릴 줄 알았는데 그만뒀어.

사용법



import에서 PIXI와 eaflet-pixi-overlay를 로드합니다.
import * as PIXI from 'pixi.js';
import 'leaflet-pixi-overlay'

나머지는 참고 과 거의 같습니다.
이하가 되었습니다.
import * as React from 'react';

//leaflet
import 'leaflet/dist/leaflet.css';
import * as L from 'leaflet';

//pixi-overlay
import * as PIXI from 'pixi.js';
import 'leaflet-pixi-overlay'



interface ResourceWithMarker extends PIXI.loaders.Resource {
    marker: PIXI.loaders.Resource;
}



export class MapWorldPixi extends React.Component<{}, {}> {

    componentDidMount() {
        // create the Leaflet map object
        this.init();
    }


    private init() {

        //// this function creates the Leaflet map object and is called after the Map component mounts
        let map = L.map('mapUI').setView([51.505, -0.09], 13);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(map);



        let loader = new PIXI.loaders.Loader();
        loader.add('marker', 'marker-icon.png'); //リソースにmarkerという名で'img/marker-icon.png'を登録

        loader.load(function (loader: PIXI.loaders.Loader, resource: ResourceWithMarker) {  //リソース(marker)をロードする
            var markerTexture = resource.marker.texture;


            var markerLatLng: L.LatLng = new L.LatLng(51.5, -0.09);  //[51.5, -0.09];
            var marker = new PIXI.Sprite(markerTexture);
            marker.anchor.set(0.5, 1); //原点をX:中央 Y:下 に設定

            var pixiContainer = new PIXI.Container();
            pixiContainer.addChild(marker);

            var firstDraw = true;
            var prevZoom: number;


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


                if (firstDraw) {
                    var markerCoords = project(markerLatLng); //Leaflet座標系LatLngからオーバーレイの座標系に投影されたL.Pointを返す。
                    marker.x = markerCoords.x; //ex. markerLatLng[0] 51.5 → 65503.232
                    marker.y = markerCoords.y; //ex. markerLatLng[1] -0.09 → 43589.11367487424
                }

                if (firstDraw || prevZoom !== zoom) { //Leafletのズーム率  ex. 0~18
                    marker.scale.set(1 / scale); //マーカーのサイズを常に倍率1にする。
                }

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

            }, pixiContainer);
           pixiOverlay.addTo(map);
        });

    }


    public render() {
        return <div id="mapUI">
            <div id='map'></div>
        </div>;
    }

}


아래와 같은 화면이 나오면 성공

샘플

참고



좋은 웹페이지 즐겨찾기