Skip to main content

Generate Territories

|

This example demonstrates how to generate polygon territories from a list of coordinates and display them on a map. The example covers the following features:

  • Creating territories from a set of geographic coordinates
  • Specifying the number of territories to generate
  • Visualizing both the original coordinates and generated territories on a map
  • Handling territory generation results

When dealing with many locations to visit, it's often beneficial to first divide them into territories before creating optimizations for customers within each territory.

When you run the example application:

  • A list of coordinates is displayed as points on the map
  • Territories are generated from these coordinates
  • The generated territories are displayed as colored polygons on the map

Create a List of Coordinates

Create a CoordinatesList containing all the geographic points you want to divide into territories:

    gem::CoordinatesList coords = { gem::Coordinates(47.592266,8.089206),
gem::Coordinates(48.568867,9.122461),
gem::Coordinates(50.487137,14.161686),
gem::Coordinates(49.851322,20.489012),
gem::Coordinates(49.471581,7.480935),
gem::Coordinates(46.858112,21.328030),
gem::Coordinates(51.427933,9.794261),
gem::Coordinates(46.602039,10.907111),
gem::Coordinates(48.667385,17.154114),
gem::Coordinates(46.674530,25.333998),
gem::Coordinates(48.248165,18.071995),
gem::Coordinates(48.694458,19.731777),
gem::Coordinates(51.356140,15.819277),
gem::Coordinates(51.602428,27.123756),
gem::Coordinates(51.611862,4.796660),
gem::Coordinates(49.301449,23.506264),
gem::Coordinates(49.621101,6.395834),
gem::Coordinates(48.567471,17.284821),
gem::Coordinates(49.604858,18.538603),
gem::Coordinates(51.599285,7.911033),
gem::Coordinates(46.873657,8.260807),
gem::Coordinates(47.746155,20.826370),
gem::Coordinates(52.115623,16.879551),
gem::Coordinates(50.366787,7.117288),
gem::Coordinates(46.785622,4.617757),
gem::Coordinates(51.643478,6.422852),
gem::Coordinates(47.214272,6.709096),
gem::Coordinates(51.503738,26.488468),
gem::Coordinates(51.522953,12.511396),
gem::Coordinates(50.644344,13.998848),
gem::Coordinates(46.965187,20.015100),
gem::Coordinates(49.337257,16.126698),
gem::Coordinates(52.110031,12.255091),
gem::Coordinates(50.760151,22.095486),
gem::Coordinates(50.960152,20.884787),
gem::Coordinates(47.572002,14.907236) };

Initialize Map Components

Set up the map view to display the coordinates:

MapViewListenerImpl mapListener;
auto oglContext = session.produceOpenGLContext(Environment::WindowFrameworks::Available, "Territories");
gem::StrongPointer<gem::MapView> mapView = gem::MapView::produce(oglContext, &mapListener);

Display Coordinates on the Map

Create a marker collection to visualize the input coordinates, and display them on the map.

auto col = gem::MarkerCollection(gem::EMarkerType::MT_Point, "Coordinates marker");
col.add(coords);

gem::MarkerCollectionRenderSettings markerCollDisplaySettings;
markerCollDisplaySettings.pointsGroupingZoomLevel = 0; // Don't group points

mapView->preferences().markers().add(col, markerCollDisplaySettings);
mapView->centerOnArea(col.getArea());
auto ret = WAIT_UNTIL(std::bind(&MapViewListenerImpl::IsFinished, &mapListener), 15000);

Generate Territories

Use the vrp::Service to generate territories from the coordinates:

ProgressListener listener;
gem::vrp::Service serv;

gem::vrp::TerritoryList territories;
int territoriesNumber = 3; // Specify number of territories you want to generate
int res = serv.generateTerritories(&listener, territories, coords, territoriesNumber);
WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &listener), 10000);
Note

To generate one territory, you need at least 3 coordinates. For N territories, you need at least 3×N coordinates.

Display Territories on the Map

Once generated you can diplay them on the map as colored polygons.

if(listener.IsFinished() && listener.GetError() == gem::KNoError && res == gem::KNoError) {
std::cout << "Territories generated successfully" << std::endl;

for(gem::vrp::Territory territory : territories) {
std::cout << "Territory " << territory.getId() << " has the points:" << std::endl;

gem::CoordinatesList territoryCoords;
for(int i = 0; i < territory.getData().size(); i++) {
territoryCoords.push_back(gem::Coordinates(territory.getData()[i][0], territory.getData()[i][1]));
}

auto territoryCol = gem::MarkerCollection(gem::EMarkerType::MT_Polygon, territory.getName());
territoryCol.add(territoryCoords);

gem::MarkerCollectionRenderSettings markerCollDisplaySettingsTerritory;
markerCollDisplaySettingsTerritory.polygonFillColor = territory.getColor();

mapView->preferences().markers().add(territoryCol, markerCollDisplaySettingsTerritory);
}

ret = WAIT_UNTIL(std::bind(&MapViewListenerImpl::IsFinished, &mapListener), 15000);
WAIT_UNTIL_WINDOW_CLOSE();
} else {
std::cout << "Territories couldn't be generated" << std::endl;
}