diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoVacuumHandler.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoVacuumHandler.java index 75f4918e3c5..74f7b3e45ed 100644 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoVacuumHandler.java +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/handler/MiIoVacuumHandler.java @@ -45,6 +45,7 @@ import org.openhab.binding.miio.internal.cloud.MiCloudException; import org.openhab.binding.miio.internal.robot.ConsumablesType; import org.openhab.binding.miio.internal.robot.FanModeType; import org.openhab.binding.miio.internal.robot.RRMapDraw; +import org.openhab.binding.miio.internal.robot.RRMapDrawOptions; import org.openhab.binding.miio.internal.robot.RobotCababilities; import org.openhab.binding.miio.internal.robot.StatusDTO; import org.openhab.binding.miio.internal.robot.StatusType; @@ -88,7 +89,6 @@ import com.google.gson.JsonObject; @NonNullByDefault public class MiIoVacuumHandler extends MiIoAbstractHandler { private final Logger logger = LoggerFactory.getLogger(MiIoVacuumHandler.class); - private static final float MAP_SCALE = 2.0f; private static final DateTimeFormatter DATEFORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss"); private static final Gson GSON = new GsonBuilder().serializeNulls().create(); private final ChannelUID mapChannelUid; @@ -110,6 +110,7 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler { private boolean hasChannelStructure; private ConcurrentHashMap deviceCapabilities = new ConcurrentHashMap<>(); private ChannelTypeRegistry channelTypeRegistry; + private RRMapDrawOptions mapDrawOptions = new RRMapDrawOptions(); public MiIoVacuumHandler(Thing thing, MiIoDatabaseWatchService miIoDatabaseWatchService, CloudConnector cloudConnector, ChannelTypeRegistry channelTypeRegistry) { @@ -171,7 +172,6 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler { } return null; }); - updateState(RobotCababilities.SEGMENT_CLEAN.getChannel(), new StringType("-")); } @Override @@ -490,6 +490,9 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler { public void initialize() { super.initialize(); hasChannelStructure = false; + this.mapDrawOptions = RRMapDrawOptions + .getOptionsFromFile(BINDING_USERDATA_PATH + File.separator + "mapConfig.json", logger); + updateState(RobotCababilities.SEGMENT_CLEAN.getChannel(), new StringType("-")); } @Override @@ -651,6 +654,7 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler { if (mapDl != null) { byte[] mapData = mapDl.getBytes(); RRMapDraw rrMap = RRMapDraw.loadImage(new ByteArrayInputStream(mapData)); + rrMap.setDrawOptions(mapDrawOptions); ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (logger.isDebugEnabled()) { final String mapPath = BINDING_USERDATA_PATH + File.separator + map @@ -658,7 +662,7 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler { CloudUtil.writeBytesToFileNio(mapData, mapPath); logger.debug("Mapdata saved to {}", mapPath); } - ImageIO.write(rrMap.getImage(MAP_SCALE), "jpg", baos); + ImageIO.write(rrMap.getImage(), "jpg", baos); byte[] byteArray = baos.toByteArray(); if (byteArray != null && byteArray.length > 0) { return new RawType(byteArray, "image/jpeg"); diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/robot/RRMapDraw.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/robot/RRMapDraw.java index 183e499f052..3469d877d4a 100644 --- a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/robot/RRMapDraw.java +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/robot/RRMapDraw.java @@ -62,41 +62,18 @@ public class RRMapDraw { private static final int MAP_WALL = 0x01; private static final int MAP_INSIDE = 0xFF; private static final int MAP_SCAN = 0x07; - private static final Color COLOR_MAP_INSIDE = new Color(32, 115, 185); - private static final Color COLOR_MAP_OUTSIDE = new Color(19, 87, 148); - private static final Color COLOR_MAP_WALL = new Color(100, 196, 254); - private static final Color COLOR_CARPET = new Color(0xDF, 0xDF, 0xDF, 0xA0); - private static final Color COLOR_GREY_WALL = new Color(93, 109, 126); - private static final Color COLOR_PATH = new Color(147, 194, 238); - private static final Color COLOR_ZONES = new Color(0xAD, 0xD8, 0xFF, 0x8F); - private static final Color COLOR_NO_GO_ZONES = new Color(255, 33, 55, 127); - private static final Color COLOR_CHARGER_HALO = new Color(0x66, 0xfe, 0xda, 0x7f); - private static final Color COLOR_ROBO = new Color(75, 235, 149); - private static final Color COLOR_SCAN = new Color(0xDF, 0xDF, 0xDF); - private static final Color ROOM1 = new Color(240, 178, 122); - private static final Color ROOM2 = new Color(133, 193, 233); - private static final Color ROOM3 = new Color(217, 136, 128); - private static final Color ROOM4 = new Color(52, 152, 219); - private static final Color ROOM5 = new Color(205, 97, 85); - private static final Color ROOM6 = new Color(243, 156, 18); - private static final Color ROOM7 = new Color(88, 214, 141); - private static final Color ROOM8 = new Color(245, 176, 65); - private static final Color ROOM9 = new Color(0xFc, 0xD4, 0x51); - private static final Color ROOM10 = new Color(72, 201, 176); - private static final Color ROOM11 = new Color(84, 153, 199); - private static final Color ROOM12 = new Color(255, 213, 209); - private static final Color ROOM13 = new Color(228, 228, 215); - private static final Color ROOM14 = new Color(82, 190, 128); - private static final Color ROOM15 = new Color(72, 201, 176); - private static final Color ROOM16 = new Color(165, 105, 189); - private static final Color[] ROOM_COLORS = { ROOM1, ROOM2, ROOM3, ROOM4, ROOM5, ROOM6, ROOM7, ROOM8, ROOM9, ROOM10, - ROOM11, ROOM12, ROOM13, ROOM14, ROOM15, ROOM16 }; - private final @Nullable Bundle bundle = FrameworkUtil.getBundle(getClass()); - private boolean multicolor = false; - private final RRMapFileParser rmfp; + private final @Nullable Bundle bundle = FrameworkUtil.getBundle(getClass()); + private final RRMapFileParser rmfp; private final Logger logger = LoggerFactory.getLogger(RRMapDraw.class); + private RRMapDrawOptions drawOptions = new RRMapDrawOptions(); + private boolean multicolor = false; + private int firstX = 0; + private int lastX = 0; + private int firstY = 0; + private int lastY = 0; + public RRMapDraw(RRMapFileParser rmfp) { this.rmfp = rmfp; } @@ -109,6 +86,14 @@ public class RRMapDraw { return rmfp.getImgHeight(); } + public void setDrawOptions(RRMapDrawOptions options) { + this.drawOptions = options; + } + + public RRMapDrawOptions getDrawOptions() { + return drawOptions; + } + public RRMapFileParser getMapParseDetails() { return this.rmfp; } @@ -145,29 +130,29 @@ public class RRMapDraw { byte walltype = rmfp.getImage()[x + rmfp.getImgWidth() * y]; switch (walltype & 0xFF) { case MAP_OUTSIDE: - g2d.setColor(COLOR_MAP_OUTSIDE); + g2d.setColor(drawOptions.getColorMapOutside()); break; case MAP_WALL: - g2d.setColor(COLOR_MAP_WALL); + g2d.setColor(drawOptions.getColorMapWall()); break; case MAP_INSIDE: - g2d.setColor(COLOR_MAP_INSIDE); + g2d.setColor(drawOptions.getColorMapInside()); break; case MAP_SCAN: - g2d.setColor(COLOR_SCAN); + g2d.setColor(drawOptions.getColorScan()); break; default: int obstacle = (walltype & 0x07); int mapId = (walltype & 0xFF) >>> 3; switch (obstacle) { case 0: - g2d.setColor(COLOR_GREY_WALL); + g2d.setColor(drawOptions.getColorGreyWall()); break; case 1: g2d.setColor(Color.BLACK); break; case 7: - g2d.setColor(ROOM_COLORS[mapId % 15]); + g2d.setColor(drawOptions.getRoomColors()[mapId % 15]); roomIds.add(mapId); multicolor = true; break; @@ -207,7 +192,7 @@ public class RRMapDraw { // ignore break; default: - g2d.setColor(COLOR_CARPET); + g2d.setColor(drawOptions.getColorCarpet()); float xPos = scale * (rmfp.getImgWidth() - x); float yP = scale * y; g2d.draw(new Line2D.Float(xPos, yP, xPos, yP)); @@ -230,7 +215,7 @@ public class RRMapDraw { switch (pathType) { case RRMapFileParser.PATH: if (!multicolor) { - g2d.setColor(COLOR_PATH); + g2d.setColor(drawOptions.getColorPath()); } else { g2d.setColor(Color.WHITE); } @@ -268,7 +253,7 @@ public class RRMapDraw { float w = Math.max(x, x1) - sx; float sy = Math.min(y, y1); float h = Math.max(y, y1) - sy; - g2d.setColor(COLOR_ZONES); + g2d.setColor(drawOptions.getColorZones()); g2d.fill(new Rectangle2D.Float(sx, sy, w, h)); } } @@ -290,7 +275,7 @@ public class RRMapDraw { noGo.lineTo(x2, y2); noGo.lineTo(x3, y3); noGo.lineTo(x, y); - g2d.setColor(COLOR_NO_GO_ZONES); + g2d.setColor(drawOptions.getColorNoGoZones()); g2d.fill(noGo); g2d.setColor(area.getKey() == 9 ? Color.RED : Color.WHITE); g2d.draw(noGo); @@ -316,13 +301,13 @@ public class RRMapDraw { float radius = 3 * scale; Stroke stroke = new BasicStroke(2 * scale); g2d.setStroke(stroke); - g2d.setColor(COLOR_CHARGER_HALO); + g2d.setColor(drawOptions.getColorChargerHalo()); final float chargerX = toXCoord(rmfp.getChargerX()) * scale; final float chargerY = toYCoord(rmfp.getChargerY()) * scale; drawCircle(g2d, chargerX, chargerY, radius, false); drawCenteredImg(g2d, scale / 8, "charger.png", chargerX, chargerY); radius = 3 * scale; - g2d.setColor(COLOR_ROBO); + g2d.setColor(drawOptions.getColorRobo()); final float roboX = toXCoord(rmfp.getRoboX()) * scale; final float roboY = toYCoord(rmfp.getRoboY()) * scale; drawCircle(g2d, roboX, roboY, radius, false); @@ -410,18 +395,22 @@ public class RRMapDraw { } catch (IOException e) { logger.debug("Error loading image ohlogo.png:: {}", e.getMessage()); } + if (drawOptions.getText().isBlank()) { + return; + } String fontName = getAvailableFont("Helvetica,Arial,Roboto,Verdana,Times,Serif,Dialog".split(",")); if (fontName == null) { return; // no available fonts to draw text } - Font font = new Font(fontName, Font.BOLD, 14); + int fz = (int) (drawOptions.getTextFontSize() * scale); + Font font = new Font(fontName, Font.BOLD, fz); g2d.setFont(font); - String message = "Openhab rocks your Xiaomi vacuum!"; + String message = drawOptions.getText(); FontMetrics fontMetrics = g2d.getFontMetrics(); int stringWidth = fontMetrics.stringWidth(message); - if ((stringWidth + textPos) > rmfp.getImgWidth() * scale) { - font = new Font(fontName, Font.BOLD, - (int) Math.floor(14 * (rmfp.getImgWidth() * scale - textPos - offset * scale) / stringWidth)); + if ((stringWidth + textPos) > width) { + int fzn = (int) Math.floor(((float) (width - textPos) / stringWidth) * fz); + font = new Font(fontName, Font.BOLD, fzn > 0 ? fzn : 1); g2d.setFont(font); } int stringHeight = fontMetrics.getAscent(); @@ -449,6 +438,39 @@ public class RRMapDraw { return fonts[0]; } + /** + * Finds the perimeter of the used area in the map + */ + private void getMapArea(Graphics2D g2d, float scale) { + int firstX = rmfp.getImgWidth(); + int lastX = 0; + int firstY = rmfp.getImgHeight(); + int lastY = 0; + for (int y = 0; y < rmfp.getImgHeight() - 1; y++) { + for (int x = 0; x < rmfp.getImgWidth() + 1; x++) { + int walltype = rmfp.getImage()[x + rmfp.getImgWidth() * y] & 0xFF; + if (walltype > MAP_OUTSIDE) { + if (y < firstY) { + firstY = y; + } + if (y > lastY) { + lastY = y; + } + if (x < firstX) { + firstX = x; + } + if (x > lastX) { + lastX = x; + } + } + } + } + this.firstX = firstX; + this.lastX = lastX; + this.firstY = rmfp.getImgHeight() - lastY; + this.lastY = rmfp.getImgHeight() - firstY; + } + private @Nullable URL getImageUrl(String image) { final Bundle bundle = this.bundle; if (bundle != null) { @@ -464,6 +486,10 @@ public class RRMapDraw { } } + public BufferedImage getImage() { + return getImage(drawOptions.getScale()); + } + public BufferedImage getImage(float scale) { int width = (int) Math.floor(rmfp.getImgWidth() * scale); int height = (int) Math.floor(rmfp.getImgHeight() * scale); @@ -481,9 +507,34 @@ public class RRMapDraw { drawRobo(g2d, scale); drawGoTo(g2d, scale); drawObstacles(g2d, scale); - g2d = bi.createGraphics(); - drawOpenHabRocks(g2d, width, height, scale); - return bi; + if (drawOptions.getCropBorder() < 0) { + g2d = bi.createGraphics(); + if (drawOptions.isShowLogo()) { + drawOpenHabRocks(g2d, width, height, scale); + } + return bi; + } + // crop the image to the used perimeter + getMapArea(g2d, scale); + int firstX = (this.firstX - drawOptions.getCropBorder()) > 0 ? this.firstX - drawOptions.getCropBorder() : 0; + int lastX = (this.lastX + drawOptions.getCropBorder()) < rmfp.getImgWidth() + ? this.lastX + drawOptions.getCropBorder() + : rmfp.getImgWidth(); + int firstY = (this.firstY - drawOptions.getCropBorder()) > 0 ? this.firstY - drawOptions.getCropBorder() : 0; + int lastY = (this.lastY + drawOptions.getCropBorder() + (int) (8 * scale)) < rmfp.getImgHeight() + ? this.lastY + drawOptions.getCropBorder() + (int) (8 * scale) + : rmfp.getImgHeight(); + int nwidth = (int) Math.floor((lastX - firstX) * scale); + int nheight = (int) Math.floor((lastY - firstY) * scale); + BufferedImage bo = new BufferedImage(nwidth, nheight, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D crop = bo.createGraphics(); + crop.transform(AffineTransform.getTranslateInstance(-firstX * scale, -firstY * scale)); + crop.drawImage(bi, 0, 0, null); + if (drawOptions.isShowLogo()) { + crop = bo.createGraphics(); + drawOpenHabRocks(crop, nwidth, nheight, scale * .75f); + } + return bo; } public boolean writePic(String filename, String formatName, float scale) throws IOException { diff --git a/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/robot/RRMapDrawOptions.java b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/robot/RRMapDrawOptions.java new file mode 100644 index 00000000000..260afa4ecbe --- /dev/null +++ b/bundles/org.openhab.binding.miio/src/main/java/org/openhab/binding/miio/internal/robot/RRMapDrawOptions.java @@ -0,0 +1,317 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.miio.internal.robot; + +import java.awt.Color; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.PrintWriter; +import java.lang.reflect.Type; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.slf4j.Logger; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * This class provides the configuration for the vacuum map drawing + * + * @author Marcel Verpaalen - Initial contribution + */ +@NonNullByDefault +public class RRMapDrawOptions { + + private static final Color COLOR_MAP_INSIDE = new Color(32, 115, 185); + private static final Color COLOR_MAP_OUTSIDE = new Color(19, 87, 148); + private static final Color COLOR_MAP_WALL = new Color(100, 196, 254); + private static final Color COLOR_CARPET = new Color(0xDF, 0xDF, 0xDF, 0xA0); + private static final Color COLOR_GREY_WALL = new Color(93, 109, 126); + private static final Color COLOR_PATH = new Color(147, 194, 238); + private static final Color COLOR_ZONES = new Color(0xAD, 0xD8, 0xFF, 0x8F); + private static final Color COLOR_NO_GO_ZONES = new Color(255, 33, 55, 127); + private static final Color COLOR_CHARGER_HALO = new Color(0x66, 0xfe, 0xda, 0x7f); + private static final Color COLOR_ROBO = new Color(75, 235, 149); + private static final Color COLOR_SCAN = new Color(0xDF, 0xDF, 0xDF); + private static final Color ROOM1 = new Color(240, 178, 122); + private static final Color ROOM2 = new Color(133, 193, 233); + private static final Color ROOM3 = new Color(217, 136, 128); + private static final Color ROOM4 = new Color(52, 152, 219); + private static final Color ROOM5 = new Color(205, 97, 85); + private static final Color ROOM6 = new Color(243, 156, 18); + private static final Color ROOM7 = new Color(88, 214, 141); + private static final Color ROOM8 = new Color(245, 176, 65); + private static final Color ROOM9 = new Color(0xFc, 0xD4, 0x51); + private static final Color ROOM10 = new Color(72, 201, 176); + private static final Color ROOM11 = new Color(84, 153, 199); + private static final Color ROOM12 = new Color(255, 213, 209); + private static final Color ROOM13 = new Color(228, 228, 215); + private static final Color ROOM14 = new Color(82, 190, 128); + private static final Color ROOM15 = new Color(72, 201, 176); + private static final Color ROOM16 = new Color(165, 105, 189); + private static final Color[] ROOM_COLORS = { ROOM1, ROOM2, ROOM3, ROOM4, ROOM5, ROOM6, ROOM7, ROOM8, ROOM9, ROOM10, + ROOM11, ROOM12, ROOM13, ROOM14, ROOM15, ROOM16 }; + + private static final Gson GSON = new GsonBuilder().setPrettyPrinting() + .registerTypeAdapter(Color.class, new JsonSerializer() { + @Override + public JsonElement serialize(Color src, @Nullable Type typeOfSrc, + @Nullable JsonSerializationContext context) { + JsonObject colorSave = new JsonObject(); + colorSave.addProperty("red", src.getRed()); + colorSave.addProperty("green", src.getGreen()); + colorSave.addProperty("blue", src.getBlue()); + colorSave.addProperty("alpha", src.getAlpha()); + return colorSave; + } + }).registerTypeAdapter(Color.class, new JsonDeserializer() { + @Override + @Nullable + public Color deserialize(@Nullable JsonElement json, @Nullable Type typeOfT, + @Nullable JsonDeserializationContext context) throws JsonParseException { + if (json == null) { + throw new JsonParseException("missing json text"); + } + JsonObject colorSave = json.getAsJsonObject(); + Color color = new Color(colorSave.get("red").getAsInt(), colorSave.get("green").getAsInt(), + colorSave.get("blue").getAsInt(), colorSave.get("alpha").getAsInt()); + return color; + } + }).create(); + + @SerializedName("colorMapInside") + @Expose + private Color colorMapInside = COLOR_MAP_INSIDE; + @SerializedName("colorMapOutside") + @Expose + private Color colorMapOutside = COLOR_MAP_OUTSIDE; + @SerializedName("colorMapWall") + @Expose + private Color colorMapWall = COLOR_MAP_WALL; + @SerializedName("colorCarpet") + @Expose + private Color colorCarpet = COLOR_CARPET; + @SerializedName("colorGreyWall") + @Expose + private Color colorGreyWall = COLOR_GREY_WALL; + @SerializedName("colorPath") + @Expose + private Color colorPath = COLOR_PATH; + @SerializedName("colorZones") + @Expose + private Color colorZones = COLOR_ZONES; + @SerializedName("colorNoGoZones") + @Expose + private Color colorNoGoZones = COLOR_NO_GO_ZONES; + @SerializedName("colorChargerHalo") + @Expose + private Color colorChargerHalo = COLOR_CHARGER_HALO; + @SerializedName("colorRobo") + @Expose + private Color colorRobo = COLOR_ROBO; + @SerializedName("colorScan") + @Expose + private Color colorScan = COLOR_SCAN; + + @SerializedName("roomColors") + @Expose + private Color[] roomColors = ROOM_COLORS; + + @SerializedName("showLogo") + @Expose + private boolean showLogo = true; + @SerializedName("text") + @Expose + private String text = "Openhab rocks your Xiaomi vacuum!"; + @SerializedName("textFontSize") + @Expose + private int textFontSize = 12; + @SerializedName("scale") + @Expose + private float scale = 2.0f; + @SerializedName("cropBorder") + @Expose + private int cropBorder = 10; + + public Color getColorMapInside() { + return colorMapInside; + } + + public void setColorMapInside(Color colorMapInside) { + this.colorMapInside = colorMapInside; + } + + public Color getColorMapOutside() { + return colorMapOutside; + } + + public void setColorMapOutside(Color colorMapOutside) { + this.colorMapOutside = colorMapOutside; + } + + public Color getColorMapWall() { + return colorMapWall; + } + + public void setColorMapWall(Color colorMapWall) { + this.colorMapWall = colorMapWall; + } + + public Color getColorCarpet() { + return colorCarpet; + } + + public void setColorCarpet(Color colorCarpet) { + this.colorCarpet = colorCarpet; + } + + public Color getColorGreyWall() { + return colorGreyWall; + } + + public void setColorGreyWall(Color colorGreyWall) { + this.colorGreyWall = colorGreyWall; + } + + public Color getColorPath() { + return colorPath; + } + + public void setColorPath(Color colorPath) { + this.colorPath = colorPath; + } + + public Color getColorZones() { + return colorZones; + } + + public void setColorZones(Color colorZones) { + this.colorZones = colorZones; + } + + public Color getColorNoGoZones() { + return colorNoGoZones; + } + + public void setColorNoGoZones(Color colorNoGoZones) { + this.colorNoGoZones = colorNoGoZones; + } + + public Color getColorChargerHalo() { + return colorChargerHalo; + } + + public void setColorChargerHalo(Color colorChargerHalo) { + this.colorChargerHalo = colorChargerHalo; + } + + public Color getColorRobo() { + return colorRobo; + } + + public void setColorRobo(Color colorRobo) { + this.colorRobo = colorRobo; + } + + public Color getColorScan() { + return colorScan; + } + + public void setColorScan(Color colorScan) { + this.colorScan = colorScan; + } + + public Color[] getRoomColors() { + return roomColors; + } + + public void setRoomColors(Color[] roomColors) { + this.roomColors = roomColors; + } + + public boolean isShowLogo() { + return showLogo; + } + + public void setShowLogo(boolean showLogo) { + this.showLogo = showLogo; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public final int getTextFontSize() { + return textFontSize; + } + + public final void setTextFontSize(int textFontSize) { + this.textFontSize = textFontSize; + } + + public float getScale() { + return scale; + } + + public void setScale(float scale) { + this.scale = scale; + } + + public final int getCropBorder() { + return cropBorder; + } + + public final void setCropBorder(int cropBorder) { + this.cropBorder = cropBorder; + } + + public static void writeOptionsToFile(RRMapDrawOptions options, String fileName, Logger logger) { + String json = GSON.toJson(options, RRMapDrawOptions.class); + try (PrintWriter pw = new PrintWriter(fileName)) { + pw.println(json); + logger.debug("Vacuum map draw options file created: {}", fileName); + } catch (FileNotFoundException e) { + logger.info("Error writing Vacuum map draw options file: {}", e.getMessage()); + } + } + + public static RRMapDrawOptions getOptionsFromFile(String fileName, Logger logger) { + try { + RRMapDrawOptions options = GSON.fromJson(new FileReader(fileName), RRMapDrawOptions.class); + return options; + } catch (FileNotFoundException e) { + logger.debug("Vacuum map draw options file {} not found. Using defaults", fileName); + return new RRMapDrawOptions(); + } catch (JsonParseException e) { + logger.info("Error reading vacuum map draw options file {}: {}", fileName, e.getMessage()); + } + logger.info("Write default map draw options to {}", fileName); + RRMapDrawOptions options = new RRMapDrawOptions(); + writeOptionsToFile(options, fileName, logger); + return new RRMapDrawOptions(); + } +}