柿子树备忘录

vuePress-theme-reco 柿子树    2023
柿子树备忘录

Choose mode

  • dark
  • auto
  • light
首页
个人笔记
  • Web
  • GIS
  • Database
  • DevOps
  • 可视化
地图故事
生活点滴
归档
关于我
author-avatar

柿子树

109

Article

73

Tag

首页
个人笔记
  • Web
  • GIS
  • Database
  • DevOps
  • 可视化
地图故事
生活点滴
归档
关于我
  • GIS理论基础

    • GIS基础知识
    • 地图坐标系统
  • GeoServer笔记

    • 思维导图
    • 一、OGC简述

    • 二、基本使用

    • 三、服务标准

    • 四、图层加载

    • 五、服务端开发

  • Openlayers

    • 思维导图
    • 一、快速起步

    • 二、ol结构体系

    • 三、数据源加载

    • 四、常用控件

    • 五、几何对象与Style样式

    • 六、事件交互

      • interactions
      • 在线编辑
    • 七、OGC服务

    • 八、常用示例

  • CesiumJS

    • 思维导图
  • WorldWind

    • WorldWindJava 学习笔记
    • OpenGL中的坐标系

在线编辑

vuePress-theme-reco 柿子树    2023

在线编辑

ac 2020-11-01 OpenLayersDrawModify

# 1 Draw 对象

ol在客户端(浏览器)可以通过Draw交互对象在map中绘制几何图形。

初始化Draw对象时,在构造参数options中指定type参数和用于存储所绘制图形的数据源source即可,但type类型必须是'Point', 'LineString', 'LinearRing', 'Polygon', 'MultiPoint', 'MultiLineString', 'MultiPolygon', 'GeometryCollection', 'Circle'中的类型。

当然在Draw中也提供了一些方法用于绘制自定义图形。

new Draw(options),options常用的构造参数

name type Description
type module:ol/geom/GeometryType (opens new window) 指定要绘制的几何类型
clickTolerance number 绘制时鼠标点击的容差
features ol/Collection~Collection (opens new window)<ol/Feature> 用于存储绘制图形的要素集合
source ol/source/Vector~VectorSource (opens new window) 用于存储绘制图形的数据源
dragVertexDelay number (defaults to 500) 当前顶点被拖动到其确切位置之前的延迟(毫秒)。
snapTolerance number(defaults to 12) 可拖放对象离目标对象的距离低于此像素值时开始靠拢
stopClick boolean(defaults to false) 停止在绘图期间触发的单击、singleclick和doubleclick事件。
finishCondition ol/events/condition~Condition (opens new window) 绘制结束的条件函数
style ol/style/Style~StyleLike (opens new window) 绘制图形使用的渲染样式
geometryFunction ol/interaction/Draw~GeometryFunction (opens new window) 当绘制图形的坐标发生变化时,调用的函数。它接受一个坐标数组、一个可选的现有几何图形和一个投影作为参数,并返回一个几何图形。
freehand boolean(defaults to false) 自由模式,自定义绘制图形
maxPoints number 绘制多边形或线的最多点数个数
minPoints number 绘制多边形或线的最少点数个数,线默认为2,多边形默认为3

与Draw绘制对象对应的有一个ol/interaction/Draw~DrawEvent事件类来处理绘制交互过程中的事件,如:

  • drawstart:开始绘制要素时触发
  • drawend:绘制结束后触发

示例:

