docs: protected void handleImplicitWayRelations() {
          if (!this.tagValues) {
              return;
          }
  
          /*int progressImplicitRelations = 0;
          float limitImplicitRelations = this.tilesToPartElements.entrySet().size();*/
  
          // Iterate through tiles which contain parts
          for (Map.Entry<TileCoordinate, TLongHashSet> tilePartElementEntry : this.tilesToPartElements.entrySet()) {
              TLongHashSet tileRootElementSet = this.tilesToRootElements.get(tilePartElementEntry.getKey());
  
              // Continue if no part or no roots are in list; maybe unnecessary
              if (tileRootElementSet == null || tileRootElementSet.isEmpty()
                      || tilePartElementEntry.getValue().isEmpty()) {
                  continue;
              }
  
              // Log
              /*String wayRelLog = "Progress: Implicit relations "
                      + ((int) ((progressImplicitRelations / limitImplicitRelations) * 100))
                      + "%% - Tile (" + tilePartElementEntry.getKey().getX()
                      + ", " + tilePartElementEntry.getKey().getY() + ")";
              progressImplicitRelations++;
              int nRootElements = 0;*/
  
              // Load parts only once in cache
              List<TDWay> pElems = new ArrayList<>();
              TLongIterator tilePartElementIterator = tilePartElementEntry.getValue().iterator();
              while (tilePartElementIterator.hasNext()) {
                  TDWay pElem = getWay(tilePartElementIterator.next());
                  pElems.add(pElem);
              }
  
              // Iterate through potential roots
              TLongIterator tileRootElementIterator = tileRootElementSet.iterator();
              while (tileRootElementIterator.hasNext()) {
                  /*if(this.progressLogs) {
                      if (++nRootElements % 1000 == 0) {
                          System.out.print((wayRelLog + " - Elements " + nfCounts.format(nRootElements) + "\r"));
                      }
                  }*/
  
                  // Init root element
                  TDWay rElem = getWay(tileRootElementIterator.next());
                  BoundingBox rBox = GeoUtils.mapWayToBoundingBox(rElem);
                  if (rBox == null) {
                      continue;
                  }
                  Polygon rPolygon = null; // Lazy initialization, because root may not be needed
  
                  // Iterate through parts
                  for (int i = pElems.size() - 1; i >= 0; i--) {
                      TDWay pElem = pElems.get(i);
  
                      // Exclude most elements with bounding box
                      if (pElem.getWayNodes().length < 3) {
                          continue;
                      }
                      if (!rBox.contains(LatLongUtils.microdegreesToDegrees(pElem.getWayNodes()[0].getLatitude()),
                              LatLongUtils.microdegreesToDegrees(pElem.getWayNodes()[0].getLongitude()))) {
                          continue;
                      }
  
                      // Now calculate exact polygons
                      Polygon pPolygon = GeoUtils.mapWayToPolygon(pElem);
                      if (pPolygon == null) {
                          continue;
                      }
  
                      if (rPolygon == null) {
                          rPolygon = GeoUtils.mapWayToPolygon(rElem);
                          if (rPolygon == null) {
                              continue;
                          }
                      }
  
                      /* Use interior point cause
                       * - boundary points may intersect with other geometries
                       * - part polygon often not completely covered by root polygon
                       */
                      if (rPolygon.covers(pPolygon.getInteriorPoint())) {
                          // Memorize multi-polygons
                          if (!this.partRootRelations.containsKey(rElem.getId())) {
                              this.partRootRelations.put(rElem.getId(), null); // Add root element
                          }
                          this.partRootRelations.put(pElem.getId(), rElem.getId()); // Add part element
  
                          // Remove part which is already referenced
                          pElems.remove(pElem);
                          tilePartElementEntry.getValue().remove(pElem.getId());
                      }
                  }
              }
          }
          LOGGER.info("calculated " + nfCounts.format(partRootRelations.size()) + " implicit relations");
      }