- URL:
- https://<root>/services/<serviceName>/FeatureServer/<layerId>/queryBins
- Methods:
GET
- Version Introduced:
- 11.3
Description
The query
operation returns an array of results divided into bins based on a numeric or date field. The response includes statistical aggregations for each bin, such as a count
or avg
.
The parameters property define the bins, the aggregate information returned, and the included features. The out
parameter defines the information each bin will provide. Included features can be specified by providing a WHERE condition, and a spatial filter, similar to a query operation.
Bins are defined using the bin
parameter. The contents of the bin
parameter provide flexibility for defining bin boundaries. The bin
parameter's parameters
property defines the way each bin is calculated. The properties can be defined with the amount of bins present, the range of the bins, the bin boundaries or defining bins with the help of dates (e.g. fixed
, auto
, fixed
, or date
).
A bin can either be based on a date or on a numeric value.
Dates
Defining bins providing calendar-awareness with a fixed number of seconds, minutes, hours, days, weeks, months, quarters, or years.
Calendar-aware intervals understand that daylight savings changes the length of specific days, months have different amounts of days, and leap seconds can be tacked onto a particular year.
The starting position of the bin is the earliest moment in the specified unit. For example, each year begins at midnight of January 1. An offset inside the bin parameter can provide an offset to the starting position of the bin. This can contain a positive or negative integer value.
The offset is optional.
When dealing with dates, the unit
property defines the time width of each bin, such as one year, quarter, month, day, or hour. The offset
property defines an offset within that time unit. For example, if your bin unit is day
, and you want bin boundaries to go from noon to noon on the next day, the offset would be 12 hours
Intervals
- Declaring the interval. The total range will be divided into equal bins of the declared size. The number of bins will be variable depending on the whole range and the defined interval.
- Defining the number of bins. The interval is calculated automatically by the total range divided by the number of bins.
- Defining fixed boundaries of each bin. This allows bins of different sizes.
The interval operations can be used with numeric and date fields. Note that dates are treated as numbers in this case.
When using query
on a date field use Unix format for esri
fields and a standardized iso-string for esri
(2023-12-15T12:00:00.000).
Request parameters
Parameter | Details |
---|---|
(Required) | A JSON parameter that describes the characteristics of the bins, such as the size of the bin and its starting position. The size of each bin is either determined by a parameter or calculated dynamically. A bin can either be based on a date or on a numeric value. For more information and examples for supported bin types, see the Binning section below. Syntax
Example
|
| Results can be returned in ascending or descending order. The default is ascending ( Values: |
| Defines the timezone for the calculation of bins and the output of dates. Example
|
| The definitions for one or more field-based statistics to be calculated. Defaults to a histogram ( The current supported spatial aggregations are Syntax
Example
|
| A WHERE clause for the query filter. SQL-92 WHERE clause syntax on the fields in the layer is supported for most data sources. Some data sources have restrictions on what is supported. Hosted feature services in ArcGIS Enterprise running on a spatiotemporal data source only support a subset of SQL-92. For example, spatiotemporal-based feature services support the
For information on how to format time and date information, see the Date-time queries section. Example
|
| The geometry to apply as the spatial filter. The structure of the geometry is the same as the structure of the JSON geometry objects returned by the REST API. In addition to the JSON structures, you can specify the geometry of envelopes and points with a simple comma-separated syntax. Syntax
Example
|
| The type of geometry specified by the Values: |
| 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. The geodesic buffer is created based on the datum of the output spatial reference if it exists. If there is no output spatial reference, the input geometry spatial reference is used. Otherwise, the native layer spatial reference is used to generate the geometry buffer used in the query. This parameter only applies if Syntax
Example
|
| The unit for calculating the buffer distance. If Values: |
| The spatial relationship to be applied to the input geometry while performing the query. The supported spatial relationships
include intersects, contains, envelop intersects, within, and so on. The default spatial relationship is intersects
( Values: |
| The spatial reference used for input and output geometry if |
| The spatial reference of the input geometry. The spatial reference can be specified as either a well-known ID or as a spatial reference JSON object. If the |
| The spatial reference of the returned geometry. The spatial reference can be specified as either a well-known ID or as a spatial reference JSON object. If |
| A JSON object used to project the geometry onto a virtual grid, likely representing pixels on the screen. The properties of the JSON object include Example
|
| This parameter applies a datum transformation while projecting geometries in the results when outSR is different than the layer's spatial reference. When specifying transformations, you need to think about which datum transformation best projects the layer (not the feature service) to the outSR and sourceSpatialReference property in the layer resource report. For a list of valid datum transformation ID values and well-known text strings, see Using spatial references. For more information on datum transformations, see the transformation parameter in the Project operation. synatx
Example
|
| This parameter changes the default name of the lower Example
|
| This parameter changes the default name of the upper Example
|
| Specifies whether the operation will run synchronously (false) or asynchronously (true). Values: |
| The response format. The default format is Values: |
Support parameters
The support parameters defined in query
define which query
operation is allowed in the dialect of the feature layer. The following support parameters are defined:
supports
Date Bin supports
Fixed Interval Bin supports
Auto Interval Bin supports
Fixed Boundaries Bin supported
(provides a list of the supported statistics operations for the dialect)Statistic Types
Binning
There are four different binning operations that all work slightly differently, especially when it comes to boundaries. It is important to understand what each operations goal is to understand how the binning works and how the boundaries are defined.
autoIntervalBin
For Auto Interval the focus lies in the number of bins. The size of the bins will be calculated using the range of the dataset and the number of bins. The last item of the range will be added to the last bin.
For example, in a dataset having items 10, 34, 56 and 88, and a desired number of bins of 3, this would be the distribution:
[10 – 36]
: 10, 34 [36 – 62]
: 56 [62 – 88]
: 88
{
"type": "autoIntervalBin",
"onField": < numericField | dateField >,
"parameters": {
"numberOfBins": <integer>,
"start": < numeric | date >,
"end": < numeric | date >
}
}
{
"type": "autoIntervalBin",
"onField": "the_field",
"parameters": {
"numberOfBins": 10,
"start": 0,
"end": 12500.5
}
}
Output
The output of the bins always has a lower boundary and an upper boundary. The lower boundary is inclusive and the upper boundary is exclusive. The only exception to this is the upper boundary of the last bin, which is also inclusive.
In the following example items 0, 10, 40 and 99 would be in bin 1. Item 100 would be in bin 2. But item 300 would be in bin 3:
0 (inclusive) – 100 (exclusive)
100(inclusive) – 200 (exclusive)
200 (inclusive) – 300 (inclusive)
While the output works the same for each binning operation, the way the bins are calculated differs.
Date-time queries
Date and time format
The INTERVAL
syntax can be used in place of the date-time queries and is standardized across all map and feature services. The INTERVAL syntax can be used to specify either the current date or timestamp in the query:
//Date
<DateField> >= CURRENT_DATE -+ INTERVAL '<IntervalValue>' <TimeStampFormat>
//Timestamp
<DateField> >= CURRENT_TIMESTAMP -+ INTERVAL '<IntervalValue>' <TimeStampFormat>
For the syntax demonstrated above, you can interchange the CURRENT
and CURRENT
values. Both can be used with +
or -
of INTERVAL
values.
The examples below outline the different ways in which the INTERVAL syntax can be modified for the purposes of your query:
//'DD' Day
<DateField> >= CURRENT_TIMESTAMP -+ INTERVAL 'DD' DAY
//'HH' Hour
<DateField> >= CURRENT_TIMESTAMP -+ INTERVAL 'HH' HOUR
//'MI' Minute
<DateField> >= CURRENT_TIMESTAMP -+ INTERVAL 'MI' MINUTE
//'SS(.FFF)' Second
<DateField> >= CURRENT_TIMESTAMP -+ INTERVAL 'SS(.FFF)' SECOND
//'DD HH' DAY TO HOUR
<DateField> >= CURRENT_TIMESTAMP -+ INTERVAL 'DD HH' DAY TO HOUR
//'DD HH:MI' DAY TO MINUTE
<DateField> >= CURRENT_TIMESTAMP -+ INTERVAL 'DD HH:MI' DTY TO MINUTE
//'DD HH:MI:SS(.FFF)' DAY TO SECOND
<DateField> >= CURRENT_TIMESTAMP -+ INTERVAL 'DD HH:MI:SS(.FFF)' DAY TO SECOND
//'HH:MI' HOUR TO MINUTE
<DateField> >= CURRENT_TIMESTAMP -+ INTERVAL 'HH:MI' HOUR TO MINUTE
//'HH:SS(.FFF)' HOUR TO SECOND
<DateField> >= CURRENT_TIMESTAMP -+ INTERVAL 'HH:SS(.FFF)' HOUR TO SECOND
//'MI:SS(.FFF)' MINUTE TO SECOND
<DateField> >= CURRENT_TIMESTAMP -+ INTERVAL 'MI:SS(.FFF)' MINUTE TO SECOND
To demonstrate the INTERVAL
format, the example below uses the INTERVAL syntax to query data gathered over the 3 days, 5 hours, 32 minutes, and 28 seconds:
DateField >= CURRENT_TIMESTAMP - INTERVAL '3 05:32:28' DAY TO SECOND
Percentile statistic type
The percentile statistic
is supported if the supports
layer property (in advanced
) is true
. The percentile indicates the value below or above which a given percentage of values in a group of data values falls. For example, the ninetieth percentile (value 0.9) is the value below which 90 percent of the data values may be found. For percentile statistics, there are two statistic
, PERCENTILE
(discrete) and PERCENTILE
(continuous). Discrete returns a data value from within that dataset while continuous is an interpolated value.
The order
statistic parameter can also be used to calculate the percentile. For example, in a set of 10 values from 1 to 10, the percentile value
for 0.9 with order
set as ascending (ASC
) is 9, while the percentile for value
0.9 with order
set as descending (DESC
) is 2. The default is ASC
.
Syntax
[
{
"statisticType": "<PERCENTILE_CONT | PERCENTILE_DISC>",
"statisticParameters": {
"value": percentile_value,
"orderBy": "<ASC | DESC>"
},
"onStatisticField": "Field1",
"outStatisticFieldName": "Out_Field_Name1"
},
{
"statisticType": "<PERCENTILE_CONT | PERCENTILE_DISC>",
"statisticParameters": {
"value": percentile_value,
"orderBy": "<ASC | DESC>"
},
"onStatisticField": "Field2",
"outStatisticFieldName": "Out_Field_Name2"
}
]
Example
[
{
"statisticType": "PERCENTILE_CONT",
"statisticParameters": {
"value": 0.9
},
"onStatisticField": "NEAR_DIST",
"outStatisticFieldName": "pop90_cont"
},
{
"statisticType": "PERCENTILE_DISC",
"statisticParameters": {
"value": 0.9,
"orderBy": "DESC"
},
"onStatisticField": "population",
"outStatisticFieldName": "pop90_desc"
}
]
Quantization parameters JSON properties
Property | Description |
---|---|
| An extent defining the quantization grid bounds. Its spatialReference matches the input geometry spatial reference if one is specified for the query. Otherwise, the extent will be in the layer's spatial reference. |
| Geometry coordinates are optimized for viewing and displaying of data. The view value specifies that geometry coordinates should be optimized for viewing and displaying of data. The edit value specifies that full-resolution geometries should be returned, which can support lossless editing. Value: |
| Integer coordinates will be returned relative to the origin position defined by this property value. The default value is Values: |
| The tolerance is the size of one pixel in the outSpatialReference units. This number is used to convert the coordinates to integers by building a grid with resolution matching the tolerance. Each coordinate is then snapped to one pixel on the grid. Consecutive coordinates snapped to the same pixel are removed to reduce the overall response size. The units of If |
Example usages
The following examples demonstrate different ways to modify the features returned by the query
operation.
Example one
Suppose you want to find out what the average income is for each generation in the US. You'd like to define your bins as the different age groups (2012-1997-1981-1965-1955-1946-1928-1922)
Since the bins do not all have the same size we will use the bin type boundaries. Since you're looking at year of birth, you'll use a field named year
as the on
.
Bin={
"type": "fixedBoundariesBin",
"onField": "yearOfBirth",
"parameters": {
"boundaries": [1922,1928,1946,1955,1965,1981,1997,2012]
}
}
You can define what information is returned using the out
parameters. For analysis, you're interested in seeing the counts and averages of the data. This will return the amount of people in the generation and the average income:
outStatistics = [
{
"statisticType": "count",
"onStatisticField": "yearOfBirth",
"outStatisticFieldName": "sum_of_people"
},
{
"statisticType": "avg",
"onStatisticField": "yearlyIncome",
"outStatisticFieldName": "avg_income"
}
]
Now you have the basics of your desired result. You can further refine results by providing filters on the data, such as filtering certain products using a where filter, or using spatial filters to look at regional data.
Example URL
The following is a sample GET request for the query
operation, demonstrating the workflow discussed above:
https://machine.domain.com/webadaptor/rest/services/Hosted/Sales21/FeatureServer/0/queryBins?bin={"type":"fixedBoundariesBin","onField":"yearOfBirth","parameters":{"boundaries":[1922,1928,1946,1955,1965,1981,1997,2012]}}&outStatistics=[{"statisticType":"count","onStatisticField":"yearOfBirth","outStatisticFieldName":"sum_of_people"},{"statisticType":"avg","onStatisticField":"yearlyIncome","outStatisticFieldName":"avg_income"}]&f=pjson
JSON Response example
The following JSON response is a sample of the information returned from the request:
{
"features": [
{
"attributes": {
"lowerBoundary": 1922,
"upperBoundary": 1928,
"sum_of_people": 54,
"avg_income": 0
}
},
{
"attributes": {
"lowerBoundary": 1928,
"upperBoundary": 1946,
"sum_of_people": 664000,
"avg_income": 0
}
},
{
"attributes": {
"lowerBoundary": 1946,
"upperBoundary": 1955,
"sum_of_people": 18226800,
"avg_income": 41969
}
},
{
"attributes": {
"lowerBoundary": 1955,
"upperBoundary": 1965,
"sum_of_people": 68325600,
"avg_income": 71183
}
},
{
"attributes": {
"lowerBoundary": 1965,
"upperBoundary": 1981,
"sum_of_people": 65105200,
"avg_income": 102512
}
},
{
"attributes": {
"lowerBoundary": 1981,
"upperBoundary": 1997,
"sum_of_people": 71944400,
"avg_income": 84563
}
},
{
"attributes": {
"lowerBoundary": 1997,
"upperBoundary": 2012,
"sum_of_people": 69321600,
"avg_income": 42335
}
}
],
"exceededTransferLimit": false,
"fields": [
{
"defaultValue": null,
"name": "lowerBoundary",
"length": 131089,
"alias": "lowerBoundary",
"type": "esriFieldTypeInteger"
},
{
"defaultValue": null,
"name": "upperBoundary",
"length": 131089,
"alias": "upperBoundary",
"type": "esriFieldTypeInteger"
},
{
"defaultValue": null,
"name": "sum_of_people",
"length": 20,
"alias": "sum_of_people",
"type": "esriFieldTypeBigInteger"
},
{
"defaultValue": null,
"name": "avg_income",
"length": 131089,
"alias": "avg_income",
"type": "esriFieldTypeDouble"
}
]
}
Example two
You want to create a histogram graph again for income date but this time you want to showcase how many people earn how much in steps of $5000. That means the on
will be annual
. We will choose a bin with an interval of 5000, starting at 0 and capping it at 200,000. Since histogram is the default, we don’t need the out
parameter.
Bin={
"type": "fixedIntervalBin",
"onField": "annual_income",
"parameters": {
"interval": 50000,
"start": 0,
"end": 200000
}
}
Example URL
The following is a sample GET request for the query
operation, demonstrating the workflow discussed above:
https://machine.domain.com/webadaptor/rest/services/Hosted/AZTempRec/0/queryBins?bin={"type":"fixedIntervalBin","onField":"annual_income","parameters":{"interval":50000,"start":0,"end":200000}}&f=pjson
JSON Response example
{
"features": [
{
"attributes": {
"lowerBoundary": 0,
"upperBoundary": 50000,
"frequency": 105475
}
},
{
"attributes ": {
"lowerBoundary": 50000,
"upperBoundary": 100000,
"frequency": 2849115
}
},
{
"attributes": {
"lowerBoundary":100000,
"upperBoundary": 150000,
"frequency": 1568721
}
},
{
"attributes": {
"lowerBoundary": 150000,
"upperBoundary": 200000,
"frequency": 1053475
}
}
],
"exceededTransferLimit": false,
"fields": [
{
"defaultValue": null,
"name": "boundary",
"length": 131089,
"alias": "boundary",
"type": "esriFieldTypeDouble"
},
{
"defaultValue": null,
"name": "frequency",
"length": 20,
"alias": "frequency",
"type": "esriFieldTypeBigInteger"
}
]
}
Example three
Suppose you want to do a daily breakdown of sales for the month of January 2021. You'd like to define your days as starting at 8:00am.
You'd start by defining the bins. You want a breakdown of single days, so you'll use the unit type day. By default, daily bins start at 00:00:00 UTC. To get the desired bins, you want to shift the time forward 8 hours by providing an offset. This gives you the bin definition. Since you're looking at sales, you'll use the date
field as the on
.
Bin={
"type": "dateBin",
"onField": "dateSold",
"parameters": {
"unit": "day",
"start": 1609516800000,
"end": 1612195199999,
"offset": {
"number": 8,
"unit": "hour"
}
}
}
You're not sure that the data stretches across every day of the month. The last two days fall on a weekend, and the stores are only open on weekdays. If you only have data to the January 29, you could miss the last two days from appearing in the result, but you would instead like those to show up as days with zero sales. To ensure that all days in January are displayed, as well as restricting the included features to only January (and to 7:59 am on February 1), you can define a time extent on the data from January 1 at 8:00 a.m. to February 1 at 7:59:59:9999 a.m.
Note that if you wish to restrict the days to January, but to not include the last two days, you can use the where parameter.
You can define what information is returned using the statistics parameters. For analysis, you're interested in seeing the counts and averages of the data. This will return the count of items and the average sales price:
outStatistics=[
{
"statisticType": "count",
"onStatisticField": "objectid",
"outStatisticFieldName": "item_sold_count"
},
{
"statisticType": "avg",
"onStatisticField": "price",
"outStatisticFieldName": "avg_daily_revenue"
}
]
Now you have the basics of your desired result. You can further refine results by providing filters on the data, such as filtering certain products using a where filter, or using spatial filters to look at regional data.
Example URL
The following is a sample GET request for the query
operation, that demonstrates the workflow discussed above:
https://machine.domain.com/webadaptor/rest/services/Hosted/Sales21/FeatureServer/0/queryBins?bin={"type":"dateBin","onField":"dateSold","parameters":{"unit":"day","offset":{"number":8,"unit":"hour"},"start":1609516800000,"end":1612195199999}}& outStatistics=[{"statisticType": "count","onStatisticField": "objectid","outStatisticFieldName": "item_sold_count"},{"statisticType": "avg","onStatisticField": "price","outStatisticFieldName": "avg_daily_revenue "}]&where=&binOrder=&geometry=&inSR=&outSR=&spatialRel=esriSpatialRelIntersects&returnCentroid=false&quantizationParameters=&resultOffset=&resultRecordCount=&returnExceededLimitFeatures=false&f=pjson
JSON Response example
The following JSON response is a sample of the information returned from the request:
{
"features": [
{
"attributes": {
"lowerBoundary": 1609516800000,
"upperBoundary": 1609603200000,
"avg_daily_revenue": 300.40,
"item_sold_count": 79
}
},
{
"attributes": {
"lowerBoundary": 1609603200000,
"upperBoundary": 1612195199999,
"avg_daily_revenue": null,
"item_sold_count": 0
}
}
],
"fields": [
{
"name": "lowerBoundary",
"type": " esriFieldTypeDate"
},
{
"name": "upperBoundary",
"type": "esriFieldTypeDate"
},
{
"name": "item_sold_count",
"alias": "item_sold_count",
"type": "esriFieldTypeInteger"
},
{
"name": "avg_daily_revenue",
"alias": "avg_daily_revenue",
"type": "esriFieldTypeDouble"
}
]
}
Example four
You want to create yearly bins for Arizona temperature data, beginning from 1/1/1976 and ending on the final date contained in the record data, starting at 5:00 a.m. You want to include only data that contains a temperature reading for each year together with the centroid. To achieve this, the following information is included in your request:
bin={
"type": "dateBin",
"onField": "recorded_date",
"parameters": {
"unit": "year",
"offset": {
"number": 5,
"unit": "hour"
},
"start": 189331200000
}
}
outTimeReference ={
"timeZone": "Mountain Standard Time",
"respectsDaylightSaving": true
}
outStatistics=[
{
"statisticType": "count",
"onStatisticField": "temperature",
"outStatisticFieldName": "results_count"
},
{
"statisticType": "avg",
"onStatisticField": "temperature",
"outStatisticFieldName": "temperature_avg"
}
]
where=temperature is not null
returnCentroid=true
Example URL
The following is a sample request URL for the workflow discussed above:
https://machine.domain.com/webadaptor/rest/services/Hosted/AZTempRec/0/ queryBins?bin={"type":"dateBin","onField":"recorded_date","parameters":{"unit":"year","offset":{"number":5,"unit":"hour"},"start":189331200000}}& outStatistics=[{"statisticType": "count","onStatisticField": "temperature","outStatisticFieldName": "results_count"},{"statisticType": "avg","onStatisticField": "temperature","outStatisticFieldName": "temperature_avg"}]&outTimeReference={"timeZone":"Mountain Standard Time","respectsDaylightSaving":"true"}&where=temperature is not null &binOrder=&geometry=&inSR=&outSR=&spatialRel=esriSpatialRelIntersects &returnCentroid=true &quantizationParameters=&resultOffset=&resultRecordCount=&returnExceededLimitFeatures=false&f=pjson
JSON Response example
{
"features": [
{
"centroid": {
"x": -84.02204922365141,
"y": 35.93228062956047
},
"attributes": {
"lowerBoundary": "1976-01-01T05:00:00-07",
"upperBoundary": "1977-01-01T05:00:00-07",
"temperature_avg": 59.82,
"results_count": 60964
}
},
{
"centroid": {
"x": -84.32106073325814,
"y": 35.930795102124708
},
"attributes": {
"lowerBoundary": "1977-01-01T05:00:00-07",
"upperBoundary": "1978-01-01T05:00:00-07",
"temperature_avg": 59.77,
"results_count": 67719
}
},
"fields": [
{
"name": "lowerBundary",
"type": "esriFieldTypeTimestampOffset"
},
{
"name": "upperBundary",
"type": "esriFieldTypeTimestampOffset"
},
{
"name": "results _count",
"alias": "results _count",
"type": "esriFieldTypeInteger"
},
{
"name": "temperature_avg",
"alias": "temperature_avg",
"type": "esriFieldTypeDouble"
}
],
"geometryType": "esriGeometryPoint"
]
}
JSON Response syntax
{
"fields": [
{
"name": "<fieldName1>",
"type": "<fieldType1>",
"alias": "<fieldAlias1>"
},
{
"name": "<fieldName2>",
"type": "<fieldType2>",
"alias": "<fieldAlias2>"
}
],
"features": [
<feature1>,
<feature2>
]
}