/* * Copyright (C) 2012 Dr. John Lindsay <jlindsay@uoguelph.ca> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package whitebox.serialization; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.reflect.TypeToken; import java.awt.Color; import java.awt.Font; import java.io.File; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import whitebox.cartographic.*; import whitebox.interfaces.CartographicElement; import whitebox.structures.BoundingBox; import whitebox.interfaces.MapLayer; /** * * @author johnlindsay */ public class CartographicElementDeserializer implements JsonDeserializer<CartographicElement> { private String workingDirectory; private String paletteDirectory = null; public CartographicElementDeserializer(String currentWorkingDirectory, String paletteDirectory) { this.workingDirectory = currentWorkingDirectory; this.paletteDirectory = paletteDirectory; } @Override public CartographicElement deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException { if (workingDirectory == null || paletteDirectory == null) { throw new JsonParseException("The current working directory or palette directory must be set"); } GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(MapLayer.class, new MapLayerDeserializer(workingDirectory, paletteDirectory)); gsonBuilder.registerTypeAdapter(CartographicElement.class, new CartographicElementDeserializer(workingDirectory, paletteDirectory)); Gson gson = gsonBuilder.create(); Type clrType = new TypeToken<Color>() {}.getType(); Color clr; Type fontType = new TypeToken<Font>() {}.getType(); Font font; Type bbType = new TypeToken<BoundingBox>() {}.getType(); BoundingBox bb; JsonObject jo = je.getAsJsonObject(); String elementType = jo.getAsJsonPrimitive("cartographicElementType").getAsString(); String name = jo.getAsJsonPrimitive("name").getAsString(); switch (elementType) { case "MAP_AREA": MapArea ma = new MapArea(name); ma.setVisible(jo.getAsJsonPrimitive("isVisible").getAsBoolean()); ma.setHeight(jo.getAsJsonPrimitive("height").getAsInt()); ma.setWidth(jo.getAsJsonPrimitive("width").getAsInt()); ma.setLineWidth(jo.getAsJsonPrimitive("lineWidth").getAsFloat()); ma.setReferenceMarksSize(jo.getAsJsonPrimitive("referenceMarksSize").getAsInt()); ma.setRotation(jo.getAsJsonPrimitive("rotation").getAsDouble()); ma.setBackgroundVisible(jo.getAsJsonPrimitive("isBackgroundVisible").getAsBoolean()); ma.setBorderVisible(jo.getAsJsonPrimitive("isBorderVisible").getAsBoolean()); ma.setNeatlineVisible(jo.getAsJsonPrimitive("isNeatlineVisible").getAsBoolean()); ma.setReferenceMarksVisible(jo.getAsJsonPrimitive("isReferenceMarksVisible").getAsBoolean()); ma.setSizeMaximizedToScreenSize(jo.getAsJsonPrimitive("isSizeMaximizedToScreenSize").getAsBoolean()); ma.setUpperLeftX(jo.getAsJsonPrimitive("upperLeftX").getAsInt()); ma.setUpperLeftY(jo.getAsJsonPrimitive("upperLeftY").getAsInt()); ma.setElementNumber(jo.getAsJsonPrimitive("elementNumber").getAsInt()); ma.setName(jo.getAsJsonPrimitive("name").getAsString()); clr = gson.fromJson(jo.get("backgroundColour"), clrType); ma.setBackgroundColour(clr); clr = gson.fromJson(jo.get("borderColour"), clrType); ma.setBorderColour(clr); clr = gson.fromJson(jo.get("fontColour"), clrType); ma.setFontColour(clr); font = gson.fromJson(jo.get("labelFont"), fontType); ma.setLabelFont(font); bb = gson.fromJson(jo.get("currentExtent"), bbType); ma.setCurrentExtent(bb); bb = gson.fromJson(jo.get("currentMapExtent"), bbType); ma.setCurrentMapExtent(bb); Type listOfLayerObject = new TypeToken<List<MapLayer>>() {}.getType(); ArrayList<MapLayer> mlList = gson.fromJson(jo.get("layersList"), listOfLayerObject); for (MapLayer ml : mlList) { ma.addLayer(ml); } ma.setActiveLayer(jo.getAsJsonPrimitive("activeLayerOverlayNumber").getAsInt()); return ma; case "MAP_TITLE": MapTitle mt = new MapTitle(name); mt.setVisible(jo.getAsJsonPrimitive("isVisible").getAsBoolean()); mt.setLabel(jo.getAsJsonPrimitive("label").getAsString()); mt.setElementNumber(jo.getAsJsonPrimitive("elementNumber").getAsInt()); mt.setMargin(jo.getAsJsonPrimitive("margin").getAsInt()); mt.setBackgroundVisible(jo.getAsJsonPrimitive("isBackgroundVisible").getAsBoolean()); mt.setBorderVisible(jo.getAsJsonPrimitive("isBorderVisible").getAsBoolean()); mt.setOutlineVisible(jo.getAsJsonPrimitive("isOutlineVisible").getAsBoolean()); clr = gson.fromJson(jo.get("backColour"), clrType); mt.setBackColour(clr); clr = gson.fromJson(jo.get("borderColour"), clrType); mt.setBorderColour(clr); clr = gson.fromJson(jo.get("fontColour"), clrType); mt.setFontColour(clr); clr = gson.fromJson(jo.get("outlineColour"), clrType); mt.setOutlineColour(clr); font = gson.fromJson(jo.get("labelFont"), fontType); mt.setLabelFont(font); mt.setUpperLeftX(jo.getAsJsonPrimitive("upperLeftX").getAsInt()); mt.setUpperLeftY(jo.getAsJsonPrimitive("upperLeftY").getAsInt()); mt.setHeight(jo.getAsJsonPrimitive("height").getAsInt()); mt.setWidth(jo.getAsJsonPrimitive("width").getAsInt()); if (jo.has("rotation")) { mt.setRotation(jo.getAsJsonPrimitive("rotation").getAsDouble()); } return mt; case "MAP_TEXT_AREA": MapTextArea mta = new MapTextArea(name); mta.setVisible(jo.getAsJsonPrimitive("isVisible").getAsBoolean()); mta.setLabel(jo.getAsJsonPrimitive("label").getAsString()); mta.setUpperLeftX(jo.getAsJsonPrimitive("upperLeftX").getAsInt()); mta.setUpperLeftY(jo.getAsJsonPrimitive("upperLeftY").getAsInt()); mta.setElementNumber(jo.getAsJsonPrimitive("elementNumber").getAsInt()); mta.setHeight(jo.getAsJsonPrimitive("height").getAsInt()); mta.setWidth(jo.getAsJsonPrimitive("width").getAsInt()); mta.setMargin(jo.getAsJsonPrimitive("margin").getAsInt()); mta.setBackgroundVisible(jo.getAsJsonPrimitive("isBackgroundVisible").getAsBoolean()); mta.setBorderVisible(jo.getAsJsonPrimitive("isBorderVisible").getAsBoolean()); clr = gson.fromJson(jo.get("backColour"), clrType); mta.setBackColour(clr); clr = gson.fromJson(jo.get("borderColour"), clrType); mta.setBorderColour(clr); clr = gson.fromJson(jo.get("fontColour"), clrType); mta.setFontColour(clr); font = gson.fromJson(jo.get("labelFont"), fontType); mta.setLabelFont(font); if (jo.has("rotation")) { mta.setRotation(jo.getAsJsonPrimitive("rotation").getAsFloat()); } return mta; case "NORTH_ARROW": NorthArrow na = new NorthArrow(name); na.setVisible(jo.getAsJsonPrimitive("isVisible").getAsBoolean()); na.setUpperLeftX(jo.getAsJsonPrimitive("upperLeftX").getAsInt()); na.setUpperLeftY(jo.getAsJsonPrimitive("upperLeftY").getAsInt()); na.setElementNumber(jo.getAsJsonPrimitive("elementNumber").getAsInt()); na.setMargin(jo.getAsJsonPrimitive("margin").getAsInt()); na.setMarkerSize(jo.getAsJsonPrimitive("markerSize").getAsInt()); na.setLineWidth(jo.getAsJsonPrimitive("lineWidth").getAsFloat()); na.setBackgroundVisible(jo.getAsJsonPrimitive("isBackgroundVisible").getAsBoolean()); na.setBorderVisible(jo.getAsJsonPrimitive("isBorderVisible").getAsBoolean()); clr = gson.fromJson(jo.get("backColour"), clrType); na.setBackColour(clr); clr = gson.fromJson(jo.get("borderColour"), clrType); na.setBorderColour(clr); clr = gson.fromJson(jo.get("outlineColour"), clrType); na.setOutlineColour(clr); return na; case "MAP_IMAGE": String fileName = jo.getAsJsonPrimitive("fileName").getAsString(); // see whether it exists, and if it doesn't, see whether a file of the same // name exists in the working directory or any of its subdirectories. if (!new File(fileName).exists()) { flag = true; findFile(new File(workingDirectory), new File(fileName).getName()); if (!retFile.equals("")) { fileName = retFile; } else { throw new JsonParseException("Could not locate image file referred to in map file."); } } MapImage mi = new MapImage(name, fileName); mi.setVisible(jo.getAsJsonPrimitive("isVisible").getAsBoolean()); mi.setElementNumber(jo.getAsJsonPrimitive("elementNumber").getAsInt()); mi.setLineWidth(jo.getAsJsonPrimitive("lineWidth").getAsFloat()); mi.setBorderVisible(jo.getAsJsonPrimitive("isBorderVisible").getAsBoolean()); clr = gson.fromJson(jo.get("borderColour"), clrType); mi.setBorderColour(clr); mi.setUpperLeftX(jo.getAsJsonPrimitive("upperLeftX").getAsInt()); mi.setUpperLeftY(jo.getAsJsonPrimitive("upperLeftY").getAsInt()); mi.setHeight(jo.getAsJsonPrimitive("height").getAsInt()); mi.setWidth(jo.getAsJsonPrimitive("width").getAsInt()); mi.setMaintainAspectRatio(jo.getAsJsonPrimitive("maintainAspectRatio").getAsBoolean()); return mi; case "NEATLINE": Neatline nl = new Neatline(name); nl.setVisible(jo.getAsJsonPrimitive("isVisible").getAsBoolean()); nl.setUpperLeftX(jo.getAsJsonPrimitive("upperLeftX").getAsInt()); nl.setUpperLeftY(jo.getAsJsonPrimitive("upperLeftY").getAsInt()); nl.setElementNumber(jo.getAsJsonPrimitive("elementNumber").getAsInt()); nl.setDoubleLineGap(jo.getAsJsonPrimitive("doubleLineGap").getAsInt()); nl.setInnerLineWidth(jo.getAsJsonPrimitive("innerLineWidth").getAsFloat()); nl.setOuterLineThickness(jo.getAsJsonPrimitive("outerLineWidth").getAsFloat()); nl.setBackgroundVisible(jo.getAsJsonPrimitive("isBackgroundVisible").getAsBoolean()); nl.setBorderVisible(jo.getAsJsonPrimitive("isBorderVisible").getAsBoolean()); nl.setDoubleLine(jo.getAsJsonPrimitive("isDoubleLine").getAsBoolean()); clr = gson.fromJson(jo.get("backgroundColour"), clrType); nl.setBackgroundColour(clr); clr = gson.fromJson(jo.get("borderColour"), clrType); nl.setBorderColour(clr); nl.setHeight(jo.getAsJsonPrimitive("height").getAsInt()); nl.setWidth(jo.getAsJsonPrimitive("width").getAsInt()); return nl; case "MAP_SCALE": MapScale ms = new MapScale(name); ms.setVisible(jo.getAsJsonPrimitive("isVisible").getAsBoolean()); ms.setUpperLeftX(jo.getAsJsonPrimitive("upperLeftX").getAsInt()); ms.setUpperLeftY(jo.getAsJsonPrimitive("upperLeftY").getAsInt()); ms.setElementNumber(jo.getAsJsonPrimitive("elementNumber").getAsInt()); clr = gson.fromJson(jo.get("backColour"), clrType); ms.setBackColour(clr); clr = gson.fromJson(jo.get("borderColour"), clrType); ms.setBorderColour(clr); clr = gson.fromJson(jo.get("fontColour"), clrType); ms.setFontColour(clr); clr = gson.fromJson(jo.get("outlineColour"), clrType); ms.setOutlineColour(clr); ms.setBackgroundVisible(jo.getAsJsonPrimitive("backgroundVisible").getAsBoolean()); ms.setBorderVisible(jo.getAsJsonPrimitive("borderVisible").getAsBoolean()); ms.setOutlineVisible(jo.getAsJsonPrimitive("outlineVisible").getAsBoolean()); ms.setConversionToMetres(jo.getAsJsonPrimitive("conversionToMetres").getAsDouble()); ms.setHeight(jo.getAsJsonPrimitive("height").getAsInt()); ms.setWidth(jo.getAsJsonPrimitive("width").getAsInt()); ms.setLineWidth(jo.getAsJsonPrimitive("lineWidth").getAsFloat()); ms.setLowerLabel(jo.getAsJsonPrimitive("lowerLabel").getAsString()); ms.setMargin(jo.getAsJsonPrimitive("margin").getAsInt()); ms.setNumberDivisions(jo.getAsJsonPrimitive("numberDivisions").getAsInt()); ms.setRepresentativeFractionVisible(jo.getAsJsonPrimitive("representativeFractionVisible").getAsBoolean()); if (jo.has("graphicalScaleVisible")) { // added as a property later. ms.setGraphicalScaleVisible(jo.getAsJsonPrimitive("graphicalScaleVisible").getAsBoolean()); } ms.setUnits(jo.getAsJsonPrimitive("units").getAsString()); ms.setMapAreaElementNumber(jo.getAsJsonPrimitive("mapAreaElementNumber").getAsInt()); if (jo.has("labelFont")) { font = gson.fromJson(jo.get("labelFont"), fontType); ms.setLabelFont(font); } if (jo.has("scaleStyle")) { String style = jo.getAsJsonPrimitive("scaleStyle").getAsString(); switch (style) { case "COMPLEX": ms.setScaleStyle(MapScale.ScaleStyle.COMPLEX); break; case "SIMPLE": ms.setScaleStyle(MapScale.ScaleStyle.SIMPLE); break; case "COMPACT": ms.setScaleStyle(MapScale.ScaleStyle.COMPACT); break; default: ms.setScaleStyle(MapScale.ScaleStyle.STANDARD); } } return ms; case "LEGEND": Legend l = new Legend(name); l.setVisible(jo.getAsJsonPrimitive("isVisible").getAsBoolean()); l.setLabel(jo.getAsJsonPrimitive("label").getAsString()); font = gson.fromJson(jo.get("labelFont"), fontType); l.setLabelFont(font); l.setMargin(jo.getAsJsonPrimitive("margin").getAsInt()); l.setElementNumber(jo.getAsJsonPrimitive("elementNumber").getAsInt()); clr = gson.fromJson(jo.get("backgroundColour"), clrType); l.setBackgroundColour(clr); clr = gson.fromJson(jo.get("borderColour"), clrType); l.setBorderColour(clr); clr = gson.fromJson(jo.get("fontColour"), clrType); l.setFontColour(clr); l.setBackgroundVisible(jo.getAsJsonPrimitive("backgroundVisible").getAsBoolean()); l.setBorderVisible(jo.getAsJsonPrimitive("borderVisible").getAsBoolean()); l.setLineWidth(jo.getAsJsonPrimitive("lineWidth").getAsFloat()); l.setBorderWidth(jo.getAsJsonPrimitive("borderWidth").getAsFloat()); l.setHeight(jo.getAsJsonPrimitive("height").getAsInt()); l.setWidth(jo.getAsJsonPrimitive("width").getAsInt()); l.setUpperLeftX(jo.getAsJsonPrimitive("upperLeftX").getAsInt()); l.setUpperLeftY(jo.getAsJsonPrimitive("upperLeftY").getAsInt()); return l; case "CARTOGRAPHIC_ELEMENT_GROUP": CartographicElementGroup ceg = new CartographicElementGroup(name); ceg.setElementNumber(jo.getAsJsonPrimitive("elementNumber").getAsInt()); Type listOfCartographicElementsObject = new TypeToken<List<CartographicElement>>() {}.getType(); JsonElement je2 = jo.get("elementList"); ArrayList<CartographicElement> cartoElementList = gson.fromJson(je2, listOfCartographicElementsObject); ceg.setElementList(cartoElementList); return ceg; } return null; } private static String retFile = ""; private boolean flag = true; private void findFile(File dir, String fileName) { if (flag) { File[] files = dir.listFiles(); for (int i = 0; i < files.length; i++) { if (files[i].isDirectory()) { findFile(files[i], fileName); } else if (files[i].getName().equals(fileName)) { retFile = files[i].toString(); flag = false; break; } } } } }