缓冲区分析—ArcGIS API for JavaScript

版权声明:微信公众号:GIS派。本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/agisboy/article/details/77453436

缓冲区分析是地理信息系统中的空间分析基本功能之一,是众多空间分析方法的基础。缓冲区分析是指为了识别某地理实体或空间物体对其周围的邻近性或影响度而在其周围建立的一定宽度的带状区。

缓冲区介绍

缓冲区分析是地理信息系统最重要和最基本的空间操作功能之一。缓冲区指的是以点、线、面实体基础,在其周边建立一定范围的面状区域。缓冲区在空间分析中是十分常见的,例如:
- 点缓冲区分析:噪音污染源所影响的一定空间范围、爆炸影响范围等;
- 线缓冲区分析:道路两侧绿化面积、江景楼盘面积等;
- 面缓冲区分析:公共设施(商场、邮局、银行、医院等)的服务半径,大型水库建设引起的搬迁等

本文主要介绍如何使用ArcGIS API for JavaScript建立点线面的缓冲区。

GeometryService介绍

GeometryService是一个可以用来调用ArcGIS Server的几何服务的工具类,通过GeometryService,我们可以很简便的做一些基本的几何操作,比如联合、剪切、简化以及缓冲区等,本文主要介绍缓冲区操作。
GeometryService的构造函数只有一个参数,一个有效的符合ArcGIS REST风格的GeometryServer服务地址:

var geometryService=new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");

我们可以使用ArcGIS公开的服务地址:https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer。但是该服务毕竟在国外的服务器,稳定性不强,如果大家有自己的ArcGIS Server,可以直接使用ArcGIS server中自带的几何服务,获取方法如下:
1、登入ArcGIS Server Manager,在【utilities】文件夹下找到几何服务

2、点击【功能】REST URL即我们需要的地址

创建缓冲区

获得需要绘制缓冲区的几何图形

在创建缓冲区前我们要先指定要绘制缓冲区的图形,我们的需求一般分两种:
- 给已有图层的图形绘制缓冲区;
- 动态绘制图形,然后自动创建缓冲区;

如果是我们要给图层的图形创建缓冲区,我们可以调用FeatureLayer.graphics获得一个Graphic数组,然后再分别获得Graphic.geometry获得一个图形数组:

var featureLayer=new FeatureLayer(...)
featureLayer.on("load",function(){
    for(var i=0;i<featureLayer.graphics.length;i++){
        var geometries=featureLayer.graphics[i].geometry
    }
})

这个图形数组也可以是通过查询获得,具体做法请参考空间查询—ArcGIS API for JavaScript

我们也可以直接添加图形,然后自动给这个图形创建缓冲区:

var points=[new Point(116.026,28.6826),new Point(116.05,28.66),new Point(116.11,28.70),new Point(115.95,28.65)];
var polylines=[new Polyline([[115.88,28.70],[115.88,28.67]]),new Polyline([[115.82,28.64],[115.89,28.59]])];
var polygons=[new Polygon([[115.798499,28.783553],[115.75998,28.895433],[115.900834,28.821535],[115.785276,28.759237],[115.713987,28.733902]])];
map.on("load",function(){

    var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,new Color([255,0,0]), 4)

    var markerSymbol=new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 10,
                new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,new Color([100,100,100,0.1]), 1),
                new Color([255,0,0]));

    var fillSymbol=new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, 
                new SimpleLineSymbol("solid", new Color([255,0,0]), 1), 
                new Color([255,0,0]));

            for(var i=0;i<points.length;i++){
                map.graphics.add(new Graphic(points[i],markerSymbol))
            }
            for(var i=0;i<polylines.length;i++){
                map.graphics.add(new Graphic(polylines[i],lineSymbol))
            }
            for(var i=0;i<polygons.length;i++){
                map.graphics.add(new Graphic(polygons[i],fillSymbol))
            }
});

