// Path: mapsforge-core/src/main/java/org/mapsforge/core/util/Parameters.java
// public final class Parameters {
// 
//     public enum ParentTilesRendering {QUALITY, SPEED, OFF}
// 
//     public enum SymbolScaling {ALL, POI}
// 
//     /**
//      * If true will use anti-aliasing in rendering.
//      */
//     public static boolean ANTI_ALIASING = true;
// 
//     /**
//      * If true the <code>FrameBufferHA3</code> will be used instead of default <code>FrameBufferHA2}</code>.
//      */
//     public static boolean FRAME_BUFFER_HA3 = true;
// 
//     /**
//      * Process layer scroll events.
//      */
//     public static boolean LAYER_SCROLL_EVENT = false;
// 
//     /**
//      * Maximum buffer size for map files.
//      */
//     public static int MAXIMUM_BUFFER_SIZE = 10000000;
// 
//     /**
//      * The default number of threads is one greater than the number of processors, as one thread is
//      * likely to be blocked on I/O reading map data. Technically this value can change to a better
//      * implementation, maybe one that also takes the available memory into account would be good.
//      * For stability reasons (see #591), we set default number of threads to 1.
//      */
//     public static int NUMBER_OF_THREADS = 1;//Runtime.getRuntime().availableProcessors() + 1;
// 
//     /**
//      * Parent tiles rendering mode.
//      */
//     public static ParentTilesRendering PARENT_TILES_RENDERING = ParentTilesRendering.QUALITY;
// 
//     /**
//      * If square frame buffer is enabled, the frame buffer allocated for drawing will be
//      * large enough for drawing in either orientation, so no change is needed when the device
//      * orientation changes. To avoid overly large frame buffers, the aspect ratio for this policy
//      * determines when this will be used.
//      */
//     public static boolean SQUARE_FRAME_BUFFER = true;
// 
//     /**
//      * Symbol scaling mode.
//      */
//     public static SymbolScaling SYMBOL_SCALING = SymbolScaling.POI;
// 
//     /**
//      * Validate coordinates.
//      */
//     public static boolean VALIDATE_COORDINATES = true;
// 
//     private Parameters() {
//         throw new IllegalStateException();
//     }
// }


import org.mapsforge.core.graphics.*;
import org.mapsforge.core.mapelements.MapElementContainer;
import org.mapsforge.core.model.Point;
import org.mapsforge.core.model.Rectangle;
import org.mapsforge.core.model.Tile;
import org.mapsforge.core.util.Parameters;
import org.mapsforge.map.rendertheme.RenderContext;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
    private void drawCircleContainer(ShapePaintContainer shapePaintContainer) {
        CircleContainer circleContainer = (CircleContainer) shapePaintContainer.shapeContainer;
        Point point = circleContainer.point;
        this.canvas.drawCircle((int) point.x, (int) point.y, (int) circleContainer.radius, shapePaintContainer.paint);
    }

    private void drawHillshading(HillshadingContainer container) {
        canvas.shadeBitmap(container.bitmap, container.hillsRect, container.tileRect, container.magnitude);
    }

    private void drawPath(RenderContext renderContext, ShapePaintContainer shapePaintContainer, Point[][] coordinates, float dy) {
        this.path.clear();

        for (Point[] innerList : coordinates) {
            Point[] points;
            if (dy != 0f) {
                points = RendererUtils.parallelPath(innerList, dy);
            } else {
                points = innerList;
            }
            if (points.length >= 2) {
                Point point = points[0];
                this.path.moveTo((float) point.x, (float) point.y);
                for (int i = 1; i < points.length; ++i) {
                    point = points[i];
                    this.path.lineTo((int) point.x, (int) point.y);
                }
            }
        }

// Path: mapsforge-core/src/main/java/org/mapsforge/core/util/Parameters.java
// public final class Parameters {
// 
//     public enum ParentTilesRendering {QUALITY, SPEED, OFF}
// 
//     public enum SymbolScaling {ALL, POI}
// 
//     /**
//      * If true will use anti-aliasing in rendering.
//      */
//     public static boolean ANTI_ALIASING = true;
// 
//     /**
//      * If true the <code>FrameBufferHA3</code> will be used instead of default <code>FrameBufferHA2}</code>.
//      */
//     public static boolean FRAME_BUFFER_HA3 = true;
// 
//     /**
//      * Process layer scroll events.
//      */
//     public static boolean LAYER_SCROLL_EVENT = false;
// 
//     /**
//      * Maximum buffer size for map files.
//      */
//     public static int MAXIMUM_BUFFER_SIZE = 10000000;
// 
//     /**
//      * The default number of threads is one greater than the number of processors, as one thread is
//      * likely to be blocked on I/O reading map data. Technically this value can change to a better
//      * implementation, maybe one that also takes the available memory into account would be good.
//      * For stability reasons (see #591), we set default number of threads to 1.
//      */
//     public static int NUMBER_OF_THREADS = 1;//Runtime.getRuntime().availableProcessors() + 1;
// 
//     /**
//      * Parent tiles rendering mode.
//      */
//     public static ParentTilesRendering PARENT_TILES_RENDERING = ParentTilesRendering.QUALITY;
// 
//     /**
//      * If square frame buffer is enabled, the frame buffer allocated for drawing will be
//      * large enough for drawing in either orientation, so no change is needed when the device
//      * orientation changes. To avoid overly large frame buffers, the aspect ratio for this policy
//      * determines when this will be used.
//      */
//     public static boolean SQUARE_FRAME_BUFFER = true;
// 
//     /**
//      * Symbol scaling mode.
//      */
//     public static SymbolScaling SYMBOL_SCALING = SymbolScaling.POI;
// 
//     /**
//      * Validate coordinates.
//      */
//     public static boolean VALIDATE_COORDINATES = true;
// 
//     private Parameters() {
//         throw new IllegalStateException();
//     }
// }


// Path: mapsforge-map/src/main/java/org/mapsforge/map/layer/renderer/CanvasRasterer.java
import org.mapsforge.core.graphics.*;
import org.mapsforge.core.mapelements.MapElementContainer;
import org.mapsforge.core.model.Point;
import org.mapsforge.core.model.Rectangle;
import org.mapsforge.core.model.Tile;
import org.mapsforge.core.util.Parameters;
import org.mapsforge.map.rendertheme.RenderContext;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

    private void drawCircleContainer(ShapePaintContainer shapePaintContainer) {
        CircleContainer circleContainer = (CircleContainer) shapePaintContainer.shapeContainer;
        Point point = circleContainer.point;
        this.canvas.drawCircle((int) point.x, (int) point.y, (int) circleContainer.radius, shapePaintContainer.paint);
    }

    private void drawHillshading(HillshadingContainer container) {
        canvas.shadeBitmap(container.bitmap, container.hillsRect, container.tileRect, container.magnitude);
    }

    private void drawPath(RenderContext renderContext, ShapePaintContainer shapePaintContainer, Point[][] coordinates, float dy) {
        this.path.clear();

        for (Point[] innerList : coordinates) {
            Point[] points;
            if (dy != 0f) {
                points = RendererUtils.parallelPath(innerList, dy);
            } else {
                points = innerList;
            }
            if (points.length >= 2) {
                Point point = points[0];
                this.path.moveTo((float) point.x, (float) point.y);
                for (int i = 1; i < points.length; ++i) {
                    point = points[i];
                    this.path.lineTo((int) point.x, (int) point.y);
                }
            }
        }

        if (Parameters.NUMBER_OF_THREADS > 1) {