constructor(map, data, tilewidth, tileheight, orientation, tilesets, z) {
		// super constructor
		super(0, 0, 0, 0);

		// tile width & height
		this.tilewidth = data.tilewidth || tilewidth;
		this.tileheight = data.tileheight || tileheight;

		// layer orientation
		this.orientation = orientation;

		/**
		 * Horizontal layer offset in tiles
		 * @default 0
		 * @type {number}
		 */
		this.x = 0;

		/**
		 * Vertical layer offset in tiles
		 * @default 0
		 * @type {number}
		 */
		this.y = 0;

		/**
		 * The Layer corresponding Tilesets
		 * @type {TMXTilesetGroup}
		 */
		this.tilesets = tilesets;

		// the default tileset
		// XXX: Is this even used?
		this.tileset = this.tilesets ? this.tilesets.getTilesetByIndex(0) : null;

		// Biggest tile size to draw
		this.maxTileSize = {
			width: 0,
			height: 0,
		};
		for (let i = 0; i < this.tilesets.length; i++) {
			const tileset = this.tilesets.getTilesetByIndex(i);
			this.maxTileSize.width = Math.max(
				this.maxTileSize.width,
				tileset.tilewidth,
			);
			this.maxTileSize.height = Math.max(
				this.maxTileSize.height,
				tileset.tileheight,
			);
		}

		/**
		 * All animated tilesets in this layer
		 * @type {TMXTileset[]}
		 */
		this.animatedTilesets = [];

		/**
		 * Layer contains tileset animations
		 * @type {boolean}
		 */
		this.isAnimated = false;

		/**
		 * the order in which tiles on orthogonal tile layers are rendered.
		 * (valid values are "left-down", "left-up", "right-down", "right-up")
		 * @type {string}
		 * @default "right-down"
		 */
		this.renderorder = data.renderorder || "right-down";

		/**
		 * the layer class
		 * @type {string}
		 */
		this.class = data.class;

		// for displaying order
		this.pos.z = z;

		// tiled default coordinates are top-left
		this.anchorPoint.set(0, 0);

		// additional TMX flags
		this.name = data.name;
		this.cols = +data.width;
		this.rows = +data.height;

		// layer opacity
		const visible = typeof data.visible !== "undefined" ? +data.visible : 1;
		this.setOpacity(visible ? +data.opacity : 0);

		// layer tint
		if (typeof data.tintcolor === "string") {
			// Tiled provides #RRGGBB or #AARRGGBB
			this.tint.parseHex(data.tintcolor, true);
		}

		// layer "real" size
		if (this.orientation === "isometric") {
			this.width = (this.cols + this.rows) * (this.tilewidth / 2);
			this.height = (this.cols + this.rows) * (this.tileheight / 2);
		} else {
			this.width = this.cols * this.tilewidth;
			this.height = this.rows * this.tileheight;
		}

		// check if we have any user-defined properties
		TMXUtils.applyTMXProperties(this, data);

		// set a renderer
		this.setRenderer(map.getRenderer());

		// initialize the data array
		this.layerData = initArray(this.rows, this.cols);

		if (map.infinite === 0) {
			// initialize and set the layer data
			setLayerData(
				this,
				this,
				TMXUtils.decode(data.data, data.encoding, data.compression),
			);
		} else if (map.infinite === 1) {
			// infinite map, initialize per chunk
			data.chunks.forEach((chunk) => {
				// initialize and set the layer data
				setLayerData(
					this,
					chunk,
					TMXUtils.decode(chunk.data, data.encoding, data.compression),
				);
			});
		}
	}
@param {object} map - layer data in JSON format ({@link http://docs.mapeditor.org/en/stable/reference/tmx-map-format/#layer})
@param {object} data - layer data in JSON format ({@link http://docs.mapeditor.org/en/stable/reference/tmx-map-format/#layer})
@param {number} tilewidth - width of each tile in pixels
@param {number} tileheight - height of each tile in pixels
@param {string} orientation - "isometric" or "orthogonal"
@param {TMXTilesetGroup} tilesets - tileset as defined in Tiled
@param {number} z - z-index position