executeJob method

  1. @override
Future<JobResult> executeJob(
  1. Job job
)
override

Executes a given job and returns a future with the bitmap of this job. @returns null if the datastore does not support the requested tile @returns the Bitmap for the requested tile

Implementation

@override
Future<JobResult> executeJob(Job job) async {
  Timing timing = Timing(log: _log, active: true);
  // current performance measurements for isolates indicates that isolates are too slow so it makes no sense to use them currently. Seems
  // we need something like 600ms to start an isolate whereas the whole read-process just needs about 200ms
  RenderContext renderContext = RenderContext(job, renderTheme);
  this.renderTheme.prepareScale(job.tile.zoomLevel);

  DatastoreReadResult? mapReadResult;
  IsolateMapReplyParams params = await _datastoreReader.read(
      datastore, job.tile, renderContext.projection, renderContext);
  mapReadResult = params.result;
  renderContext = params.renderContext;
  timing.lap(100,
      "${mapReadResult?.ways.length} ways and ${mapReadResult?.pointOfInterests.length} pois read for tile ${renderContext.job.tile}");
  if (mapReadResult == null) {
    TileBitmap bmp = await createNoDataBitmap(job.tileSize);
    return JobResult(bmp, JOBRESULT.UNSUPPORTED);
  }
  if ((mapReadResult.ways.length) > 100000) {
    _log.warning(
        "Many ways (${mapReadResult.ways.length}) in this readResult, consider shrinking your mapfile.");
  }
  await renderContext.initDrawingLayers(symbolCache);
  timing.lap(100,
      "${mapReadResult.ways.length} ways and ${mapReadResult.pointOfInterests.length} pois initialized for tile ${renderContext.job.tile}");
  CanvasRasterer canvasRasterer = CanvasRasterer(job.tileSize.toDouble(),
      job.tileSize.toDouble(), "MapDatastoreRenderer ${job.tile.toString()}");
  canvasRasterer.startCanvasBitmap();
  timing.lap(100, "startCanvasBitmap for tile ${renderContext.job.tile}");
  canvasRasterer.drawWays(renderContext);
  timing.lap(100,
      "${renderContext.drawingLayers.length} way-layers for tile ${renderContext.job.tile}");

  int labelCount = 0;
  List<RenderInfo<Shape>>? renderInfos;
  if (this.renderLabels) {
    _LabelResult labelResult = _processLabels(renderContext);
    labelCount = labelResult.labelsToDisposeAfterDrawing.length +
        labelResult.labelsForNeighbours.length;
    //_log.info("Labels to draw: $labelsToDraw");
    // now draw the ways and the labels
    canvasRasterer.drawMapElements(
        labelResult.labelsForNeighbours, renderContext.projection, job.tile);
    canvasRasterer.drawMapElements(labelResult.labelsToDisposeAfterDrawing,
        renderContext.projection, job.tile);
    // labelResult.labelsToDisposeAfterDrawing.forEach((element) {
    //   element.dispose();
    // });
    timing.lap(100, "$labelCount labels for tile ${renderContext.job.tile}");
    // labelsToDraw.forEach((element) {
    //   _log.info(
    //       "  $element, ${element.boundaryAbsolute!.intersects(renderContext.projection.boundaryAbsolute(job.tile)) ? "intersects" : "non-intersects"}");
    // });
  } else {
    // store elements for this tile in the label cache
    renderInfos = LayerUtil.collisionFreeOrdered(
        renderContext.labels, renderContext.projection);
    // this.labelStore.storeMapItems(
    //     job.tile, renderContext.labels, renderContext.projection);
    timing.lap(100, "storeMapItems for tile ${renderContext.job.tile}");
  }
//    if (!job.labelsOnly && renderContext.renderTheme.hasMapBackgroundOutside()) {
//      // blank out all areas outside of map
//      Rectangle insideArea = this.mapDataStore.boundingBox().getPositionRelativeToTile(job.tile);
//      if (!job.hasAlpha) {
//        renderContext.canvasRasterer.fillOutsideAreas(renderContext.renderTheme.getMapBackgroundOutside(), insideArea);
//      } else {
//        renderContext.canvasRasterer.fillOutsideAreas(Color.TRANSPARENT, insideArea);
//      }
//    }
  TileBitmap? bitmap =
      (await canvasRasterer.finalizeCanvasBitmap() as TileBitmap?);
  int actions = (canvasRasterer.canvas as FlutterCanvas).actions;
  canvasRasterer.destroy();
  timing.lap(100,
      "$labelCount elements and labels, $actions actions in canvas for tile ${renderContext.job.tile}");
  //_log.info("Executing ${job.toString()} returns ${bitmap.toString()}");
  //_log.info("ways: ${mapReadResult.ways.length}, Areas: ${Area.count}, ShapePaintPolylineContainer: ${ShapePaintPolylineContainer.count}");
  return JobResult(bitmap, JOBRESULT.NORMAL, renderInfos);
}