如何在 PixiOverlay 上绘制 svg 标记?

How to draw svg markers on PixiOverlay?

我正在尝试在 PixiOverlay.js 上绘制 svg 标记(使用 Pixi.js 的绘图叠加层)。我自己对 Pixi 完全陌生,我想我把一些东西放在一起画了一个菱形,看第一个代码片段(如果不正确,或者需要改进让我知道)

在 pixiOverlay github 页面上有一个 nice demo 可以在地图上呈现大量的多边形。我已将此演示精简到最低限度(请参阅下面的第二个代码片段)。在这段代码中有一个 drawPoly 函数,顾名思义,它绘制多边形。

我想用另一个函数替换它,该函数仅在某个预定义点(例如,可以是多边形坐标中的第一个点,或者只是一个随机点)绘制菱形 svg 标记

请问我该怎么做?

在现实生活中我有很多这样的标记,都是一些几何形状,三角形,星形,正方形,圆形等,总共会有几千个(大约100K甚至更多,取决于当然在缩放级别上。在 zoom=0 时可能接近一百万)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
<script src='https://d157l7jdn8e5sf.cloudfront.net/dev/pixi.js'></script>
<!--<script src="https://cdn.rawgit.com/manubb/Leaflet.PixiOverlay/master/docs/js/example.min.js">--></script>

<script id="rendered-js">
    var renderer;
    renderer = PIXI.autoDetectRenderer();
    document.body.appendChild(renderer.view);

    var graphics = new PIXI.Graphics();
    graphics.lineStyle(5, 0x00FF00, 1);
    graphics.moveTo(0, 75);
    graphics.lineTo(50, 0);
    graphics.lineTo(100, 75);
    graphics.lineTo(50, 150);
    graphics.lineTo(0, 75);
    graphics.cacheAsBitmap = true;

    renderer.render(graphics);



</script>
</body>
</html>

<!DOCTYPE html>
<html style="height: 100%; margin: 0;">
<head>
    <title>Leaflet.PixiOverlay example</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">

    <!--jquery -->
    <script src="https://code.jquery.com/jquery-3.3.1.js"></script>

    <!--d3 -->
    <script src='https://d3js.org/d3.v4.min.js'></script>

    <!-- leaflet v 1.0.3 -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css"/>
    <script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js"></script>

    <!--  I think this Pixi.js and PixiOverlay.js in one file?? -->
    <script src="https://cdn.rawgit.com/manubb/Leaflet.PixiOverlay/master/docs/js/example.min.js"></script>


</head>
<body style="height: 100%; margin: 0; overflow: hidden;">
<div id="mymap" style="height: 100%; width: 100%;" >
</div>
<script>
    var countries =
        {
            "type": "FeatureCollection",
            "features": [
                {
                    "type": "Feature",
                    "properties": {"name": "UK"},
                    "geometry": {
                        "type": "Polygon",
                        "coordinates": [
                            [
                                [-4.965, 58.58], [-5.97, 57.58], [-6.459, 56.31], [-5.05, 54.72],[-3.47, 54.36], [-4.08, 53.27],[-5.22, 51.78],[-3.38, 51.37],[-5.58, 50.12], [1.31, 51.09],[0.61, 51.42], [1.66, 52.69],[0.04, 52.88], [0.39, 53.40],[-2.32, 55.97], [-1.80, 57.53],[-3.95, 57.58], [-3.03, 58.60], [-4.96, 58.58],
                            ]
                        ]
                    }
                },
                {
                    "type": "Feature",
                    "properties": {"name": "France"},
                    "geometry": {
                        "type": "Polygon",
                        "coordinates": [
                            [
                                [2.54, 51.09],[-4.65, 48.37],[-1.23, 46.01],[-1.49, 43.61],[3.03, 42.45],[3.64, 43.45],[7.69, 43.77], [5.97, 46.37],[8.04, 48.98],[2.54, 51.09],
                            ]
                        ]
                    }
                }
            ]
        };

    function drawPoly(color, alpha, project, container) {
        return function (poly) {
            var shape = new PIXI.Polygon(poly[0].map(function (point) {
                var proj = project([point[1], point[0]]);
                return new PIXI.Point(proj.x, proj.y);
            }));
            container.beginFill(color, alpha);
            container.drawShape(shape);
        };
    }

    function renderChart() {
        var map = L.map('mymap').setView(new L.LatLng(50, 1.0), 5);
        L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            minZoom: 0,
            maxZoom: 9
        }).addTo(map);
        map.zoomControl.setPosition('bottomright');

        var firstDraw = true;
        var pixiContainer = new PIXI.Graphics();
        var doubleBuffering = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

        var pixiOverlay = L.pixiOverlay(function (utils) {
            var container = utils.getContainer();
            var renderer = utils.getRenderer();
            var project = utils.latLngToLayerPoint;
            var bounds;
            if (firstDraw) {
                countries.features.forEach(function (feature, index) {
                    var color = 0xFF0000,
                        alpha = 0.8;
                    if (feature.geometry === null) return;
                    if (feature.geometry.type === 'Polygon') {
                        bounds = L.bounds(feature.geometry.coordinates[0]);
                        drawPoly(color, alpha, project, container)(feature.geometry.coordinates);
                    }
                });
            }
            firstDraw = false;
            renderer.render(container);
        }, pixiContainer, {
            doubleBuffering: doubleBuffering,
            destroyInteractionManager: true
        });

        pixiOverlay.addTo(map);

    };

    renderChart()


