OpenLayers基础教程——地图交互之绘制图形

1、前言

前面的博客其实已经介绍过了如何在openlayers中绘制图形,不过那是基于已有的坐标进行绘制。很多时候,用户往往需要使用鼠标自行在地图上进行图形绘制,这就涉及到了openlayers中的地图交互功能,下面开始介绍。

2、绘制基础图形

openlayers中,实现地图交互的类是ol.interaction,默认情况下,openlayers只支持Point(点)LineString(线)Polygon(面)Circle(圆)这四种基本图形。下面一段代码实现了这四种基本图形的绘制:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <title>OpenLayers</title>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #group {
            position: absolute;
            right: 20px;
            top: 20px;
            z-index: 200;
        }
    </style>
    <!-- openlayers -->
    <link href="libs/ol/ol.css" rel="stylesheet" />
    <script src="libs/ol/ol.js"></script>
    <!-- bootstrap -->
    <link href="libs/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
    <script src="libs/bootstrap/js/jquery-3.4.1.min.js"></script>
    <script src="libs/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
    <div id="map">
        <div id="group" class="btn-group">
            <button id="point" type="button" class="btn btn-primary">画点</button>
            <button id="lineString" type="button" class="btn btn-success">画线</button>
            <button id="polygon" type="button" class="btn btn-warning">画面</button>
            <button id="circle" type="button" class="btn btn-info">画圆</button>
            <button id="stop" type="button" class="btn btn-danger">结束</button>
        </div>
    </div>

    <script>
        // 创建图层
        var source = new ol.source.Vector();
        var layer = new ol.layer.Vector({
            source: source
        });

        // 创建地图
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                layer
            ],
            view: new ol.View({
                projection: 'EPSG:4326',
                center: [120, 30],
                zoom: 8
            })
        });

        //
        var draw;

        // 绘制点
        $('#point').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'Point',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    })
                })
            });
            map.addInteraction(draw);
        })

        // 绘制线
        $('#lineString').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'LineString',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'yellow',
                        width: 2
                    })
                })
            });
            map.addInteraction(draw);
        })

        // 绘制面
        $('#polygon').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'Polygon',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'yellow',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'blue'
                    })
                })
            });
            map.addInteraction(draw);
        })

        // 绘制圆
        $('#circle').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'Circle',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'yellow',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'blue'
                    })
                })
            });
            map.addInteraction(draw);
        })

        // 结束绘制
        $('#stop').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
        })
    </script>
</body>
</html>

运行结果如下图所示:
在这里插入图片描述

3、设置图形样式

我们也可以对绘制的图形的样式进行设置,还是老方法:创建layer时指定样式即可。代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <title>OpenLayers</title>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #group {
            position: absolute;
            right: 20px;
            top: 20px;
            z-index: 200;
        }
    </style>
    <!-- openlayers -->
    <link href="libs/ol/ol.css" rel="stylesheet" />
    <script src="libs/ol/ol.js"></script>
    <!-- bootstrap -->
    <link href="libs/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
    <script src="libs/bootstrap/js/jquery-3.4.1.min.js"></script>
    <script src="libs/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
    <div id="map">
        <div id="group" class="btn-group">
            <button id="point" type="button" class="btn btn-primary">画点</button>
            <button id="lineString" type="button" class="btn btn-success">画线</button>
            <button id="polygon" type="button" class="btn btn-warning">画面</button>
            <button id="circle" type="button" class="btn btn-info">画圆</button>
            <button id="stop" type="button" class="btn btn-danger">结束</button>
        </div>
    </div>

    <script>
        // 创建图层
        var source = new ol.source.Vector();
        var layer = new ol.layer.Vector({
            source: source,
            style: function (feature, resolution) {
                var style = new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'green',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'skyblue'
                    })
                });
                return style;
            }
        });

        // 创建地图
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                layer
            ],
            view: new ol.View({
                projection: 'EPSG:4326',
                center: [120, 30],
                zoom: 8
            })
        });

        //
        var draw;

        // 绘制点
        $('#point').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'Point',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    })
                })
            });
            map.addInteraction(draw);
        })

        // 绘制线
        $('#lineString').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'LineString',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'yellow',
                        width: 2
                    })
                })
            });
            map.addInteraction(draw);
        })

        // 绘制面
        $('#polygon').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'Polygon',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'yellow',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'blue'
                    })
                })
            });
            map.addInteraction(draw);
        })

        // 绘制圆
        $('#circle').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'Circle',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'yellow',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'blue'
                    })
                })
            });
            map.addInteraction(draw);
        })

        // 绘制预案
        $('#stop').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
        })
    </script>
