@@ -44,6 +44,9 @@ class ArcGIS < BaseDirectStream
44
44
# Used to display more data only (for local debugging purposes)
45
45
DEBUG = false
46
46
47
+ VECTOR_LAYER_TYPE = 'Feature Layer' . freeze
48
+ OID_FIELD_TYPE = 'esriFieldTypeOID' . freeze
49
+
47
50
attr_reader :metadata
48
51
49
52
# Constructor
@@ -249,8 +252,15 @@ def get_subresource_metadata(id, subresource_id)
249
252
# non-rails symbolize keys
250
253
data = ::JSON . parse ( response . body ) . inject ( { } ) { |memo , ( k , v ) | memo [ k . to_sym ] = v ; memo }
251
254
255
+ raise ResponseError . new ( "Invalid layer type: '#{ data [ :type ] } '" ) if data [ :type ] != VECTOR_LAYER_TYPE
252
256
raise ResponseError . new ( "Missing data: 'fields'" ) if data [ :fields ] . nil?
253
257
258
+ if data [ :supportedQueryFormats ] . present?
259
+ supported_formats = data . fetch ( :supportedQueryFormats ) . gsub ( ' ' , '' ) . split ( ',' )
260
+ else
261
+ supported_formats = [ ]
262
+ end
263
+
254
264
begin
255
265
@metadata = {
256
266
arcgis_version : data . fetch ( :currentVersion ) ,
@@ -259,14 +269,14 @@ def get_subresource_metadata(id, subresource_id)
259
269
type : data . fetch ( :type ) ,
260
270
geometry_type : data . fetch ( :geometryType ) ,
261
271
copyright : data . fetch ( :copyrightText , '' ) ,
262
- fields : data . fetch ( :fields ) . map { |field |
272
+ fields : data . fetch ( :fields ) . try ( : map) { |field |
263
273
{
264
274
name : field [ 'name' ] ,
265
275
type : field [ 'type' ]
266
276
}
267
277
} ,
268
278
max_records_per_query : data . fetch ( :maxRecordCount , 500 ) ,
269
- supported_formats : data . fetch ( :supportedQueryFormats ) . gsub ( ' ' , '' ) . split ( ',' ) ,
279
+ supported_formats : supported_formats ,
270
280
advanced_queries_supported : data . fetch ( :supportsAdvancedQueries , false )
271
281
}
272
282
rescue => exception
@@ -337,6 +347,9 @@ def get_layers_list(url)
337
347
raise ResponseError . new ( "Missing data: #{ exception . to_s } #{ request_url } #{ exception . backtrace } " )
338
348
end
339
349
350
+ # We only support vector layers (not raster layers)
351
+ data = data . reject { |layer | layer [ 'type' ] != VECTOR_LAYER_TYPE }
352
+
340
353
raise ResponseError . new ( "Empty layers list #{ request_url } " ) if data . length == 0
341
354
342
355
begin
@@ -388,10 +401,18 @@ def get_by_ids(url, ids, fields)
388
401
raise InvalidInputDataError . new ( "'ids' empty or invalid" ) if ( ids . nil? || ids . length == 0 )
389
402
raise InvalidInputDataError . new ( "'fields' empty or invalid" ) if ( fields . nil? || fields . length == 0 )
390
403
404
+ oid_field = fields . find { |field | field [ :type ] == OID_FIELD_TYPE }
405
+
391
406
if ids . length == 1
392
- ids_field = { objectIds : ids . first }
407
+ ids_field = { objectIds : ids . first }
393
408
else
394
- ids_field = { where : "OBJECTID >=#{ ids . first } AND OBJECTID <=#{ ids . last } " }
409
+ if oid_field
410
+ # Note that ids is sorted
411
+ ids_field = { where : "#{ oid_field [ :name ] } >=#{ ids . first } AND #{ oid_field [ :name ] } <=#{ ids . last } " }
412
+ else
413
+ # This could be innefficient with large number of ids, but it is limited to MAX_BLOCK_SIZE
414
+ ids_field = { objectIds : ids . join ( ',' ) }
415
+ end
395
416
end
396
417
397
418
prepared_fields = Addressable ::URI . encode ( fields . map { |field | "#{ field [ :name ] } " } . join ( ',' ) )
0 commit comments