-->小诗
缓冲区分析是围绕空间对象,使用一个或多个与这些对象的距离值(称为缓冲半径)作为半径,生成一个或多个区域的过程。缓冲区也可以理解为空间对象的一种影响或服务范围。
缓冲区分析的基本作用对象是点、线、面。SuperMap 支持对二维点、线、面数据集(或记录集)和网络数据集进行缓冲区分析。其中,对网络数据集进行缓冲区分析时,是对其中的弧段作缓冲区。缓冲区的类型可以分为单重缓冲区(或称简单缓冲区)和多重缓冲区。下面以简单缓冲区为例分别介绍点、线、面的缓冲区。
缓冲区分析应用场景
缓冲区分析在 GIS 空间分析中经常用到,且往往结合叠加分析来共同解决实际问题。缓冲区分析在农业、城市规划、生态保护、防洪抗灾、军事、地质、环境等诸多领域都有应用。
例如扩建道路时,可根据道路扩宽宽度对道路创建缓冲区,然后将缓冲区图层与建筑图层叠加,通过叠加分析查找落入缓冲区而需要被拆除的建筑;又如,为了保护环境和耕地,可对湿地、森林、草地和耕地进行缓冲区分析,在缓冲区内不允许进行工业建设。
点缓冲区
点的缓冲区是以点对象为圆心,以给定的缓冲距离为半径生成的圆形区域。当缓冲距离足够大时,两个或多个点对象的缓冲区可能有重叠。选择合并缓冲区时,重叠部分将被合并,最终得到的缓冲区是一个复杂面对象。
线缓冲区
线的缓冲区是沿线对象的法线方向,分别向线对象的两侧平移一定的距离而得到两条线,并与在线端点处形成的光滑曲线(也可以形成平头)接合形成的封闭区域。同样,当缓冲距离足够大时,两个或多个线对象的缓冲区可能有重叠。合并缓冲区的效果与点的合并缓冲区相同。
面缓冲区
面的缓冲区生成方式与线的缓冲区类似,区别是面的缓冲区仅在面边界的一侧延展或收缩。当缓冲半径为正值时,缓冲区向面对象边界的外侧扩展;为负值时,向边界内收缩。同样,当缓冲距离足够大时,两个或多个面对象的缓冲区可能有重叠。也可以选择合并缓冲区,其效果与点的合并缓冲区相同。
下面跟着小编一起看看具体创建缓冲区的过程吧:
创建点对象缓冲区
下面示例示范对一个点数据集创建缓冲区,并且将结果存放到结果面数据集中。
要点:
- 打开UDB数据源,获取点数据集,并创建结果面数据集。
- 查询点记录集和创建 结果面记录集。
- 设置缓冲区分析参数,创建缓冲区对象,并将结果写到结果面记录集中。
- 关闭数据源,释放内存。
UGint BufferExample::CreatePointBuffer()
{
// 获取数据源
UGDataSource* pDatasource = m_workspace->GetDatasource(_U("data"));
// 获取点数据集
const UGString strPointDatasetName = _U("Point");
UGDatasetVector* pDatasetPoint = (UGDatasetVector*)pDatasource->GetDataset(strPointDatasetName);
// 创建结果面数据集,用于保存缓冲区对象
UGString strResultDatasetName = _U("BufferResult");
UGDatasetVectorInfo datasetInfo;
datasetInfo.m_nType = UGDataset::Region;
datasetInfo.m_strName = pDatasource->GetUnoccupiedDatasetName(strResultDatasetName);
UGDatasetVector* pResultDataset = pDatasource->CreateDatasetVector(datasetInfo);
// 查询点记录集
pDatasetPoint->Open();
pResultDataset->Open();
pResultDataset->SetPrjCoordSys(pDatasetPoint->GetPrjCoordSys());
UGQueryDef queryDefPoint;
queryDefPoint.m_nCursorType = UGQueryDef::OpenStatic;
queryDefPoint.m_nOptions = UGQueryDef::Geometry;
UGRecordset* pRecordset = pDatasetPoint->Query(queryDefPoint);
UGQueryDef queryDefRegion;
UGRecordset* pRecordsetRegion = pResultDataset->Query(queryDefRegion);
UGBufferParam bufferParam;
// 设置缓冲区半径;
bufferParam.m_dBufferRadius = 10;
// 设置缓冲区半径单位,此时为米,如果设置AU_KILOMETER,则表示为10千米
// 如果数据的坐标系为平面坐标系,则此参数无效,设置的缓冲区半径单位与数据单位一致。
bufferParam.m_nRaidusUnit = AU_METER;
// 设置每段弧段由多少段线段拟合
bufferParam.m_nSemicircleSegments = 20;
UGPrjCoordSys& prjCoordSys =(UGPrjCoordSys&)pDatasetPoint->GetPrjCoordSys();
pRecordsetRegion->EditBulk(TRUE);
UGGeometry* pGeometry = NULL;
UGGeoRegion geoResultRegion;
while (!pRecordset->IsEOF())
{
if(!pRecordset->GetGeometry(pGeometry) || pGeometry == NULL)
{
pRecordset->MoveNext();
continue;
}
if(UGGeoOperator::CreateBuffer(pGeometry, bufferParam, geoResultRegion, &prjCoordSys))
{
pRecordsetRegion->AddNew(&geoResultRegion);
}
pRecordset->MoveNext();
}
pRecordsetRegion->EditBulk(FALSE);
if(pGeometry != NULL)
{
delete pGeometry;
pGeometry = NULL;
}
pDatasetPoint->ReleaseRecordset(pRecordset);
pRecordset = NULL;
pResultDataset->ReleaseRecordset(pRecordsetRegion);
pRecordsetRegion = NULL;
std::cout << "创建缓冲区成功" << endl;
pDatasource->Close();
delete pDatasource;
pDatasource = NULL;
return 1;
}
创建线对象缓冲区和创建面对象缓冲区跟点是类似的,这里就不一一举例了
这里将其中的区别做一下说明:
线记录创建缓冲区:
1、UGBufferParam.m_nSideType 线对象的缓冲边类型支持 UGFULL, UGLEFT, UGRIGHT, UGFULLDIFFR,分半是全部缓冲、左缓冲、右缓冲、左右不等缓冲。
2、UGBufferParam.m_nEndType; 缓冲类型分为两种:UGFLAT 平头缓冲,UGROUND 圆头缓冲,
(1)对于单边缓冲区(UGLEFT, UGRIGHT),m_nEndType 只能为 UGFLAT。
(2)对于全缓冲(UGFULL), 则 m_nEndType可以为 UGFLAT 和 UGROUND
(3)对于左右不等缓冲(UGFULLDIFFR), m_nEndType 只能为 UGFLAT
3、 UGBufferParam.m_dBufferRadius 设置缓冲半径。
如果m_bFieldRadius为TRUE,则m_dBufferRadius无效,此时会使用m_strBufferRadius或 m_strDiffBufferRadius作为缓冲半径。
如果设置的m_nSideType 为左右不等缓冲(UGFULLDIFFR),则此参数无效。
当为左右不等缓冲时,需要设置m_dDiffBufferRadius或m_strDiffBufferRadius,
m_dDiffBufferRadius[0]表示左边缓冲半径,m_dDiffBufferRadius[1]表示右边缓冲半径
或者是
m_strDiffBufferRadius[0]表示左边的缓冲半径字段,m_strDiffBufferRadius[1]表示右边的缓冲半径字段
面记录创建缓冲区
1、面缓冲区分析时,只支持左边缓冲(按面对象外边界顺时针走向),且端点类型必须为平头,
所以用户可以不设置m_nSideType 、m_nEndType这两个参数。
2、设置缓冲半径,这个是一样的。
如果m_bFieldRadius为TRUE,则需要设置m_strBufferRadius,此时m_dBufferRadius无效
3、 如果缓冲半径小于0时,则生成紧缩多边形,就是往对象内进行缓冲。