首页 > 其他分享 >leaflet多边形填充图片

leaflet多边形填充图片

时间:2023-02-07 18:44:44浏览次数:47  
标签:function canvas 多边形 填充 ctx leaflet ._ return data

效果图:

 leaflet 有imageOverlay图层根据两个点坐标生成图像,但体验感不太好,设计上传一张图片后,常常不能对齐,就尝试自己封装个图层。如上图所示,图片有两种方式,一种方式是使用canvas  createPattern方法平铺纹理,另一种是通过canvas clip剪切方法,

这个方法对图片尺寸有些要求,图片尺寸必须和裁剪的矩形宽高成比例且不能有空白区域,不然不能对齐。

代码如下:

<!DOCTYPE html>
<html>

<head>
    <title>Leaflet debug page</title>
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
        integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ=="
        crossorigin="" />
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"
        integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ=="
        crossorigin=""></script>
    <script src="../dist/leaflet.polygonImage.js"></script>
    <script src="./data/index.js"></script>
</head>

<body>
    <div id="map" style="width: 1920px; height: 1080px; border: 1px solid #ccc"></div>


    <script>
        var map = L.map('map').setView([37, 102], 4.2);
        L.tileLayer('http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}', {
            attribution: ''
        }).addTo(map);
        let coordinates = L.geoJSON(boundaries).getLayers()[0]._latlngs;

        var polygonimg = L.polygonimg(coordinates, {
            img: "./img/map.png", // 裁剪图片
            //  img: "./img/img1.png", // 平铺纹理图片
            type: "clip", //clip  repeat

        }).addTo(map);
    </script>

</body>

</html>  
leaflet.polygonImage.js:
  (function (root, plugin) {
            /**
             * UMD wrapper.
             * When used directly in the Browser it expects Leaflet to be globally
             * available as `L`. The plugin then adds itself to Leaflet.
             * When used as a CommonJS module (e.g. with browserify) only the plugin
             * factory gets exported, so one hast to call the factory manually and pass
             * Leaflet as the only parameter.
             * @see {@link https://github.com/umdjs/umd}
             */
            if (typeof define === 'function' && define.amd) {
                define(['leaflet'], plugin);
            } else if (typeof exports === 'object') {
                module.exports = plugin;
            } else {
                plugin(root.L);
            }
        }(this, function (L) {
            // Plugin is already added to Leaflet
            if (L.Polygonimg) {
                return L;
            }

            /**
             * Core renderer.
             * @constructor
             * @param {HTMLElement | string} canvas - &lt;canvas> element or its id
             * to initialize the instance on.
             */
            var Polygonimg = function (canvas) {
                if (!(this instanceof Polygonimg)) {
                    return new Polygonimg(canvas);
                }


                this._canvas = canvas = typeof canvas === 'string' ?
                    document.getElementById(canvas) :
                    canvas;

                this._ctx = canvas.getContext('2d');
                this._width = canvas.width;
                this._height = canvas.height;
                this._data = [];
                this._img = '';
                this._type = "cover"
                //  this.draw();
            };

            Polygonimg.prototype = {
                /**
                 * Sets the width of the canvas. Used when clearing the canvas.
                 * @param {number} width - Width of the canvas.
                 */
                width: function (width) {
                    this._width = width;
                    return this;
                },

                /**
                 * Sets the height of the canvas. Used when clearing the canvas.
                 * @param {number} height - Height of the canvas.
                 */
                height: function (height) {
                    this._height = height;
                    return this;
                },
                img: function (img) {
                    this._img = img;
                    return this;
                },
                type: function (type) {
                    this._type = type;
                    return this
                },
                size: function (size) {
                    this._size = size;
                    return this;
                },
                bounds: function (bounds) {
                    this._bounds = bounds;
                    return this;
                },
                /**
                 * Sets the data that gets drawn on the canvas.
                 * @param {(Path|Path[])} data - A single path or an array of paths.
                 */
                data: function (data) {
                    this._data = data;
                    return this;
                },
                /**
                 * Draws the currently set paths.
                 */
                draw: function () {
                    console.log(this)
                    this._ctx.globalCompositeOperation = 'source-over';
                    this._ctx.lineCap = 'round';

                    var ctx = this._ctx;
                    var data = this._data;
                    let that = this;
                    var bounds = this._bounds;
                    var size = this._size;

                    var canvasImage = new Image();
                    //赋值图片地址
                    canvasImage.src = this._img;

                    //开始一个新的绘制路径
                    //  this._ctx.beginPath();
                    //设置路径起点坐标

                    canvasImage.onload = function () {

                        if (that._type == 'clip') {
                            //保存画布当前状态
                            ctx.save();
                            //开始一个新的绘制路径
                            ctx.beginPath();
                            //设置路径起点坐标
                            for (let i = 0; i < data.length; i++) {
                                for (let j = 0; j < data[i].length; j++) {
                                    if (j == 0) {
                                        ctx.moveTo(data[i][j].x, data[i][j].y);
                                    } else {
                                        ctx.lineTo(data[i][j].x, data[i][j].y);
                                    }
                                }
                            }

                            //先关闭绘制路径。注意,此时将会使用直线连接当前端点和起始端点。
                            ctx.closePath();
                            // 剪切,将在面积内的图片显示
                            ctx.clip();
                            ctx.drawImage(this, bounds.min.x, bounds.min.y, size.x, size.y);
                            ctx.restore();
                        } else if (that._type == 'repeat') {
                            //开始一个新的绘制路径
                            ctx.beginPath();
                            //设置路径起点坐标
                            for (let i = 0; i < data.length; i++) {
                                for (let j = 0; j < data[i].length; j++) {
                                    if (j == 0) {
                                        ctx.moveTo(data[i][j].x, data[i][j].y);
                                    } else {
                                        ctx.lineTo(data[i][j].x, data[i][j].y);
                                    }
                                }
                            }
                            //先关闭绘制路径。注意,此时将会使用直线连接当前端点和起始端点。
                            ctx.closePath();
                            ctx.stroke();
                            //使用createPattern平铺
                            ctx.fillStyle = ctx.createPattern(canvasImage, 'repeat')
                            ctx.fill()
                        }


                    };

                },


            };


            var Renderer = L.Canvas.extend({
                _initContainer: function () {
                    L.Canvas.prototype._initContainer.call(this);
                    this._polygonimg = new Polygonimg(this._container);
                },
                _update: function () {
                    L.Canvas.prototype._update.call(this);
                    this._polygonimg.width(this._container.width);
                    this._polygonimg.height(this._container.height);
                },

                _updatePoly: function (layer) {
                    if (!this._drawing) {
                        return;
                    }

                    var parts = layer._parts;
                    //    console.log(layer, 'parts')

                    var bounds = layer._rawPxBounds
                    var size = bounds.getSize()
                    if (!parts.length) {
                        return;
                    }

                    this._updateOptions(layer);

                    this._polygonimg
                        .data(parts)
                        .bounds(bounds)
                        .size(size)
                        .draw();
                },

                _updateOptions: function (layer) {

                    if (layer.options.img) {
                        this._polygonimg.img(layer.options.img);
                    }
                    if (layer.options.type) {
                        this._polygonimg.type(layer.options.type);
                    }
                }
            });

            var renderer = function (options) {
                return L.Browser.canvas ? new Renderer(options) : null;
            };




            L.Polygonimg = L.Polygon.extend({
                statics: {
                    Renderer: Renderer,
                    renderer: renderer
                },

                options: {
                    renderer: renderer(),

                }
            });

            L.polygonimg = function (latlngs, options) {
                return new L.Polygonimg(latlngs, options);
            };


            return L;
        }));

 data为leaflet多边形数据,平铺纹理我想通过修改canvas像素点位置来自定义纹理的宽高,奈何能力有限没搞出来,感兴趣的朋友欢迎交流。

