Skip to content

Commit ada6807

Browse files
committed
Add Yaml Carto Reader and Writer
1 parent 3c7bbea commit ada6807

23 files changed

+1025
-7
lines changed
Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
package geoscript.carto.io
2+
3+
import geoscript.carto.*
4+
import geoscript.filter.Color
5+
import geoscript.render.io.YamlMapReader
6+
import org.yaml.snakeyaml.Yaml
7+
8+
import java.awt.*
9+
import java.text.DateFormat
10+
import java.text.SimpleDateFormat
11+
12+
/**
13+
* Read a CartoBuilder from a YAML String
14+
* @author Jared Erickson
15+
*/
16+
class YamlCartoReader implements CartoReader {
17+
18+
@Override
19+
String getName() {
20+
"yaml"
21+
}
22+
23+
@Override
24+
CartoBuilder read(String str) {
25+
Yaml yaml = new Yaml()
26+
Map config = yaml.load(str)
27+
28+
YamlMapReader mapReader = new YamlMapReader()
29+
Map mapItems = [:]
30+
CartoBuilder cartoBuilder = CartoFactories.findByName(config.type)
31+
.create(new PageSize(config.width, config.height))
32+
config.items.each { Map item ->
33+
String itemType = item.type
34+
if (itemType.equalsIgnoreCase("rectangle")) {
35+
RectangleItem rectangleItem = new RectangleItem(
36+
item.x, item.y, item.width, item.height
37+
)
38+
if (item.strokeColor) {
39+
rectangleItem.strokeColor(new Color(item.strokeColor).asColor())
40+
}
41+
if (item.fillColor) {
42+
rectangleItem.fillColor(new Color(item.fillColor).asColor())
43+
}
44+
if (item.strokeWidth) {
45+
rectangleItem.strokeWidth(item.strokeWidth as float)
46+
}
47+
cartoBuilder.rectangle(rectangleItem)
48+
} else if (itemType.equalsIgnoreCase("dateText")) {
49+
DateTextItem dateTextItem = new DateTextItem(
50+
item.x, item.y, item.width, item.height
51+
)
52+
if (item.format) {
53+
dateTextItem.format(item.format)
54+
}
55+
if (item.date) {
56+
DateFormat dateFormat = new SimpleDateFormat(dateTextItem.format)
57+
dateTextItem.date(dateFormat.parse(item.date))
58+
}
59+
if (item.color) {
60+
dateTextItem.color(new Color(item.color).asColor())
61+
}
62+
if (item.font) {
63+
dateTextItem.font(getFont(item.font))
64+
}
65+
if (item.horizontalAlign) {
66+
dateTextItem.horizontalAlign(HorizontalAlign.valueOf(item.horizontalAlign.toString().toUpperCase()))
67+
}
68+
if (item.verticalAlign) {
69+
dateTextItem.verticalAlign(VerticalAlign.valueOf(item.verticalAlign.toString().toUpperCase()))
70+
}
71+
cartoBuilder.dateText(dateTextItem)
72+
} else if (itemType.equalsIgnoreCase("image")) {
73+
ImageItem imageItem = new ImageItem(item.x, item.y, item.width, item.height)
74+
imageItem.path(new File(item.path).absoluteFile)
75+
cartoBuilder.image(imageItem)
76+
} else if (itemType.equalsIgnoreCase("line")) {
77+
LineItem lineItem = new LineItem(item.x, item.y, item.width, item.height)
78+
if (item.strokeColor) {
79+
lineItem.strokeColor(new Color(item.strokeColor).asColor())
80+
}
81+
if (item.strokeWidth) {
82+
lineItem.strokeWidth(item.strokeWidth as float)
83+
}
84+
cartoBuilder.line(lineItem)
85+
} else if (itemType.equalsIgnoreCase("map")) {
86+
MapItem mapItem = new MapItem(item.x, item.y, item.width, item.height)
87+
mapItem.map(mapReader.read(item))
88+
mapItems[item.name] = mapItem
89+
cartoBuilder.map(mapItem)
90+
} else if (itemType.equalsIgnoreCase("overViewMap")) {
91+
OverviewMapItem overviewMapItem = new OverviewMapItem(item.x, item.y, item.width, item.height)
92+
overviewMapItem.overviewMap(mapReader.read(item))
93+
overviewMapItem.linkedMap(mapItems[item.linkedMap].map)
94+
if (item.zoomIntoBounds) {
95+
overviewMapItem.zoomIntoBounds(item.zoomIntoBounds)
96+
}
97+
if (item.scaleFactor) {
98+
overviewMapItem.scaleFactor(item.scaleFactor)
99+
}
100+
cartoBuilder.overViewMap(overviewMapItem)
101+
} else if (itemType.equalsIgnoreCase("northArrow")) {
102+
NorthArrowItem northArrowItem = new NorthArrowItem(item.x, item.y, item.width, item.height)
103+
if (item.style) {
104+
northArrowItem.style(NorthArrowStyle.valueOf(item.style.toString()))
105+
}
106+
if (item.fillColor1) {
107+
northArrowItem.fillColor1(new Color(item.fillColor1).asColor())
108+
}
109+
if (item.fillColor2) {
110+
northArrowItem.fillColor2(new Color(item.fillColor2).asColor())
111+
}
112+
if (item.strokeColor1) {
113+
northArrowItem.strokeColor1(new Color(item.strokeColor1).asColor())
114+
}
115+
if (item.strokeColor2) {
116+
northArrowItem.strokeColor2(new Color(item.strokeColor2).asColor())
117+
}
118+
if (item.strokeWidth) {
119+
northArrowItem.strokeWidth(item.strokeWidth as float)
120+
}
121+
if (item.drawText != null) {
122+
northArrowItem.drawText(item.drawText)
123+
}
124+
if (item.font) {
125+
northArrowItem.font(getFont(item.font))
126+
}
127+
if (item.textColor) {
128+
northArrowItem.textColor(new Color(item.textColor).asColor())
129+
}
130+
cartoBuilder.northArrow(northArrowItem)
131+
} else if (itemType.equalsIgnoreCase("text")) {
132+
TextItem textItem = new TextItem(item.x, item.y, item.width, item.height)
133+
textItem.text(item.text)
134+
if (item.color) {
135+
textItem.color(new Color(item.color).asColor())
136+
}
137+
if (item.font) {
138+
textItem.font(getFont(item.font))
139+
}
140+
if (item.horizontalAlign) {
141+
textItem.horizontalAlign(HorizontalAlign.valueOf(item.horizontalAlign.toString().toUpperCase()))
142+
}
143+
if (item.verticalAlign) {
144+
textItem.verticalAlign(VerticalAlign.valueOf(item.verticalAlign.toString().toUpperCase()))
145+
}
146+
cartoBuilder.text(textItem)
147+
} else if (itemType.equalsIgnoreCase("paragraph")) {
148+
ParagraphItem paragraphItem = new ParagraphItem(item.x, item.y, item.width, item.height)
149+
paragraphItem.text(item.text)
150+
if (item.color) {
151+
paragraphItem.color(new Color(item.color).asColor())
152+
}
153+
if (item.font) {
154+
paragraphItem.font(getFont(item.font))
155+
}
156+
cartoBuilder.paragraph(paragraphItem)
157+
} else if (itemType.equalsIgnoreCase("scaleText")) {
158+
ScaleTextItem scaleTextItem = new ScaleTextItem(item.x, item.y, item.width, item.height)
159+
scaleTextItem.map(mapItems[item.map].map)
160+
if (item.format) {
161+
scaleTextItem.format(item.format)
162+
}
163+
if (item.prefixText) {
164+
scaleTextItem.prefixText(item.prefixText)
165+
}
166+
if (item.color) {
167+
scaleTextItem.color(new Color(item.color).asColor())
168+
}
169+
if (item.font) {
170+
scaleTextItem.font(getFont(item.font))
171+
}
172+
if (item.horizontalAlign) {
173+
scaleTextItem.horizontalAlign(HorizontalAlign.valueOf(item.horizontalAlign.toString().toUpperCase()))
174+
}
175+
if (item.verticalAlign) {
176+
scaleTextItem.verticalAlign(VerticalAlign.valueOf(item.verticalAlign.toString().toUpperCase()))
177+
}
178+
cartoBuilder.scaleText(scaleTextItem)
179+
} else if (itemType.equalsIgnoreCase("scaleBar")) {
180+
ScaleBarItem scaleBarItem = new ScaleBarItem(item.x, item.y, item.width, item.height)
181+
scaleBarItem.map(mapItems[item.map].map)
182+
if (item.strokeColor) {
183+
scaleBarItem.strokeColor(new Color(item.strokeColor).asColor())
184+
}
185+
if (item.fillColor) {
186+
scaleBarItem.fillColor(new Color(item.fillColor).asColor())
187+
}
188+
if (item.barStrokeColor) {
189+
scaleBarItem.barStrokeColor(new Color(item.barStrokeColor).asColor())
190+
}
191+
if (item.font) {
192+
scaleBarItem.font(getFont(item.font))
193+
}
194+
if (item.textColor) {
195+
scaleBarItem.textColor(new Color(item.textColor).asColor())
196+
}
197+
if (item.barStrokeWidth) {
198+
scaleBarItem.barStrokeWidth(item.barStrokeWidth as float)
199+
}
200+
if (item.strokeWidth) {
201+
scaleBarItem.strokeWidth(item.strokeWidth as float)
202+
}
203+
if (item.border) {
204+
scaleBarItem.border(item.border as int)
205+
}
206+
if (item.units) {
207+
scaleBarItem.units(ScaleBarItem.Units.valueOf(item.units.toString().toUpperCase()))
208+
}
209+
cartoBuilder.scaleBar(scaleBarItem)
210+
} else if (itemType.equalsIgnoreCase("grid")) {
211+
GridItem gridItem = new GridItem(item.x, item.y, item.width, item.height)
212+
if (item.size) {
213+
gridItem.size(item.size as int)
214+
}
215+
if (item.strokeWidth) {
216+
gridItem.strokeWidth(item.strokeWidth as float)
217+
}
218+
if (item.strokeColor) {
219+
gridItem.strokeColor(new Color(item.strokeColor).asColor())
220+
}
221+
cartoBuilder.grid(gridItem)
222+
} else if (itemType.equalsIgnoreCase("table")) {
223+
TableItem tableItem = new TableItem(item.x, item.y, item.width, item.height)
224+
tableItem.columns(item.columns.collect { it })
225+
item.rows.each { Map row ->
226+
tableItem.row(row)
227+
}
228+
if (item.columnRowStyle) {
229+
setRowStyle(tableItem.columnRowStyle, item.columnRowStyle)
230+
}
231+
if (item.evenRowStyle) {
232+
setRowStyle(tableItem.evenRowStyle, item.evenRowStyle)
233+
}
234+
if (item.oddRowStyle) {
235+
setRowStyle(tableItem.oddRowStyle, item.oddRowStyle)
236+
}
237+
cartoBuilder.table(tableItem)
238+
} else if (itemType.equalsIgnoreCase("legend")) {
239+
LegendItem legendItem = new LegendItem(item.x, item.y, item.width, item.height)
240+
legendItem.addMap(mapItems[item.map].map)
241+
if (item.backgroundColor) {
242+
legendItem.backgroundColor(new Color(item.backgroundColor).asColor())
243+
}
244+
if (item.title) {
245+
legendItem.title(item.title)
246+
}
247+
if (item.titleFont) {
248+
legendItem.titleFont(getFont(item.titleFont))
249+
}
250+
if (item.titleColor) {
251+
legendItem.titleColor(new Color(item.titleColor).asColor())
252+
}
253+
if (item.textFont) {
254+
legendItem.textFont(getFont(item.textFont))
255+
}
256+
if (item.textColor) {
257+
legendItem.textColor(new Color(item.textColor).asColor())
258+
}
259+
if (item.numberFormat) {
260+
legendItem.numberFormat(item.numberFormat)
261+
}
262+
if (item.legendEntryWidth) {
263+
legendItem.legendEntryWidth(item.legendEntryWidth as int)
264+
}
265+
if (item.legendEntryHeight) {
266+
legendItem.legendEntryHeight(item.legendEntryHeight as int)
267+
}
268+
if (item.gapBetweenEntries) {
269+
legendItem.gapBetweenEntries(item.gapBetweenEntries as int)
270+
}
271+
cartoBuilder.legend(legendItem)
272+
}
273+
}
274+
cartoBuilder
275+
}
276+
277+
private Font getFont(Map fontItem) {
278+
String name = fontItem.name
279+
int style = Font.PLAIN
280+
if (fontItem.style.equalsIgnoreCase("bold")) {
281+
style = Font.BOLD
282+
} else if (fontItem.style.equalsIgnoreCase("italic")) {
283+
style = Font.ITALIC
284+
}
285+
int size = fontItem.size.toString().toInteger()
286+
new Font(name, style, size)
287+
}
288+
289+
private void setRowStyle(TableItem.RowStyle rowStyle, Map item) {
290+
if (item.backgroundColor) {
291+
rowStyle.backGroundColor = new Color(item.backgroundColor).asColor()
292+
}
293+
if (item.font) {
294+
rowStyle.font = getFont(item.font as Map)
295+
}
296+
if (item.textColor) {
297+
rowStyle.textColor = new Color(item.textColor).asColor()
298+
}
299+
if (item.strokeColor) {
300+
rowStyle.strokeColor = new Color(item.strokeColor).asColor()
301+
}
302+
}
303+
304+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package geoscript.render.io
2+
3+
import geoscript.geom.Bounds
4+
import geoscript.layer.Renderables
5+
import geoscript.render.Map as GMap
6+
import groovy.json.JsonSlurper
7+
import org.yaml.snakeyaml.Yaml
8+
9+
/**
10+
* Read a Map from a JSON String.
11+
* <pre>
12+
* ---
13+
* width: 400
14+
* height: 400
15+
* imageType: png
16+
* backgroundColor: blue
17+
* proj: EPSG:4326
18+
* bounds:
19+
* minX: -135.911779
20+
* minY: 36.993573
21+
* maxX: -96.536779
22+
* maxY: 51.405899
23+
* layers:
24+
* - layertype: layer
25+
* file: "states.shp"
26+
* </pre>
27+
* @author Jared Erickson
28+
*/
29+
class YamlMapReader implements MapReader {
30+
31+
@Override
32+
String getName() {
33+
"yaml"
34+
}
35+
36+
@Override
37+
GMap read(String str) {
38+
Yaml yaml = new Yaml()
39+
Map values = yaml.load(str)
40+
read(values)
41+
}
42+
43+
/**
44+
* Read a GeoScript Map from a map of values
45+
* @param values A Map of values
46+
* @return A GeoScript Map
47+
*/
48+
GMap read(Map values) {
49+
GMap map = new GMap(
50+
width: values.get("width", 600),
51+
height: values.get("height", 400),
52+
type: values.get("imageType", "png"),
53+
backgroundColor: values.get("backgroundColor"),
54+
fixAspectRatio: values.get("fixAspectRation", true),
55+
layers: Renderables.getRenderables(values.get("layers"))
56+
)
57+
if (values.get("proj")) {
58+
map.proj = values.get("proj")
59+
}
60+
if (values.get("bounds")) {
61+
Map bounds = values.get("bounds")
62+
map.bounds = new Bounds(bounds.minX, bounds.minY, bounds.maxX, bounds.maxY, bounds?.proj)
63+
}
64+
map
65+
}
66+
67+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
geoscript.carto.io.JsonCartoReader
2-
geoscript.carto.io.XmlCartoReader
2+
geoscript.carto.io.XmlCartoReader
3+
geoscript.carto.io.YamlCartoReader
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
geoscript.render.io.XmlMapReader
2-
geoscript.render.io.JsonMapReader
2+
geoscript.render.io.JsonMapReader
3+
geoscript.render.io.YamlMapReader

0 commit comments

Comments
 (0)