ArcGIS开发基础教程(三):核心概念之图层和数据(上)

1,796 阅读4分钟

核心概念之图层和数据(上)

图层是可在Map中使用的数据集合。图层数据可以在前端创建,或者由 ArcGIS Online 和 ArcGIS Enterprise 发布,或由外部服务器托管。

要素集合

要素(feature)

: 要素是对地理位置或实体的记录。每个要素都包含为一种几何类型(点、折线或多边形)定义的空间坐标和存储其他信息的属性字段。

图层通常用来管理和显示大量的要素集合。要素集合又分为结构化和非结构化1。如果要显示要素集合时,一般的做法是:

  • 如果数据是结构化的,使用FeatureLayer来显示数据

  • 如果是非结构化的,用GraphicsLayer来显示数据

image-20210902145834267

Map作为数据的容器,存放着各种不同类型的图层,图层又是由要素集合组成,每个要素都要包含attributesgeometrysymbol属性才能正常显示,popupTemplate为可选属性,定义了要素弹出窗口的显示内容。

常见图层类型

ArcGIS API for JavaScript有许多图层类,可用于访问和显示图层数据。所有的图层类都继承于Layer。使用哪种图层类取决于数据的格式和数据的存储位置。每个图层类还带有不同的方法。

常用图层类型介绍如下:

  • FeatureLayer,存储在ArcGIS Enterprise中的地理数据,主要用于显示、查询、过滤和编辑大量的地理要素。
  • GraphicsLayer,临时存储在内存中的地理数据,主要用于在地图上以图形或文字的形式显示少数地理要素。
  • CSVLayer/KMLLayer/GeoJSONLayer,存储在可通过网络访问的外部文件中的地理数据,主要用于将外部文件存储的地理数据显示为一个图层。
  • TileLayer/VectorTileLayer,数据以切片方案存储,以实现快速渲染,主要用于在地理背景中显示底图和其他切片数据集。
  • MapImageLayer,存储在ArcGIS Enterprise中并动态生成图片展示相应地理数据。主要用于展示由ArcGIS Server服务动态渲染的图层。
  • ImageryLayer,存储在ArcGIS Enterprise中的地理相关影像。主要用于展示卫星或其他影像数据。

FeatureLayer介绍

FeatureLayer的数据源可以是内存中由应用程序加载的数据,也可以是从ArcGIS Enterprise上托管的REST API服务中请求的数据。在ArcGIS Enterprise中发布服务数据是首选方法,尤其是在访问和显示大量地理数据时。图层在客户端和服务器上都得到了高度优化,可以快速显示,并支持一些其他功能。

服务端构建图层

FeatureLayer支持从REST API服务返回的要素集合生成图层。这是访问和显示大型数据集的最有效方式。

var layer = new FeatureLayer({
  url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0"
});

map.layers.add(layer);

客户端构建图层

通常情况下,图层数据是从ArcGIS Enterprise上托管的REST API服务加载的,但也可以直接从内存中的要素集合中创建一个FeatureLayer

示例JSON数据:

{
  "places": [
    {
      "id": 1,
      "address": "200 N Spring St, Los Angeles, CA 90012",
      "longitude": -118.24354,
      "latitude": 34.05389
    },
    {
      "id": 2,
      "address": "419 N Fairfax Ave, Los Angeles, CA 90036",
      "longitude": -118.31966,
      "latitude": 34.13375
    }
  ]
}

从示例JSON数据中创建一个FeatureLayer需要以下步骤:

  1. places数组每一项转化为一个具有属性和几何的Graphic对象。Graphic对象主要包含attributesgeometry属性,分别负责设置要素的图形和属性。

    const graphics = places.map(function (place) {
      return new Graphic({
        attributes: {
          ObjectId: place.id,
          address: place.address
        },
        geometry: {
          longitude: place.longitude,
          latitude: place.latitude
        }
      });
    });
    
  2. 创建一个FeatureLayer对象,并指定objectIdField, fields, renderer, and source属性。objectIdField用于标识该要素的唯一地段名,可理解为指定哪个字段为id字段,field属性是一个对象数组,用于指定要素含有哪些字段及值类型,renderer属性用于设置要素的渲染器,source属性指定创建FeatureLayer的图形对象的集合。

    const featureLayer = new FeatureLayer({
      source: graphics,
      renderer: {
        type: "simple",                    // autocasts as new SimpleRenderer()
        symbol: {                          // autocasts as new SimpleMarkerSymbol()
          type: "simple-marker",
          color: "#102A44",
          outline: {                       // autocasts as new SimpleLineSymbol()
            color: "#598DD8",
            width: 2
          }
        }
      },
      objectIdField: "ObjectID",           // This must be defined when creating a layer from `Graphic` objects
      fields: [
        {
          name: "ObjectID",
          alias: "ObjectID",
          type: "oid"
        },
        {
          name: "address",
          alias: "address",
          type: "string"
        }
      ]
    });
    
    map.layers.add(featureLayer);
    

GraphicsLayer介绍

Graphics 通常用于向地图临时添加文本、和具有不同类型的图形。创建graphics layer的最简单方法是将 Graphic 对象创建为一个数组,并将这个数组传递给一个新的 GraphicsLayer 对象的 graphics 属性。

可以将graphic理解为单个要素,所以需要attributesgeometrysymbol属性才能正常显示。

const pointGraphic = new Graphic({
  attributes: {
    name: "LA City Hall",
    address: "200 N Spring St, Los Angeles, CA 90012"
  },
  geometry: {
    type: "point",                     // autocasts as new Point()
    longitude: -118.24354,
    latitude: 34.05389
  },
  symbol: {
    type: "simple-marker",             // autocasts as new SimpleMarkerSymbol()
    color: [ 226, 119, 40 ],
    outline: {                         // autocasts as SimpleLineSymbol()
      color: [ 255, 255, 255 ],
      width: 2
    }
  }
});

const graphicsLayer = new GraphicsLayer({
  graphics: [ pointGraphic ]
});

map.layers.add(graphicsLayer);

Footnotes

  1. 如果每个要素都有相同的几何类型和相同的属性名,则是结构化的。反之,则是非结构化的。