docs: def query(self,
                where="1=1",
                out_fields="*",
                timeFilter=None,
                geometryFilter=None,
                returnGeometry=True,
                returnCountOnly=False,
                returnIDsOnly=False,
                returnFeatureClass=False,
                returnDistinctValues=False,
                returnExtentOnly=False,
                groupByFieldsForStatistics=None,
                statisticFilter=None,
                resultOffset=None,
                resultRecordCount=None,
                out_fc=None,
                objectIds=None,
                distance=None,
                units=None,
                maxAllowableOffset=None,
                outSR=None,
                geometryPrecision=None,
                gdbVersion=None,
                orderByFields=None,
                outStatistics=None,
                returnZ=False,
                returnM=False,
                multipatchOption=None,
                quanitizationParameters=None,
                returnCentroid=False,
                as_json=False,
                **kwargs):
          """ queries a feature service based on a sql statement
              Inputs:
                  where - the selection sql statement
                  out_fields - the attribute fields to return
                  objectIds -  The object IDs of this layer or table to be
                              queried.
                  distance - The buffer distance for the input geometries.
                            The distance unit is specified by units. For
                            example, if the distance is 100, the query
                            geometry is a point, units is set to meters, and
                            all points within 100 meters of the point are
                            returned.
                  units - The unit for calculating the buffer distance. If
                          unit is not specified, the unit is derived from the
                          geometry spatial reference. If the geometry spatial
                          reference is not specified, the unit is derived
                          from the feature service data spatial reference.
                          This parameter only applies if
                          supportsQueryWithDistance is true.
                          Values: esriSRUnit_Meter | esriSRUnit_StatuteMile |
                          esriSRUnit_Foot | esriSRUnit_Kilometer |
                          esriSRUnit_NauticalMile | esriSRUnit_USNauticalMile
                  timeFilter - a TimeFilter object where either the start time
                              or start and end time are defined to limit the
                              search results for a given time.  The values in
                              the timeFilter should be as UTC timestampes in
                              milliseconds.  No checking occurs to see if they
                              are in the right format.
                  geometryFilter - a GeometryFilter object to parse down a given
                                 query by another spatial dataset.
                  maxAllowableOffset - This option can be used to specify the
                                       maxAllowableOffset to be used for
                                       generalizing geometries returned by
                                       the query operation.
                                       The maxAllowableOffset is in the units
                                       of outSR. If outSR is not specified,
                                       maxAllowableOffset is assumed to be in
                                       the unit of the spatial reference of
                                       the map.
                  outSR - The spatial reference of the returned geometry.
                  geometryPrecision -  This option can be used to specify the
                                       number of decimal places in the
                                       response geometries returned by the
                                       Query operation.
                  gdbVersion - Geodatabase version to query
                  returnDistinctValues -  If true, it returns distinct values
                                          based on the fields specified in
                                          outFields. This parameter applies
                                          only if the
                                          supportsAdvancedQueries property of
                                          the layer is true.
                  returnIDsOnly -  If true, the response only includes an
                                   array of object IDs. Otherwise, the
                                   response is a feature set. The default is
                                   false.
                  returnCountOnly -  If true, the response only includes the
                                     count (number of features/records) that
                                     would be returned by a query. Otherwise,
                                     the response is a feature set. The
                                     default is false. This option supersedes
                                     the returnIdsOnly parameter. If
                                     returnCountOnly = true, the response will
                                     return both the count and the extent.
                  returnExtentOnly -  If true, the response only includes the
                                      extent of the features that would be
                                      returned by the query. If
                                      returnCountOnly=true, the response will
                                      return both the count and the extent.
                                      The default is false. This parameter
                                      applies only if the
                                      supportsReturningQueryExtent property
                                      of the layer is true.
                  orderByFields - One or more field names on which the
                                  features/records need to be ordered. Use
                                  ASC or DESC for ascending or descending,
                                  respectively, following every field to
                                  control the ordering.
                  groupByFieldsForStatistics - One or more field names on
                                               which the values need to be
                                               grouped for calculating the
                                               statistics.
                  outStatistics - The definitions for one or more field-based
                                  statistics to be calculated.
                  returnZ -  If true, Z values are included in the results if
                             the features have Z values. Otherwise, Z values
                             are not returned. The default is false.
                  returnM - If true, M values are included in the results if
                            the features have M values. Otherwise, M values
                            are not returned. The default is false.
                  multipatchOption - This option dictates how the geometry of
                                     a multipatch feature will be returned.
                  resultOffset -  This option can be used for fetching query
                                  results by skipping the specified number of
                                  records and starting from the next record
                                  (that is, resultOffset + 1th).
                  resultRecordCount - This option can be used for fetching
                                      query results up to the
                                      resultRecordCount specified. When
                                      resultOffset is specified but this
                                      parameter is not, the map service
                                      defaults it to maxRecordCount. The
                                      maximum value for this parameter is the
                                      value of the layer's maxRecordCount
                                      property.
                  quanitizationParameters - Used to project the geometry onto
                                            a virtual grid, likely
                                            representing pixels on the screen.
                  returnCentroid - Used to return the geometry centroid
                                   associated with each feature returned. If
                                   true, the result includes the geometry
                                   centroid. The default is false.
                  as_json - If true, the query will return as the raw JSON.
                            The default is False.
                  returnFeatureClass - If true and arcpy is installed, the
                                       script will attempt to save the result
                                       of the query to a feature class.
                  out_fc - only valid if returnFeatureClass is set to True.
                           Output location of query. If out_fc is set to None,
                           then the feature class will be saved to the scratch
                           File Geodatabase with a random name.
                 kwargs - optional parameters that can be passed to the Query
                   function.  This will allow users to pass additional
                   parameters not explicitly implemented on the function. A
                   complete list of functions available is documented on the
                   Query REST API.
              Output:
                 A list of Feature Objects (default) or a path to the output featureclass if
                 returnFeatureClass is set to True.
           """
          url = self._url + "/query"
          params = {"f" : "json"}
          params['where'] = where
          params['outFields'] = out_fields
          params['returnGeometry'] = returnGeometry
          params['returnDistinctValues'] = returnDistinctValues
          params['returnCentroid'] = returnCentroid
          params['returnCountOnly'] = returnCountOnly
          params['returnExtentOnly'] = returnExtentOnly
          params['returnIdsOnly'] = returnIDsOnly
          params['returnZ'] = returnZ
          params['returnM'] = returnM
          if resultRecordCount:
              params['resultRecordCount'] = resultRecordCount
          if resultOffset:
              params['resultOffset'] = resultOffset
          if quanitizationParameters:
              params['quanitizationParameters'] = quanitizationParameters
          if multipatchOption:
              params['multipatchOption'] = multipatchOption
          if orderByFields:
              params['orderByFields'] = orderByFields
          if groupByFieldsForStatistics:
              params['groupByFieldsForStatistics'] = groupByFieldsForStatistics
          if statisticFilter and \
             isinstance(statisticFilter, filters.StatisticFilter):
              params['outStatistics'] = statisticFilter.filter
          if outStatistics:
              params['outStatistics'] = outStatistics
          if outSR:
              params['outSR'] = outSR
          if maxAllowableOffset:
              params['maxAllowableOffset'] = maxAllowableOffset
          if gdbVersion:
              params['gdbVersion'] = gdbVersion
          if geometryPrecision:
              params['geometryPrecision'] = geometryPrecision
          if objectIds:
              params['objectIds'] = objectIds
          if distance:
              params['distance'] = distance
          if units:
              params['units'] = units
          if timeFilter and \
             isinstance(timeFilter, TimeFilter):
              for k,v in timeFilter.filter.items():
                  params[k] = v
          elif isinstance(timeFilter, dict):
              for k,v in timeFilter.items():
                  params[k] = v
          if geometryFilter and \
             isinstance(geometryFilter, GeometryFilter):
              for k,v in geometryFilter.filter.items():
                  params[k] = v
          elif geometryFilter and \
               isinstance(geometryFilter, dict):
              for k,v in geometryFilter.items():
                  params[k] = v
          if len(kwargs) > 0:
              for k,v in kwargs.items():
                  params[k] = v
                  del k,v
  
          result = self._post(url=url,
                              securityHandler=self._securityHandler,
                              param_dict=params,
                              proxy_url=self._proxy_url,
                              proxy_port=self._proxy_port)
          if 'error' in result:
              raise ValueError(result)
          if as_json or \
             returnCountOnly == True or \
             returnIDsOnly == True:
              return result
          elif returnFeatureClass and\
               not returnCountOnly and \
               not returnIDsOnly:
              uid = create_uid()
              if out_fc is None:
                  out_fc = os.path.join(scratchGDB(),
                                        "a{fid}".format(fid=uid))
              text = json.dumps(result)
              temp = scratchFolder() + os.sep + uid + ".json"
              with open(temp, 'wb') as writer:
                  if six.PY3:
                      text = bytes(text, 'UTF-8')
                  writer.write(text)
                  writer.flush()
                  del writer
              fc = json_to_featureclass(json_file=temp,
                                        out_fc=out_fc)
              os.remove(temp)
              return fc
          else:
              return FeatureSet.fromJSON(jsonValue=json.dumps(result))
          return result