meface/docs/article/gis/openlayers/62oledits.md

325 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 在线编辑
date: 2020-11-2
author: ac
tags:
- OpenLayers
- Draw
- Modify
categories:
- GIS
---
## 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](https://openlayers.org/en/latest/apidoc/module-ol_geom_GeometryType.html) | 指定要绘制的几何类型 |
| clickTolerance | number | 绘制时鼠标点击的容差 |
| features | [ol/Collection~Collection](https://openlayers.org/en/latest/apidoc/module-ol_Collection-Collection.html)<[ol/Feature]()> | 用于存储绘制图形的要素集合 |
| source | [ol/source/Vector~VectorSource](https://openlayers.org/en/latest/apidoc/module-ol_source_Vector-VectorSource.html) | 用于存储绘制图形的数据源 |
| dragVertexDelay | number (defaults to 500) | 当前顶点被拖动到其确切位置之前的延迟(毫秒)。 |
| snapTolerance | number(defaults to 12) | 可拖放对象离目标对象的距离低于此像素值时开始靠拢 |
| stopClick | boolean(defaults to false) | 停止在绘图期间触发的单击、singleclick和doubleclick事件。 |
| finishCondition | [ol/events/condition~Condition](https://openlayers.org/en/latest/apidoc/module-ol_events_condition.html#~Condition) | 绘制结束的条件函数 |
| style | [ol/style/Style~StyleLike](https://openlayers.org/en/latest/apidoc/module-ol_style_Style.html#~StyleLike) | 绘制图形使用的渲染样式 |
| **geometryFunction** | [ol/interaction/Draw~GeometryFunction](https://openlayers.org/en/latest/apidoc/module-ol_interaction_Draw.html#~GeometryFunction) | 当绘制图形的坐标发生变化时,调用的函数。它接受一个坐标数组、一个可选的现有几何图形和一个投影作为参数,并返回一个几何图形。 |
| freehand | boolean(defaults to false) | 自由模式,自定义绘制图形 |
| maxPoints | number | 绘制多边形或线的最多点数个数 |
| minPoints | number | 绘制多边形或线的最少点数个数线默认为2多边形默认为3 |
与`Draw`绘制对象对应的有一个`ol/interaction/Draw~DrawEvent`事件类来处理绘制交互过程中的事件,如:
- `drawstart`:开始绘制要素时触发
- `drawend`:绘制结束后触发
示例:
<img src="./images/image1980.png" alt="image1980" style="zoom: 80%;" />
```html
<!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>
```
## 2 Modify对象
如果需要对客户端绘制的图层或要素服务提供的图层进行修改,我们可以使用`ol`中的modify交互对象完成这类需求。跟Draw对象类似初始化Modify实例时需要在构造参数中使用source或features指定数据源或要素集合。将Modify实例添加到map上后就可以修改指定的要素了。通常跟snap交互控件一起使用方便捕捉几何图形的顶点进行修改。
示例:
<img src="./images/image-20201119180610414.png" alt="image-20201119180610414" style="zoom: 67%;" />
```html
<!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] TopoJSON https://www.jianshu.com/p/351fbc010412?from=singlemessage