#CarPal routing optimization package

**Installation**

`pip install CarpalRouting`

---

**How distance is calculated**
There are 2 algorithms for calculate the distance between 2 points on the map: _Manhattan distance_ and _Haversine formula_

In our engine, we chose Haversine formula for distance calculation, for more info about this formulat please visit [wikipedia page](https://en.wikipedia.org/wiki/Haversine_formula)

---

#This package can solve problems with following scenarios:

**Scenario 1: I have specific number of vehicles, pickup locations and delivery locations, Generate the optimal routes based on what I have, and give me the locations that unable to be covered**


Code example:

    from CarpalRouting.file_reader import ExcelReader
    from CarpalRouting.optimize import Routing

    ...
    ...

    routes, addresses = Routing(addresses=addresses, 
                                locations=locations,
                                start_times=start_times,
                                max_weights=max_weights,
                                num_vehicles=20).generate_routes(vehicle_capacity=1000, speed=50)

    num_of_routes = len(routes)

Scenario 2: By given specific No. of locations and vehicle types, the package should build optimal routes with recommended No. of vehicles needed for each vehicle specifications(capacity, speed etc)




**Same day delivery**

Same day delivery is a bit more tricky compare to Next day delivery. All locations need to be grouped in to different delivery WAVEs before starting routing optimization process.


**Geo Fencing**

To verify if a geolocation is within a geo fence, we use the algorithm call [Point-In-Polygon](https://en.wikipedia.org/wiki/Point_in_polygon).


Code example:

    from CarpalRouting.geofence import GeoTools, GeoArea
    from CarpalRouting.models import Coordinates

    edge_locations = [[lat, long],[lat, long],[lat, long],[lat, long],[lat, long],[lat, long]...]
    to_be_checked_loc = [lat, long]

    #verify which geo locations in the list are in the polygon area
    in_area = GeoTools.is_point_in_polygon(edge_coordinates=edge_locations, coordinates=to_be_checked_loc)

    #grouping locations by geo polygon groups
    edge_location_grps = [[[lat, long],[lat, long],[lat, long]],[[lat, long],[lat, long],[lat, long]],...]

    coordinates = [Coordinates(item[0], item[1]) for item in to_be_checked_loc]
    geo_areas = GeoTools.group_locations_by_polygon(edge_coordinates_group=edge_location_grps, coordinates=coordinates)

    #print locations within each geo area
    for item in geo_areas:
        print(item.locations)

    ...
    

You can use this basic function to craft more functionality by using filters, looping etc.

