OpenLayers之图形交互绘制

一、实验内容

  1. 回顾鼠标事件及事件对象,练习鼠标坐标获取;
  2. 点、线、面、圆等常规图形的交互绘制;
  3. 点、线、面、圆等常规图形的样式编辑;
  4. 点、线、面、圆等常规图形编辑;

二、实验步骤

2.1 鼠标坐标获取

<html>

<head>
    <meta charset="utf-8">
    <title>实时获得鼠标屏幕坐标</title>
    <style>
        html,
        body {
            height: 100%;
        }

        #mymap {
            width: 100%;
            height: 95%;
            position: absolute;
            background-color: ghostwhite;
        }
    </style>
    <script>
        function getCoordinate(e) {
            let x = e.clientX;
            let y = e.clientY;
            document.getElementById("showcoor").innerHTML = "鼠标坐标值:(" + x + "," + y + ")";
        }
        function clearCoordinates() {
            document.getElementById("showcoor").innerHTML = "显示坐标值";
        }
        function getCoordinate1(e) {
            let x = e.screenX;
            let y = e.screenY;
            document.getElementById("showcoor1").innerHTML = "鼠标坐标值:(" + x + "," + y + ")";
        }
    </script>
</head>

<body>
    <div id="showcoor">鼠标移动时的坐标值</div>
    <div id="showcoor1">鼠标单击时的坐标值</div>
    <div id="mymap" onmousemove="getCoordinate(event)" onmouseout="clearCoordinates()"
        onmousedown="getCoordinate1(event)"></div>
</body>

</html>

image-20210606144831912

2.2 利用HTML5 Canvas绘制点线面

html文件:

<html>

<head>
    <meta charset="utf-8">
    <title>canvas绘制图形</title>
    <script src="02.js"></script>
    <style>
        html,
        body {
            height: 100%;
        }

        #map {
            z-index: 10;
            position: absolute;
            background-color: ghostwhite;
            border: 1px solid;
        }


        #menuf {
            position: absolute;
            top: 30px;
            left: 20px;
            z-index: 11;
        }

        .btn {
            background-color: rgba(0, 60, 136, .5);
            display: block;
            margin: 1px;
            padding: 0;
            color: #fff;
            font-size: 1.14em;
            text-decoration: none;
            text-align: center;
            height: 1.375em;
            width: 1.375em;
            line-height: .4em;
            border: none;
            border-radius: 0 0 2px 2px;
            float: left;
        }
    </style>
</head>

<body>
    <div id="menu">
        <button id="lineBtn" class="btn" onclick="drawLine()">线</button>
        <button id="rectBtn" class="btn" onclick="drawRect()">面</button>
        <button id="defaultBtn" class="btn" onclick="drawDefault()">乱</button>
        <button id="eraserBtn" class="btn" onclick="drawEraser()">消</button>
    </div>
    <canvas id="map" width="1000" height="600"></canvas>

</body>

</html>

JavaScript文件:

