/*
* 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;
}
}
}
}
}