天天看點

geoServerWFS 服務實作空間查詢 - 使用 ES6 Promise.all 處理異步請求

前言

日常積累,歡迎指正

Promise.all的使用場景

某方法需要在多個異步操作完成後執行就可以使用

Promise.all

來優雅的解決,對應的還有一個

Promise.race

,關于它的使用和使用場景暫不讨論

執行個體

我的執行個體場景

在實作 GIS 功能中的空間查詢時,我的查詢對象是兩個服務,并且對這兩個服務的查詢操作都是異步的。任意一個服務查詢結果存在就代表我的空間查詢操作是成功的,查詢操作成功後我需要使用 InfoWindow 來展示我剛才查詢到的結果。這就意味着我需要等待兩個異步全部完成後才能做後續操作。

我的代碼執行個體

this.調用的變量了解成全局變量即可

// 
this.map.on('click', (evt) => {
  this.evt = evt
  const circle = new Circle(evt.mapPoint)
  this.queryExtent = circle.getExtent()
  if (this.isQuery) {
    this.queryservices(layerTreeData, this.queryExtent) // 方法調用
  }
})


queryservices = (data, queryExtent) => {
  if (data && data.length > 0) {
    const qureyLayers = data.filter(item => item.isQuery) // 擷取所有可查詢資料源

    const functions: any = []
    for (const queryLayer of qureyLayers) {
      const f: any = this.queryservice(queryLayer.owsurl, queryLayer.layers, queryExtent)
      functions.push(f)
    }
    Promise.all(functions).then((res) => {
      const features: any = res.filter(item => item)
      if (features.length > 0) {
        const arcgisJson = geojsonToArcGIS({
          'type': features[0].geometry.type,
          'coordinates': features[0].geometry.coordinates
        })
        this.createResult(arcgisJson, features[0].properties, this.evt)
      }
    })

  }
}

queryservice = (owcUrl, typeName, queryExtent) => {
  const params = {
    'service': 'WFS',
    'version': '1.0.0',
    'request': 'GetFeature',
    'typeName': `${typeName}`,
    'maxFeatures': 50,
    'outputFormat': 'application/json',
    'CQL_FILTER': `BBOX(the_geom, ${queryExtent.xmin}, ${queryExtent.ymin}, ${queryExtent.xmax}, ${queryExtent.ymax})`
  }
  return new Promise((resolve, reject) => {
    $.ajax({
      url: `${arcgisProxy}?${owcUrl}`,
      type: 'post',
      data: params,
      cache: false,
      dataType: 'json',
      success: (data) => {
        resolve(...data.features)
      },
      error: (err) => {
        reject(err)
      }
    })
  })
}

createResult = (arcgisJson, attr, evt) => {
  esriLoader.loadModules(['esri/InfoTemplate', 'esri/graphic', 'esri/geometry/Polyline',
    'esri/symbols/CartographicLineSymbol',
    'esri/Color',
  ]).then(([InfoTemplate, Graphic, Polyline,
    CartographicLineSymbol,
    Color

  ]) => {
    const line = new CartographicLineSymbol(
      CartographicLineSymbol.STYLE_SOLID,
      new Color([255, 0, 0]), 2,
      CartographicLineSymbol.CAP_ROUND,
      CartographicLineSymbol.JOIN_MITER, 2
    )
    const argisGeometry = new Polyline(arcgisJson)
    const infoTemplate = new InfoTemplate('管道屬性',
      `<table class = 'pipelineAttrTable'>
				<tbody>
					<tr><th >管道名稱</th><td >${attr.Name} </td></tr>
					<tr><th >管道編碼</th><td >${attr.code} </td></tr>
				</tbody>
			</table>`)
    this.map.graphics.clear()
    const graphic = new Graphic(argisGeometry, line)
    this.map.graphics.add(graphic)
    this.map.infoWindow.setContent(infoTemplate.content)
    this.map.infoWindow.setTitle(infoTemplate.title)
    this.map.infoWindow.show(evt.screenPoint, this.map.getInfoWindowAnchor(evt.screenPoint))
  })
}

// queryservices()方法的第一個參數資料結構類似于:
layerTreeData = [
  {
    title: 'xxx',
    pkey: 'xx',
    key: 'xx',
    id: 'xx',
    checked: true,
    isBaseMap: false,
    type: 'WMS',
    url: 'xx',
    subLayerid: '',
    subgeotype: '',
    layers: [],
    imageFormat: 'png',
    isQuery: false
  },
  {
    title: '主管線',
    pkey: '1',
    key: '2',
    id: 'WMS-zhu',
    checked: true,
    isBaseMap: false,
    type: 'WMS',
    url: 'http://xxx.xxx.xxx.xxx:xxxx/geoserver/xx/wms',
    owsurl: 'http://xxx.xxx.xxx.xxx:xxxx/geoserver/xx/ows',
    subLayerid: '',
    subgeotype: '',
    layers: ['xxx:xxx'],
    imageFormat: 'png',
    isQuery: true
  },
  {
    title: 'xxx',
    pkey: '1',
    key: '3',
    id: 'WMS-xxx',
    checked: true,
    isBaseMap: false,
    type: 'WMS',
    url: 'http://xxx.xxx.xxx.xxx:xxxx/geoserver/xx/wms',
    owsurl: 'http://xxx.xxx.xxx.xxx:xxxx/geoserver/xx/ows',
    subLayerid: '',
    subgeotype: '',
    layers: ['xxx:xxx'],
    imageFormat: 'png',
    isQuery: true
  },
  {
    title: 'xxxx',
    pkey: '1',
    key: '4',
    id: 'WMS-xxxx',
    checked: true,
    isBaseMap: false,
    type: 'WMS',
    url: 'http://xxx.xxx.xxx.xxx:xxxx/geoserver/xx/wms',
    subLayerid: '',
    subgeotype: '',
    layers: ['xxxx:xxxx'],
    imageFormat: 'png',
    isQuery: false
  }
]