ArcGIS API for JavaScript取得包含及相交大于一半的要素

现有这样一个需求:

某国土部门旧的不动产测绘数据包含宗地和自然幢,现以ArcGIS地图服务的方式提供。由于过去在测绘时,没有将宗地和自然幢进行属性关联(即,在自然幢图层字段中保存其对应的宗地代码),只保存了二者的空间关系(宗地包含了自然幢),且可能存在不完整包含的情况。现需在取得宗地范围后,查询其所包含的自然幢。如果一个自然幢完整于位于宗地范围内,或大部分面积(比如,超过一半)位于宗地范围内,即认为其与该宗地需关联起来。简单地说,就是用宗地去查询它完整包含及大部分包含的自然幢。

我们用ArcGIS API for JavaScript V3.23实现了这个功能,代码如下:

<!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>Select with feature layer</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.23/dijit/themes/tundra/tundra.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.23/esri/css/esri.css">
  <style>
    html, body, #mapDiv {
      padding: 0;
      margin: 0;
      height: 100%;
    }
    #messages{
      background-color: #fff;
      box-shadow: 0 0 5px #888;
      font-size: 1.1em;
      max-width: 15em;
      padding: 0.5em;
      position: absolute;
      right: 20px;
      top: 20px;
      z-index: 40;
    }
  </style>
  <script src="https://js.arcgis.com/3.23/"></script>
  <script>
    var map;
    require([
      "esri/map", "esri/layers/FeatureLayer", 
      "esri/tasks/query", "esri/geometry/Circle",
      "esri/graphic", "esri/symbols/SimpleMarkerSymbol",
      "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",
      "esri/geometry/geometryEngine", "esri/config", "esri/Color", "dojo/dom", "dojo/domReady!"
      ], function(
        Map, FeatureLayer,
        Query, Circle,
        Graphic, SimpleMarkerSymbol,
        SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,
        geometryEngine, esriConfig, Color, dom
        ) {
        // Use a proxy page if a URL generated by this page is greater than 2000 characters
        //
        // This should not be needed as nearly all query & select functions are performed on the client
        esriConfig.defaults.io.proxyUrl = "/proxy/";

        map = new Map("mapDiv", { 
          basemap: "streets",
          center: [-95.249, 38.954],
          zoom: 4,
          slider: true
        });
        
        var featureLayer = new FeatureLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/2",{
          outFields: ["fid"]
        });

        // Selection symbol used to draw the selected census block points within the buffer polygon
        var symbol = new SimpleMarkerSymbol(
          SimpleMarkerSymbol.STYLE_CIRCLE, 
          12, 
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_NULL, 
            new Color([247, 34, 101, 0.9]), 
            1
            ),
          new Color([207, 34, 171, 0.5])
          );
        featureLayer.setSelectionSymbol(symbol); 
        
        var nullSymbol = new SimpleMarkerSymbol().setSize(0);
        featureLayer.setRenderer(new SimpleRenderer(nullSymbol));
        
        map.addLayer(featureLayer);
        
        var circleSymb = new SimpleFillSymbol(
          SimpleFillSymbol.STYLE_NULL,
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_SHORTDASHDOTDOT,
            new Color([105, 105, 105]),
            2
            ), new Color([255, 255, 0, 0.25])
          );

        var circle;

          var resultSymb = new SimpleFillSymbol(
          SimpleFillSymbol.STYLE_FORWARD_DIAGONAL,
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_SOLID,
            new Color([255, 0, 0]),
            2
            ), new Color([255, 0, 255, 0.25])
          );
        
        map.on("click", function(evt){
          circle = new Circle({
            center: evt.mapPoint,
            geodesic: true,
            radius: 100000,
            radiusUnit: "esriMiles"
          });
          map.graphics.clear();
          var graphic = new Graphic(circle, circleSymb);
          map.graphics.add(graphic);

          var query = new Query();
          //传入的查询范围
          query.geometry = circle.getExtent();
          //执行查询操作
          featureLayer.queryFeatures(query, selectIntersects);
        });

        /**
         * 处理相交要素
         * @param  {[type]} response [description]
         * @return {[type]}          [description]
         */
        function selectIntersects(response){
          var feature;
          var features = response.features;
          var interstctsFeature = [];
          for (var i = 0; i < features.length; i++) {
            var skip = true;
            feature = features[i];
            //取得要素自身的面积
            var fArea = geometryEngine.geodesicArea(feature.geometry,109413);
            //只处理相交情形
            if(geometryEngine.intersects(feature.geometry,circle)){
              //取得差异部分
              var differenceGeometry = geometryEngine.difference(feature.geometry,circle);
              //差异部分为空时,为包含要素,否则为相交要素
              if(null != differenceGeometry){
                //取得差异部分的面积
                var dArea = geometryEngine.geodesicArea(differenceGeometry,109413);
                var radio = dArea * 100 / fArea;
                //差异部分面积占比小于一半,是我们想要的结果
                if(radio < 50){
                  skip = false;
                }
              } else {
                skip = false;
              }
            }          
            if(!skip){
              interstctsFeature.push(feature);
            }
          }

          //将要素图形绘制到地图上
          for(var j =0; j<interstctsFeature.length; j++){
            var graphic = new Graphic(interstctsFeature[j].geometry, resultSymb);
            map.graphics.add(graphic);
          }
        }
        
      });
    </script>
  </head>

  <body>
    <span id="messages">Click on the map to select...</span>
    <div id="mapDiv"></div>
  </body>
  </html>

效果如下(在地图上点击,缓冲一个圆形,查询其完整和大部分包含的美国的州):




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值