{ "cells": [ { "cell_type": "markdown", "id": "c7b9fee7", "metadata": { "tags": [] }, "source": [ "# Use Sagemaker to use Optimization Libraries\n", "We will test ecerithing using a local endpoint and will use SKLearn container as starting point to run optimization algorithm. \n", "The first step is to set-up the evironment importing required libraries and defining a bucket to host our model data." ] }, { "cell_type": "code", "execution_count": 2, "id": "81fe6c07", "metadata": {}, "outputs": [], "source": [ "import boto3\n", "import numpy as np\n", "import sagemaker\n", "\n", "from sagemaker import get_execution_role\n", "\n", "sagemaker_session = sagemaker.Session()\n", "\n", "# Get a SageMaker-compatible role used by this Notebook Instance.\n", "role = get_execution_role()\n", "\n", "bucket = sagemaker_session.default_bucket()\n", "prefix = \"blogpost_location_service\"\n", "\n", "my_session = boto3.session.Session()\n", "my_region = my_session.region_name" ] }, { "cell_type": "markdown", "id": "0b4b16c0", "metadata": {}, "source": [ "## Build a Sagemaker Model based on SKLearn\n", "To test the algorithm we will use a standard SKLearn container providing information about the script that we would like to run (scripts-or-tools/algorithm.py) and additional libraries that shall be installed in order to be able to execute the script (scripts-or-tools/requirements.txt).\n", "The key part of our script are:\n", "- **__main__** - this is run during the training phase\n", "- **model_fn** - executed during endpoint deployment start-up phase to load weight related to trained model\n", "- **input_fn** - executed everitime inference method is invoked to adapt input data format to expected model format\n", "- **predict_fn** - executes the inference here we use or-tools library in order to solve our Capacity Constrained Vehicle Routing Problem\n", "- **output_fn** - executed right after the inference to adapt inference output data to expected output format that shall be returned to the caller. \n", " \n", "In this specific example since the optimization algorithm doesn't need a training phase we fill in the main function to generate dummy training data and the model_fn fucntion to load dummy training data.\n", "\n", "Below you can see the detailed content of algorithm.py" ] }, { "cell_type": "code", "execution_count": 3, "id": "3b416974", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "from __future__ import print_function\n", "\n", "import csv\n", "import json\n", "import numpy as np\n", "import pandas as pd\n", "import boto3\n", "\n", "import os\n", "import argparse\n", "\n", "from ortools.constraint_solver import routing_enums_pb2\n", "from ortools.constraint_solver import pywrapcp\n", "\n", "from sagemaker_containers.beta.framework import (\n", " content_types, encoders, env, modules, transformer, worker)\n", " \n", "\n", " \n", "#####\n", "#Sagemaker interface\n", "#####\n", "def model_fn (model_dir):\n", " print (\"ModelFN\")\n", " return (\"DUMMY MODEL\")\n", "\n", "def input_fn(input_data, content_type):\n", " \"\"\"Parse input data payload\n", "\n", " We currently only take csv input. Since we need to process both labelled\n", " and unlabelled data we first determine whether the label column is present\n", " by looking at how many columns were provided.\n", " \"\"\"\n", " print (\"InputFN\")\n", " print (\"content_type:\",content_type)\n", " print (\"input_data:\",input_data)\n", " if content_type == 'application/json':\n", " # Read the raw input data as CSV.\n", " list=json.loads(input_data)\n", " #Catching multiple nested json to string encapsulation \n", " if (type(list)==str):\n", " list=json.loads(input_data)\n", " if (type(list)==str):\n", " list=json.loads(input_data)\n", " return list\n", " else:\n", " raise ValueError(\"{} not supported by script!\".format(content_type))\n", "\n", "\n", "def output_fn(prediction, accept):\n", " \"\"\"Format prediction output\n", "\n", " The default accept/content-type between containers for serial inference is JSON.\n", " We also want to set the ContentType or mimetype as the same value as accept so the next\n", " container can read the response payload correctly.\n", " \"\"\"\n", " if accept == \"application/json\":\n", " \n", " if prediction['result']!='NOT FOUND':\n", " data=prediction['data']\n", " manager=prediction['manager']\n", " routing=prediction['routing']\n", " solution=prediction['solution']\n", "\n", " \"\"\"Prints solution on console.\"\"\"\n", " routes=[]\n", " print(f'Objective: {solution.ObjectiveValue()}')\n", " max_route_distance = 0\n", " for vehicle_id in range(data['num_vehicles']):\n", " index = routing.Start(vehicle_id)\n", " plan_output = 'Route for vehicle {}:\\n'.format(vehicle_id)\n", " route_distance = 0\n", " route=[]\n", " while not routing.IsEnd(index):\n", " plan_output += ' {} -> '.format(manager.IndexToNode(index))\n", " route.append(manager.IndexToNode(index))\n", " previous_index = index\n", " index = solution.Value(routing.NextVar(index))\n", " route_distance += routing.GetArcCostForVehicle(\n", " previous_index, index, vehicle_id)\n", "\n", " plan_output += '{}\\n'.format(manager.IndexToNode(index))\n", " route.append(manager.IndexToNode(index))\n", " plan_output += 'Distance of the route: {}m\\n'.format(route_distance)\n", " print(plan_output)\n", " routes.append(route)\n", " max_route_distance = max(route_distance, max_route_distance)\n", " print('Maximum of the route distances: {}m'.format(max_route_distance))\n", " else:\n", " routes='NOT FOUND'\n", " return (json.dumps(routes))\n", "\n", " else:\n", " raise RuntimeException(\"{} accept type is not supported by this script.\".format(accept))\n", "\n", "def predict_fn(input_data, model):\n", " \"\"\"Preprocess input data\n", "\n", " We implement this because the default predict_fn uses .predict(), but our model is a preprocessor\n", " so we want to use .transform().\n", "\n", " The output is returned in the following order:\n", "\n", " rest of features either one hot encoded or standardized\n", " \"\"\"\n", " # Create the routing index manager.\n", " manager = pywrapcp.RoutingIndexManager(len(input_data['distance_matrix']),\n", " input_data['num_vehicles'], input_data['depot'])\n", "\n", " # Create Routing Model.\n", " routing = pywrapcp.RoutingModel(manager)\n", "\n", " # Create and register a transit callback.\n", " def distance_callback(from_index, to_index):\n", " \"\"\"Returns the distance between the two nodes.\"\"\"\n", " # Convert from routing variable Index to distance matrix NodeIndex.\n", " from_node = manager.IndexToNode(from_index)\n", " to_node = manager.IndexToNode(to_index)\n", " return input_data['distance_matrix'][from_node][to_node]\n", "\n", " transit_callback_index = routing.RegisterTransitCallback(distance_callback)\n", "\n", " # Define cost of each arc.\n", " routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)\n", " \n", " # Create and register a demand callback.\n", " def demand_callback(from_index):\n", " \"\"\"Returns the demand of the node.\"\"\"\n", " # Convert from routing variable Index to demands NodeIndex.\n", " from_node = manager.IndexToNode(from_index)\n", " #Consume a slot\n", " return 1\n", "\n", " demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback)\n", "\n", " routing.AddDimensionWithVehicleCapacity(\n", " demand_callback_index,\n", " 0, # null capacity slack\n", " input_data['vehicle_capacities'], # vehicle maximum capacities\n", " True, # start cumul to zero\n", " 'Capacity')\n", "\n", "\n", "\n", " # Add Distance constraint.\n", " dimension_name = 'Distance'\n", " routing.AddDimension(\n", " transit_callback_index,\n", " 0, # no slack\n", " 3000, # vehicle maximum travel distance\n", " True, # start cumul to zero\n", " dimension_name)\n", " distance_dimension = routing.GetDimensionOrDie(dimension_name)\n", " distance_dimension.SetGlobalSpanCostCoefficient(5000)\n", "\n", " # Setting first solution heuristic.\n", " search_parameters = pywrapcp.DefaultRoutingSearchParameters()\n", " search_parameters.first_solution_strategy = (\n", " routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)\n", "\n", " search_parameters.local_search_metaheuristic = (\n", " routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)\n", " search_parameters.time_limit.FromSeconds(10)\n", "\n", "\n", " # Solve the problem.\n", " solution = routing.SolveWithParameters(search_parameters)\n", " if solution:\n", " prediction={\n", " 'data':input_data,\n", " 'manager':manager,\n", " 'routing':routing,\n", " 'solution':solution,\n", " 'result':'OK'\n", " }\n", " else:\n", " prediction={'result':'NOT FOUND'}\n", " return prediction\n", "\n", "\n", "##Dummy Training Function\n", "\n", "if __name__ == '__main__':\n", "\n", " # Sagemaker specific arguments. Defaults are set in the environment variables. \n", " parser = argparse.ArgumentParser()\n", "\n", " parser.add_argument('--model-dir', type=str, default=os.environ['SM_MODEL_DIR'])\n", "\n", " args = parser.parse_args()\n", " \n", " \n", " with open( os.path.join(args.model_dir, \"model.data\"), 'w') as f:\n", " f.write('ok')\n", " f.close()\n", " print(\"mode saved!\")\n", " \n" ] } ], "source": [ "!cat scripts-or-tools/algorithm.py" ] }, { "cell_type": "markdown", "id": "46d88634", "metadata": {}, "source": [ "We can build a dummi model.tar.gz locally, save it in an s3 bucket and use this one to build our SKLearn model." ] }, { "cell_type": "code", "execution_count": 4, "id": "daec1ad9-71da-4229-ace6-53da6bc4953d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "./dummy.ok\n", "upload: ./model.tar.gz to s3://sagemaker-eu-west-1-113878695749/blogpost_location_service/20221021-155050/model.tar.gz\n", "Data saved to: s3://sagemaker-eu-west-1-113878695749/blogpost_location_service/20221021-155050\n" ] } ], "source": [ "from datetime import datetime\n", "timestamp = datetime.now().strftime(\"%Y%m%d-%H%M%S\")\n", "!rm model.tar.gz\n", "!touch dummy.ok; tar -czvf model.tar.gz ./dummy.ok\n", "!aws s3 cp model.tar.gz s3://{bucket}/{prefix}/{timestamp}/model.tar.gz\n", "print (f\"Data saved to: s3://{bucket}/{prefix}/{timestamp}\")" ] }, { "cell_type": "markdown", "id": "fa94dfe0-3be1-46ae-98b0-6e699068865f", "metadata": {}, "source": [ "We are now ready to use SKLearnModel passing information about our local scripts and dummy model.tar.gz file. " ] }, { "cell_type": "code", "execution_count": 5, "id": "31d381ce-0f12-4cf6-9082-b1d6e6fcc490", "metadata": {}, "outputs": [], "source": [ "from sagemaker.sklearn.model import SKLearnModel\n", "modelName=f\"RouteOptimiser-{timestamp}\"\n", "sklearn_preprocessor = SKLearnModel(\n", " role=role,\n", " predictor_cls = sagemaker.predictor.Predictor,\n", " sagemaker_session = sagemaker_session,\n", " name=modelName,\n", " model_data=f\"s3://{bucket}/{prefix}/{timestamp}/model.tar.gz\",\n", " source_dir = 'scripts-or-tools',\n", " entry_point= 'algorithm.py',\n", " framework_version ='0.23-1'\n", ")" ] }, { "cell_type": "markdown", "id": "e2b02136", "metadata": {}, "source": [ "## Model Deploy\n", "We can now deploy our model to accepts json as input and output format on a serverless endpoint defining a serverless inference config in order to specify the memory that should be allocated to run our optimization algorithm and a maximum concurrency." ] }, { "cell_type": "code", "execution_count": 6, "id": "fc3c59fd-48d3-41b6-991b-32ccfaffcc00", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-----!" ] } ], "source": [ "from sagemaker.serverless import ServerlessInferenceConfig\n", "from sagemaker.serializers import JSONSerializer\n", "from sagemaker.deserializers import JSONDeserializer\n", "\n", "# Create an empty ServerlessInferenceConfig object to use default values\n", "serverless_config = ServerlessInferenceConfig(\n", " memory_size_in_mb=4096,\n", " max_concurrency=10)\n", "\n", "predictor=sklearn_preprocessor.deploy(\n", " serverless_inference_config=serverless_config,\n", " serializer=JSONSerializer(content_type='application/json'),\n", " deserializer=JSONDeserializer(accept='application/json'))\n" ] }, { "cell_type": "code", "execution_count": null, "id": "e9f1bc29", "metadata": { "scrolled": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "5df9c02c", "metadata": {}, "source": [ "## Now we are Ready for Testing\n", "To run a full test of the optimization algorithm we would like to start from some ponts on a map, I select for this test some points in a area of Rome full of oneway streets to see which is the result." ] }, { "cell_type": "markdown", "id": "afbb6103-45e1-4371-9e7c-3cd256a80438", "metadata": {}, "source": [ "In order to be able to use location services we need to retrieve the name of the instances that cloudformation has created for us.\n", "Please configure the name of the cloudformation template you executed to set-up the environmetn" ] }, { "cell_type": "code", "execution_count": 8, "id": "f109ad14-630a-444f-a8f4-512b43fad955", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'CREATE_COMPLETE'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import time\n", "cf=boto3.client ('cloudformation')\n", "stackName='LocationServiceDemo'\n", "response = cf.describe_stacks( StackName=stackName) \n", "\n", "while response['Stacks'][0]['StackStatus'] == 'CREATE_IN_PROGRESS':\n", " time.sleep(10)\n", " response = cf.describe_stacks( StackName=stackName) \n", " print (response['Stacks'][0]['StackStatus'])\n", "response['Stacks'][0]['StackStatus'] " ] }, { "cell_type": "code", "execution_count": 9, "id": "14e9d82e-f40d-4932-bc9c-67d389ffb5bf", "metadata": {}, "outputs": [], "source": [ "for output in response['Stacks'][0]['Outputs']:\n", " if output['OutputKey']=='CalculatorName':\n", " locationCalculatorName=output['OutputValue']\n", " if output['OutputKey']=='MapName':\n", " locationMapName=output['OutputValue']" ] }, { "cell_type": "markdown", "id": "ec898a5a", "metadata": {}, "source": [ "Define a list of points, the first is the starting and the ending point of te garbage collection route, the other points are where garbage bins are located" ] }, { "cell_type": "code", "execution_count": 10, "id": "7a45b383", "metadata": {}, "outputs": [], "source": [ "PointOfInterest=[\n", " [12.461333,41.906652 ], #via Properzio -oneway\n", " [12.462247,41.906664 ], #via Tibullo - oneway\n", " [12.463036,41.906764 ], #via Terenzio - oneway\n", " [12.460591,41.906862 ] #via Cola Di Rienzo 2-ways\n", "]" ] }, { "cell_type": "markdown", "id": "b830bf66", "metadata": {}, "source": [ "Generate Route Matrix to be used by optimization algorith leveraging AWS Location Services.\n", "Set-up contrstaints in order to be able to find routes allowed for garbage trucks (size and weight)." ] }, { "cell_type": "code", "execution_count": 12, "id": "25bebfbd", "metadata": {}, "outputs": [], "source": [ "location=boto3.client('location')\n", "response=location.calculate_route_matrix(\n", " CalculatorName= locationCalculatorName,\n", " DepartNow= True,\n", " DistanceUnit= \"Kilometers\",\n", " TravelMode= \"Truck\",\n", " TruckModeOptions= {\n", " 'AvoidFerries': True,\n", " 'AvoidTolls': True,\n", " 'Dimensions': {\n", " 'Height': 3.5,\n", " 'Length': 4.95,\n", " 'Unit': \"Meters\",\n", " 'Width': 1.9,\n", " },\n", " 'Weight': {\n", " 'Total': 4500,\n", " 'Unit': \"Kilograms\",\n", " },\n", " },\n", " DeparturePositions=PointOfInterest,\n", " DestinationPositions=PointOfInterest)\n" ] }, { "cell_type": "markdown", "id": "eaa72e8c", "metadata": {}, "source": [ "Fill in the Distance matrix with the information returned by Amazon Location service calculate_route_matrix and store in a numpy matrix" ] }, { "cell_type": "code", "execution_count": 13, "id": "e994c697", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0. , 0.812, 0.731, 0.679],\n", " [0.824, 0. , 0.674, 0.622],\n", " [0.787, 0.718, 0. , 0.263],\n", " [0.88 , 0.837, 0.756, 0. ]])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "DistanceMatrix=np.zeros((len(response['RouteMatrix']),len(response['RouteMatrix'][0])))\n", "for i in range (0,len(response['RouteMatrix'])):\n", " for j in range (0,len(response['RouteMatrix'][i])):\n", " DistanceMatrix[i][j]=response['RouteMatrix'][i][j]['Distance']\n", " \n", "DistanceMatrix" ] }, { "cell_type": "markdown", "id": "d6dcc822", "metadata": {}, "source": [ "Distance Matrix is Asymmetric to reflect that some points are in one-way roads. \n", "\n", "## Prepare data for Optimization Algorithm\n", "Prepare data structure to submit problem to solver:\n", "- distance_matrix contains the distance matrix\n", "- num_vehicles contains the number of trucks I can have to collect trash\n", "- depot is the item in the instance matrix that is the depot (start and end point of the trash collection cycle)\n", "- vehicle_capacities is an array that specify the capacity (number of trash bins that can be collected before the truck becomes full) for each truck in the fleet\n" ] }, { "cell_type": "code", "execution_count": 14, "id": "da8d33cc", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 15 ms, sys: 15 µs, total: 15 ms\n", "Wall time: 16.6 s\n" ] }, { "data": { "text/plain": [ "[[0, 3, 2, 1, 0]]" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "data = {}\n", "data['distance_matrix'] = DistanceMatrix.tolist()\n", "data['num_vehicles'] = 1\n", "data['depot'] = 0\n", "data['vehicle_capacities']=[20]\n", "\n" ] }, { "cell_type": "markdown", "id": "36fa5742-f640-4b95-b540-2181d2e45a04", "metadata": {}, "source": [ "Now we are ready to call the solver" ] }, { "cell_type": "code", "execution_count": 24, "id": "4e16378d-b678-4947-b913-bd050c15cfc2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[0, 3, 2, 1, 0]]" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "prediction_result=predictor.predict (data)\n", "\n", "prediction_result" ] }, { "cell_type": "markdown", "id": "0bc794d1", "metadata": {}, "source": [ "Result contains an ordered list of the edges that the truck has to go through.\n", "Now we want to convert back edge indexes to geo referenced points" ] }, { "cell_type": "code", "execution_count": 15, "id": "eb155929", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[12.460591, 41.906862], [12.463036, 41.906764], [12.462247, 41.906664]]" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "optimized_path=prediction_result[0]\n", "WayPoints=[]\n", "#loop on points skipping first and last\n", "for i in range (1,len(optimized_path)-1):\n", " WayPoints.append(PointOfInterest[optimized_path[i]])\n", " \n", "WayPoints " ] }, { "cell_type": "markdown", "id": "5617311b", "metadata": {}, "source": [ "## Plot route on a map" ] }, { "cell_type": "markdown", "id": "bdb0d5ad", "metadata": {}, "source": [ "Use AWS Location service to extract routes details used to draw the route on a map leveraing IncludeLegGeometry feature available in Amazon Location Service calculate_route method. \n", "\n", "We provede start and end route points and all trash bin point in the same order as returned by the optimization algorithm. \n", "We also provide additional informatin about the type of vehicle (\"Truck\") and its size in order to retrieve the correct path and avoid ruoutes that are not matching this requirement." ] }, { "cell_type": "code", "execution_count": 17, "id": "b44f5742", "metadata": {}, "outputs": [], "source": [ "response = location.calculate_route(\n", " CalculatorName= locationCalculatorName,\n", " DepartNow=True,\n", " DeparturePosition=PointOfInterest[optimized_path[0]], #Start and Endpoint are the same\n", " DestinationPosition=PointOfInterest[optimized_path[0]],\n", " DistanceUnit='Kilometers',\n", " IncludeLegGeometry=True, # Ask location services to break down the route in segmets that can be easily print on a map\n", " TravelMode='Truck',\n", " TruckModeOptions= {\n", " 'AvoidFerries': True,\n", " 'AvoidTolls': True,\n", " 'Dimensions': {\n", " 'Height': 3.5,\n", " 'Length': 4.95,\n", " 'Unit': \"Meters\",\n", " 'Width': 1.9,\n", " },\n", " 'Weight': {\n", " 'Total': 4500,\n", " 'Unit': \"Kilograms\",\n", " },\n", " },\n", " WaypointPositions=WayPoints # Ordered list of the trash bin to be collected as returned by the optimizer\n", ")" ] }, { "cell_type": "markdown", "id": "15e3e5fb", "metadata": {}, "source": [ "The response contains a Geometry element including the information about all legs buildling the full route." ] }, { "cell_type": "code", "execution_count": 18, "id": "e8ab8156", "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "{'ResponseMetadata': {'RequestId': '9a4947e7-70aa-44e6-b68e-7dff25f0df08',\n", " 'HTTPStatusCode': 200,\n", " 'HTTPHeaders': {'date': 'Fri, 21 Oct 2022 16:14:55 GMT',\n", " 'content-type': 'application/json',\n", " 'content-length': '5693',\n", " 'connection': 'keep-alive',\n", " 'x-amzn-requestid': '9a4947e7-70aa-44e6-b68e-7dff25f0df08',\n", " 'access-control-allow-origin': '*',\n", " 'x-amz-apigw-id': 'aXPMBHJiDoEFRRg=',\n", " 'access-control-expose-headers': 'x-amzn-errortype,x-amzn-requestid,x-amzn-errormessage,x-amzn-trace-id,x-amz-apigw-id,date',\n", " 'x-amzn-trace-id': 'Root=1-6352c57f-10426ac201d6beda14d31cfc'},\n", " 'RetryAttempts': 0},\n", " 'Legs': [{'Distance': 0.679,\n", " 'DurationSeconds': 230,\n", " 'EndPosition': [12.4605994, 41.9068425],\n", " 'Geometry': {'LineString': [[12.461333, 41.906652],\n", " [12.46137, 41.90703],\n", " [12.46179, 41.90714],\n", " [12.46229, 41.90726],\n", " [12.46278, 41.90738],\n", " [12.4633, 41.90751],\n", " [12.46394, 41.90767],\n", " [12.46419, 41.90715],\n", " [12.46368, 41.90705],\n", " [12.46296, 41.90692],\n", " [12.46278, 41.90738],\n", " [12.46229, 41.90726],\n", " [12.46179, 41.90714],\n", " [12.46137, 41.90703],\n", " [12.461, 41.90694],\n", " [12.460599, 41.906843]]},\n", " 'StartPosition': [12.4613328, 41.9066519],\n", " 'Steps': [{'Distance': 0.042,\n", " 'DurationSeconds': 22,\n", " 'EndPosition': [12.46137, 41.90703],\n", " 'GeometryOffset': 0,\n", " 'StartPosition': [12.461333, 41.906652]},\n", " {'Distance': 0.226,\n", " 'DurationSeconds': 81,\n", " 'EndPosition': [12.46394, 41.90767],\n", " 'GeometryOffset': 1,\n", " 'StartPosition': [12.46137, 41.90703]},\n", " {'Distance': 0.061,\n", " 'DurationSeconds': 18,\n", " 'EndPosition': [12.46419, 41.90715],\n", " 'GeometryOffset': 6,\n", " 'StartPosition': [12.46394, 41.90767]},\n", " {'Distance': 0.106,\n", " 'DurationSeconds': 35,\n", " 'EndPosition': [12.46296, 41.90692],\n", " 'GeometryOffset': 7,\n", " 'StartPosition': [12.46419, 41.90715]},\n", " {'Distance': 0.053,\n", " 'DurationSeconds': 35,\n", " 'EndPosition': [12.46278, 41.90738],\n", " 'GeometryOffset': 9,\n", " 'StartPosition': [12.46296, 41.90692]},\n", " {'Distance': 0.191,\n", " 'DurationSeconds': 39,\n", " 'EndPosition': [12.460599, 41.906843],\n", " 'GeometryOffset': 10,\n", " 'StartPosition': [12.46278, 41.90738]}]},\n", " {'Distance': 1.09,\n", " 'DurationSeconds': 429,\n", " 'EndPosition': [12.4630188, 41.9067604],\n", " 'Geometry': {'LineString': [[12.460599, 41.906843],\n", " [12.46026, 41.90676],\n", " [12.45966, 41.90661],\n", " [12.45921, 41.9065],\n", " [12.45907, 41.90647],\n", " [12.45897, 41.90645],\n", " [12.45884, 41.90643],\n", " [12.45872, 41.90642],\n", " [12.45861, 41.90642],\n", " [12.45842, 41.90643],\n", " [12.45781, 41.90648],\n", " [12.45672, 41.90656],\n", " [12.45669, 41.9063],\n", " [12.45668, 41.90616],\n", " [12.45777, 41.90592],\n", " [12.45795, 41.90588],\n", " [12.45811, 41.90585],\n", " [12.45826, 41.90583],\n", " [12.45843, 41.90581],\n", " [12.45857, 41.9058],\n", " [12.45882, 41.90579],\n", " [12.45881, 41.90595],\n", " [12.45881, 41.90602],\n", " [12.45881, 41.90609],\n", " [12.45907, 41.90607],\n", " [12.45976, 41.90601],\n", " [12.46021, 41.90597],\n", " [12.46124, 41.90589],\n", " [12.46197, 41.90585],\n", " [12.46215, 41.90584],\n", " [12.46267, 41.90581],\n", " [12.46307, 41.90578],\n", " [12.46322, 41.90577],\n", " [12.4634, 41.90576],\n", " [12.46338, 41.90583],\n", " [12.46335, 41.90592],\n", " [12.46332, 41.906],\n", " [12.46323, 41.90621],\n", " [12.46316, 41.90638],\n", " [12.4631, 41.90654],\n", " [12.463019, 41.90676]]},\n", " 'StartPosition': [12.4605994, 41.9068425],\n", " 'Steps': [{'Distance': 0.154,\n", " 'DurationSeconds': 55,\n", " 'EndPosition': [12.45884, 41.90643],\n", " 'GeometryOffset': 0,\n", " 'StartPosition': [12.460599, 41.906843]},\n", " {'Distance': 0.177,\n", " 'DurationSeconds': 130,\n", " 'EndPosition': [12.45672, 41.90656],\n", " 'GeometryOffset': 6,\n", " 'StartPosition': [12.45884, 41.90643]},\n", " {'Distance': 0.045,\n", " 'DurationSeconds': 26,\n", " 'EndPosition': [12.45668, 41.90616],\n", " 'GeometryOffset': 11,\n", " 'StartPosition': [12.45672, 41.90656]},\n", " {'Distance': 0.182,\n", " 'DurationSeconds': 46,\n", " 'EndPosition': [12.45882, 41.90579],\n", " 'GeometryOffset': 13,\n", " 'StartPosition': [12.45668, 41.90616]},\n", " {'Distance': 0.033,\n", " 'DurationSeconds': 12,\n", " 'EndPosition': [12.45881, 41.90609],\n", " 'GeometryOffset': 20,\n", " 'StartPosition': [12.45882, 41.90579]},\n", " {'Distance': 0.384,\n", " 'DurationSeconds': 128,\n", " 'EndPosition': [12.4634, 41.90576],\n", " 'GeometryOffset': 23,\n", " 'StartPosition': [12.45881, 41.90609]},\n", " {'Distance': 0.115,\n", " 'DurationSeconds': 32,\n", " 'EndPosition': [12.463019, 41.90676],\n", " 'GeometryOffset': 33,\n", " 'StartPosition': [12.4634, 41.90576]}]},\n", " {'Distance': 0.717,\n", " 'DurationSeconds': 206,\n", " 'EndPosition': [12.4622294, 41.9066649],\n", " 'Geometry': {'LineString': [[12.463019, 41.90676],\n", " [12.46296, 41.90692],\n", " [12.46278, 41.90738],\n", " [12.4633, 41.90751],\n", " [12.46394, 41.90767],\n", " [12.46419, 41.90715],\n", " [12.46439, 41.90664],\n", " [12.46461, 41.90617],\n", " [12.46477, 41.90565],\n", " [12.46421, 41.9057],\n", " [12.46381, 41.90573],\n", " [12.4634, 41.90576],\n", " [12.46322, 41.90577],\n", " [12.46307, 41.90578],\n", " [12.46267, 41.90581],\n", " [12.46215, 41.90584],\n", " [12.46221, 41.90647],\n", " [12.462229, 41.906665]]},\n", " 'StartPosition': [12.4630188, 41.9067604],\n", " 'Steps': [{'Distance': 0.071,\n", " 'DurationSeconds': 24,\n", " 'EndPosition': [12.46278, 41.90738],\n", " 'GeometryOffset': 0,\n", " 'StartPosition': [12.463019, 41.90676]},\n", " {'Distance': 0.102,\n", " 'DurationSeconds': 43,\n", " 'EndPosition': [12.46394, 41.90767],\n", " 'GeometryOffset': 2,\n", " 'StartPosition': [12.46278, 41.90738]},\n", " {'Distance': 0.234,\n", " 'DurationSeconds': 63,\n", " 'EndPosition': [12.46477, 41.90565],\n", " 'GeometryOffset': 4,\n", " 'StartPosition': [12.46394, 41.90767]},\n", " {'Distance': 0.218,\n", " 'DurationSeconds': 58,\n", " 'EndPosition': [12.46215, 41.90584],\n", " 'GeometryOffset': 8,\n", " 'StartPosition': [12.46477, 41.90565]},\n", " {'Distance': 0.092,\n", " 'DurationSeconds': 18,\n", " 'EndPosition': [12.462229, 41.906665],\n", " 'GeometryOffset': 15,\n", " 'StartPosition': [12.46215, 41.90584]}]},\n", " {'Distance': 0.824,\n", " 'DurationSeconds': 238,\n", " 'EndPosition': [12.4613328, 41.9066519],\n", " 'Geometry': {'LineString': [[12.462229, 41.906665],\n", " [12.46226, 41.90697],\n", " [12.46229, 41.90726],\n", " [12.46278, 41.90738],\n", " [12.4633, 41.90751],\n", " [12.46394, 41.90767],\n", " [12.46419, 41.90715],\n", " [12.46439, 41.90664],\n", " [12.46461, 41.90617],\n", " [12.46477, 41.90565],\n", " [12.46421, 41.9057],\n", " [12.46381, 41.90573],\n", " [12.4634, 41.90576],\n", " [12.46322, 41.90577],\n", " [12.46307, 41.90578],\n", " [12.46267, 41.90581],\n", " [12.46215, 41.90584],\n", " [12.46197, 41.90585],\n", " [12.46124, 41.90589],\n", " [12.46131, 41.90642],\n", " [12.461333, 41.906652]]},\n", " 'StartPosition': [12.4622294, 41.9066649],\n", " 'Steps': [{'Distance': 0.066,\n", " 'DurationSeconds': 27,\n", " 'EndPosition': [12.46229, 41.90726],\n", " 'GeometryOffset': 0,\n", " 'StartPosition': [12.462229, 41.906665]},\n", " {'Distance': 0.145,\n", " 'DurationSeconds': 57,\n", " 'EndPosition': [12.46394, 41.90767],\n", " 'GeometryOffset': 2,\n", " 'StartPosition': [12.46229, 41.90726]},\n", " {'Distance': 0.234,\n", " 'DurationSeconds': 63,\n", " 'EndPosition': [12.46477, 41.90565],\n", " 'GeometryOffset': 5,\n", " 'StartPosition': [12.46394, 41.90767]},\n", " {'Distance': 0.294,\n", " 'DurationSeconds': 74,\n", " 'EndPosition': [12.46124, 41.90589],\n", " 'GeometryOffset': 9,\n", " 'StartPosition': [12.46477, 41.90565]},\n", " {'Distance': 0.085,\n", " 'DurationSeconds': 17,\n", " 'EndPosition': [12.461333, 41.906652],\n", " 'GeometryOffset': 18,\n", " 'StartPosition': [12.46124, 41.90589]}]}],\n", " 'Summary': {'DataSource': 'Here',\n", " 'Distance': 3.31,\n", " 'DistanceUnit': 'Kilometers',\n", " 'DurationSeconds': 1103,\n", " 'RouteBBox': [12.45668, 41.90565, 12.46477, 41.90767]}}" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "response" ] }, { "cell_type": "markdown", "id": "e282ca65", "metadata": {}, "source": [ "Extract paths from the overall route to be able to render them on Map" ] }, { "cell_type": "code", "execution_count": 19, "id": "66aa7d80", "metadata": { "scrolled": true }, "outputs": [], "source": [ "path=[]\n", "for leg in response['Legs']:\n", " path.append ([leg['StartPosition'][0],leg['StartPosition'][1]])\n", " for poi in leg['Geometry']['LineString']:\n", " path.append ([poi[0],poi[1]])\n", " \n" ] }, { "cell_type": "markdown", "id": "a1816ef0", "metadata": {}, "source": [ "## Visualize the results. \n", "\n", "We will use IPython and Amazon Location Services to visualize the output leveraging a template html page that will load all the relevant javascript libraries, then we customize this teplate in order to add all the information data we would like to display, and then we use IFrame to render the generated html file." ] }, { "cell_type": "code", "execution_count": 22, "id": "fd7803fa", "metadata": { "tags": [] }, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from IPython.display import IFrame\n", "import json\n", "\n", "Zoom=16\n", " \n", "#Transform python variables into json srtings\n", "jsonPointOfInterest=json.dumps(PointOfInterest)\n", "jsonOptimized_path=json.dumps(optimized_path)\n", "jsonPath=json.dumps(path)\n", "def get_credentials( role):\n", " sts_client = boto3.client(\"sts\")\n", "\n", " role_arn = role\n", " role_session_name = \"MAPS\"\n", "\n", " resp = sts_client.assume_role(\n", " RoleArn=role_arn,\n", " RoleSessionName=role_session_name\n", " )\n", "\n", " return resp[\"Credentials\"]\n", "\n", "credentials=get_credentials(role)\n", "\n", "jsonPointOfInterest=json.dumps(PointOfInterest)\n", "jsonOptimized_path=json.dumps(optimized_path)\n", "jsonPath=json.dumps (path)\n", "\n", "\n", "with open (\"./locationservice-pages/all-in-one.html_template\") as template:\n", " html_template=template.read()\n", " \n", "with open (\"./locationservice-pages/all-in-one.html\",\"w\") as page:\n", " html_page=html_template.format(mapName=locationMapName,\n", " accessKeyId=credentials['AccessKeyId'],\n", " secretAccessKey=credentials['SecretAccessKey'],\n", " sessionToken=credentials['SessionToken'],\n", " center =json.dumps([PointOfInterest[optimized_path[0]][0],PointOfInterest[optimized_path[0]][1]]),\n", " jsonPointOfInterest=jsonPointOfInterest,\n", " jsonOptimized_path=jsonOptimized_path,\n", " jsonPath=jsonPath,\n", " region=my_region,\n", " zoom=Zoom\n", " )\n", " page.write(html_page)\n", " \n", "IFrame(src='./locationservice-pages/all-in-one.html', width=800, height=500)" ] }, { "cell_type": "markdown", "id": "13c75384-a66c-4284-830b-18151a375563", "metadata": {}, "source": [ "## Create an API endpoint to expose Inference endpoint to the front-end application.\n", "The next step is related to create an API Gateway to expose the service to our font-end application, the API Gateway will call a lambda function that is interacting with location service to prepare the distance matrix and call Sagemaker endpoint to execute the inference.\n", "Hereafter the name of the Sagemaker Endpoint to input in cloudformation template to build API Gateway and lambda components." ] }, { "cell_type": "code", "execution_count": 28, "id": "ac043405-e0e5-4b90-be1d-6b3872ed56a2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'RouteOptimiser-20221021-155050-2022-10-21-15-50-56-575'" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "predictor.endpoint_name" ] }, { "cell_type": "code", "execution_count": null, "id": "5b3ced06-5a9d-4d3a-b56f-6bdb07203d91", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "c8d532d6-ed72-4b57-a7be-31f0ce549fc3", "metadata": {}, "source": [ "## Let's build our webapp\n", "We are now ready to build our Web App leveraging amplify" ] }, { "cell_type": "code", "execution_count": null, "id": "82e0a8d5-cea3-4a6d-93f6-86a176f3456e", "metadata": {}, "outputs": [], "source": [ "raise Exception (\"Execute the following step after testing the web app.\")" ] }, { "cell_type": "markdown", "id": "691f5dfe", "metadata": {}, "source": [ "## Cleanup\n", "\n", "Delete API Gateway, predictor endpoint and location service map and route calculator, sagemaker model and content of S3 bucket. " ] }, { "cell_type": "code", "execution_count": null, "id": "2093d99a", "metadata": {}, "outputs": [], "source": [ "predictor.delete_endpoint()" ] }, { "cell_type": "code", "execution_count": null, "id": "76aa4665-35a9-483b-942c-3236b6fb4979", "metadata": {}, "outputs": [], "source": [ "!aws sagemaker delete-model --model-name {modelName}" ] }, { "cell_type": "code", "execution_count": null, "id": "722f2f6f-367d-4426-8cab-1e4c4ad4c329", "metadata": {}, "outputs": [], "source": [ "!aws s3 rm s3://{bucket}/{prefix} --recursive" ] }, { "cell_type": "markdown", "id": "c86e098f-a4b2-4053-8898-aa5d32a577bd", "metadata": {}, "source": [ "You can now click on \"Running Terminals and Kernels\" on the left of the screen and terminate the instance running this notebook to avoid incurring in unexpected costs." ] }, { "attachments": { "3273430a-98ef-4e41-9a00-9ce0458bf8e3.png": { "image/png": "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" } }, "cell_type": "markdown", "id": "3d823176-55b7-46fe-9812-f7d96b623439", "metadata": {}, "source": [ "![image.png](attachment:3273430a-98ef-4e41-9a00-9ce0458bf8e3.png)" ] } ], "metadata": { "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3 (Data Science)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:eu-west-1:470317259841:image/datascience-1.0" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10" } }, "nbformat": 4, "nbformat_minor": 5 }