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;
@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;
private boolean hasChannelStructure;
private ConcurrentHashMap<RobotCababilities, Boolean> deviceCapabilities = new ConcurrentHashMap<>();
private ChannelTypeRegistry channelTypeRegistry;
+ private RRMapDrawOptions mapDrawOptions = new RRMapDrawOptions();
public MiIoVacuumHandler(Thing thing, MiIoDatabaseWatchService miIoDatabaseWatchService,
CloudConnector cloudConnector, ChannelTypeRegistry channelTypeRegistry) {
}
return null;
});
- updateState(RobotCababilities.SEGMENT_CLEAN.getChannel(), new StringType("-"));
}
@Override
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
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
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");
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 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;
}
return rmfp.getImgHeight();
}
+ public void setDrawOptions(RRMapDrawOptions options) {
+ this.drawOptions = options;
+ }
+
+ public RRMapDrawOptions getDrawOptions() {
+ return drawOptions;
+ }
+
public RRMapFileParser getMapParseDetails() {
return this.rmfp;
}
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;
// 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));
switch (pathType) {
case RRMapFileParser.PATH:
if (!multicolor) {
- g2d.setColor(COLOR_PATH);
+ g2d.setColor(drawOptions.getColorPath());
} else {
g2d.setColor(Color.WHITE);
}
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));
}
}
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);
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);
} 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();
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) {
}
}
+ 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);
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 {
--- /dev/null
+/**
+ * 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<Color>() {
+ @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<Color>() {
+ @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();
+ }
+}