QGIS二次开发07:buffer实现

在GIS应用中buffer,也就是缓冲是很普通和重要的实现,具体就是以一个空间对象(geometry)按照一定的缓冲半径进行扩展后形成新的空间对象,生成的空间对象为面类型(Polygon)。点线面都可以进行缓冲处理。

1、基本介绍

在QGIS中,buffer作为QgsGeometry类的一个成员函数,格式如下:

QgsGeometry buffer (double distance, int segments) const


QgsGeometry buffer(	double 	distance,int segments,Qgis::EndCapStyle endCapStyle,Qgis::JoinStyle 	joinStyle,
double 	miterLimit 
)		const

其中distance是缓冲半径,单位同地图;segments为拟合点个数,个数越多生成的边界越光滑;其余参数针对连接点和端点样式设置。

调用例子:

//点缓冲,10个地图单位
QgsGeometry geoPoint = QgsGeometry::fromPointXY(10,10);
QgsGeometry geoPointBuffer = geoPoint.buffer(10,40);

//线缓冲,10个地图单位
QgsGeometry geoLine = QgsGeometry::fromPolylineXY(lineXY);//lineXY为点串
QgsGeometry geoLineBuffer = geoLine.buffer(10,40)

在现实应用中地图单位有可能是度、米等,大家习惯上多采用缓冲xx米,因此在实际应用中要进行单位转换。比如上面的例子,假设地图单位是度(degrees),则调用为缓冲10度,显然这种使用不是太符合实际情况。

2、单位转换

可以使用QgsUnitTypes::fromUnitToUnitFactor()获取不同单位间的转换系数。跟踪QGIS源码中涉及单位转换的都是用这个来实现的,而且同一组转换系数是固定。(由此也产生了疑问:地球椭圆的特性决定不一致性,尤其是区域涉及大范围会导致计算的差异更大。网上也有很多关于这方面的帖子,都是涉及参考坐标系、投影等测绘知识,这里不再讨论。)

3、封装

/**
 * 点缓冲,缓冲半径单位米
 * @brief SHGeoHelper::bufferByMetre
 * @param xy
 * @param off 缓冲半径,单位米
 * @param mapCanvas
 * @return
 */
QgsGeometry SHGeoHelper::bufferByMeter(QgsGeometry geo, float off, QgsMapCanvas *mapCanvas){    
	if (!mapCanvas)return geo;
	if (off <= 0)return geo;

	QgsUnitTypes::DistanceUnit unit = mapCanvas->mapUnits();
	double factor = QgsUnitTypes::fromUnitToUnitFactor(QgsUnitTypes::DistanceMeters, unit);
	double distance = factor * off;
	return geo.buffer(distance, 36);
}

4、界面效果

5、延伸思考

在gis应用中有点击查询的需求,也就是鼠标点击地图上某处,查询与点击处存在相交的空间对象。为了提高命中率,在实际开发中往往是点击处缓冲出一个区域,再用这个区域来进行查询。这种情况下缓冲单位为米就不是太恰当,因为在不同比例尺下,以米为单位的缓冲区域可能会过大或过小,此时采用像素为单位进行缓冲就比较合适,这使在不同比例尺下缓冲出来的区域相对当前视口都是大小一致的。

此时就需要计算当前窗口像素和地图单位的转换系数,并通过此将指定像素值转换为地图单位下的对应值。 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值