arcgis_vrps 0.0.2.1 → 0.0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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