</script>
</body>
</html>

就像 drawPoly() 为 drawMarker() 创建另一个函数一样,将您的标记代码放入其中并传递容器(如您给出的示例中所做的那样)。

我用过你的例子:

<!DOCTYPE html>
<html style="height: 100%; margin: 0;">
<head>
    <title>Leaflet.PixiOverlay example</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">

    <!--jquery -->
    <script src="https://code.jquery.com/jquery-3.3.1.js"></script>

    <!--d3 -->
    <script src='https://d3js.org/d3.v4.min.js'></script>

    <!-- leaflet v 1.0.3 -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css"/>
    <script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js"></script>

    <!--  I think this Pixi.js and PixiOverlay.js in one file?? -->
    <script src="https://cdn.rawgit.com/manubb/Leaflet.PixiOverlay/master/docs/js/example.min.js"></script>


</head>
<body style="height: 100%; margin: 0; overflow: hidden;">
<div id="mymap" style="height: 100%; width: 100%;" >
</div>
<script>
    var countries =
        {
            "type": "FeatureCollection",
            "features": [
                {
                    "type": "Feature",
                    "properties": {"name": "UK"},
                    "geometry": {
                        "type": "Polygon",
                        "coordinates": [
                            [
                                [-4.965, 58.58], [-5.97, 57.58], [-6.459, 56.31], [-5.05, 54.72],[-3.47, 54.36], [-4.08, 53.27],[-5.22, 51.78],[-3.38, 51.37],[-5.58, 50.12], [1.31, 51.09],[0.61, 51.42], [1.66, 52.69],[0.04, 52.88], [0.39, 53.40],[-2.32, 55.97], [-1.80, 57.53],[-3.95, 57.58], [-3.03, 58.60], [-4.96, 58.58],
                            ]
                        ]
                    }
                },
                {
                    "type": "Feature",
                    "properties": {"name": "France"},
                    "geometry": {
                        "type": "Polygon",
                        "coordinates": [
                            [
                                [2.54, 51.09],[-4.65, 48.37],[-1.23, 46.01],[-1.49, 43.61],[3.03, 42.45],[3.64, 43.45],[7.69, 43.77], [5.97, 46.37],[8.04, 48.98],[2.54, 51.09],
                            ]
                        ]
                    }
                }
            ]
        };
  
  
 function drawMarker(container, coords)
 {
      var graphics = new PIXI.Graphics();
    graphics.lineStyle(10, 0xFFF0000, 1);
    graphics.moveTo(0, 75);
    graphics.lineTo(50, 0);
    graphics.lineTo(100, 75);
    graphics.lineTo(50, 150);
    graphics.lineTo(0, 75);
    graphics.cacheAsBitmap = true;
    //graphics.width = 1000;
    
    posX = 3000; //just a temp value
    posY = 2000; // just a temp value
    
    graphics.x = posX;
    graphics.y = posY;
    
    
    console.log(graphics.y);
   container.addChild(graphics);
 } 

    function drawPoly(color, alpha, project, container) {
        return function (poly) {
            var shape = new PIXI.Polygon(poly[0].map(function (point) {
                var proj = project([point[1], point[0]]);
                return new PIXI.Point(proj.x, proj.y);
            }));
  
            container.beginFill(color, alpha);
            container.drawShape(shape);
        };
    }

    function renderChart() {
        var map = L.map('mymap').setView(new L.LatLng(50, 1.0), 5);
        L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            minZoom: 0,
            maxZoom: 9
        }).addTo(map);
        map.zoomControl.setPosition('bottomright');

        var firstDraw = true;
        var pixiContainer = new PIXI.Graphics();
        var doubleBuffering = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;

        var pixiOverlay = L.pixiOverlay(function (utils) {
            var container = utils.getContainer();
            var renderer = utils.getRenderer();
            var project = utils.latLngToLayerPoint;
            var bounds;
            if (firstDraw) {
                countries.features.forEach(function (feature, index) {
                    var color = 0xFF0000,
                        alpha = 0.8;
                    if (feature.geometry === null) return;
                    if (feature.geometry.type === 'Polygon') {
                        bounds = L.bounds(feature.geometry.coordinates[0]);
                       // drawPoly(color, alpha, project, container)(feature.geometry.coordinates);
         drawMarker(container, feature.geometry.coordinates);
                    }
                });
            }
            firstDraw = false;
            renderer.render(container);
        }, pixiContainer, {
            doubleBuffering: doubleBuffering,
            destroyInteractionManager: true
        });

        pixiOverlay.addTo(map);

    };

    renderChart()


</script>
</body>
</html>