I am using the explorer edition of the Here Routes SDK for Android. I am trying to add customizable polygons to a list of areas in which the route must avoid when being calculated.

I tried using avoidanceOptions.addAvoidArea(), but the method is not recognised and I cannot find documentation for it.

I have found avoidanceOptions.avoidAreas.add() in the documentation: "https://developer.here.com/documentation/android-sdk-explore/4.13.4.0/api_reference/com/here/sdk/routing/AvoidanceOptions.html#avoidAreas", but avoidAreas is a List. I need to use a GeoPolygon as I cannot be limited to rectangles.

Has the feature of avoiding polygons been removed and is there perhaps a different way to accomplish this task?

I did intially try to use avoidanceOptions.avoidAreas.add() using a GeoPolygon, but that did not work as it was expecting a GeoBox. I was expecting the polygon to be added to the list of areas to avoid when the route is calculated. I added this last paragraph because Stack Overflow was asking me to elaborate. I don't really know what else to say. This is my first question.

2

There are 2 best solutions below

0
On

Unfortunately, SDK 4.x doesn't allow to calculate route avoidance by polygon but only by rectangle(i.e. GeoBox) Therefore workaround is to:

  1. split polygon to many rectangles and this is geometry task.

  2. Or use HERE Map Attributes API v8 + custom function "isPointInPolygon" to get segmentIds which you can then use in avoidanceOptions (carOptions.avoidanceOptions.segments.add(new SegmentReference()) - see little explanation bellow at the bottom

  3. split polygon to many rectangles: Several relevant algorithms and libraries that may help you with your task of splitting a polygon into smaller rectangles. Here's a summary:

  4. Polygon Splitting: The polygon-splitter JavaScript library can be used to split a polygon into smaller parts using a line. This library works with various types of polygons including concave polygons, polygons with holes, and multi-part geometries【 https://github.com/rowanwins/polygon-splitter 】.

  5. Fitting Rectangles in a Circle: A Stack Overflow answer provides a JavaScript function for fitting as many squares as possible into a circle. This approach could potentially be adapted to work with polygons, but it would likely require significant modifications【 Placing rectangles inside a circle properly 】.

  6. Dividing a Polygon into Rectangles: A question was posed on the Computer Science Stack Exchange about dividing a polygon into as few rectangles as possible. Although there was no definitive solution provided, it was suggested that the problem might involve an acceptable level of non-polygon area to be covered by rectangles【 https://cs.stackexchange.com/questions/146085/algorithm-for-dividing-a-polygon-into-rectangles 】. The original poster later found a Wikipedia article on Polygon Covering, which might provide further insights.

Please note that the feasibility and complexity of this task could vary greatly depending on the specifics of your use case, such as the shapes of the polygons and the constraints on the rectangles.

  1. Or use HERE Map Attributes API v8 + custom function "isPointInPolygon"...:

  2. Calculate first tileIds for every vertices of your polygon utilizing formula(https://developer.here.com/documentation/content-map-attributes/dev_guide/topics/here-map-content.html):

tile size = 180° / 2^level [degree]

tileY = trunc((latitude + 90°) / tile size)

tileX = trunc((longitude + 180°) / tile size)

tileID = tileY * 2 * (2^level) + tileX Where the level is always "road functional class" + 8 E.g. the layer containing the functional class 2 (= roughly second level) roads has tiling level 10. And you need to calculate tileIds for every Functional class (from 1 to 5)

  1. For all tileIds you can get segmentIds send request like https://smap.hereapi.com/v8/maps/attributes?in=tile%3A430628%2C27537700%2C27537701%2C110158410&layers=ROAD_GEOM_FC1%2CROAD_GEOM_FC4%2CROAD_GEOM_FC4%2CROAD_GEOM_FC5&apikey=yourapikey

  2. In response you can see field TOPOLOGY_ID - this is your segmentId

  3. You need now to check all coordinates of geometries if they in your polygon utilize this example: http://jsfiddle.net/m1ey7p2h/1/

    function isPointInPolygon(testPoint, polygPoints) { let result = false; let j = polygPoints.length - 1; for(i=0,len=j+1; i<len; i++){ let p = polygPoints[i]; let lP = polygPoints[j]; if(p.y < testPoint.y && lP.y >= testPoint.y || lP.y < testPoint.y && p.y >= testPoint.y){ if((p.x + (testPoint.y - p.y) / (lP.y - p.y) * (lP.x - p.x)) < testPoint.x){ result = !result; } } j = i; } return result; }

0
On

Usage example of AvoidanceOptions for areas:

GeoCoordinates southWest = new GeoCoordinates(southWest.latitude, southWest.longitude);
GeoCoordinates northEast = new GeoCoordinates(northEast.latitude, northEast.longitude);

carOptions.avoidanceOptions.avoidAreas.add(new GeoBox(southWest, northEast));

See also this question.