arcgis_vrps 0.0.2.1 → 0.0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: efed1acbb3635ceace46ddc8f06f8f2e6b693154
4
- data.tar.gz: e60638a995344f0ee9fb9a165d2d98ab285e03af
3
+ metadata.gz: d3af625d3074f6f84386182d7b120aa4a57c0d99
4
+ data.tar.gz: 2f2d8fd5876c98473a09c5ba532d4b3c81be802c
5
5
  SHA512:
6
- metadata.gz: 2c33fc1bdc389abc94fb995155a14827946de2cdbcc0554adbce10392e037177671096d01288c70b4107064cdce09862e54a022d0450610d49c686037353da7d
7
- data.tar.gz: 5fbaea051725e894cb647c21ad30dc16c8e56a24b339b6cf4777048659022af027cfa2cb2963bd7c2ef39cae337b9c9df21f052ea0b41fa9125b0fd8e7c9c12b
6
+ metadata.gz: 2c67e0d567464c17c154c44ec418ad0ff9fcf3ad9021ec9f8defd751005faaee6aed6a72fe3da0ef0ea927e284d5f17d27fb03a79e74fd54d628e3b70964d311
7
+ data.tar.gz: 66e43e5f763b7b51399bb11c17e69b0486ad63be53d55e6e011072fc33527cb84e3057a123ae0aad2d0b6db37ae48c0e643999c057ee37205c983c1e7f15ecf8
data/README.md ADDED
@@ -0,0 +1,18 @@
1
+ # Overview #
2
+ A ruby gem as an interface for ArcGIS (platform of Esri) Vehicle Routing Problem service REST API
3
+
4
+ You can install this gem by:
5
+
6
+ gem install arcgis_vrps
7
+
8
+ If at any moment you get the error similar to:
9
+
10
+ SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
11
+
12
+ Please follow the steps outlined [here](https://gist.github.com/fnichol/867550)
13
+
14
+
15
+ To debug / test the gem do the following on the command line:
16
+
17
+ - irb -Ilib -rarcgis_vrps
18
+ - a=Arcgis_Vrps.new
data/lib/arcgis_vrps.rb CHANGED
@@ -1,10 +1,549 @@
1
+ # This require has to be below cause the above is using it.
2
+ # Else, you'll get error: Uninitialized constant
3
+ require 'json'
4
+ require 'net/http'
5
+ require 'arcgis_vrps/orders'
6
+ require 'arcgis_vrps/depots'
7
+ require 'arcgis_vrps/routes'
8
+ require 'arcgis_vrps/auth'
9
+ require 'test/data_load'
10
+
1
11
  class Arcgis_Vrps
2
- def self.hi(language = "english")
3
- translator = Translator.new(language)
4
- translator.hi
12
+ # Use for testing for now
13
+ # def initialize()
14
+ # auth = Auth.new("rdvAIjUCEMegkoId", "a22acf9678c24b34960c320dddfe96cc")
15
+ # @token = auth.generateToken
16
+
17
+ # puts
18
+ # puts "Token generated #{@token}"
19
+ # puts
20
+
21
+ # loadSampleData(false) # This will get coordinates from MapSynq for all McD and write to /lib/test/sample_data/coordinateArray file. Change to true if the file don't exist
22
+ # # mockCase1() # Routes without any start & end time (Basic routing)
23
+ # mockCase2(5) # 9 locations with set times that vehicles must reach (no overlapping time)
24
+ # # mockCase3() # 8 locations with set times that vehicles must reach (with overlapping time)
25
+ # # mockCase4() # Same as use case 3 but with more overlapping times than routes available
26
+
27
+ # # getOutputRoutes("jf163f4d4f7874fd69b4f6f90e2d5d9aa")
28
+ # # getOutputOrders("jf163f4d4f7874fd69b4f6f90e2d5d9aa")
29
+ # end
30
+
31
+ # def initialize(client_id, client_secret)
32
+ auth = Auth.new(client_id, client_secret)
33
+ @token = auth.generateToken
34
+
35
+ # puts
36
+ # puts "Token generated #{@token}"
37
+ # puts
38
+
5
39
  end
6
- end
7
40
 
8
- # This require has to be below cause the above is using it.
9
- # Else, you'll get error: Uninitialized constant
10
- require 'arcgis_vrps/sample'
41
+ def submitJob(ordersObj, depotsObj, routesObj, timer) # TODO: Check to decide whether to use synchronous or async
42
+
43
+ puts "Submitting job"
44
+
45
+ jobStatusNoOfCalls = 0
46
+
47
+ t1 = Time.now
48
+
49
+ submitJobUrl = 'https://logistics.arcgis.com/arcgis/rest/services/World/VehicleRoutingProblem/GPServer/SolveVehicleRoutingProblem/submitJob'
50
+
51
+ params = {
52
+ orders: ordersObj.to_json,
53
+ depots: depotsObj.to_json,
54
+ routes: routesObj.to_json,
55
+ default_date: (Time.now.to_f * 1000).to_i,
56
+ # default_date: 1441933200000,
57
+ token: @token,
58
+ f: 'json',
59
+ time_units: 'Seconds',
60
+ distance_units: 'Meters'
61
+ }
62
+
63
+ res = Net::HTTP.post_form(URI(submitJobUrl), params)
64
+
65
+ @jobId = JSON.parse(res.body)["jobId"]
66
+
67
+
68
+ if @jobId.nil?
69
+ raise "Error! #{res.body}"
70
+ else
71
+ puts "Received job ID: #{@jobId}"
72
+ print "Getting job status..."
73
+
74
+ if timer.nil?
75
+ timer = 1 # Timer of 500ms to constantly check for updates
76
+ end
77
+
78
+ start_time = Time.now
79
+ end_time = start_time+timer
80
+
81
+ completed = false
82
+
83
+ begin
84
+ while completed == false
85
+ print "."
86
+ jobStatusNoOfCalls += 1
87
+ while Time.now < end_time
88
+ end
89
+
90
+ completed = getJobStatus()
91
+ end
92
+ print "Completed!\n"
93
+ puts
94
+ # puts completed.to_s
95
+ # puts
96
+
97
+ t2 = Time.now
98
+
99
+ time_jobStatusIsComplete = t2-t1
100
+
101
+ puts "Time taken for job to be completed: #{time_jobStatusIsComplete}"
102
+ puts
103
+
104
+ routesReceived = getOutputRoutes(nil).to_json
105
+ routesReceived = "Routes received: \n #{routesReceived}"
106
+ ordersReceived = getOutputOrders(nil).to_json
107
+ ordersReceived = "Orders received: \n #{ordersReceived}"
108
+
109
+ t3 = Time.now
110
+
111
+ time_fullJobComplete = t3-t1
112
+
113
+ extraContent = "Total time taken for getting routes and orders: #{time_fullJobComplete} \nNumber of calls to jobStatus: #{jobStatusNoOfCalls} \n\n"
114
+
115
+ puts extraContent
116
+ puts
117
+
118
+ return extraContent, routesReceived, ordersReceived
119
+ rescue Exception => e
120
+ puts
121
+ puts e
122
+ puts
123
+ end
124
+ end
125
+ end
126
+
127
+ def getJobStatus
128
+ urlWithJobId = 'https://logistics.arcgis.com/arcgis/rest/services/World/VehicleRoutingProblem/GPServer/SolveVehicleRoutingProblem/jobs/'+@jobId
129
+ res = Net::HTTP.post_form URI(urlWithJobId),
130
+ token: @token,
131
+ returnMessages: true,
132
+ f: 'json'
133
+
134
+ status = JSON.parse(res.body)["jobStatus"]
135
+ # puts res.body
136
+ # puts
137
+
138
+ if status == "esriJobSucceeded"
139
+ return res.body
140
+ elsif status == "esriJobFailed"
141
+ raise "\nJob failed with the following message stack:\n #{res.body}"
142
+ else
143
+ return false
144
+ end
145
+ end
146
+
147
+ def getOutputRoutes(jobId)
148
+ unless jobId.nil?
149
+ @jobId = jobId
150
+ end
151
+
152
+ urlWithJobId = 'https://logistics.arcgis.com/arcgis/rest/services/World/VehicleRoutingProblem/GPServer/SolveVehicleRoutingProblem/jobs/'+@jobId+'/results/out_routes'
153
+
154
+ res = Net::HTTP.post_form URI(urlWithJobId),
155
+ token: @token,
156
+ f: 'json'
157
+
158
+ # We return the entire string is because it have meta data about the geometry type, spatial reference, etc
159
+ routesFeatures = JSON.parse(res.body)
160
+ # JSON.parse(res.body)["value"]["features"]["geometry"]["paths"] will return an array of coordinates in the following format: [longitude, latitude]
161
+ # routesFeatures = JSON.parse(res.body)["value"]["features"]
162
+
163
+ if routesFeatures.nil?
164
+ routesFeatures = res.body
165
+ end
166
+
167
+ return routesFeatures
168
+ end
169
+
170
+ def getOutputOrders(jobId)
171
+ unless jobId.nil?
172
+ @jobId = jobId
173
+ end
174
+
175
+ urlWithJobId = 'https://logistics.arcgis.com/arcgis/rest/services/World/VehicleRoutingProblem/GPServer/SolveVehicleRoutingProblem/jobs/'+@jobId+'/results/out_stops'
176
+
177
+ res = Net::HTTP.post_form URI(urlWithJobId),
178
+ token: @token,
179
+ f: 'json'
180
+
181
+ # We return the entire string is because it have meta data about the geometry type, spatial reference, etc
182
+ ordersFeatures = JSON.parse(res.body)
183
+ # ordersFeatures = JSON.parse(res.body)["value"]["features"]
184
+
185
+ if ordersFeatures.nil?
186
+ ordersFeatures = res.body
187
+ end
188
+
189
+ return ordersFeatures
190
+ end
191
+
192
+ def loadSampleData(loadFromFile)
193
+ @loadData = Data_Load.new()
194
+
195
+ if loadFromFile
196
+ @loadData.getCoordinateFromMapSynq()
197
+ @loadData.writeCoordinateToFile()
198
+ end
199
+ end
200
+
201
+ def mockCase1(numberOfVehicles) # Routes without any start & end time (Basic routing)
202
+
203
+ puts "Setting up orders"
204
+
205
+ @loadData.getCoordinateFromFile()
206
+ coordinate = @loadData.coordinateArrayFromFile
207
+
208
+ ord = Orders.new()
209
+
210
+ i = 0
211
+ coordinate.each do |coor|
212
+ store_name = "Store_"+i.to_s
213
+
214
+ orderAttributeObj = ord.getBasicOrderAttributeObj(store_name)
215
+ ord.addOrders(coor[0], coor[1], orderAttributeObj)
216
+
217
+ if i == 50
218
+ break
219
+ end
220
+
221
+ i += 1
222
+ end
223
+
224
+ ordersObj = ord.getOrderObj(nil)
225
+
226
+ puts "Setting up depots"
227
+
228
+ dep = Depots.new()
229
+ deportAttributeObj = dep.getDepotAttributeObj("depot_1")
230
+ dep.addDepots(103.848427, 1.277751, deportAttributeObj)
231
+ depotsObj = dep.getDepotObj(nil)
232
+
233
+ puts "Setting up routes"
234
+
235
+ route = Routes.new()
236
+
237
+ startDateTime = (Time.now.to_f * 1000).to_i
238
+
239
+ for i in 1..numberOfVehicles
240
+ truck_name = "Truck_#{i}"
241
+ route.addRoutes(truck_name, "depot_1", startDateTime, startDateTime)
242
+ end
243
+
244
+ routesObj = route.getRouteObj()
245
+
246
+ begin
247
+ contents = submitJob(ordersObj, depotsObj, routesObj, nil)
248
+
249
+ writeToFile("Mock Case 1 - #{numberOfVehicles}.json", contents)
250
+ rescue Exception => e
251
+ puts
252
+ puts e
253
+ puts
254
+ end
255
+ end
256
+
257
+ def mockCase2(numberOfVehicles) # 9 locations with set times that vehicles must reach (no overlapping time)
258
+
259
+ puts "Setting up orders"
260
+
261
+ @loadData.getCoordinateFromFile()
262
+ coordinate = @loadData.coordinateArrayFromFile
263
+
264
+ ord = Orders.new()
265
+
266
+ i = 0
267
+
268
+ minutesInSeconds = 1800000 # 30 minutes in milliseconds
269
+ timeWindowStart1 = 1441933200000 # Default date time: 11th Sept 2015, 9:00:00 AM in milliseconds
270
+ timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run
271
+
272
+ coordinate.each do |coor|
273
+ store_name = "Store_"+i.to_s
274
+ serviceTime = 30
275
+
276
+ if i < 9 && i >= 0
277
+ if i < 5 && i >= 1 # Can reach later than the set time here
278
+ timeWindowStart1 += (minutesInSeconds*2) # Add 1 hour every run
279
+ timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run
280
+ maxViolationTime1 = nil
281
+ elsif i < 9 && i >= 5 # Can reach later than the set time based on the x minute set by MaxViolationTime1
282
+ timeWindowStart1 += (minutesInSeconds*2) # Add 1 hour every run
283
+ timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run
284
+ maxViolationTime1 = 0
285
+ end
286
+ orderAttributeObj = ord.getOrderAttributeObj(store_name, serviceTime, timeWindowStart1, timeWindowEnd1, maxViolationTime1)
287
+ elsif i >= 9
288
+ timeWindowStart1 = nil
289
+ timeWindowEnd1 = nil
290
+ maxViolationTime1 = nil
291
+ orderAttributeObj = ord.getBasicOrderAttributeObj(store_name)
292
+ end
293
+
294
+ ord.addOrders(coor[0], coor[1], orderAttributeObj)
295
+
296
+ if i == 49
297
+ break
298
+ end
299
+
300
+ i += 1
301
+ end
302
+
303
+ ordersObj = ord.getOrderObj(nil)
304
+
305
+ puts "Setting up depots"
306
+
307
+ dep = Depots.new()
308
+ deportAttributeObj = dep.getDepotAttributeObj("depot_1")
309
+ dep.addDepots(103.848427, 1.277751, deportAttributeObj)
310
+ depotsObj = dep.getDepotObj(nil)
311
+
312
+ puts "Setting up routes"
313
+
314
+ route = Routes.new()
315
+
316
+ startDateTime = 1441933200000
317
+ for i in 1..numberOfVehicles
318
+ truck_name = "Truck_#{i}"
319
+ route.addRoutes(truck_name, "depot_1", startDateTime, startDateTime)
320
+ end
321
+
322
+ routesObj = route.getRouteObj()
323
+
324
+ # puts
325
+ # puts ordersObj.to_json
326
+ # puts
327
+ # puts depotsObj.to_json
328
+ # puts
329
+ # puts routesObj.to_json
330
+ # puts
331
+
332
+ begin
333
+ contents = submitJob(ordersObj, depotsObj, routesObj, nil)
334
+
335
+ writeToFile("Mock Case 2 - #{numberOfVehicles}.json", contents)
336
+ rescue Exception => e
337
+ puts
338
+ puts e
339
+ puts
340
+ end
341
+ end
342
+
343
+ def mockCase3(numberOfVehicles) # 8 locations with set times that vehicles must reach (with overlapping time)
344
+
345
+ puts "Setting up orders"
346
+
347
+ @loadData.getCoordinateFromFile()
348
+ coordinate = @loadData.coordinateArrayFromFile
349
+
350
+ ord = Orders.new()
351
+
352
+ i = 0
353
+
354
+ minutesInSeconds = 1800000 # 30 minutes in milliseconds
355
+ timeWindowStart1 = 1441933200000 # Default date time: 11th Sept 2015, 9:00:00 AM in milliseconds
356
+ timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run
357
+
358
+ countThree = 0
359
+ countFive = 0
360
+
361
+ coordinate.each do |coor|
362
+ store_name = "Store_"+i.to_s
363
+ serviceTime = 30
364
+
365
+ if ((i%3 == 0 || i%5 == 0) && (countThree < 4 || countFive < 4))
366
+ if timeWindowStart1.nil? || timeWindowStart1 >= 1441944000000
367
+ timeWindowStart1 = 1441933200000
368
+ end
369
+
370
+ if i%3 == 0 && countThree < 4
371
+ timeWindowStart1 += (minutesInSeconds*2) # Add 1 hour every run
372
+ timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run
373
+ maxViolationTime1 = nil
374
+ countThree += 1
375
+ elsif i%5 == 0 && countFive < 4
376
+ timeWindowStart1 += (minutesInSeconds*2) # Add 1 hour every run
377
+ timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run
378
+ maxViolationTime1 = 0
379
+ countFive += 1
380
+ end
381
+ orderAttributeObj = ord.getOrderAttributeObj(store_name, serviceTime, timeWindowStart1, timeWindowEnd1, maxViolationTime1)
382
+ else
383
+ timeWindowStart1 = nil
384
+ timeWindowEnd1 = nil
385
+ maxViolationTime1 = nil
386
+ orderAttributeObj = ord.getBasicOrderAttributeObj(store_name)
387
+ end
388
+
389
+ ord.addOrders(coor[0], coor[1], orderAttributeObj)
390
+
391
+ if i == 49
392
+ break
393
+ end
394
+
395
+ i += 1
396
+ end
397
+
398
+ ordersObj = ord.getOrderObj(nil)
399
+
400
+ puts "Setting up depots"
401
+
402
+ dep = Depots.new()
403
+ deportAttributeObj = dep.getDepotAttributeObj("depot_1")
404
+ dep.addDepots(103.848427, 1.277751, deportAttributeObj)
405
+ depotsObj = dep.getDepotObj(nil)
406
+
407
+ puts "Setting up routes"
408
+
409
+ route = Routes.new()
410
+
411
+ startDateTime = 1441933200000
412
+ for i in 1..numberOfVehicles
413
+ truck_name = "Truck_#{i}"
414
+ route.addRoutes(truck_name, "depot_1", startDateTime, startDateTime)
415
+ end
416
+
417
+ routesObj = route.getRouteObj()
418
+
419
+ # puts
420
+ # puts ordersObj.to_json
421
+ # puts
422
+ # puts depotsObj.to_json
423
+ # puts
424
+ # puts routesObj.to_json
425
+ # puts
426
+
427
+ begin
428
+ contents = submitJob(ordersObj, depotsObj, routesObj, nil)
429
+
430
+ writeToFile("Mock Case 3 - #{numberOfVehicles}.json", contents)
431
+ rescue Exception => e
432
+ puts
433
+ puts e
434
+ puts
435
+ end
436
+ end
437
+
438
+ def mockCase4(numberOfVehicles) # Same as use case 3 but with more overlapping times than routes available
439
+
440
+ puts "Setting up orders"
441
+
442
+ @loadData.getCoordinateFromFile()
443
+ coordinate = @loadData.coordinateArrayFromFile
444
+
445
+ ord = Orders.new()
446
+
447
+ i = 0
448
+
449
+ minutesInSeconds = 1800000 # 30 minutes in milliseconds
450
+ timeWindowStart1 = 1441933200000 # Default date time: 11th Sept 2015, 9:00:00 AM in milliseconds
451
+ timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run
452
+
453
+ countThree = 0
454
+ countFive = 0
455
+
456
+ coordinate.each do |coor|
457
+ store_name = "Store_"+i.to_s
458
+ serviceTime = 30
459
+
460
+ if i < 6
461
+ # This if block is to set 3 with MaxViolationTime1 and 3 without
462
+ # if i < 3 && i >= 0
463
+ # maxViolationTime1 = nil
464
+ # elsif i < 6 && i >= 3
465
+ # maxViolationTime1 = 0
466
+ # end
467
+ maxViolationTime1 = 0 # This is to set all 6 with MaxViolationTime1
468
+ orderAttributeObj = ord.getOrderAttributeObj(store_name, serviceTime, timeWindowStart1, timeWindowEnd1, maxViolationTime1)
469
+ else
470
+ timeWindowStart1 = nil
471
+ timeWindowEnd1 = nil
472
+ maxViolationTime1 = nil
473
+ orderAttributeObj = ord.getBasicOrderAttributeObj(store_name)
474
+ end
475
+
476
+ ord.addOrders(coor[0], coor[1], orderAttributeObj)
477
+
478
+ if i == 49
479
+ break
480
+ end
481
+
482
+ i += 1
483
+ end
484
+
485
+ ordersObj = ord.getOrderObj(nil)
486
+
487
+ puts "Setting up depots"
488
+
489
+ dep = Depots.new()
490
+ deportAttributeObj = dep.getDepotAttributeObj("depot_1")
491
+ dep.addDepots(103.848427, 1.277751, deportAttributeObj)
492
+ depotsObj = dep.getDepotObj(nil)
493
+
494
+ puts "Setting up routes"
495
+
496
+ route = Routes.new()
497
+
498
+ startDateTime = 1441933200000
499
+ for i in 1..numberOfVehicles
500
+ truck_name = "Truck_#{i}"
501
+ route.addRoutes(truck_name, "depot_1", startDateTime, startDateTime)
502
+ end
503
+
504
+ routesObj = route.getRouteObj()
505
+
506
+ # puts
507
+ # puts ordersObj.to_json
508
+ # puts
509
+ # puts depotsObj.to_json
510
+ # puts
511
+ # puts routesObj.to_json
512
+ # puts
513
+
514
+ begin
515
+ contents = submitJob(ordersObj, depotsObj, routesObj, nil)
516
+
517
+ writeToFile("Mock Case 4 - location - 6.json", contents)
518
+ rescue Exception => e
519
+ puts
520
+ puts e
521
+ puts
522
+ end
523
+ end
524
+
525
+ def writeCoordinateToFile
526
+ @loadData.getCoordinateFromFile(true)
527
+ coordinate = @loadData.coordinateArrayFromFile
528
+ writeToFile("coordinateArray", coordinate.to_json);
529
+ end
530
+
531
+ def writeToFile(filename, contents)
532
+ puts "Writing to file #{filename}"
533
+
534
+ File.open("lib/test/sample_data/#{filename}", "w") do |file|
535
+ if contents.kind_of?(Array)
536
+ contents.each do |content|
537
+ file.puts content
538
+ file.puts
539
+ end
540
+ else
541
+ file.puts contents
542
+ file.puts
543
+ end
544
+ end
545
+
546
+ puts "Done writing to file #{filename}"
547
+ puts
548
+ end
549
+ end
@@ -0,0 +1,29 @@
1
+ require 'json'
2
+ require 'net/http'
3
+
4
+ class Auth
5
+ def initialize(client_id, client_secret)
6
+ if client_id.nil? || client_id.empty? || client_secret.nil? || client_secret.empty?
7
+ raise ArgumentError, "Both Client ID & Client Secret has to be set"
8
+ end
9
+
10
+ @client_id = client_id
11
+ @client_secret = client_secret
12
+ end
13
+
14
+ def generateToken
15
+ begin
16
+ res = Net::HTTP.post_form URI('https://www.arcgis.com/sharing/rest/oauth2/token'),
17
+ f: 'json',
18
+ client_id: @client_id,
19
+ client_secret: @client_secret,
20
+ grant_type: 'client_credentials'
21
+
22
+ token = JSON.parse(res.body)['access_token']
23
+ # puts "\n"+res.body
24
+ return token
25
+ rescue => e
26
+ puts e
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,57 @@
1
+ class Depots
2
+ # Longitude => xCoordinate, Latitude => yCoordinate
3
+ def addDepots (xCoordinate, yCoordinate, depotAttributeObj)
4
+ my_depot = {
5
+ :geometry => {
6
+ :x => xCoordinate,
7
+ :y => yCoordinate
8
+ },
9
+ :attributes => depotAttributeObj
10
+ }
11
+ if @depotArr.nil?
12
+ @depotArr = []
13
+ end
14
+
15
+ @depotArr.push(my_depot)
16
+ end
17
+
18
+ def getDepotArr
19
+ return @depotArr
20
+ end
21
+
22
+ def getDepotAttributeObj(depotName)
23
+ depotAttributeObj = {
24
+ :Name => depotName
25
+ }
26
+
27
+ return depotAttributeObj
28
+ end
29
+
30
+ # Get the Orders Attribute Object from the param passed in
31
+ # def getDepotAttributeObj(depotName, timeStart1, timeEnd1)
32
+ # depotAttributeObj = {
33
+ # :Name => depotName,
34
+ # :TimeWindowStart1 => timeStart1,
35
+ # :TimeWindowEnd1 => timeEnd1
36
+ # }
37
+
38
+ # return depotAttributeObj
39
+ # end
40
+
41
+ def getDepotObj (wkid)
42
+ if wkid.nil?
43
+ depotObj = {
44
+ :features => @depotArr
45
+ }
46
+ else
47
+ depotObj = {
48
+ :spatialReference => {
49
+ :wkid => wkid
50
+ },
51
+ :features => @depotArr
52
+ }
53
+ end
54
+
55
+ return depotObj
56
+ end
57
+ end
@@ -0,0 +1,85 @@
1
+ class Orders
2
+ # Longitude => xCoordinate, Latitude => yCoordinate
3
+ def addOrders (xCoordinate, yCoordinate, orderAttributeObj)
4
+ my_order = {
5
+ :geometry => {
6
+ :x => xCoordinate,
7
+ :y => yCoordinate
8
+ },
9
+ :attributes => orderAttributeObj
10
+ }
11
+ if @orderArr.nil?
12
+ @orderArr = []
13
+ end
14
+
15
+ @orderArr.push(my_order)
16
+ end
17
+
18
+ def getOrderArr
19
+ return @orderArr
20
+ end
21
+
22
+ # Get basic Orders Attribute Object from the param passed in
23
+ def getBasicOrderAttributeObj (orderName)
24
+ orderAttributeObj = {
25
+ :Name => orderName
26
+ }
27
+
28
+ return orderAttributeObj
29
+ end
30
+
31
+ # Get orders attribute object from the param passed in
32
+ # timeWindow* refers to the time that the service
33
+ def getOrderAttributeObj (orderName, serviceTime, timeWindowStart1, timeWindowEnd1, maxViolationTime1)
34
+ if maxViolationTime1.nil?
35
+ orderAttributeObj = {
36
+ :Name => orderName,
37
+ :ServiceTime => serviceTime,
38
+ :TimeWindowStart1 => timeWindowStart1,
39
+ :TimeWindowEnd1 => timeWindowEnd1
40
+ }
41
+ else
42
+ orderAttributeObj = {
43
+ :Name => orderName,
44
+ :ServiceTime => serviceTime,
45
+ :TimeWindowStart1 => timeWindowStart1,
46
+ :TimeWindowEnd1 => timeWindowEnd1,
47
+ :MaxViolationTime1 => maxViolationTime1
48
+ }
49
+ end
50
+
51
+
52
+ return orderAttributeObj
53
+ end
54
+
55
+ # Get the Orders Attribute Object from the param passed in
56
+ # def getOrderAttributeObj (orderName, deliveryQty, serviceTime, timeStart1, timeEnd1, maxViolationTime)
57
+ # orderAttributeObj = {
58
+ # :Name => orderName,
59
+ # :DeliveryQuantities => deliveryQty,
60
+ # :ServiceTime => serviceTime,
61
+ # :TimeWindowStart1 => timeStart1,
62
+ # :TimeWindowEnd1 => timeEnd1,
63
+ # :MaxViolationTime1 => maxViolationTime
64
+ # }
65
+
66
+ # return orderAttributeObj
67
+ # end
68
+
69
+ def getOrderObj (wkid)
70
+ if wkid.nil?
71
+ orderObj = {
72
+ :features => @orderArr
73
+ }
74
+ else
75
+ orderObj = {
76
+ :spatialReference => {
77
+ :wkid => wkid
78
+ },
79
+ :features => @orderArr
80
+ }
81
+ end
82
+
83
+ return orderObj
84
+ end
85
+ end
@@ -0,0 +1,56 @@
1
+ class Routes
2
+ def addRoutes (routeName, startDepotName, earliestStartTime, latestStartTime)
3
+ my_route = {
4
+ :attributes => {
5
+ :Name => routeName,
6
+ :StartDepotName => startDepotName, # Either this or EndDepotName must be present. This is a foreign key to the "Name" attribute in the depots param. Thus, the values MUST match
7
+ :EarliestStartTime => earliestStartTime,
8
+ :LatestStartTime => latestStartTime
9
+ }
10
+ }
11
+
12
+ if @routeArr.nil?
13
+ @routeArr = []
14
+ end
15
+
16
+ @routeArr.push(my_route)
17
+ end
18
+
19
+ # def addRoutes (routeName, startDepotName, endDepotName, startDepotServiceTime, earliestStartTime, latestStartTime, capacities, costPerUnitTime, costPerUnitDistance, maxOrderCount, maxTotalTime, maxTotalTravelTime, maxTotalDistance)
20
+ # my_route = {
21
+ # :attributes => {
22
+ # :Name => routeName,
23
+ # :StartDepotName => startDepotName, # Either this or EndDepotName must be present. This is a foreign key to the "Name" attribute in the depots param. Thus, the values MUST match
24
+ # :EndDepotName => endDepotName,
25
+ # :StartDepotServiceTime => startDepotServiceTime,
26
+ # :EarliestStartTime => earliestStartTime,
27
+ # :LatestStartTime => latestStartTime,
28
+ # :Capacities => capacities,
29
+ # :CostPerUnitTime => costPerUnitTime,
30
+ # :CostPerUnitDistance => costPerUnitDistance,
31
+ # :MaxOrderCount => maxOrderCount,
32
+ # :MaxTotalTime => maxTotalTime,
33
+ # :MaxTotalTravelTime => maxTotalTravelTime,
34
+ # :MaxTotalDistance => maxTotalDistance
35
+ # }
36
+ # }
37
+
38
+ # if @routeArr.nil?
39
+ # @routeArr = []
40
+ # end
41
+
42
+ # @routeArr.push(my_route)
43
+ # end
44
+
45
+ def getRouteArr
46
+ return @routeArr
47
+ end
48
+
49
+ def getRouteObj
50
+ routeObj = {
51
+ :features => @routeArr
52
+ }
53
+
54
+ return routeObj
55
+ end
56
+ end
@@ -0,0 +1,116 @@
1
+ require 'net/http'
2
+
3
+ class Data_Load
4
+ attr_accessor :coordinateArrayFromFile, :postcodeArrayFromFile, :coordinateArrayFromServer
5
+
6
+ def initialize
7
+ # Will there be an instance where @postcodeArrayFromFile is nil?
8
+ if @postcodeArrayFromFile.nil?
9
+ @postcodeArrayFromFile = []
10
+ end
11
+
12
+ if @coordinateArrayFromServer.nil?
13
+ @coordinateArrayFromServer = []
14
+ end
15
+
16
+ if @coordinateArrayFromFile.nil?
17
+ @coordinateArrayFromFile = []
18
+ end
19
+ end
20
+
21
+ def getCoordinateFromMapSynq
22
+ puts "Getting postcodes from file..."
23
+
24
+ getPostcodeFromFile()
25
+
26
+ print "Requesting coordinates from server..."
27
+
28
+ @postcodeArrayFromFile.each do |postcode|
29
+ print "."
30
+
31
+ mapsynqUrl = "http://www.mapsynq.com/home/search1?q=#{postcode}&lat=&lon=&page=1"
32
+
33
+ begin
34
+ url = URI.parse(mapsynqUrl)
35
+ req = Net::HTTP::Get.new(url.to_s)
36
+ res = Net::HTTP.start(url.host, url.port) {|http|
37
+ http.request(req)
38
+ }
39
+
40
+ result = JSON.parse(res.body)["result"]
41
+
42
+ unless result.empty?
43
+ yCoordinate = result[0]["true_latitude"]
44
+ xCoordinate = result[0]["true_longitude"]
45
+ coordinate = "#{xCoordinate}-#{yCoordinate}"
46
+
47
+ coordinateArrayFromServer.push(coordinate)
48
+ end
49
+ rescue
50
+ puts $!, $@
51
+ puts
52
+ next
53
+ end
54
+ end
55
+ print "\n"
56
+ puts "Done requesting coordinates from server"
57
+ puts
58
+ end
59
+
60
+ def getPostcodeFromFile
61
+ puts "Getting postcodes from file"
62
+
63
+ File.open("lib/test/sample_data/postcodes", "r") do |file|
64
+ while line = file.gets
65
+ @postcodeArrayFromFile.push(line.strip)
66
+ end
67
+ end
68
+
69
+ puts "Done getting postcodes from file"
70
+ puts
71
+ end
72
+
73
+ def getCoordinateFromFile(convertToNumbers = nil)
74
+ puts "Getting coordinates from file"
75
+ if convertToNumbers.nil?
76
+ convertToNumbers = false
77
+ end
78
+
79
+ File.open("lib/test/sample_data/coordinates", "r") do |file|
80
+ while line = file.gets
81
+ coordinate = line.strip.split("-")
82
+ if convertToNumbers == true
83
+ if coordinate[0].is_number? && coordinate[1].is_number?
84
+ coordinate[0] = coordinate[0].to_f
85
+ coordinate[1] = coordinate[1].to_f
86
+ else
87
+ raise "Error! #{coordinate[0]} & #{coordinate[1]} is not a number!"
88
+ end
89
+ end
90
+ @coordinateArrayFromFile.push(coordinate)
91
+ end
92
+ end
93
+
94
+ puts "Done getting coordinates from file"
95
+ puts
96
+ end
97
+
98
+ def writeCoordinateToFile
99
+ puts "Writing coordinates to file"
100
+
101
+ File.open("lib/test/sample_data/coordinates", "w") do |file|
102
+ @coordinateArrayFromServer.each do |coordinate|
103
+ file.puts coordinate
104
+ end
105
+ end
106
+
107
+ puts "Done writing coordinates to file"
108
+ puts
109
+ end
110
+ end
111
+
112
+ class String
113
+ def is_number?
114
+ true if Float(self) rescue false
115
+ end
116
+ end
@@ -0,0 +1,129 @@
1
+ 018954
2
+ 237978
3
+ 098138
4
+ 731678
5
+ 259727
6
+ 569922
7
+ 560163
8
+ 560448
9
+ 567740
10
+ 329783
11
+ 588177
12
+ 469661
13
+ 467360
14
+ 460539
15
+ 470632
16
+ 470744
17
+ 330022
18
+ 579837
19
+ 569981
20
+ 048508
21
+ 188024
22
+ 188426
23
+ 650632
24
+ 659841
25
+ 650152
26
+ 650374
27
+ 677743
28
+ 738099
29
+ 819643
30
+ 819633
31
+ 486038
32
+ 680624
33
+ 680623
34
+ 689812
35
+ 689810
36
+ 680533
37
+ 768677
38
+ 688892
39
+ 208539
40
+ 120451
41
+ 129588
42
+ 545078
43
+ 528833
44
+ 519498
45
+ 629117
46
+ 670445
47
+ 258748
48
+ 238884
49
+ 179097
50
+ 640762
51
+ 380113
52
+ 237994
53
+ 099253
54
+ 530208
55
+ 538692
56
+ 530684
57
+ 538766
58
+ 099010
59
+ 188067
60
+ 609601
61
+ 209037
62
+ 609731
63
+ 608549
64
+ 618640
65
+ 649849
66
+ 600256
67
+ 649520
68
+ 648886
69
+ 649296
70
+ 397726
71
+ 760846
72
+ 229899
73
+ 179030
74
+ 238868
75
+ 510258
76
+ 238863
77
+ 039594
78
+ 138588
79
+ 569830
80
+ 637331
81
+ 117587
82
+ 556083
83
+ 188721
84
+ 769098
85
+ 188307
86
+ 449408
87
+ 519640
88
+ 059108
89
+ 640638
90
+ 238839
91
+ 350148
92
+ 119963
93
+ 828815
94
+ 149066
95
+ 149053
96
+ 179103
97
+ 159460
98
+ 545082
99
+ 797653
100
+ 540118
101
+ 544964
102
+ 550267
103
+ 555951
104
+ 455871
105
+ 138651
106
+ 609081
107
+ 757713
108
+ 520513
109
+ 520512
110
+ 529341
111
+ 529510
112
+ 529284
113
+ 529705
114
+ 529757
115
+ 168732
116
+ 319515
117
+ 310490
118
+ 310109
119
+ 319387
120
+ 609971
121
+ 307591
122
+ 208767
123
+ 126844
124
+ 738931
125
+ 730900
126
+ 730768
127
+ 758382
128
+ 760293
129
+ 769027
metadata CHANGED
@@ -1,47 +1,67 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arcgis_vrps
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2.1
4
+ version: 0.0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kiong
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2015-09-08 00:00:00.000000000 Z
12
- dependencies: []
13
- description: "A ruby gem interface for ArcGIS (platform of Esri) Vehicle Routing Problem
14
- service REST API\n\n You can find the code here => https://github.com/tlkiong/arcgis_vrps\n
15
- \ "
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ~>
17
+ - !ruby/object:Gem::Version
18
+ version: '1.8'
19
+ name: json
20
+ prerelease: false
21
+ type: :runtime
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
27
+ description: A ruby gem interface for ArcGIS (platform of Esri) Vehicle Routing Problem service REST API
16
28
  email: kiong90@gmail.com
17
29
  executables: []
18
30
  extensions: []
19
- extra_rdoc_files: []
31
+ extra_rdoc_files:
32
+ - README.md
20
33
  files:
21
- - lib/arcgis_vrps.rb
22
- - lib/arcgis_vrps/sample.rb
34
+ - ./lib/arcgis_vrps.rb
35
+ - ./lib/arcgis_vrps/auth.rb
36
+ - ./lib/arcgis_vrps/depots.rb
37
+ - ./lib/arcgis_vrps/orders.rb
38
+ - ./lib/arcgis_vrps/routes.rb
39
+ - ./lib/test/data_load.rb
40
+ - ./lib/test/sample_data/postcodes
41
+ - README.md
23
42
  homepage: http://rubygems.org/gems/arcgis_vrps
24
43
  licenses:
25
44
  - MIT
26
- metadata: {}
27
- post_install_message:
45
+ metadata:
46
+ source_code: https://github.com/tlkiong/arcgis_vrps
47
+ post_install_message:
28
48
  rdoc_options: []
29
49
  require_paths:
30
50
  - lib
31
51
  required_ruby_version: !ruby/object:Gem::Requirement
32
52
  requirements:
33
- - - ">="
53
+ - - '>='
34
54
  - !ruby/object:Gem::Version
35
55
  version: '0'
36
56
  required_rubygems_version: !ruby/object:Gem::Requirement
37
57
  requirements:
38
- - - ">="
58
+ - - '>='
39
59
  - !ruby/object:Gem::Version
40
60
  version: '0'
41
61
  requirements: []
42
- rubyforge_project:
43
- rubygems_version: 2.2.3
44
- signing_key:
62
+ rubyforge_project:
63
+ rubygems_version: 2.1.9
64
+ signing_key:
45
65
  specification_version: 4
46
- summary: An interface for ArcGIS Vehicle Routing Problem service REST API
66
+ summary: ArcGIS Vehicle Routing Problem service API
47
67
  test_files: []
@@ -1,14 +0,0 @@
1
- class Arcgis_Vrps::Translator
2
- def initialize(language)
3
- @language = language
4
- end
5
-
6
- def hi
7
- case @language
8
- when "spanish"
9
- "hola mundo"
10
- else
11
- "hello world"
12
- end
13
- end
14
- end