325 lines
13 KiB
Markdown
325 lines
13 KiB
Markdown
|
---
|
|||
|
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
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|