ARCGIS API 判断点与面相交

应用场景:输入某点经纬度信息,判断该点落在哪个面里
具体应用:客户通过页面的文本框输入某资源点的经纬度,返回该资源点的地市信息,这里以海南地市为例子。效果如下:
在这里插入图片描述
在这里插入图片描述
实现功能有两种方法

方法一:

接口通过接收输入的经纬度,传给后端数据库作为参数(以Sqlserver数据库为例),通过数据库两个要素的相交计算,将计算的结果再通过接口传回给前端。
运用到两种空间数据的计算方法:

  1. 点经纬度转shape: geometry::Point(lon,lat,4326) shape
  2. 判断两个要素相交: a.SHAPE.STIntersects(b.SHAPE)=1
    在这里插入图片描述

方法二:

通过ARCGIS JS API,两个要素相交的判断 geometryEngine.intersects(geometry1, geometry2),如果相交,返回true,不相交则返回false
在这里插入图片描述
本文主要介绍方法二的实现,通过获取本地json数据,创建要素图层的方法,(具体方法在我的另一篇文章里有介绍:不依赖地图服务创建要素图层)获取到每个地市的geometry。海南地市矢量数据:
在这里插入图片描述
海南地市json数据下载链接:city.json

具体代码如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>判断点落面</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/css/esri.css">
  <style>
    body,
    html {
      margin: 0;
      padding: 0;
      width: 100%;
      height: 100%;
      font-family: Arial;
    }
    #map {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
      border: 0px dashed black;
      background-color: rgb(0, 38, 48);
    }

  </style>
</head>
<body>
  <input type="text" id="x" style="width:120px;height:30px;" placeholder="请输入经度"/>
  <input type="text" id="y" style="width:120px;height:30px;" placeholder="请输入纬度"/>
  <button id="btn" onclick="getCity()" style="background-color: #4CAF50;
  border: none;
  color: white;
  padding: 5px 5px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 15px;
  margin: 1px 1px;
  cursor: pointer;">查询</button><br>
  所属城市:<input type="text" id="z" value=""/>
<div id="map">
</div>
</body>

<!-- 引入ARCGIS API -->
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://js.arcgis.com/3.20"></script>
<script type="text/javascript">
  var map, getCity;
  require([
    "esri/map",
    'esri/Color',
    'esri/geometry/Point',
    "esri/layers/GraphicsLayer",
    'esri/geometry/geometryEngine',
    "esri/tasks/FeatureSet",
    "esri/layers/FeatureLayer",
    "esri/layers/ArcGISTiledMapServiceLayer",
    'esri/graphic',
    'esri/symbols/SimpleMarkerSymbol',
    'esri/symbols/SimpleLineSymbol',
    "esri/geometry/Extent",
    "dojo/domReady!"
  ], function(
    Map,
    Color,
    Point,
    GraphicsLayer,
    geometryEngine,
    FeatureSet,
    FeatureLayer,
    ArcGISTiledMapServiceLayer,
    Graphic,
    SimpleMarkerSymbol,
    SimpleLineSymbol,
    Extent
  ) {

    //地图范围
    var mapExtent = new Extent({
      xmax: 113.799760210539,
      xmin: 106.57095767482662,
      ymax: 20.459116202966324,
      ymin: 18.27952992162579,
      spatialReference: {
        wkid: 4326
      }
    })
    map = new Map("map", {
      extent: mapExtent,
      sliderStyle: "small",
      logo: false,
    });

    map.on('load', function () {
      map.hideZoomSlider()
      map.hidePanArrows()
    })

    //arcgis 在线切片底图图
    var myTileLayer = new ArcGISTiledMapServiceLayer("https://map.geoq.cn/arcgis/rest/services/ChinaOnlineCommunity_Mobile/MapServer", {
      visible: true
    });
    map.addLayer(myTileLayer)

    //点绘制图层
    var pointGh = new GraphicsLayer()
    map.addLayer(pointGh)

    //获取本地json数据,根据json数据创建要素图层
    getCity = function () {
      pointGh.clear() //每次查询前都清空点图层
      let json = null
      let url = "city.json"/*json文件url*/
      let request = new XMLHttpRequest();
      request.open("get", url);/*设置请求方法与路径*/
      request.send(null);/*不发送数据到服务器*/
      request.onload = function () {/*XHR对象获取到返回信息后执行*/
        if (request.status == 200) {/*返回状态为0,即为数据获取成功*/
          json = JSON.parse(request.responseText);
          let featureSet = new FeatureSet(json)
          let layerDefinition = {  //要素描述
            "geometryType": "esriGeometryPolygon",
            "fields":[
              {
                "name" : "FID", //字段名称
                "type" : "esriFieldTypeOID", //字段类型
                "alias" : "FID"
              },
              {
                "name" : "city_name",
                "type" : "esriFieldTypeString",
                "alias" : "city_name",
                "length" : 254
              },
              {
                "name" : "value",
                "type" : "esriFieldTypeInteger",
                "alias" : "value"
              }
            ]
          }
          //要素合集
          let featureCollection = {
            layerDefinition: layerDefinition,
            featureSet: featureSet
          }
          let featurelayer = new FeatureLayer(featureCollection) //使用要素合集创建要素图层
          //只是用作相交判断,不需要将地市图层添加到地图
          //map.addLayer(featurelayer) 
          //获取文本框输入的经纬度,这里默认输入的是数字,严谨情况下需要做判断输入的是否为数字
          let x = $("#x").val() 
          let y = $("#y").val() 
          let lon = parseFloat(x) //转为float类型
          let lat = parseFloat(y) //转为float类型
          let markerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_CIRCLE, 10, //点样式
            new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
            new Color([255, 0, 0]), 0.01),
            new Color([255, 0, 0, 0.5]))
          let point = new Point(lon, lat) //根据输入的经纬度生成点
          let gra = new Graphic(point)
          gra.setSymbol(markerSymbol)
          pointGh.add(gra) //添加到地图
          map.centerAndZoom(point,8)  //定位和缩放
          let cityName = ""
          let num
          let isInList = [] //用于放置相交的结果
          for (let i=0; i<featurelayer.graphics.length; i++) {  //遍历地市图层要素
            let geo = featurelayer.graphics[i].geometry
            //判断点要素与地市图层要素是否相交,相交返回true,不相交返回false
            let isIn = geometryEngine.intersects(geo, point)
            isInList.push(isIn) //点与每个地市是否相交的结果放入集合
            if (isIn == true) { //相交时获取该地市名称
               cityName = featurelayer.graphics[i].attributes.city_name
               num = i //相交时获取该地市相交顺序编号
            }
          }
          if (isInList[num] == true) { //根据编号判断是否相交
            console.log(cityName)
            document.getElementById("z").value = cityName //将结果写入所属地市文本框
            isInList.length = 0 //将集合清空
          }else {
            document.getElementById("z").value = "不在海南范围内"
            isInList.length = 0 //将集合清空
          }
        }
      }
    }
  });
</script>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值