以上代码给地图添加了4个点,两条线,一个多边形,效果如下:

配置BufferParameters缓冲区参数

通过配置BufferParameters,我们可以指定GeometryService如何生成缓冲区。
- geometries:指定生成缓冲区的几何数组;
- unit :生成缓冲区距离单位;
- distances :生成缓冲区的距离数组;
- bufferSpatialReference:缓冲区投影坐标;
- outSpatialReference :缓冲区输出面的投影坐标

因为要给点线面生成缓冲区,所以配置了三组参数,分别适用于点、线、面:

// 点缓冲区
var pointParams = new BufferParameters();
pointParams.geometries  = points;  
pointParams.distances = [ 1];
pointParams.unit = GeometryService.UNIT_KILOMETER;
pointParams.bufferSpatialReference = new SpatialReference({wkid: 32662});
pointParams.outSpatialReference = new SpatialReference({wkid: 4326})

// 线缓冲区
var polyineParams=new BufferParameters();
polyineParams.geometries=polylines;
polyineParams.distances = [ 1];
polyineParams.unit = GeometryService.UNIT_KILOMETER;
polyineParams.bufferSpatialReference = new SpatialReference({wkid: 32662});
polyineParams.outSpatialReference = new SpatialReference({wkid: 4326});

// 面缓冲区
var polygonParams=new BufferParameters();
polygonParams.geometries=polygons;
polygonParams.geodesic=true;
polygonParams.distances = [ 1];
polygonParams.unit = GeometryService.UNIT_KILOMETER;
polygonParams.bufferSpatialReference = new SpatialReference({wkid: 32662});
polygonParams.outSpatialReference = new SpatialReference({wkid: 4326});

生成缓冲区

调用GeometryService的buffer方法,根据BufferParameters指定的参数绘制缓冲区,如果绘制成功返回一个几何数组,我们可以渲染这些几何图形然后添加到地图上显示:

geometryService.buffer(pointParams,function(features) {
    var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, 
        new SimpleLineSymbol("solid", new Color([197,97,20]), 1), 
        new Color([197,97,20,1]));

    for(var i=0;i<features.length;i++){
        map.graphics.add(new Graphic(features[i],symbol))
    }
});

geometryService.buffer(polyineParams,function(features) {
    var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, 
        new SimpleLineSymbol("solid", new Color([197,97,20]), 1), 
        new Color([197,97,20,1]));

    for(var i=0;i<features.length;i++){
        map.graphics.add(new Graphic(features[i],symbol))
    }
});

geometryService.buffer(polygonParams,function(features) {
    var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, 
        new SimpleLineSymbol("solid", new Color([197,97,20]), 1), 
        new Color([197,97,20,1]));

    for(var i=0;i<features.length;i++){
        map.graphics.add(new Graphic(features[i],symbol))
    }
});

demo完整代码

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Buffer</title>

