/** {@inheritDoc } */
 @Override
 public MathTransform getMathTransform(
     final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS)
     throws FactoryException {
   return canvas.getMathTransform(
       sourceCRS, targetCRS, DefaultRenderingContext2D.class, "getMathTransform");
 }
 /** {@inheritDoc } */
 @Override
 public AffineTransform getAffineTransform(
     final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS)
     throws FactoryException {
   final MathTransform mt =
       canvas.getMathTransform(
           sourceCRS, targetCRS, DefaultRenderingContext2D.class, "getAffineTransform");
   try {
     return (AffineTransform) mt;
   } catch (ClassCastException cause) {
     throw new FactoryException(Errors.format(Errors.Keys.NOT_AN_AFFINE_TRANSFORM), cause);
   }
 }
  /** {@inheritDoc } */
  @Override
  public LabelRenderer getLabelRenderer(final boolean create) {
    if (labelRenderer == null && create) {
      Class candidate = (Class) canvas.getRenderingHint(GO2Hints.KEY_LABEL_RENDERER_CLASS);

      if (candidate != null && LabelRenderer.class.isAssignableFrom(candidate)) {
        try {
          labelRenderer = (LabelRenderer) candidate.newInstance();
          labelRenderer.setRenderingContext(this);
        } catch (InstantiationException ex) {
          LOGGER.log(Level.WARNING, null, ex);
        } catch (IllegalAccessException ex) {
          LOGGER.log(Level.WARNING, null, ex);
        }
      } else {
        labelRenderer = new DecimationLabelRenderer();
        labelRenderer.setRenderingContext(this);
      }
    }
    return labelRenderer;
  }
 /** {@inheritDoc } */
 @Override
 public double getScale() {
   return canvas.getController().getScale();
 }
  public void initParameters(
      final AffineTransform2D objToDisp,
      final CanvasMonitor monitor,
      final Shape paintingDisplayShape,
      final Shape paintingObjectiveShape,
      final Shape canvasDisplayShape,
      final Shape canvasObjectiveShape,
      final double dpi) {
    this.canvasObjectiveBBox = canvas.getController().getVisibleEnvelope();
    this.objectiveCRS = canvasObjectiveBBox.getCoordinateReferenceSystem();
    this.objectiveCRS2D = canvas.getObjectiveCRS2D();
    this.displayCRS = canvas.getDisplayCRS();
    this.objectiveToDisplay = objToDisp;
    try {
      this.displayToObjective = (AffineTransform2D) objToDisp.inverse();
    } catch (NoninvertibleTransformException ex) {
      Logging.getLogger(DefaultRenderingContext2D.class).log(Level.WARNING, null, ex);
    }
    this.monitor = monitor;

    this.labelRenderer = null;

    this.coeffs.clear();
    // set the Pixel coeff = 1
    this.coeffs.put(NonSI.PIXEL, 1f);

    // calculate canvas shape/bounds values ---------------------------------
    this.canvasDisplayShape = canvasDisplayShape;
    final Rectangle2D canvasDisplayBounds = canvasDisplayShape.getBounds2D();
    this.canvasDisplaybounds = canvasDisplayBounds.getBounds();
    this.canvasObjectiveShape = canvasObjectiveShape;

    final Rectangle2D canvasObjectiveBounds = canvasObjectiveShape.getBounds2D();

    // calculate the objective bbox with there temporal and elevation parameters ----
    this.canvasObjectiveBBox2D = new Envelope2D(objectiveCRS2D, canvasObjectiveBounds);

    // calculate the resolution -----------------------------------------------
    this.dpi = dpi;
    this.resolution = new double[canvasObjectiveBBox.getDimension()];
    this.resolution[0] = canvasObjectiveBounds.getWidth() / canvasDisplayBounds.getWidth();
    this.resolution[1] = canvasObjectiveBounds.getHeight() / canvasDisplayBounds.getHeight();
    for (int i = 2; i < resolution.length; i++) {
      // other dimension are likely to be the temporal and elevation one.
      // we set a hug resolution to ensure that only one slice of data will be retrived.
      resolution[i] = Double.MAX_VALUE;
    }
    adjustResolutionWithDPI(resolution);

    // calculate painting shape/bounds values -------------------------------
    this.paintingDisplayShape = paintingDisplayShape;
    final Rectangle2D paintingDisplayBounds = paintingDisplayShape.getBounds2D();
    this.paintingDisplaybounds = paintingDisplayBounds.getBounds();
    this.paintingObjectiveShape = paintingObjectiveShape;

    final Rectangle2D paintingObjectiveBounds = paintingObjectiveShape.getBounds2D();
    this.paintingObjectiveBBox2D = new Envelope2D(objectiveCRS2D, paintingObjectiveBounds);
    this.paintingObjectiveBBox = new GeneralEnvelope(canvasObjectiveBBox);
    ((GeneralEnvelope) this.paintingObjectiveBBox)
        .setRange(0, paintingObjectiveBounds.getMinX(), paintingObjectiveBounds.getMaxX());
    ((GeneralEnvelope) this.paintingObjectiveBBox)
        .setRange(1, paintingObjectiveBounds.getMinY(), paintingObjectiveBounds.getMaxY());

    try {
      geoScale = canvas.getController().getGeographicScale();
    } catch (TransformException ex) {
      // could not calculate the geographic scale.
      geoScale = 1;
      LOGGER.log(Level.WARNING, null, ex);
    }

    // set temporal and elevation range--------------------------------------
    final Date[] temporal = canvas.getController().getTemporalRange();
    if (temporal != null) {
      temporalRange[0] = temporal[0];
      temporalRange[1] = temporal[1];
    } else {
      Arrays.fill(temporalRange, null);
    }

    final Double[] elevation = canvas.getController().getElevationRange();
    if (elevation != null) {
      elevationRange[0] = elevation[0];
      elevationRange[1] = elevation[1];
    } else {
      Arrays.fill(elevationRange, null);
    }

    // calculate the symbology encoding scale -------------------------------
    seScale = GO2Utilities.computeSEScale(this);
  }