featureservice
Advanced tools
Comparing version
@@ -5,2 +5,10 @@ # Change Log | ||
## [1.2.1] - 2015-08-17 | ||
### Changed | ||
* All requests accept gzip or deflate compressed | ||
* Requests are decoded async (for compatibility with node < 0.11.12) | ||
### Fixed | ||
* Pages are built correctly for layers with an index > 0 | ||
## [1.2.0] - 2015-08-11 | ||
@@ -81,12 +89,13 @@ ### Fixed | ||
[1.2.0]: https://github.com/koopjs/featureservice/ompare/v1.1.1...v1.2.0 | ||
[1.1.1]: https://github.com/koopjs/featureservice/ompare/v1.1.0...v1.1.1 | ||
[1.1.0]: https://github.com/koopjs/featureservice/ompare/v1.0.0...v1.1.0 | ||
[1.0.0]: https://github.com/koopjs/featureservice/ompare/v0.2.0...v1.0.0 | ||
[0.2.0]: https://github.com/koopjs/featureservice/ompare/v0.1.0...v0.2.0 | ||
[0.1.0]: https://github.com/koopjs/featureservice/ompare/v0.0.4...v0.1.0 | ||
[0.0.4]: https://github.com/koopjs/featureservice/ompare/v0.0.3...v0.0.4 | ||
[0.0.3]: https://github.com/koopjs/featureservice/ompare/v0.0.2...v0.0.3 | ||
[0.0.2]: https://github.com/koopjs/featureservice/ompare/v0.0.1...v0.0.2 | ||
[1.2.1]: https://github.com/koopjs/featureservice/compare/v1.2.0...v1.2.1 | ||
[1.2.0]: https://github.com/koopjs/featureservice/compare/v1.1.1...v1.2.0 | ||
[1.1.1]: https://github.com/koopjs/featureservice/compare/v1.1.0...v1.1.1 | ||
[1.1.0]: https://github.com/koopjs/featureservice/compare/v1.0.0...v1.1.0 | ||
[1.0.0]: https://github.com/koopjs/featureservice/compare/v0.2.0...v1.0.0 | ||
[0.2.0]: https://github.com/koopjs/featureservice/compare/v0.1.0...v0.2.0 | ||
[0.1.0]: https://github.com/koopjs/featureservice/compare/v0.0.4...v0.1.0 | ||
[0.0.4]: https://github.com/koopjs/featureservice/compare/v0.0.3...v0.0.4 | ||
[0.0.3]: https://github.com/koopjs/featureservice/compare/v0.0.2...v0.0.3 | ||
[0.0.2]: https://github.com/koopjs/featureservice/compare/v0.0.1...v0.0.2 | ||
[0.0.1]: https://github.com/koopjs/featureservice/releases/tag/v0.0.1 | ||
39
index.js
@@ -49,2 +49,3 @@ var queue = require('async').queue | ||
*/ | ||
// TODO combine this with _requestFeatures | ||
FeatureService.prototype.request = function (url, callback) { | ||
@@ -61,3 +62,4 @@ var uri = urlUtils.parse(encodeURI(decodeURI(url))) | ||
headers: { | ||
'User-Agent': 'featureservices-node' | ||
'User-Agent': 'featureservices-node', | ||
'Accept-Encoding': 'gzip, deflate' | ||
} | ||
@@ -79,11 +81,3 @@ } | ||
response.on('end', function () { | ||
var err | ||
var json | ||
var buffer = Buffer.concat(data) | ||
try { | ||
json = JSON.parse(buffer.toString()) | ||
} catch (error) { | ||
err = error | ||
} | ||
callback(err, json) | ||
self._decode(response, data, callback) | ||
}) | ||
@@ -313,3 +307,3 @@ | ||
resultOffset = i * max | ||
var pageUrl = url + '/' + (this.options.layer || 0) + '/query?outSR=4326&f=json&outFields=*&where=1=1' | ||
var pageUrl = url + '/' + (this.layer) + '/query?outSR=4326&f=json&outFields=*&where=1=1' | ||
pageUrl += '&resultOffset=' + resultOffset | ||
@@ -342,3 +336,3 @@ pageUrl += '&resultRecordCount=' + max | ||
var where = [oidField, ' > ', pageMin, ' AND ', oidField, '<=', pageMax].join('') | ||
var pageUrl = this.url + '/' + (this.options.layer || 0) + '/query?outSR=4326&where=' + where + '&f=json&outFields=*' | ||
var pageUrl = this.url + '/' + (this.layer) + '/query?outSR=4326&where=' + where + '&f=json&outFields=*' | ||
pageUrl += '&geometry=&returnGeometry=true&geometryPrecision=10' | ||
@@ -427,2 +421,4 @@ reqs.push({req: pageUrl}) | ||
if (err) return self._catchErrors(task, err, uri, cb) | ||
// server responds 200 with error in the payload so we have to inspect | ||
if (json.error) return self._catchErrors(task, json.error, uri, cb) | ||
cb(null, json) | ||
@@ -459,3 +455,2 @@ }) | ||
FeatureService.prototype._decode = function (res, data, callback) { | ||
var json | ||
var encoding = res.headers['content-encoding'] | ||
@@ -467,18 +462,16 @@ if (!data.length > 0) return callback(new Error('Response from the server was empty')) | ||
if (encoding === 'gzip') { | ||
json = JSON.parse(zlib.gunzipSync(buffer).toString().replace(/NaN/g, 'null')) | ||
zlib.gunzip(buffer, function (err, data) { | ||
callback(err, JSON.parse(data.toString().replace(/NaN/g, 'null'))) | ||
}) | ||
} else if (encoding === 'deflate') { | ||
json = JSON.parse(zlib.inflateSync(buffer).toString()) | ||
zlib.inflate(buffer, function (err, data) { | ||
callback(err, JSON.parse(data.toString().replace(/NaN/g, 'null'))) | ||
}) | ||
} else { | ||
json = JSON.parse(buffer.toString().replace(/NaN/g, 'null')) | ||
callback(null, JSON.parse(buffer.toString().replace(/NaN/g, 'null'))) | ||
} | ||
} catch (e) { | ||
console.trace(e) | ||
callback(new Error('Failed to parse feature response')) | ||
callback(new Error('Failed to parse server response')) | ||
} | ||
// ArcGIS Server responds 200 on errors so we have to inspect the payload | ||
if (json.error) { | ||
return callback(json.error) | ||
} | ||
// everything has worked so callback with the decoded JSON | ||
callback(null, json) | ||
} | ||
@@ -485,0 +478,0 @@ |
{ | ||
"name": "featureservice", | ||
"description": "Get all features from an Esri Feature Service", | ||
"version": "1.2.0", | ||
"version": "1.2.1", | ||
"author": "Chris Helm", | ||
@@ -6,0 +6,0 @@ "bugs": { |
@@ -24,8 +24,8 @@ # featureservice | ||
```javascript | ||
var FeatureService = require('featureservice') | ||
var FeatureService = require('featureservice') | ||
// a url to a feature service | ||
var url = 'http://....../FeatureServer/0' | ||
// a url to a feature service | ||
var url = 'http://....../FeatureServer/0' | ||
var service = new FeatureService(url, options) | ||
var service = new FeatureService(url, options) | ||
``` | ||
@@ -48,3 +48,2 @@ | ||
}) | ||
``` | ||
@@ -71,3 +70,2 @@ | ||
</html> | ||
``` | ||
@@ -74,0 +72,0 @@ |
@@ -8,3 +8,3 @@ var sinon = require('sinon') | ||
var service = new FeatureService('http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/0', {objectIdField: 'OBJECTID'}) | ||
var service = new FeatureService('http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/1', {objectIdField: 'OBJECTID'}) | ||
@@ -38,4 +38,4 @@ var layerInfo = JSON.parse(fs.readFileSync('./test/fixtures/layerInfo.json')) | ||
t.equal(pages.length, 2) | ||
t.equal(pages[0].req, 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/0/query?outSR=4326&where=OBJECTID > 0 AND OBJECTID<=2&f=json&outFields=*&geometry=&returnGeometry=true&geometryPrecision=10') | ||
t.equal(pages[1].req, 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/0/query?outSR=4326&where=OBJECTID > 2 AND OBJECTID<=4&f=json&outFields=*&geometry=&returnGeometry=true&geometryPrecision=10') | ||
t.equal(pages[0].req, 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/1/query?outSR=4326&where=OBJECTID > 0 AND OBJECTID<=2&f=json&outFields=*&geometry=&returnGeometry=true&geometryPrecision=10') | ||
t.equal(pages[1].req, 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/1/query?outSR=4326&where=OBJECTID > 2 AND OBJECTID<=4&f=json&outFields=*&geometry=&returnGeometry=true&geometryPrecision=10') | ||
t.end() | ||
@@ -47,2 +47,3 @@ }) | ||
var pages = service._offsetPages(4, maxCount) | ||
t.equal(pages[0].req, 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/1/query?outSR=4326&f=json&outFields=*&where=1=1&resultOffset=0&resultRecordCount=100&geometry=&returnGeometry=true&geometryPrecision=') | ||
t.equal(pages.length, 4) | ||
@@ -55,3 +56,3 @@ | ||
var url = service._statsUrl('test', ['min', 'max']) | ||
t.equal(url, 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/0/query?f=json&outFields=&outStatistics=[{"statisticType":"min","onStatisticField":"test","outStatisticFieldName":"min_test"},{"statisticType":"max","onStatisticField":"test","outStatisticFieldName":"max_test"}]') | ||
t.equal(url, 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/1/query?f=json&outFields=&outStatistics=[{"statisticType":"min","onStatisticField":"test","outStatisticFieldName":"min_test"},{"statisticType":"max","onStatisticField":"test","outStatisticFieldName":"max_test"}]') | ||
t.end() | ||
@@ -66,3 +67,3 @@ }) | ||
t.equal(err, null) | ||
t.equal(service.request.calledWith('http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/0?f=json'), true) | ||
t.equal(service.request.calledWith('http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/1?f=json'), true) | ||
service.request.restore() | ||
@@ -79,3 +80,3 @@ t.end() | ||
t.equal(err, null) | ||
var expected = 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/0/query?where=1=1&returnIdsOnly=true&f=json' | ||
var expected = 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/1/query?where=1=1&returnIdsOnly=true&f=json' | ||
t.equal(service.request.calledWith(expected), true) | ||
@@ -93,3 +94,3 @@ service.request.restore() | ||
t.equal(err, null) | ||
var expected = 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/0/query?where=1=1&returnCountOnly=true&f=json' | ||
var expected = 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/1/query?where=1=1&returnCountOnly=true&f=json' | ||
t.equal(service.request.calledWith(expected), true) | ||
@@ -104,3 +105,3 @@ service.request.restore() | ||
service.timeOut = 5 | ||
nock('http://www.timeout.com').get('/').socketDelay(100) | ||
nock('http://www.timeout.com').get('/').socketDelay(100).reply({}.toString()) | ||
@@ -165,3 +166,3 @@ service.request('http://www.timeout.com', function (err, data) { | ||
test('should callback with an error when decoding json with an error in the response', function (t) { | ||
test('should trigger catchErrors with an error when receiving json with an error in the response', function (t) { | ||
var data = { | ||
@@ -174,9 +175,17 @@ error: { | ||
} | ||
var res = {headers: {}} | ||
var service = new FeatureService('http://service.com/mapserver/2') | ||
service._decode(res, [new Buffer(JSON.stringify(data))], function (err, json) { | ||
var fixture = nock('http://www.error.com') | ||
fixture.get('/').reply(200, JSON.stringify(data)) | ||
sinon.stub(service, '_catchErrors', function (task, err, url, callback) { | ||
callback(err) | ||
}) | ||
var task = {req: 'http://www.error.com'} | ||
service._requestFeatures(task, function (err, data) { | ||
t.notEqual(typeof err, 'undefined') | ||
t.equal(err.code, 400) | ||
t.equal(err.message, 'Invalid or missing input parameters.') | ||
service._catchErrors.restore() | ||
t.end() | ||
@@ -183,0 +192,0 @@ }) |
1253265
0.23%28
3.7%1461
-0.07%76
-2.56%