</body>
</html>

运行结果如下图所示:
在这里插入图片描述

4、设置捕捉距离

假设现在绘制一个四边形,那么有两种方式可以结束绘制:1、画到第四个点时双击鼠标2、第四个点绘制完后回到第一个点,使之成为一个封闭图形。如果是用第二种方式,我们可以设置捕捉距离,以实现精确绘制,代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <title>OpenLayers</title>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #group {
            position: absolute;
            right: 20px;
            top: 20px;
            z-index: 200;
        }
    </style>
    <!-- openlayers -->
    <link href="libs/ol/ol.css" rel="stylesheet" />
    <script src="libs/ol/ol.js"></script>
    <!-- bootstrap -->
    <link href="libs/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
    <script src="libs/bootstrap/js/jquery-3.4.1.min.js"></script>
    <script src="libs/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
    <div id="map">
        <div id="group" class="btn-group">
            <button id="polygon" type="button" class="btn btn-primary">画面</button>
        </div>
    </div>

    <script>
        // 创建图层
        var source = new ol.source.Vector();
        var layer = new ol.layer.Vector({
            source: source,
            style: function (feature, resolution) {
                var style = new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'green',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'skyblue'
                    })
                });
                return style;
            }
        });

        // 创建地图
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                layer
            ],
            view: new ol.View({
                projection: 'EPSG:4326',
                center: [120, 30],
                zoom: 8
            })
        });

        //
        var draw;

        // 绘制面
        $('#polygon').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'Polygon',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'yellow',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'blue'
                    })
                }),
                snapTolerance: 40
            });
            map.addInteraction(draw);
        })
    </script>
</body>
</html>

我在这里将捕捉的距离设置为40像素,大家可以试一试,如果用第二种方式进行绘制,最后一个点会被捕捉移到第一个点的位置。

5、绘制三角形

使用上面的代码其实可以完成三角形的绘制,但我们还有另一个方法,那就是使用maxPoints属性,该属性规定了绘制的多边形最多包含几个点,这样就能帮我们自动完成三角形的绘制,代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <title>OpenLayers</title>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #group {
            position: absolute;
            right: 20px;
            top: 20px;
            z-index: 200;
        }
    </style>
    <!-- openlayers -->
    <link href="libs/ol/ol.css" rel="stylesheet" />
    <script src="libs/ol/ol.js"></script>
    <!-- bootstrap -->
    <link href="libs/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
    <script src="libs/bootstrap/js/jquery-3.4.1.min.js"></script>
    <script src="libs/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
    <div id="map">
        <div id="group" class="btn-group">
            <button id="triangle" type="button" class="btn btn-primary">画三角形</button>
        </div>
    </div>

    <script>
        // 创建图层
        var source = new ol.source.Vector();
        var layer = new ol.layer.Vector({
            source: source,
            style: function (feature, resolution) {
                var style = new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'green',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'greenyellow'
                    })
                });
                return style;
            }
        });

        // 创建地图
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                layer
            ],
            view: new ol.View({
                projection: 'EPSG:4326',
                center: [120, 30],
                zoom: 8
            })
        });

        var draw;

        // 绘制三角形
        $('#triangle').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'Polygon',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'yellow',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'blue'
                    })
                }),
                maxPoints: 3
            });
            map.addInteraction(draw);
        })
    </script>
</body>
</html>

运行结果如下图所示:
在这里插入图片描述

6、绘制正多边形