window.onload = function () {
    var canvas = document.getElementById("map");
    if (canvas.getContext) {
        var context = canvas.getContext('2d');
    }
    canvas.drawing = function (x1, y1, x2, y2, e) {
        let self = this;
        if (!context) {
            return;
        } else {
            //设置画笔的颜色和大小
            context.fillStyle = "red";
            context.strokeStyle = "blue";
            context.lineWidth = 2;
            context.save();
            context.beginPath();
            if (self.rectFlag) {
                self.initCanvas();
                if (e.shiftKey === true) {
                    let d = ((x2 - x1) < (y2 - y1)) ? (x2 - x1) : (y2 - y1); 
                    context.fillRect(x1, y1, d, d);
                }
                else {
                    context.fillRect(x1, y1, x2 - x1, y2 - y1);
                }
            }
            else if (self.lineFlag) {
                self.initCanvas();
                context.moveTo(x1, y1);
                context.lineTo(x2, y2);
                context.stroke();
            }
            else if (self.eraserFlag) {
                //橡皮擦
                context.arc(x1, y1, 10, 0, 2 * Math.PI);
                context.clip();
                context.clearRect(0, 0, canvas.width, canvas.height);
                self.X1 = self.X2;
                self.Y1 = self.Y2;
            } else {
                context.moveTo(x1, y1);
                context.lineTo(x2, y2);
                context.stroke();
                self.X1 = self.X2;
                self.Y1 = self.Y2;
            }
            context.restore();
            context.closePath();
        }
    };

    canvas.onmousedown = function mouseDownAction(e) {
        let self = this;
        self.X1 = e.offsetX;
        self.Y1 = e.offsetY;
        self.isMouseDown = true;
        self.loadImage();
    };

    canvas.onmousemove = function mouseMoveAction(e) {
        let self = this;
        if (self.isMouseDown) {
            self.X2 = e.offsetX;
            self.Y2 = e.offsetY;
            self.drawing(self.X1, self.Y1, self.X2, self.Y2, e);
        }
    };

    canvas.onmouseup = function mouseUpAction(e) {
        let self = this;
        self.lastImage = canvas.toDataURL('image/png ');
        self.isMouseDown = false;
    };

    canvas.loadImage = function () {
        let self = this;
        let img = new Image();
        img.src = self.lastImage;
        context.drawImage(img, 0, 0, canvas.width, canvas.height);
    }

    canvas.initCanvas = function () {
        context.clearRect(0, 0, canvas.width, canvas.height);
        canvas.loadImage();
    }
}

