All files / FeatureServer/lib/query index.js

100% Statements 50/50
96.07% Branches 49/51
100% Functions 7/7
100% Lines 50/50

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 1344x 4x 4x 4x 4x 4x 4x 4x               80x   80x   80x 16x     64x   64x 60x     64x 7x           57x               80x 8x     72x 2x     70x 4x     66x 2x     64x                 16x   16x 8x     8x   8x 6x     8x 4x     8x       64x                 57x   57x 8x             49x 3x     46x 8x     38x       3x   3x 5x     3x           4x  
const _ = require('lodash')
const { filterAndTransform } = require('./filter-and-transform')
const { logWarnings } = require('./log-warnings')
const { renderFeaturesResponse } = require('./render-features')
const { renderStatisticsResponse } = require('./render-statistics')
const { renderPrecalculatedStatisticsResponse } = require('./render-precalculated-statistics')
const { renderCountAndExtentResponse } = require('./render-count-and-extent')
const { getGeometryTypeFromGeojson } = require('../helpers')
 
function query (json, requestParams = {}) {
  const {
    features,
    filtersApplied: {
      all: skipFiltering
    } = {}
  } = json
 
  const { f: requestedFormat } = requestParams
 
  if (shouldRenderPrecalculatedData(json, requestParams)) {
    return renderPrecalculatedData(json, requestParams)
  }
 
  const data = (skipFiltering || !features) ? json : filterAndTransform(json, requestParams)
 
  if (shouldLogWarnings()) {
    logWarnings(data, requestParams.f)
  }
 
  if (requestedFormat === 'geojson') {
    return {
      type: 'FeatureCollection',
      features: data.features
    }
  }
 
  return renderGeoservicesResponse(data, {
    ...requestParams,
    attributeSample: _.get(json, 'features[0].properties'),
    geometryType: getGeometryTypeFromGeojson(json)
  })
}
 
function shouldRenderPrecalculatedData ({ statistics, count, extent }, { returnCountOnly, returnExtentOnly }) {
  if (statistics) {
    return true
  }
 
  if (returnCountOnly === true && count !== undefined && returnExtentOnly === true && extent) {
    return true
  }
 
  if (returnCountOnly === true && count !== undefined && !returnExtentOnly) {
    return true
  }
 
  if (returnExtentOnly === true && extent && !returnCountOnly) {
    return true
  }
 
  return false
}
 
function renderPrecalculatedData (data, {
  returnCountOnly,
  returnExtentOnly,
  outStatistics,
  groupByFieldsForStatistics
}) {
  const { statistics, count, extent } = data
 
  if (statistics) {
    return renderPrecalculatedStatisticsResponse(data, { outStatistics, groupByFieldsForStatistics })
  }
 
  const retVal = {}
 
  if (returnCountOnly) {
    retVal.count = count
  }
 
  if (returnExtentOnly) {
    retVal.extent = extent
  }
 
  return retVal
}
 
function shouldLogWarnings () {
  return process.env.NODE_ENV !== 'production' && process.env.KOOP_WARNINGS !== 'suppress'
}
 
function renderGeoservicesResponse (data, params = {}) {
  const {
    returnCountOnly,
    returnExtentOnly,
    returnIdsOnly,
    outSR
  } = params
 
  if (returnCountOnly || returnExtentOnly) {
    return renderCountAndExtentResponse(data, {
      returnCountOnly,
      returnExtentOnly,
      outSR
    })
  }
 
  if (returnIdsOnly) {
    return renderIdsOnlyResponse(data)
  }
 
  if (data.statistics) {
    return renderStatisticsResponse(data, params)
  }
 
  return renderFeaturesResponse(data, params)
}
 
function renderIdsOnlyResponse ({ features = [], metadata = {} }) {
  const objectIdFieldName = metadata.idField || 'OBJECTID'
 
  const objectIds = features.map(({ attributes }) => {
    return attributes[objectIdFieldName]
  })
 
  return {
    objectIdFieldName,
    objectIds
  }
}
 
module.exports = query