<link rel="stylesheet" href="https://js.arcgis.com/3.21/esri/css/esri.css">
<style type="text/css">
    html,body,#map{
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0}
</style>
</head>
<script type="text/javascript" src="https://js.arcgis.com/3.21/"></script>
<body>
<div id="map"></div>
</body>
<script type="text/javascript">
    require(["esri/map",
        "esri/geometry/Point",
        "esri/geometry/Polyline",
        "esri/geometry/Polygon",

        "esri/graphic",
        "esri/Color",

        "esri/tasks/BufferParameters",
        "esri/tasks/GeometryService",
        "esri/symbols/SimpleMarkerSymbol", 
        "esri/symbols/SimpleFillSymbol", 
        "esri/symbols/SimpleLineSymbol",
        "esri/SpatialReference", 

        "dojo/domReady!"],function(Map,Point,Polyline,Polygon,Graphic,Color,BufferParameters,GeometryService,SimpleMarkerSymbol,SimpleFillSymbol,SimpleLineSymbol,SpatialReference){

        var map=new Map("map",{
            basemap: "osm",
            center: [115.95,28.6826],
            zoom:"12"
        });


        var points=[new Point(116.026,28.6826),new Point(116.05,28.66),new Point(116.11,28.70),new Point(115.95,28.65)];
        var polylines=[new Polyline([[115.88,28.70],[115.88,28.67]]),new Polyline([[115.82,28.64],[115.89,28.59]])];
        var polygons=[new Polygon([[115.798499,28.783553],[115.75998,28.895433],[115.900834,28.821535],[115.785276,28.759237],[115.713987,28.733902]])];

        var geometryService=new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");

        map.on("load",function(){

            var lineSymbol=new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,new Color([255,0,0]), 4)

            var markerSymbol=new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 10,
                new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,new Color([100,100,100,0.1]), 1),
                new Color([255,0,0]));

            var fillSymbol=new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, 
                new SimpleLineSymbol("solid", new Color([255,0,0]), 1), 
                new Color([255,0,0]));

            for(var i=0;i<points.length;i++){
                map.graphics.add(new Graphic(points[i],markerSymbol))
            }
            for(var i=0;i<polylines.length;i++){
                map.graphics.add(new Graphic(polylines[i],lineSymbol))
            }
            for(var i=0;i<polygons.length;i++){
                map.graphics.add(new Graphic(polygons[i],fillSymbol))
            }


            // 点缓冲区
            var pointParams = new BufferParameters();
            pointParams.geometries  = points;  
            pointParams.distances = [ 1];
            pointParams.unit = GeometryService.UNIT_KILOMETER;
            pointParams.bufferSpatialReference = new SpatialReference({wkid: 32662});
            pointParams.outSpatialReference = new SpatialReference({wkid: 4326})

            geometryService.buffer(pointParams,function(features) {
                var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, 
                    new SimpleLineSymbol("solid", new Color([197,97,20]), 1), 
                    new Color([197,97,20,1]));

                for(var i=0;i<features.length;i++){
                    console.log(features[i]);
                    map.graphics.add(new Graphic(features[i],symbol))
                }
            });

            // 线缓冲区
            var polyineParams=new BufferParameters();
            polyineParams.geometries=polylines;
            polyineParams.distances = [ 1];
            polyineParams.unit = GeometryService.UNIT_KILOMETER;
            polyineParams.bufferSpatialReference = new SpatialReference({wkid: 32662});
            polyineParams.outSpatialReference = new SpatialReference({wkid: 4326});

            geometryService.buffer(polyineParams,function(features) {
                var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, 
                    new SimpleLineSymbol("solid", new Color([197,97,20]), 1), 
                    new Color([197,97,20,1]));

                for(var i=0;i<features.length;i++){
                    console.log(features[i]);
                    map.graphics.add(new Graphic(features[i],symbol))
                }
            });
            // 面缓冲区
            var polygonParams=new BufferParameters();
            polygonParams.geometries=polygons;
            polygonParams.geodesic=true;
            polygonParams.distances = [ 1];
            polygonParams.unit = GeometryService.UNIT_KILOMETER;
            polygonParams.bufferSpatialReference = new SpatialReference({wkid: 32662});
            polygonParams.outSpatialReference = new SpatialReference({wkid: 4326});

            geometryService.buffer(polygonParams,function(features) {
                var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, 
                    new SimpleLineSymbol("solid", new Color([197,97,20]), 1), 
                    new Color([197,97,20,0.5]));

                for(var i=0;i<features.length;i++){
                    console.log(features[i]);
                    map.graphics.add(new Graphic(features[i],symbol))
                }
            });

        })

    });

</script>
</html>

demo最终效果


GIS技术交流:GISGO(http://www.gisgo.top)
本文首发微信公众号:GISXXCOM

关注微信公众号GISXXCOM,GET更多技能
这里写图片描述

展开阅读全文

没有更多推荐了,返回首页