基于openlayers实现多边形被线和面切割_openlayers 拆分图形_混子zy的博客-CSDN博客 代码优化了切割多面(MultiPolygon)
线切割面或多面:
function drawpolylineFn() {
//业务需求 为了切割完带有原来的属性
var _features = oldfeature;
let drawSourceVector = new ol.VectorSource();
let drawLineSplit = new ol.Draw({
source: drawSourceVector,
type: 'LineString',
style: new ol.Style({
image: new ol.Circle({
radius: 5,
fill: new ol.Fill({
color: '#03a9f4',
}),
}),
stroke: new ol.Stroke({
color: '#03a9f4',
width: 2,
}),
fill: new ol.Fill({
color: 'rgba(255, 255, 255, 0.7)',
}),
}),
});
map.addInteraction(drawLineSplit);
drawLineSplit.on('drawstart', () => {
map.un(mapOnclick.type, mapOnclick.listener);
});
drawLineSplit.on('drawend', (evt) => {
map.removeInteraction(drawLineSplit);
let coorArr = evt.feature.getGeometry().getCoordinates();
let polyDikuai;
if(evt.feature.getGeometry().getType()=="MultiPolygon"){
polyDikuai = turf.multiPolygon(coorArr);
}else{
polyDikuai = turf.polygon(coorArr);
}
polyDikuai.properties = oldfeature.values_.attributes;
let polyline = turf.lineString(coorArr);
let result = polygonCut(polyDikuai, polyline);
//绘出结果 绘制出多个个多边形
if (result && result.features && result.features.length > 0) {
for (let f = 0; f < result.features.length; f++) {
let feature = result.features[f];
// aaadata = {
// type: 'MultiPolygon',
// coordinates: [feature.geometry.coordinates],
// };
if (feature.geometry && feature.geometry.type && feature.geometry.type === 'Polygon') {
} else {
continue;
}
// let polygon1 = new ol.Polygon(feature.geometry.coordinates);
let feature1 = new ol.Feature({
geometry: new ol.Polygon(feature.geometry.coordinates || []),
// attributes: _features.values_.attributes,
attributes: feature,
});
feature1.setStyle(
new ol.Style({
//填充色
fill: new ol.Fill({
color: 'rgba(244, 3, 49, 0.5)',
// color: 'rgba(255, 255, 255, 0.5)',
}),
//边线颜色
stroke: new ol.Stroke({
color: '#f40331',
width: 2,
}),
//形状
// image: new ol.Circle({
// radius: 7,
// fill: new ol.Fill({
// color: '#ffcc33',
// }),
// }),
}),
);
let Area = formatArea(feature.geometry.coordinates);
// let length = getPolygonLength(feature1);
// let name =
// features.get('region_name') === undefined
// ? '采集地块-' + Area
// : features.get('region_name');
feature1.set('Area', Area);
// feature1.set('Length', length);
// feature1.set('region_name', name);
if (topvector) {
topvector.getSource().addFeature(feature1);
}
}
setTimeout(() => {
topvector.getSource().removeFeature(_features);
}, 100);
setTimeout(() => {
map.on(mapOnclick.type, mapOnclick.listener);
}, 1000);
}
});
}
// 计算图形面积
function formatArea(c) {
var polygon = turf.polygon(c);
var area = turf.area(polygon);
return area;
}
function polygonCut(poly, line, tolerance = 0.000001, toleranceType = 'kilometers') {
if (line.geometry === void 0 || line.geometry.type.toLowerCase().indexOf('linestring') === -1) {
// throw "传入的必须为linestring";
return;
}
if (line.geometry.type === 'LineString') {
if (
turf.booleanPointInPolygon(turf.point(line.geometry.coordinates[0]), poly) ||
turf.booleanPointInPolygon(
turf.point(line.geometry.coordinates[line.geometry.coordinates.length - 1]),
poly,
)
) {
// throw "起点和终点必须在多边形之外";
return;
}
}
// 2. 计算交点,并把线的点合并
//计算相交点
let lineIntersect = turf.lineIntersect(line, poly);
//获取一个或一组Feature,并将所有位置作为点返回。拆分为点
const lineExp = turf.explode(line);
for (let i = 0; i < lineExp.features.length - 1; i++) {
lineIntersect.features.push(turf.point(lineExp.features[i].geometry.coordinates));
}
// 3. 计算线的缓冲区
const lineBuffer = turf.buffer(line, tolerance, {
units: toleranceType,
});
// 4. 计算线缓冲和多边形的difference,返回"MultiPolygon",所以将其拆开
//通过从第一个多边形剪裁第二个多边形来查找两个多边形之间的差异。
const _body = turf.difference(poly, lineBuffer);
let pieces = [];
if (_body.geometry.type === 'Polygon') {
pieces.push(turf.polygon(_body.geometry.coordinates));
} else {
_body.geometry.coordinates.forEach(function (a) {
pieces.push(turf.polygon(a));
});
}
// 5. 处理点数据
for (let p = 0; p < pieces.length; p++) {
const piece = pieces[p];
for (let c in piece.geometry.coordinates[0]) {
const coord = piece.geometry.coordinates[0][c];
const p = turf.point(coord);
for (let lp in lineIntersect.features) {
const lpoint = lineIntersect.features[lp];
//判断两点距离
if (turf.distance(lpoint, p, toleranceType) <= tolerance * 2) {
piece.geometry.coordinates[0][c] = lpoint.geometry.coordinates;
}
}
}
}
// 6. 过滤掉重复点
// for (let p=0;p<pieces.length; p++) {
// const coords = pieces[p].geometry.coordinates[0];
// pieces[p].geometry.coordinates[0] = filterDuplicatePoints(coords);
// }
// 7. 将属性赋予每一个polygon,并处理id
pieces.forEach((a, index) => {
a.properties = Object.assign({}, poly.properties);
a.properties.id += `-${index}`;
});
//获取一个或多个Feature并创建一个FeatureCollection。
return turf.featureCollection(pieces);
}
面切割面或多面:
function drawpolygonFn() {
var _features = oldfeature;
let drawSourceVector = new ol.VectorSource();
var drawFaceSplit = new ol.Draw({
source: drawSourceVector,
type: 'Polygon',
style: new ol.Style({
stroke: new ol.Stroke({
color: '#03a9f4',
width: 2,
}),
fill: new ol.Fill({
color: 'rgba(255, 255, 255, 0.7)',
}),
image: new ol.Circle({
radius: 3,
fill: new ol.Fill({
color: '#03a9f4',
}),
}),
}),
});
map.addInteraction(drawFaceSplit);
drawFaceSplit.on('drawstart', () => {
map.un(mapOnclick.type, mapOnclick.listener);
});
drawFaceSplit.on('drawend', (evt) => {
map.removeInteraction(drawFaceSplit);
let splitResult = [];
let pointslist = evt.feature.getGeometry().getCoordinates();
let polyDikuai;
if(evt.feature.getGeometry().getType()=="MultiPolygon"){
polyDikuai = turf.multiPolygon(pointslist);
}else{
polyDikuai = turf.polygon(pointslist);
}
// polyDikuai.properties = oldfeature.values_.attributes;
let polyDraw = turf.polygon(pointslist);
//取两个多边形并找到它们的交点。如果它们共享一个边界,返回边界;如果它们不相交,返回undefined。
let intersection = turf.intersect(polyDikuai, polyDraw);
debugger;
//通过从第一个多边形剪裁第二个多边形来查找两个多边形之间的差异。
let difference1 = turf.difference(polyDikuai, polyDraw);
// 判断面是否包含面
let contains = turf.booleanContains(polyDikuai, polyDraw);
let intersectionArray = intersection.geometry ? intersection.geometry.coordinates : [];
let differenceArray = difference1.geometry ? difference1.geometry.coordinates : [];
splitResult.push(intersectionArray);
if (differenceArray && differenceArray.length > 1 && !contains) {
for (let item of differenceArray) {
splitResult.push(item);
}
} else {
splitResult.push(differenceArray);
}
if (intersection && splitResult.length > 0) {
for (let item in splitResult) {
// let polygonResult = new Polygon(splitResult[item]);
let featureResult = new ol.Feature({
geometry: new ol.Polygon(splitResult[item] || []),
attributes: _features.values_.attributes,
});
featureResult.setStyle(
new ol.Style({
//填充色
fill: new ol.Fill({
color: 'rgba(244, 3, 49, 0.5)',
// color: 'rgba(255, 255, 255, 0.5)',
}),
//边线颜色
stroke: new ol.Stroke({
color: '#f40331',
width: 2,
}),
//形状
// image: new ol.Circle({
// radius: 7,
// fill: new ol.Fill({
// color: '#ffcc33',
// }),
// }),
}),
);
let Area = formatArea(splitResult[item]);
featureResult.set('Area', Area);
// featureResult.set('region_name', name);
if (topvector) {
topvector.getSource().addFeature(featureResult);
}
}
try {
setTimeout(() => {
topvector.getSource().removeFeature(_features);
}, 100);
setTimeout(() => {
map.on(mapOnclick.type, mapOnclick.listener);
}, 1000);
} catch (e) {}
}
});
}