var initDraw = function (flag) {
    document.getElementById("map").rectFlag = false;
    document.getElementById("map").lineFlag = false;
    document.getElementById("map").eraserFlag = false;
    document.getElementById("map")[flag] = true;
    //默认背景色
    document.getElementById("defaultBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("lineBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("rectBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("eraserBtn").style.background = "rgba(0,60,136,.5)";
};
var drawDefault = function () {
    initDraw();
    document.getElementById("defaultBtn").style.background = "#22A6F2";
    document.getElementById("defaultBtn").style.color = "#eee";
};
var drawLine = function () {
    initDraw("lineFlag");
    document.getElementById("lineBtn").style.background = "#22A6F2";
    document.getElementById("lineBtn").style.color = "#eee";
}
var drawRect = function () {
    initDraw("rectFlag");
    document.getElementById("rectBtn").style.background = "#22A6F2";
    document.getElementById("rectBtn").style.color = "#eee";
}
var drawEraser = function () {
    initDraw("eraserFlag");
    document.getElementById("eraserBtn").style.background = "#22A6F2";
    document.getElementById("eraserBtn").style.color = "#eee";
};

image-20210606145039547

2.3 利用OL绘制点线面

html文件:

<html>

<head>
    <meta charset="utf-8">
    <title>OL绘制图形</title>
    <link rel="stylesheet" type="text/css" href="./v6.5.0-dist/ol.css" />
    <script src="./v6.5.0-dist/ol.js"></script>
    <script src="./03.js"></script>
    <style>
        html,
        body {
            height: 100%;
        }

        #map {
            width: 100%;
            height: 99%;
            z-index: 10;
        }

        #menu {
            position: absolute;
            top: 20px;
            left: 50px;
            z-index: 11;
        }

        .btn {
            background-color: rgba(0, 60, 136, .5);
            display: block;
            margin: 1px;
            padding: 0;
            color: #fff;
            font-size: 1.14em;
            text-decoration: none;
            text-align: center;
            height: 1.375em;
            width: 1.375em;
            line-height: .4em;
            border: none;
            border-radius: 0 0 2px 2px;
            float: left;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <div id="menu">
        <button id="pointBtn" class="btn" onclick="drawPoint()">点</button>
        <button id="lineBtn" class="btn" onclick="drawLine()">线</button>
        <button id="polygonBtn" class="btn" onclick="drawPolygon()">面</button>
        <button id="squareBtn" class="btn" onclick="drawSquare()">正</button>
        <button id="recBtn" class="btn" onclick="drawRec()">长</button>
        <button id="circleBtn" class="btn" onclick="drawCircle()">圆</button>
        <button id="starBtn" class="btn" onclick="drawStar()">星</button>
        <button id="eraserBtn" class="btn" onclick="drawEraser()">清</button>
    </div>

</body>

</html>

JavaScript文件:

var draw;
var map;
var source;
var vector;
window.onload = function () {
    map = new ol.Map({
        layers: [
            new ol.layer.Tile({
                title: "天地图矢量图层",
                source: new ol.source.OSM(),
                preload: Infinity
            })
        ],
        target: 'map',
        view: new ol.View({
            //地图初始中心点
            center: [12000000, 4000000],
            minZoom: 2,
            zoom: 3
        })
    });
    source = new ol.source.Vector({ wrapX: true });
    vector = new ol.layer.Vector({
        source: source,
        style: new ol.style.Style({
            fill: new ol.style.Fill({
                color: 'rgba(255,255,255,1)'
            }),
            stroke: new ol.style.Stroke({
                color: '#ff0000',
                width: 2
            }),
            image: new ol.style.Circle({
                radius: 7,
                fill: new ol.style.Fill({
                    color: '#ff0000'
                })
            })
        })
    })
    //将绘制层添加到地图容器中
    map.addLayer(vector);
};
function addInteraction(typevalue) {
    if (typevalue !== 'None') {
        if (source == null) {
            source = new ol.source.Vector({ wrapX: true });
            //添加绘制层数据源
            vector.setSource(source);
        }
        var geometryFunction, maxPoints,minPoints=1;
        if (typevalue === 'Square') {
            typevalue = 'Circle';
            //正方形图形(圆)
            geometryFunction = ol.interaction.Draw.createRegularPolygon(4);

        }
else if (typevalue === 'Box') {
            typevalue = 'Circle';
            geometryFunction = new ol.interaction.Draw.createBox();
        } else if (typevalue === 'Star') {
            typevalue = 'Circle';
            geometryFunction = function (coordinates, geometry) {
                var center = coordinates[0];
                var last = coordinates[coordinates.length - 1];
                var dx = center[0] - last[0];
                var dy = center[1] - last[1];
                var radius = Math.sqrt(dx * dx + dy * dy);
                var rotation = Math.atan2(dy, dx);
                var newCoordinates = [];
                var numPoints = 12;
                for (var i = 0; i < numPoints; ++i) {
                    var angle = rotation + (i * 2 * Math.PI) / numPoints;
                    var fraction = i % 2 === 0 ? 1 : 0.5;
                    var offsetX = radius * fraction * Math.cos(angle);
                    var offsetY = radius * fraction * Math.sin(angle);
                    newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);
                }
                newCoordinates.push(newCoordinates[0].slice());
                if (!geometry) {
                    geometry = new ol.geom.Polygon([newCoordinates]);
                } else {
                    geometry.setCoordinates([newCoordinates]);
                }
                return geometry;
            };
        }
        draw = new ol.interaction.Draw({
            source: source,
            type: typevalue,
            //几何信息变更时调用函数
            geometryFunction: geometryFunction,
            //最大点数
            maxPoints: maxPoints,
            minPoints:minPoints
        });
        map.addInteraction(draw);
    }
    else {
        source = null;
        vector.setSource(source);
    }
}
var initDraw = function () {
    map.removeInteraction(draw);
    //默认背景色
    document.getElementById("polygonBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("lineBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("circleBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("pointBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("eraserBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("squareBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("recBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("starBtn").style.background = "rgba(0,60,136,.5)";
};
var drawPoint = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Point");
    document.getElementById("pointBtn").style.background = "#22A6F2";
    document.getElementById("pointBtn").style.color = "#eee";
};
var drawLine = function () {
    initDraw();
    addInteraction("LineString");
    document.getElementById("lineBtn").style.background = "#22A6F2";
    document.getElementById("lineBtn").style.color = "#eee";
};
var drawPolygon = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Polygon");
    document.getElementById("polygonBtn").style.background = "#22A6F2";
    document.getElementById("polygonBtn").style.color = "#eee";
};
var drawCircle = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Circle");
    document.getElementById("circleBtn").style.background = "#22A6F2";
    document.getElementById("circleBtn").style.color = "#eee";
};

var drawSquare = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Square");
    document.getElementById("squareBtn").style.background = "#22A6F2";
    document.getElementById("squareBtn").style.color = "#eee";
};
var drawRec = function () {
    initDraw();
    addInteraction("Box");
    document.getElementById("recBtn").style.background = "#22A6F2";
    document.getElementById("recBtn").style.color = "#eee";
};
var drawStar = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Star");
    document.getElementById("starBtn").style.background = "#22A6F2";
    document.getElementById("starBtn").style.color = "#eee";
};
var drawEraser = function () {
    initDraw();
    source.clear();
    document.getElementById("eraserBtn").style.background = "#22A6F2";
    document.getElementById("eraserBtn").style.color = "#eee";
};

