-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharcgis.js
229 lines (177 loc) · 6.32 KB
/
arcgis.js
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/* global require */
// import modules
var request = require('request');
var aw = require('./aw');
var arcgisSecurity = require('./arcgisSecurity');
// get credentials from a file
var config = require('./resources/arcgis_config.json');
// place to save AW Levels
var awLevels = {};
// consolidate error handling
const handleErrors = function (err, res, data, callback) {
// if a Node error is encountered
if (err) {
new Error(err);
// if the status code is anything other than 200, usually indicates a problem with the service
} else if (res.statusCode != 200) {
new Error(data);
// if the body contains an error response in the body - commonly how with ArcGIS reports errors
} else if (data.error) {
new Error(data.error);
} else {
callback(data);
}
};
// update the reach hydroline levels
var pushHydrolineLevels = function () {
// create a request object with some defaults for the reach points
var reachHydrolineRequest = request.defaults({
baseUrl: config.featureServices.reachLine, // url stored in config file
json: true
});
// call the push levels function with the request for hydrolines
pushLevels(reachHydrolineRequest, function () {
console.log('Successfully updated hydroline levels.');
});
};
exports.pushHydrolineLevels = pushHydrolineLevels;
// update reach point levels
var pushPointLevels = function () {
// create a request object with some defaults for the reach points
var reachPointRequest = request.defaults({
baseUrl: config.featureServices.reachPoint, // url stored in config file
json: true
});
// call the push levels function with the request for hydrolines
pushLevels(reachPointRequest, function () {
console.log('Successfully updated point levels.');
});
};
exports.pushPointLevels = pushPointLevels;
// get the maximum number of records returned in a single rest call with attributes
var pushLevels = function (requestObject, callback) {
// get a user token
arcgisSecurity.getUserToken(
config.arcgisCredentials.username, config.arcgisCredentials.password, function (accessToken) {
const options = {
uri: '',
qs: {
f: 'json',
token: accessToken
}
};
// get the maximum number of records to be returned for a request with attributes
requestObject(options, function (err, res, body) {
// manage errors
handleErrors(err, res, body, function (data) {
// pull the max records out of the JSON response
pushFeatureBlocks(requestObject, accessToken, data.maxRecordCount, callback);
})
});
});
};
// create a dictionary of key as reachid and value as objectid
var pushFeatureBlocks = function (requestObject, accessToken, maxRecordCount, callback) {
const options = {
uri: 'query',
method: 'post',
form: {
f: 'json',
token: accessToken,
where: '1=1',
returnIdsOnly: true
}
};
// since the only full list returned will be all the object ids, get this full list
requestObject(options, function (err, res, body) {
// if some sort of error is encountered
handleErrors(err, res, body, function(data){
// save a couple of properties, the object id list, and the number of blocks needed to get all features
var objectIdList = data.objectIds;
var blockCount = Math.ceil(objectIdList.length / maxRecordCount);
// iterate the number of blocks
for (var i = 0; i < blockCount; i++) {
// create a list of object ids to retrieve, the next block of object id's
var objectIds = objectIdList.splice(0, maxRecordCount).join(',');
// call push single hash
pushFeatureBlock(requestObject, accessToken, objectIds, callback);
}
});
});
};
// push a single hash block
var pushFeatureBlock = function (requestObject, accessToken, objectIds, callback) {
const options = {
uri: 'query',
method: 'post',
form: {
f: 'json',
token: accessToken,
where: '1=1',
obejctIds: objectIds,
outFields: 'OBJECTID, reach_id',
returnGeometry: false,
returnIdsOnly: false
}
};
// get the object id's and associated reach id's for this block of river reaches
requestObject(options, function (err, res, body) {
handleErrors(err, res, body, function(data){
// send the features to the level update function
pushLevelsToFeatureService(requestObject, accessToken, data.features, callback)
});
});
};
// wrapper for get reach levels, to ensure the levels are only retrieved once
var getAwLevels = function (callback) {
// if the object has any properties, the levels have already been populated
if (Object.keys(awLevels).length) {
// invoke the callback with the levels
callback(awLevels);
} else {
// get the levels from AW and pass them into the callback
aw.getReachLevels(function (responseLevels) {
// save the levels for next time
awLevels = responseLevels;
// invoke the callback
callback(awLevels);
});
}
};
// push updated levels to the feature service
var pushLevelsToFeatureService = function (requestObject, accessToken, features, callback) {
// get the levels from aw
getAwLevels(function (reachLevels) {
// variable to store the features with gauge readings
var updateFeatures = [];
// iterate the features from the feature service
for (var i in features) {
// if the reach has a gauge
if (reachLevels[features[i].attributes.reach_id]) {
// update the properites of the feature using the corresponding levels
features[i].attributes.condition = reachLevels[features[i].attributes.reach_id].condition;
features[i].attributes.gauge_observation = reachLevels[features[i].attributes.reach_id].stage;
// add the feature to the list to be updated
updateFeatures.push(features[i]);
}
}
const options = {
uri: 'applyEdits',
method: 'post',
form: {
f: 'json',
token: accessToken,
updates: JSON.stringify(updateFeatures),
rollbackOnFailure: true,
useGlobalIds: false
}
};
// use the updated features list to update the feature service
requestObject(options, function (err, res, body) {
handleErrors(err, res, body, function(data){
// invoke the callback...life is good
callback(data);
});
});
});
};