class Arcgis_Vrps
Public Class Methods
new(client_id, client_secret)
click to toggle source
# getOutputRoutes("jf163f4d4f7874fd69b4f6f90e2d5d9aa") # getOutputOrders("jf163f4d4f7874fd69b4f6f90e2d5d9aa")
end
# File lib/arcgis_vrps.rb, line 31 def initialize(client_id, client_secret) auth = Auth.new(client_id, client_secret) @token = auth.generateToken # puts # puts "Token generated #{@token}" # puts end
Public Instance Methods
getJobStatus()
click to toggle source
# File lib/arcgis_vrps.rb, line 157 def getJobStatus url = "https://logistics.arcgis.com/arcgis/rest/services/World/VehicleRoutingProblem/GPServer/SolveVehicleRoutingProblem/jobs/"+@jobId escaped_url = URI.encode(url) uri = URI.parse(escaped_url) req = Net::HTTP::Post.new(uri.to_s) req.set_form_data( token: @token, returnMessages: true, f: 'json' ) http = Net::HTTP.new(uri.hostname, uri.port) http.use_ssl = true res = http.request(req) status = JSON.parse(res.body)['jobStatus'] if status == "esriJobSucceeded" return res.body elsif status == "esriJobFailed" raise "\nJob failed with the following message stack:\n #{res.body}" else return false end end
getOutputOrders(jobId)
click to toggle source
# File lib/arcgis_vrps.rb, line 218 def getOutputOrders(jobId) unless jobId.nil? @jobId = jobId end url = 'https://logistics.arcgis.com/arcgis/rest/services/World/VehicleRoutingProblem/GPServer/SolveVehicleRoutingProblem/jobs/'+@jobId+'/results/out_stops' escaped_url = URI.encode(url) uri = URI.parse(escaped_url) req = Net::HTTP::Post.new(uri.to_s) req.set_form_data( token: @token, f: 'json' ) http = Net::HTTP.new(uri.hostname, uri.port) http.use_ssl = true res = http.request(req) # We return the entire string is because it have meta data about the geometry type, spatial reference, etc ordersFeatures = JSON.parse(res.body) # ordersFeatures = JSON.parse(res.body)["value"]["features"] # puts " ================================================== " # puts "ordersFeatures" # puts ordersFeatures # puts " ================================================== " if ordersFeatures.nil? ordersFeatures = res.body end return ordersFeatures end
getOutputRoutes(jobId)
click to toggle source
# File lib/arcgis_vrps.rb, line 186 def getOutputRoutes(jobId) unless jobId.nil? @jobId = jobId end url = 'https://logistics.arcgis.com/arcgis/rest/services/World/VehicleRoutingProblem/GPServer/SolveVehicleRoutingProblem/jobs/'+@jobId+'/results/out_routes' escaped_url = URI.encode(url) uri = URI.parse(escaped_url) req = Net::HTTP::Post.new(uri.to_s) req.set_form_data( token: @token, f: 'json' ) http = Net::HTTP.new(uri.hostname, uri.port) http.use_ssl = true res = http.request(req) # We return the entire string is because it have meta data about the geometry type, spatial reference, etc routesFeatures = JSON.parse(res.body) # JSON.parse(res.body)["value"]["features"]["geometry"]["paths"] will return an array of coordinates in the following format: [longitude, latitude] # routesFeatures = JSON.parse(res.body)["value"]["features"] if routesFeatures.nil? routesFeatures = res.body end return routesFeatures end
getToken()
click to toggle source
# File lib/arcgis_vrps.rb, line 41 def getToken return @token end
loadSampleData(loadFromFile)
click to toggle source
# File lib/arcgis_vrps.rb, line 254 def loadSampleData(loadFromFile) @loadData = Data_Load.new() if loadFromFile @loadData.getCoordinateFromMapSynq() @loadData.writeCoordinateToFile() end end
mockCase1(numberOfVehicles)
click to toggle source
# File lib/arcgis_vrps.rb, line 263 def mockCase1(numberOfVehicles) # Routes without any start & end time (Basic routing) puts "Setting up orders" @loadData.getCoordinateFromFile() coordinate = @loadData.coordinateArrayFromFile ord = Orders.new() i = 0 coordinate.each do |coor| store_name = "Store_"+i.to_s orderAttributeObj = ord.getBasicOrderAttributeObj(store_name) ord.addOrders(coor[0], coor[1], orderAttributeObj) if i == 50 break end i += 1 end ordersObj = ord.getOrderObj(nil) puts "Setting up depots" dep = Depots.new() deportAttributeObj = dep.getDepotAttributeObj("depot_1") dep.addDepots(103.848427, 1.277751, deportAttributeObj) depotsObj = dep.getDepotObj(nil) puts "Setting up routes" route = Routes.new() startDateTime = (Time.now.to_f * 1000).to_i for i in 1..numberOfVehicles truck_name = "Truck_#{i}" route.addRoutes(truck_name, "depot_1", startDateTime, startDateTime) end routesObj = route.getRouteObj() begin contents = submitJob(ordersObj, depotsObj, routesObj, nil) writeToFile("Mock Case 1 - #{numberOfVehicles}.json", contents) rescue Exception => e puts puts e puts end end
mockCase2(numberOfVehicles)
click to toggle source
# File lib/arcgis_vrps.rb, line 319 def mockCase2(numberOfVehicles) # 9 locations with set times that vehicles must reach (no overlapping time) puts "Setting up orders" @loadData.getCoordinateFromFile() coordinate = @loadData.coordinateArrayFromFile ord = Orders.new() i = 0 minutesInSeconds = 1800000 # 30 minutes in milliseconds timeWindowStart1 = 1441933200000 # Default date time: 11th Sept 2015, 9:00:00 AM in milliseconds timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run coordinate.each do |coor| store_name = "Store_"+i.to_s serviceTime = 30 if i < 9 && i >= 0 if i < 5 && i >= 1 # Can reach later than the set time here timeWindowStart1 += (minutesInSeconds*2) # Add 1 hour every run timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run maxViolationTime1 = nil elsif i < 9 && i >= 5 # Can reach later than the set time based on the x minute set by MaxViolationTime1 timeWindowStart1 += (minutesInSeconds*2) # Add 1 hour every run timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run maxViolationTime1 = 0 end orderAttributeObj = ord.getOrderAttributeObj(store_name, serviceTime, timeWindowStart1, timeWindowEnd1, maxViolationTime1) elsif i >= 9 timeWindowStart1 = nil timeWindowEnd1 = nil maxViolationTime1 = nil orderAttributeObj = ord.getBasicOrderAttributeObj(store_name) end ord.addOrders(coor[0], coor[1], orderAttributeObj) if i == 49 break end i += 1 end ordersObj = ord.getOrderObj(nil) puts "Setting up depots" dep = Depots.new() deportAttributeObj = dep.getDepotAttributeObj("depot_1") dep.addDepots(103.848427, 1.277751, deportAttributeObj) depotsObj = dep.getDepotObj(nil) puts "Setting up routes" route = Routes.new() startDateTime = 1441933200000 for i in 1..numberOfVehicles truck_name = "Truck_#{i}" route.addRoutes(truck_name, "depot_1", startDateTime, startDateTime) end routesObj = route.getRouteObj() # puts # puts ordersObj.to_json # puts # puts depotsObj.to_json # puts # puts routesObj.to_json # puts begin contents = submitJob(ordersObj, depotsObj, routesObj, nil) writeToFile("Mock Case 2 - #{numberOfVehicles}.json", contents) rescue Exception => e puts puts e puts end end
mockCase3(numberOfVehicles)
click to toggle source
# File lib/arcgis_vrps.rb, line 405 def mockCase3(numberOfVehicles) # 8 locations with set times that vehicles must reach (with overlapping time) puts "Setting up orders" @loadData.getCoordinateFromFile() coordinate = @loadData.coordinateArrayFromFile ord = Orders.new() i = 0 minutesInSeconds = 1800000 # 30 minutes in milliseconds timeWindowStart1 = 1441933200000 # Default date time: 11th Sept 2015, 9:00:00 AM in milliseconds timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run countThree = 0 countFive = 0 coordinate.each do |coor| store_name = "Store_"+i.to_s serviceTime = 30 if ((i%3 == 0 || i%5 == 0) && (countThree < 4 || countFive < 4)) if timeWindowStart1.nil? || timeWindowStart1 >= 1441944000000 timeWindowStart1 = 1441933200000 end if i%3 == 0 && countThree < 4 timeWindowStart1 += (minutesInSeconds*2) # Add 1 hour every run timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run maxViolationTime1 = nil countThree += 1 elsif i%5 == 0 && countFive < 4 timeWindowStart1 += (minutesInSeconds*2) # Add 1 hour every run timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run maxViolationTime1 = 0 countFive += 1 end orderAttributeObj = ord.getOrderAttributeObj(store_name, serviceTime, timeWindowStart1, timeWindowEnd1, maxViolationTime1) else timeWindowStart1 = nil timeWindowEnd1 = nil maxViolationTime1 = nil orderAttributeObj = ord.getBasicOrderAttributeObj(store_name) end ord.addOrders(coor[0], coor[1], orderAttributeObj) if i == 49 break end i += 1 end ordersObj = ord.getOrderObj(nil) puts "Setting up depots" dep = Depots.new() deportAttributeObj = dep.getDepotAttributeObj("depot_1") dep.addDepots(103.848427, 1.277751, deportAttributeObj) depotsObj = dep.getDepotObj(nil) puts "Setting up routes" route = Routes.new() startDateTime = 1441933200000 for i in 1..numberOfVehicles truck_name = "Truck_#{i}" route.addRoutes(truck_name, "depot_1", startDateTime, startDateTime) end routesObj = route.getRouteObj() # puts # puts ordersObj.to_json # puts # puts depotsObj.to_json # puts # puts routesObj.to_json # puts begin contents = submitJob(ordersObj, depotsObj, routesObj, nil) writeToFile("Mock Case 3 - #{numberOfVehicles}.json", contents) rescue Exception => e puts puts e puts end end
mockCase4(numberOfVehicles)
click to toggle source
# File lib/arcgis_vrps.rb, line 500 def mockCase4(numberOfVehicles) # Same as use case 3 but with more overlapping times than routes available puts "Setting up orders" @loadData.getCoordinateFromFile() coordinate = @loadData.coordinateArrayFromFile ord = Orders.new() i = 0 minutesInSeconds = 1800000 # 30 minutes in milliseconds timeWindowStart1 = 1441933200000 # Default date time: 11th Sept 2015, 9:00:00 AM in milliseconds timeWindowEnd1 = timeWindowStart1 + minutesInSeconds # Add 30 minutes every run countThree = 0 countFive = 0 coordinate.each do |coor| store_name = "Store_"+i.to_s serviceTime = 30 if i < 6 # This if block is to set 3 with MaxViolationTime1 and 3 without # if i < 3 && i >= 0 # maxViolationTime1 = nil # elsif i < 6 && i >= 3 # maxViolationTime1 = 0 # end maxViolationTime1 = 0 # This is to set all 6 with MaxViolationTime1 orderAttributeObj = ord.getOrderAttributeObj(store_name, serviceTime, timeWindowStart1, timeWindowEnd1, maxViolationTime1) else timeWindowStart1 = nil timeWindowEnd1 = nil maxViolationTime1 = nil orderAttributeObj = ord.getBasicOrderAttributeObj(store_name) end ord.addOrders(coor[0], coor[1], orderAttributeObj) if i == 49 break end i += 1 end ordersObj = ord.getOrderObj(nil) puts "Setting up depots" dep = Depots.new() deportAttributeObj = dep.getDepotAttributeObj("depot_1") dep.addDepots(103.848427, 1.277751, deportAttributeObj) depotsObj = dep.getDepotObj(nil) puts "Setting up routes" route = Routes.new() startDateTime = 1441933200000 for i in 1..numberOfVehicles truck_name = "Truck_#{i}" route.addRoutes(truck_name, "depot_1", startDateTime, startDateTime) end routesObj = route.getRouteObj() # puts # puts ordersObj.to_json # puts # puts depotsObj.to_json # puts # puts routesObj.to_json # puts begin contents = submitJob(ordersObj, depotsObj, routesObj, nil) writeToFile("Mock Case 4 - location - 6.json", contents) rescue Exception => e puts puts e puts end end
submitJob(ordersObj, depotsObj, routesObj, timer)
click to toggle source
# File lib/arcgis_vrps.rb, line 45 def submitJob(ordersObj, depotsObj, routesObj, timer) # TODO: Check to decide whether to use synchronous or async puts "Submitting job" jobStatusNoOfCalls = 0 t1 = Time.now.to_i url = "https://logistics.arcgis.com/arcgis/rest/services/World/VehicleRoutingProblem/GPServer/SolveVehicleRoutingProblem/submitJob" escaped_url = URI.encode(url) uri = URI.parse(escaped_url) req = Net::HTTP::Post.new(uri.to_s) # Expiration is set to 20160 minutes = 2 weeks req.set_form_data( orders: ordersObj.to_json, depots: depotsObj.to_json, routes: routesObj.to_json, # default_date: Time.now.to_f, # This must be in milliseconds default_date: 1453600108000, token: @token, f: 'json', time_units: 'Seconds', distance_units: 'Meters' ) http = Net::HTTP.new(uri.hostname, uri.port) http.use_ssl = true res = http.request(req) # print " ======================================================== " # print "req" # print ordersObj.to_json # print " ----- " # print depotsObj.to_json # print " ----- " # print routesObj.to_json # print " ----- " # print Time.now.to_i # print " ----- " # print @token # print " ======================================================== " @jobId = JSON.parse(res.body)['jobId'] if @jobId.nil? raise "Error! #{res.body}" else puts "Received job ID: #{@jobId}" print "Getting job status..." if timer.nil? timer = 1 # Timer of 500ms to constantly check for updates end start_time = Time.now end_time = start_time+timer completed = false begin while completed == false print "." jobStatusNoOfCalls += 1 while Time.now < end_time end completed = getJobStatus() end print "Completed!\n" puts # puts completed.to_s # puts t2 = Time.now.to_i time_jobStatusIsComplete = t2-t1 puts "Time taken for job to be completed: #{time_jobStatusIsComplete}" puts routesReceived = getOutputRoutes(nil) # routesReceived = "Routes received: \n #{routesReceived}" ordersReceived = getOutputOrders(nil) # ordersReceived = "Orders received: \n #{ordersReceived}" t3 = Time.now.to_i time_fullJobComplete = t3-t1 # extraContent = "Total time taken for getting routes and orders: #{time_fullJobComplete} \nNumber of calls to jobStatus: #{jobStatusNoOfCalls} \n\n" extraContent = { :time_job_status_complete => time_jobStatusIsComplete, :time_full_job_complete => time_fullJobComplete, :no_of_job_status_call => jobStatusNoOfCalls } # puts extraContent # puts return extraContent, routesReceived, ordersReceived rescue Exception => e puts puts e puts end end end
writeCoordinateToFile()
click to toggle source
# File lib/arcgis_vrps.rb, line 587 def writeCoordinateToFile @loadData.getCoordinateFromFile(true) coordinate = @loadData.coordinateArrayFromFile writeToFile("coordinateArray", coordinate.to_json); end
writeToFile(filename, contents)
click to toggle source
# File lib/arcgis_vrps.rb, line 593 def writeToFile(filename, contents) puts "Writing to file #{filename}" File.open("lib/test/sample_data/#{filename}", "w") do |file| if contents.kind_of?(Array) contents.each do |content| file.puts content file.puts end else file.puts contents file.puts end end puts "Done writing to file #{filename}" puts end