image-20210606145340073

2.4 常规图形的样式编辑

html文件:

<html>

<head>
    <meta charset="utf-8">
    <title>OL绘制图形-样式</title>
    <link rel="stylesheet" type="text/css" href="./v6.5.0-dist/ol.css" />
    <link href="./04.css" rel="stylesheet" />
    <script src="./v6.5.0-dist/ol.js"></script>
    <script src="./04.js "></script>
    <style>
        html,
        body {
            height: 100%;
        }

        #map {
            width: 100%;
            height: 99%;
            z-index: 10;
        }

        #menu {
            position: absolute;
            top: 20px;
            left: 50px;
            z-index: 11;
        }

        .btn {
            background-color: rgba(0, 60, 136, .5);
            display: block;
            margin: 1px;
            padding: 0;
            color: #fff;
            font-size: 1.14em;
            text-decoration: none;
            text-align: center;
            height: 1.375em;
            width: 1.375em;
            line-height: .4em;
            border: none;
            border-radius: 0 0 2px 2px;
            float: left;
        }
    </style>
</head>

<body>
    <div id="menu">
        <button id="pointBtn" class="btn" onclick="drawPoint()">点</button>
        <button id="lineBtn" class="btn" onclick="drawLine()">线</button>
        <button id="polygonBtn" class="btn" onclick="drawPolygon()">面</button>
        <button id="squareBtn" class="btn" onclick="drawSquare()">正</button>
        <button id="recBtn" class="btn" onclick="drawRec()">长</button>
        <button id="circleBtn" class="btn" onclick="drawCircle()">圆</button>
        <button id="starBtn" class="btn" onclick="drawStar()">星</button>
        <button id="selectBtn" class="btn" onclick="selectFea()">选</button>
        <button id="eraserBtn" class="btn" onclick="drawEraser()">清</button>
    </div>
    <div id="map"></div>
    <div id="popup" class="ol-popup">
        <a href="#" id="popup-close" class="ol-popup-closer" onclick="popupClose()"></a>
        <div id="popup-content">
            <label>&nbsp;&nbsp;边框颜色:&nbsp;&nbsp;</label>
            <input type="color" id="linecolor" value="#ff0000" /><br />
            <label>&nbsp;&nbsp;填充颜色:&nbsp;&nbsp;</label>
            <input type="color" id="fillcolor" value="#FFFFFF" /><br />
            <label>&nbsp;&nbsp;边框宽度:&nbsp;&nbsp;</label>
            <input type="text" id="linewidth" value="2" style="width:45px; " /><br />
            <button type="button" id="changeStyle" onclick="changeFeatureStyle()">修改样式</button>
        </div>
    </div>
</body>

</html>

JavaScript文件:

var draw;
var map;
var source;
var vector;
var selecTool
var menu_overlay;
window.onload = function () {
    map = new ol.Map({
        layers: [
            new ol.layer.Tile({
                title: "天地图矢量图层",
                source: new ol.source.XYZ({
                    url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x]&y={y}&l={z}&tk=1d109683f4d84198e37a38c442d68311",
                    wrapX: true
                })
            }),
            new ol.layer.Tile({
                title: "天地图矢量图层注记",
                source: new ol.source.XYZ({
                    url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x]&y={y}&l={z}&tk=1d109683f4d84198e37a38c442d68311",
                    attributions: "天地图的属性描述",
                    wrapX: true
                }),
                preload: Infinity

            })
        ],
        target: 'map',
        view: new ol.View({
            //地图初始中心点
            center: [12000000, 4000000],
            minZoom: 2,
            zoom: 3
        })
    });
    var defaultStyle = new ol.style.Style({
        fill: new ol.style.Fill({
            color: 'rgba(255,255,255,1)'
        }),
        stroke: new ol.style.Stroke({
            color: '#ff0000',
            width: 2
        }),
        image: new ol.style.Circle({
            radius: 7,
            fill: new ol.style.Fill({
                color: '#ff0000'
            })
        })
    });
    source = new ol.source.Vector({ wrapX: true });
    vector = new ol.layer.Vector({
        source: source,
        style: function (feature) {
            var customStyle = feature.get('customStyle');
            return customStyle || defaultStyle;
        }
    });
    //将绘制层添加到地图容器中
    map.addLayer(vector);
    menu_overlay = new ol.Overlay({
        element: document.getElementById("popup"),
        positioning: "center-center"
    });
    menu_overlay.setMap(map);
    map.getViewport().oncontextmenu = function (e) {
        //取消默认的右键
        e.preventDefault();
        var coordinate = map.getEventCoordinate(event);
        if (selecTool.getFeatures().getLength() != 0) {
            menu_overlay.setPosition(coordinate);
        }
    };
    selecTool = new ol.interaction.Select({
        layers: [vector]
    });
    map.addInteraction(selecTool);
    selecTool.setActive(false);
};





function addInteraction(typevalue) {
    if (typevalue !== 'None') {
        if (source == null) {
            source = new ol.source.Vector({ wrapX: true });
            //添加绘制层数据源
            vector.setSource(source);
        }
        var geometryFunction, maxPoints;
        if (typevalue === 'Square') {
            typevalue = 'Circle';
            //正方形图形(圆)
            geometryFunction = ol.interaction.Draw.createRegularPolygon(4);

        }
        else if (typevalue === 'Box') {
            typevalue = 'Circle';
            geometryFunction = new ol.interaction.Draw.createBox();
        } else if (typevalue === 'Star') {
            typevalue = 'Circle';
            geometryFunction = function (coordinates, geometry) {
                var center = coordinates[0];
                var last = coordinates[coordinates.length - 1];
                var dx = center[0] - last[0];
                var dy = center[1] - last[1];
                var radius = Math.sqrt(dx * dx + dy * dy);
                var rotation = Math.atan2(dy, dx);
                var newCoordinates = [];
                var numPoints = 12;
                for (var i = 0; i < numPoints; ++i) {
                    var angle = rotation + (i * 2 * Math.PI) / numPoints;
                    var fraction = i % 2 === 0 ? 1 : 0.5;
                    var offsetX = radius * fraction * Math.cos(angle);
                    var offsetY = radius * fraction * Math.sin(angle);
                    newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);
                }
                newCoordinates.push(newCoordinates[0].slice());
                if (!geometry) {
                    geometry = new ol.geom.Polygon([newCoordinates]);
                } else {
                    geometry.setCoordinates([newCoordinates]);
                }
                return geometry;
            };
        }
        draw = new ol.interaction.Draw({
            source: source,
            type: typevalue,
            //几何信息变更时调用函数
            geometryFunction: geometryFunction,
            //最大点数
            maxPoints: maxPoints,
        });
        map.addInteraction(draw);
    }
    else {
        source = null;
        vector.setSource(source);
    }
}
var initDraw = function () {
    map.removeInteraction(draw);
    selecTool.setActive(false);
    selecTool.getFeatures().clear();
    //默认背景色
    document.getElementById("polygonBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("lineBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("circleBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("pointBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("eraserBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("squareBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("recBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("starBtn").style.background = "rgba(0,60,136,.5)";
};
var drawPoint = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Point");
    document.getElementById("pointBtn").style.background = "#22A6F2";
    document.getElementById("pointBtn").style.color = "#eee";
};
var drawLine = function () {
    initDraw();
    addInteraction("LineString");
    document.getElementById("lineBtn").style.background = "#22A6F2";
    document.getElementById("lineBtn").style.color = "#eee ";
};
var drawPolygon = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Polygon");
    document.getElementById("polygonBtn").style.background = "#22A6F2";
    document.getElementById("polygonBtn").style.color = "#eee";
};
var drawCircle = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Circle");
    document.getElementById("circleBtn").style.background = "#22A6F2";
    document.getElementById("circleBtn").style.color = "#eee";
};

var drawSquare = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Square");
    document.getElementById("squareBtn").style.background = "#22A6F2";
    document.getElementById("squareBtn").style.color = "#eee";
};
var drawRec = function () {
    initDraw();
    addInteraction("Box");
    document.getElementById("recBtn").style.background = "#22A6F2";
    document.getElementById("recBtn").style.color = "#eee";
};
var drawStar = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Star");
    document.getElementById("starBtn").style.background = "#22A6F2";
    document.getElementById("starBtn").style.color = "#eee";
};
var drawEraser = function () {
    initDraw();
    source.clear();
    document.getElementById("eraserBtn").style.background = "#22A6F2";
    document.getElementById("eraserBtn").style.color = "#eee";
};
var selectFea = function () {
    initDraw();
    selecTool.setActive(true);
    document.getElementById("selectBtn").style.background = "#22A6F2";
    document.getElementById("selectBtn").style.color = "#eee";
};