标签:function,canvas,多边形,填充,ctx,leaflet,._,return,data
From: https://www.cnblogs.com/hardmeng/p/17099473.html

相关文章

  • 【C语言】memset() 内存填充块
    ......
  • 公共字段自动填充
    公共字段自动填充在新增员工时需要设置创建时间、创建人、修改时间、修改人等字段,在编辑员工时需要设置修改时间和修改人等字段。这些字段属于公共字段,也就是很多表中都有......
  • geotools求多边形的面积 单位米(地理坐标系转投影坐标系)
    参考:根据wkt或geometry计算面积(平方米):https://blog.csdn.net/wuxiaowu123/article/details/118153835>>如何利用PostGIS正确计算距离和面积:https://blog.csdn.net/qq_3066......
  • MySql 自动设置时间(自动获取时间,填充时间)
    应用场景:1、在数据表中,要记录每条数据是什么时候创建的,不需要应用程序去特意记录,而由数据数据库获取当前时间自动记录创建时间;2、在数据库中,要记录每条数据是什么时候修......
  • Cesium:文字转图片,图片贴到多边形上
    JS前端文字转图片:link缺点:需要在网页中有一个canvas。canvas.toDataURL("image/png")后端文字转图片:text-to-svgsvg2pnghttps://www.cnblogs.com/duasonir/p/16700591......
  • 零基础学前端之CSS填充和宽高
    这节课,我们学习CSS填充属性和CSS宽度与高度属性。还是看这个例子,每个区块除了设置外边距,还有内容周围的空间以及内容的宽高设置。CSS 填充属性用于在一个元素的内容周......
  • hdu:Shape of HDU(判断多边形凹凸)
    ProblemDescription话说上回讲到海东集团推选老总的事情,最终的结果是XHD以微弱优势当选,从此以后,“徐队”的称呼逐渐被“徐总”所取代,海东集团(HDU)也算是名副其实了。创业......
  • MybatisPlus公共字段自动填充
    MybatisPlus公共字段自动填充插入或更新的时候,为指定的字段赋予指定的值,使用的好处就是可以统一对这些字段进行处理,避免重复代码步骤实体类属性加入@TableFiled,指......
  • Cesium计算多边形面积(十一)
     //计算三角形面积functiontriangleArea(p0,p1,p2){letv0=Cesium.Cartesian3.subtract(p0,p1,newCesium.Cartesian3())......
  • MP 公共字段填充
    一、MybatisPlus1、公共字段填充​ 统一为公共字段进行处理,在插入或更新时为指定字段赋予指定的值,减少了重复代码。公共字段一般为创建/更新时间,创建/更新人。可以通过L......