image1980
<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="css/ol.css" type="text/css">
    <style>
      .map {
        height: 400px;
        width: 100%;
      }
    </style>
    <script src="lib/ol.js"></script>
    <title>图形绘制</title>
    <meta charset="UTF-8">
  </head>
  <body>
    <h2>Drawing--图形绘制</h2>
    <div id="map" class="map"></div>
    <div>
      <button onclick="addDrawInteraction('Point')">点</button>
      <button onclick="addDrawInteraction('LineString')">线</button>
      <button onclick="addDrawInteraction('Polygon')">面</button>
      <button onclick="addDrawInteraction('Circle')">圆</button>
      <button onclick="addDrawInteraction('Square')">正方形</button>
      <button onclick="addDrawInteraction('Box')">长方形</button>
      <button onclick="addDrawInteraction('None')">取消</button>
      <button onclick="addDrawInteraction('Clear')">清除</button>
    </div>
    <script type="text/javascript">

      var shenzhen = [113.958334,22.535640];
      var map = new ol.Map({
        target: 'map',
        layers: [
            //作为底图
            new ol.layer.Tile({
                source: new ol.source.OSM()
            })
        ],
        view: new ol.View({
          center: ol.proj.fromLonLat(shenzhen),
          zoom: 10
        })
      });

      //创建矢量数据源,用于存储在线绘制几何对象
      var opterationSource = new ol.source.Vector();
      var vecLayer = new ol.layer.Vector({
          source: opterationSource
      });
      map.addLayer(vecLayer);

      //创建Draw实例
      var draw = null;
      function addDrawInteraction(drawType) {
          //移除原来的draw
          map.removeInteraction(draw);
          draw = null;

          switch (drawType){
              case 'Point':
              case 'LineString':
              case 'Polygon':
              case 'Circle':
                  draw = new ol.interaction.Draw({
                      source:opterationSource,
                      type:drawType,
                      // freehand: true //自由模式,自定义绘制 图形
                  });
                  map.addInteraction(draw);
                  break;
              case 'Square':
                  draw = new ol.interaction.Draw({
                      source:opterationSource,
                      type:'Circle',
                      geometryFunction:ol.interaction.Draw.createRegularPolygon(4)
                  });
                  map.addInteraction(draw);
                  break;
              case 'Box':
                  draw = new ol.interaction.Draw({
                      source:opterationSource,
                      type:'LineString',
                      maxPoints: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);
                  break;
              case "Clear":
                  //清除数据源中存储的要素
                  opterationSource.clear() ;
                  break;
          }
          if(draw){
              bindDrawEvent();
          }
      }
      function bindDrawEvent(){
          draw.on("drawstart",function(e){
              console.log("drawstart");
          });
          draw.on("drawend",function(e){
              //从事件源中获取所绘制的几何图形
              var geometry = e.feature.getGeometry();
              console.log("drawend");
          });
      }
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

# 2 Modify对象

如果需要对客户端绘制的图层或要素服务提供的图层进行修改,我们可以使用ol中的modify交互对象完成这类需求。跟Draw对象类似,初始化Modify实例时,需要在构造参数中使用source或features指定数据源或要素集合。将Modify实例添加到map上后就可以修改指定的要素了。通常跟snap交互控件一起使用,方便捕捉几何图形的顶点进行修改。

示例:

image-20201119180610414
<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="css/ol.css" type="text/css">
    <style>
      .map {
        height: 85vh;
        width: 100%;
      }
    </style>
    <script src="lib/ol.js"></script>
    <script src="lib/jquery-3.1.1.js"></script>
    <title>图形修改</title>
    <meta charset="UTF-8">
  </head>
  <body>
    <h2>Modify--图形修改</h2>
    <div id="map" class="map"></div>
    <div>图形绘制:
      <button onclick="addDrawInteraction('Point')">点</button>
      <button onclick="addDrawInteraction('LineString')">线</button>
      <button onclick="addDrawInteraction('Polygon')">面</button>
      <button onclick="addDrawInteraction('Circle')">圆</button>
      <button onclick="addDrawInteraction('Square')">正方形</button>
      <button onclick="addDrawInteraction('Box')">长方形</button>
      <button onclick="addDrawInteraction('None')">取消</button>
      <button onclick="addDrawInteraction('Clear')">清除</button>
    </div>
    <div>图形修改:
      <button onclick="addModify()">修改</button>
      <button onclick="cancelModify()">取消</button>
    </div>
    <script type="text/javascript">

      var map = new ol.Map({
        target: 'map',
        layers: [
            new ol.layer.Tile({
                source: new ol.source.OSM()
            })
        ],
        view: new ol.View({
          center: ol.proj.fromLonLat([137.41, 23.82]),
          zoom: 4
        })
      });


      //创建矢量数据源,用于存储在线绘制几何对象
      var opterationSource = new ol.source.Vector();
      var vecLayer = new ol.layer.Vector({
          source: opterationSource
      });
      map.addLayer(vecLayer);

      //创建Draw实例
      var draw = null;
      function addDrawInteraction(drawType) {
          //移除原来的draw
          map.removeInteraction(draw);
          draw = null;
          switch (drawType){
              case 'Point':
              case 'LineString':
              case 'Polygon':
              case 'Circle':
                  draw = new ol.interaction.Draw({
                      source:opterationSource,
                      type:drawType,
                  });
                  map.addInteraction(draw);
                  break;
              case 'Square':
                  draw = new ol.interaction.Draw({
                      source:opterationSource,
                      type:'Circle',
                      geometryFunction:ol.interaction.Draw.createRegularPolygon(4)
                  });
                  map.addInteraction(draw);
                  break;
              case 'Box':
                  draw = new ol.interaction.Draw({
                      source:opterationSource,
                      type:'LineString',
                      maxPoints: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);
                  break;
              case "Clear":
                  opterationSource.clear() ;
                  break;
          }
      };
      //创建modify实例
      var modify = new ol.interaction.Modify({
          source:opterationSource
      });
      function addModify() {
          map.addInteraction(modify);
      };
      function cancelModify() {
          map.removeInteraction(modify);
      };
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

# 参考文章

[1] TopoJSON https://www.jianshu.com/p/351fbc010412?from=singlemessage