var changeFeatureStyle = function () {
    var newcolor = document.getElementById("linecolor").value;
    var fillcolor = document.getElementById("fillcolor").value;
    var linewidth = document.getElementById("linewidth").value;
    var newstyle = new ol.style.Style({
        fill: new ol.style.Fill({
            color: fillcolor
        }),
        stroke: new ol.style.Stroke({
            color: newcolor,
            width: eval(linewidth)
        }),
        image: new ol.style.Circle({
            radius: 7,
            fill: new ol.style.Fill({
                color: '#ff0000'
            })
        })
    });
    selecTool.getFeatures().item(0).set('customStyle', newstyle);
    menu_overlay.setPosition(undefined);
};
var popupClose = function () {
    menu_overlay.setPosition(undefined);
}

CSS文件:

.ol-popup {
    position: absolute;
    background-color: #fff;
    filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
    padding: 15px;
    border-radius: 10px;
    border: 1px solid #cccccc;
    bottom: 12px;
    left: -50px;
    min-width: 160px;
}

.ol-popup:after, .ol-popup:before {
    top: 100%;
    border: solid transparent;
    content: " ";
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
}

.ol-popup:after {
    border-top-color: #fff;
    border-width: 10px;
    left: 48px;
    margin-left: -10px;
}

.ol-popup:before {
    border-top-color: #cccccc;
    border-width: 11px;
    left: 48px;
    margin-left: -11px;
}

.ol-popup-closer {
    text-decoration: none;
    position: absolute;
    top: 2px;
    right: 8px;
}

.ol-popup-closer:after {
    content: " x ";
}

image-20210606145653369

2.5 常规图形编辑

html文件:

<html>

<head>
    <meta charset="utf-8">
    <title>OL绘制图形-样式</title>
    <script src="./v6.5.0-dist/ol.js"></script>
    <link rel="stylesheet" type="text/css" href="./v6.5.0-dist/ol.css" />
    <script src="./05.js"></script>


    <style>
        html,
        body {
            height: 100%;
        }

        #map {
            width: 100%;
            height: 99%;
            z-index: 10;
        }

        #menu {
            position: absolute;
            top: 20px;
            left: 50px;
            z-index: 11;
        }

        .btn {
            background-color: rgba(0, 60, 136, .5);
            display: block;
            margin: 1px;
            padding: 0;
            color: #fff;
            font-size: 1.14em;
            text-decoration: none;
            text-align: center;
            height: 1.375em;
            width: 1.375em;
            line-height: .4em;
            border: none;
            border-radius: 0 0 2px 2px;
            float: left;
        }
    </style>
</head>