正多边形是以为基础进行绘制的图形,下面代码实现了正三角形正方形正五边形正六边形的绘制:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <title>OpenLayers</title>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #group {
            position: absolute;
            right: 20px;
            top: 20px;
            z-index: 200;
        }
    </style>
    <!-- openlayers -->
    <link href="libs/ol/ol.css" rel="stylesheet" />
    <script src="libs/ol/ol.js"></script>
    <!-- bootstrap -->
    <link href="libs/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
    <script src="libs/bootstrap/js/jquery-3.4.1.min.js"></script>
    <script src="libs/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
    <div id="map">
        <div id="group" class="btn-group">
            <button type="button" class="btn btn-primary" onclick="drawRegularPolygon(3)">三角形</button>
            <button type="button" class="btn btn-success" onclick="drawRegularPolygon(4)">正方形</button>
            <button type="button" class="btn btn-warning" onclick="drawRegularPolygon(5)">正五边形</button>
            <button type="button" class="btn btn-info" onclick="drawRegularPolygon(6)">正六边形</button>
            <button type="button" class="btn btn-danger" onclick="removeDraw()">结束</button>
        </div>
    </div>

    <script>
        // 创建图层
        var source = new ol.source.Vector();
        var layer = new ol.layer.Vector({
            source: source,
            style: function (feature, resolution) {
                var style = new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'green',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'Crimson'
                    })
                });
                return style;
            }
        });

        // 创建地图
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                layer
            ],
            view: new ol.View({
                projection: 'EPSG:4326',
                center: [120, 30],
                zoom: 8
            })
        });

        // 绘制正多边形
        var draw;
        function drawRegularPolygon(pointNumber) {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'Circle',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'yellow',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'blue'
                    })
                }),
                geometryFunction: ol.interaction.Draw.createRegularPolygon(pointNumber)
            });
            map.addInteraction(draw);
        }

        // 绘制预案
        function removeDraw() {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
        }
    </script>
</body>
</html>

运行结果如下图所示:
在这里插入图片描述

7、绘制矩形

矩形的绘制较为特殊,需要用到maxPointsgeometryFunction这两个属性,同时以LineString的形式进行绘制,代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <title>OpenLayers</title>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #group {
            position: absolute;
            right: 20px;
            top: 20px;
            z-index: 200;
        }
    </style>
    <!-- openlayers -->
    <link href="libs/ol/ol.css" rel="stylesheet" />
    <script src="libs/ol/ol.js"></script>
    <!-- bootstrap -->
    <link href="libs/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
    <script src="libs/bootstrap/js/jquery-3.4.1.min.js"></script>
    <script src="libs/bootstrap/js/bootstrap.min.js"></script>
</head>
<body>
    <div id="map">
        <div id="group" class="btn-group">
            <button id="rectangle" type="button" class="btn btn-primary">绘制矩形</button>
        </div>
    </div>

    <script>
        // 创建图层
        var source = new ol.source.Vector();
        var layer = new ol.layer.Vector({
            source: source,
            style: function (feature, resolution) {
                var style = new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'green',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'DarkViolet'
                    })
                });
                return style;
            }
        });

        // 创建地图
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                layer
            ],
            view: new ol.View({
                projection: 'EPSG:4326',
                center: [120, 30],
                zoom: 8
            })
        });

        var draw;

        // 绘制正三角形
        $('#rectangle').click(function () {
            if (draw != undefined && draw != null) {
                map.removeInteraction(draw);
            }
            draw = new ol.interaction.Draw({
                source: source,
                type: 'LineString',
                style: new ol.style.Style({
                    image: new ol.style.Circle({
                        radius: 10,
                        fill: new ol.style.Fill({
                            color: 'red'
                        })
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'yellow',
                        width: 2
                    }),
                    fill: new ol.style.Fill({
                        color: 'blue'
                    })
                }),
                maxPoint: 2,
                geometryFunction: function (coordinates, geometry) {
                    if (!geometry) {
                        geometry = new ol.geom.Polygon(null);
                    }
                    var start = coordinates[0];
                    var end = coordinates[1];
                    geometry.setCoordinates([
                        [
                            start,
                            [start[0], end[1]],
                            end,
                            [end[0], start[1]],
                            start
                        ]
                    ]);
                    return geometry;
                }
            });
            map.addInteraction(draw);
        })
    </script>
</body>
</html>

运行结果如下图所示:
在这里插入图片描述

8、结语

openlayers中,基础图形的绘制很简单,只需要设置不同的type即可。而特殊的图形,诸如正方形矩形等则需要借助ol.interaction.Draw中的一些属性和方法实现。

  • 6
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值