Cesium针对ArcGIS服务进行属性查询(二维)

起因

项目原有的二维数据很多,需要针对用户注册的二维服务在 Cesium 上进行属性查询的功能(注意这些二维服务都是 Arcgis 的 MapServer)

PS:这种查询方法也适用于所有不是 Arcgis for JS API 框架的其他地图框架

思路

1、通过 info/iteminfo 获取数据的 extend(这里需要留意数据的坐标系,如果坐标系不对,还需要通过其他方法进行坐标系转换,这里就不赘述了)

2、获取到数据的 extent 后就可以进行查询了,查询的方法主要有两种 Query 和 Identify(图查属性)

若是需要属性查找则使用 find(这里暂时不赘述)

Query

Arcgis 中的 query 是精确查询,可以通过输入图形(几何)、属性(字符串)进行精确查询,但是缺点是只能针对单个图层进行查询
img

必传字段

  • geometry
    • 这里是把你进行查询的图形要素进行传入
  • geometryType
    • 传入的图形类型
    • 语法下方有,这里不赘述
  • inSR
    • 输入几何体的空间参考。
    • 4326
  • spatialRel
    • 在执行查询时要应用在输入几何体上的空间关系。支持的空间关系包括相交、包含、包络相交、内部等。默认的空间关系是相交
    • esriSpatialRelIntersects | esriSpatialRelContains | esriSpatialRelCrosses | esriSpatialRelEnvelopeIntersects | esriSpatialRelIndexIntersects | esriSpatialRelOverlaps | esriSpatialRelTouches | esriSpatialRelWithin | esriSpatialRelRelation
  • where
    • 一个用于查询过滤器的 where 子句。任何合法的 SQL where 子句都可以对层中的字段进行操作
    • 1=1--查找全部
    • POP2000 > 350000--POP2000 是该图层中其中的字段
  • outFields
    • 返回的结果集中包含的字段列表。
    • * 返回所有
    • POP2000只返回 POP2000 这个字段的信息
  • outSR
    • 返回几何体的空间参考。
    • 4326

Identify

Arcgis 中 Identify 是可以进行多图层查询的,是模糊查询,用户需要传入 Geometry 图形数据进行查询

img

必传字段

  • geometry
    • 这里是把你进行查询的图形要素进行传入
  • geometryType
    • 传入的图形类型
    • 语法下方有,这里不赘述
  • sr
    • 传入数据的坐标系
    • {wkid:4326}
  • layers
    • 要查询的图层
    • [top | visible | all]:layerId1,layerId2
  • tolerance
    • 以屏幕像素为单位的距离,在此范围内应进行识别的指定几何体。容差的值是一个整数。
    • 2
  • mapExtent
    • 当前正在查看的地图的范围或边界框,一般直接传 info 中的 extent 即可
    • -104,35.6,-94.32,41
  • returnGeometry
    • 是否返回几何要素
    • true
  • imageDisplay
    • 目前正在查看的地图的屏幕图像显示参数(宽度、高度和 DPI)
    • PS: mapExtent 和 imageDisplay 参数被服务器用来确定在当前范围内可见的层。它们还被用来计算地图上的距离,以便根据屏幕像素的公差进行搜索。
    • 1920,1080,96

共同踩坑点

这里每次都会忘记要怎么传 Geometry,这里记录一下
ArcGIs 网站参考

  • geometryType=esriGeometryEnvelope(范围)
    • {xmin: -104, ymin: 35.6, xmax: -94.32, ymax: 41}
  • geometryType=esriGeometryPoint(点的三种方式都可以)
    • -104,35.6
    • {x: -104, y: 35.6}
    • { "x": -118.15, "y": 33.80, "spatialReference": { "wkid": 4326 } }
  • esriGeometryMultipoint(多点)
    • { "points": [ [ -97.06138, 32.837 ], [ -97.06133, 32.836 ], [ -97.06124, 32.834 ], [ -97.06127, 32.832 ] ], "spatialReference": { "wkid": 4326 } }
  • esriGeometryPolyline
    • { "paths": [ [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832] ], [ [-97.06326,32.759], [-97.06298,32.755] ] ], "spatialReference": {"wkid": 4326} }
  • esriGeometryPolygon (面)
    • { "rings": [ [ [-97.06138,32.837], [-97.06133,32.836], [-97.06124,32.834], [-97.06127,32.832], [-97.06138,32.837] ], [ [-97.06326,32.759], [-97.06298,32.755], [-97.06153,32.749], [-97.06326,32.759] ] ], "spatialReference": { "wkid": 4326 } }
    • { "rings" : [ [ [ -96.929599633999942, 38.52426809800005 ], [ -96.929602437999961, 38.522448437000037 ], [ -96.92959118999994, 38.529723252000053 ], [ -96.929594022999936, 38.527905578000059 ], [ -96.929596839999988, 38.526087119000067 ], [ -96.929599633999942, 38.52426809800005 ] ] ] }

案例代码

在发起查询请求的时候,建议都用 post 请求,因为如果直接用 get 请求,url 的长度是有限制的,而且直接用 get 请求相对来说也不是很安全,因此建议直接都用 post 请求

        //案例
        // 思路很简单,先获取服务的extent,再根据这个txtent去进行identify获取识别到的多图层要素
        const item.url = 'xxx/xxx/xxx/MapServer'
        const getExtenUrl = `${item.url}/info/iteminfo?f=pjson`;
        fetch(getExtenUrl)
        .then((response) => response.json())
        .then((res) => {
          const extent = res.extent[0][0] + ',' + res.extent[0][1] + ',' + res.extent[1][0] + ',' + res.extent[1][1];
          const requestUrl = `${item.url}/identify`;
          const params = {
            f: 'pjson',
            tolerance: 2,
            returnGeometry: false,
            geometry: JSON.stringify(
              {
              x: degreePosition.longitude,
              y: degreePosition.latitude,
              spatialReference: {
                wkid: 4326,
              },
            }
            ),
            geometryType: 'esriGeometryPoint',
            mapExtent: extent,
            imageDisplay: '1920,1080,96',
            sr: 4326,
            layers: 'all',
          };
          // post数据以表单形式存储
          const formData = new FormData();
          Object.keys(params).forEach((key) => {
            formData.append(key, params[key]);
          });

          fetch(requestUrl, {
            method: 'POST',
            body: formData,
          })
          .then((response) => response.json())
          .then((res) => {
            console.log('res1111111111', res);
            if (res.results.length > 0) {
              const featureList = res.results.map((item) => {
                const feature = {
                  layerName: item.layerName,
                  attributes: item.attributes,
                };
                return feature;
              });
              console.log('featureList', featureList);
              // 这里可以根据自己的需求进行处理
              // 例如:弹出一个弹窗,展示查询到的要素信息
            }
          });
        })
posted @ 2022-12-20 18:17  百年内必成大牛  阅读(256)  评论(0编辑  收藏  举报