<body>
    <div id="menu">
        <button id="pointBtn" class="btn" onclick="drawPoint()">点</button>
        <button id="lineBtn" class="btn" onclick="drawLine()">线</button>
        <button id="polygonBtn" class="btn" onclick="drawPolygon()">面</button>
        <button id="squareBtn" class="btn" onclick="drawSquare()">正</button>
        <button id="recBtn" class="btn" onclick="drawRec()">长</button>
        <button id="circleBtn" class="btn" onclick="drawCircle()">圆</button>
        <button id="starBtn" class="btn" onclick="drawStar()">星</button>
        <button id="editBtn" class="btn" onclick="editFea()">编</button>
        <button id="eraserBtn" class="btn" onclick="drawEraser()">清</button>
    </div>
    <div id="map"></div>
    <div id="popup" class="ol-popup">
        <a href="#" id="popup-close" class="ol-popup-closer" onclick="popupClose()"></a>
        <div id="popup-content">
            <label>&nbsp;&nbsp;边框颜色:&nbsp;&nbsp;</label>
            <input type="color" id="linecolor" value="#ff0000" /><br />
            <label>&nbsp;&nbsp;填充颜色:&nbsp;&nbsp;</label>
            <input type="color" id="fillcolor" value="#FFFFFF" /><br />
            <label>&nbsp;&nbsp;边框宽度:&nbsp;&nbsp;</label>
            <input type="text" id="linewidth" value="2" style="width:45px; " /><br />
            <button type="button" id="changeStyle" onclick="changeFeatureStyle()">修改样式</button>
        </div>
    </div>
</body>

</html>

JavaScript文件:

var draw;
var map;
var source;
var vector;
var Modify;
window.onload = function () {
    map = new ol.Map({
        layers: [
            new ol.layer.Tile({
                title: "天地图矢量图层",
                source: new ol.source.XYZ({
                    url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x]&y={y}&l={z}&tk=1d109683f4d84198e37a38c442d68311",
                    wrapX: true
                })
            }),
            new ol.layer.Tile({
                title: "天地图矢量图层注记",
                source: new ol.source.XYZ({
                    url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x]&y={y}&l={z}&tk=1d109683f4d84198e37a38c442d68311",
                    attributions: "天地图的属性描述",
                    wrapX: true
                }),
                preload: Infinity

            })
        ],
        target: 'map',
        view: new ol.View({
            //地图初始中心点
            center: [12000000, 4000000],
            minZoom: 2,
            zoom: 3
        })
    });
    var defaultStyle = new ol.style.Style({
        fill: new ol.style.Fill({
            color: 'rgba(255,255,255,1)'
        }),
        stroke: new ol.style.Stroke({
            color: '#ff0000',
            width: 2
        }),
        image: new ol.style.Circle({
            radius: 7,
            fill: new ol.style.Fill({
                color: '#ff0000'
            })
        })
    });
    source = new ol.source.Vector({ wrapX: true });
    vector = new ol.layer.Vector({
        source: source,
        style: function (feature) {
            var customStyle = feature.get('customStyle');
            return customStyle || defaultStyle;
        }
    });
    //将绘制层添加到地图容器中
    map.addLayer(vector);
    Modify = {
        init: function () {
            //初始化一个交互选择控件,并添加到地图容器中
            this.select = new ol.interaction.Select();
            map.addInteraction(this.select);
            //初始化一个交互编辑控件,并添加到地图容器中
            this.modify = new ol.interaction.Modify({
                features: this.select.getFeatures()
            });
            map.addInteraction(this.modify);
        },
        setActive: function (active) {
            //激活选择要素控件
            this.select.setActive(active);
            this.modify.setActive(active);
        },
        removeInteraction: function () {
            map.removeInteraction(this.modify);
            map.removeInteraction(this.select);
        }
    };
};


function addInteraction(typevalue) {
    if (typevalue !== 'None') {
        if (source == null) {
            source = new ol.source.Vector({ wrapX: true });
            //添加绘制层数据源
            vector.setSource(source);
        }
        var geometryFunction, maxPoints;
        if (typevalue === 'Square') {
            typevalue = 'Circle';
            //正方形图形(圆)
            geometryFunction = ol.interaction.Draw.createRegularPolygon(4);

        }
        else if (typevalue === 'Box') {
            typevalue = 'Circle';
            geometryFunction = new ol.interaction.Draw.createBox();
        } else if (typevalue === 'Star') {
            typevalue = 'Circle';
            geometryFunction = function (coordinates, geometry) {
                var center = coordinates[0];
                var last = coordinates[coordinates.length - 1];
                var dx = center[0] - last[0];
                var dy = center[1] - last[1];
                var radius = Math.sqrt(dx * dx + dy * dy);
                var rotation = Math.atan2(dy, dx);
                var newCoordinates = [];
                var numPoints = 12;
                for (var i = 0; i < numPoints; ++i) {
                    var angle = rotation + (i * 2 * Math.PI) / numPoints;
                    var fraction = i % 2 === 0 ? 1 : 0.5;
                    var offsetX = radius * fraction * Math.cos(angle);
                    var offsetY = radius * fraction * Math.sin(angle);
                    newCoordinates.push([center[0] + offsetX, center[1] + offsetY]);
                }
                newCoordinates.push(newCoordinates[0].slice());
                if (!geometry) {
                    geometry = new ol.geom.Polygon([newCoordinates]);
                } else {
                    geometry.setCoordinates([newCoordinates]);
                }
                return geometry;
            };
        }
        draw = new ol.interaction.Draw({
            source: source,
            type: typevalue,
            //几何信息变更时调用函数
            geometryFunction: geometryFunction,
            //最大点数
            maxPoints: maxPoints,
        });
        map.addInteraction(draw);
    }
    else {
        source = null;
        vector.setSource(source);
    }
};
var initDraw = function () {
    map.removeInteraction(draw);
    map.removeInteraction(Modify.removeInteraction());
    //默认背景色
    document.getElementById("polygonBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("lineBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("circleBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("pointBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("eraserBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("squareBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("recBtn").style.background = "rgba(0,60,136,.5)";
    document.getElementById("starBtn").style.background = "rgba(0,60,136,.5)";
};
var drawPoint = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Point");
    document.getElementById("pointBtn").style.background = "#22A6F2";
    document.getElementById("pointBtn").style.color = "#eee";
};
var drawLine = function () {
    initDraw();
    addInteraction("LineString");
    document.getElementById("lineBtn").style.background = "#22A6F2";
    document.getElementById("lineBtn").style.color = "#eee ";
};
var drawPolygon = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Polygon");
    document.getElementById("polygonBtn").style.background = "#22A6F2";
    document.getElementById("polygonBtn").style.color = "#eee";
};
var drawCircle = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Circle");
    document.getElementById("circleBtn").style.background = "#22A6F2";
    document.getElementById("circleBtn").style.color = "#eee";
};

var drawSquare = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Square");
    document.getElementById("squareBtn").style.background = "#22A6F2";
    document.getElementById("squareBtn").style.color = "#eee";
};
var drawRec = function () {
    initDraw();
    addInteraction("Box");
    document.getElementById("recBtn").style.background = "#22A6F2";
    document.getElementById("recBtn").style.color = "#eee";
};
var drawStar = function () {
    initDraw();
    //添加交互绘制功能控件
    addInteraction("Star");
    document.getElementById("starBtn").style.background = "#22A6F2";
    document.getElementById("starBtn").style.color = "#eee";
};
var drawEraser = function () {
    initDraw();
    source.clear();
    document.getElementById("eraserBtn").style.background = "#22A6F2";
    document.getElementById("eraserBtn").style.color = "#eee";
};

var changeFeatureStyle = function () {
    var newcolor = document.getElementById("linecolor").value;
    var fillcolor = document.getElementById("fillcolor").value;
    var linewidth = document.getElementById("linewidth").value;
    var newstyle = new ol.style.Style({
        fill: new ol.style.Fill({
            color: fillcolor
        }),
        stroke: new ol.style.Stroke({
            color: newcolor,
            width: eval(linewidth)
        }),
        image: new ol.style.Circle({
            radius: 7,
            fill: new ol.style.Fill({
                color: '#ff0000'
            })
        })
    });
    selecTool.getFeatures().item(0).set('customStyle', newstyle);
    menu_overlay.setPosition(undefined);
};
var popupClose = function () {
    menu_overlay.setPosition(undefined);
}

var editFea = function () {
    initDraw();
    //初始化几何图形修改控件
    Modify.init();
    Modify.setActive(true);
    document.getElementById("editBtn").style.background = "#22A6F2";
    document.getElementById("editBtn").style.color = "#eee";
};



image-20210606150037233

posted @ 2022-03-27 18:42  当时明月在曾照彩云归  阅读(697)  评论(0编辑  收藏  举报