Skip to content

Commit 4156531

Browse files
authored
Merge pull request #75 from geoscript/GSG-72
Add title to Symbolizer
2 parents 0de2f82 + 7f59bbc commit 4156531

6 files changed

Lines changed: 114 additions & 2 deletions

File tree

src/main/groovy/geoscript/carto/LegendItem.groovy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,9 @@ class LegendItem extends Item {
239239
}
240240
layer.style.gtStyle.featureTypeStyles().each { def fts ->
241241
fts.rules().each { def rule ->
242+
String ruleName = rule.name
242243
Filter filter = rule.filter
243-
String title = numberOfRules > 1 ? CQL.toCQL(filter) : layer.name.capitalize()
244+
String title = ruleName ?: numberOfRules > 1 ? CQL.toCQL(filter) : layer.name.capitalize()
244245
Style style = SLDStyle.fromRule(rule)
245246
if (legendEntryType == LegendEntryType.POINT) {
246247
addPointEntry(title, style)

src/main/groovy/geoscript/style/Composite.groovy

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,31 @@ class Composite extends Symbolizer {
7575
this
7676
}
7777

78+
/**
79+
* Set a title for this Composite
80+
* @param title The title
81+
* @return This Composite
82+
*/
83+
@Override
84+
Symbolizer title(String title) {
85+
super.title(title)
86+
parts.each{part -> part.title(title)}
87+
this
88+
}
89+
90+
/**
91+
* Get the title.
92+
* @return The title
93+
*/
94+
@Override
95+
String getTitle() {
96+
if (!this.@title) {
97+
parts.reverse().find { Symbolizer sym -> sym.title }?.title
98+
} else {
99+
this.@title
100+
}
101+
}
102+
78103
/**
79104
* The String representation
80105
* @return The string representation

src/main/groovy/geoscript/style/Symbolizer.groovy

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ class Symbolizer implements Style, Cloneable {
4545
*/
4646
int z
4747

48+
/**
49+
* The title of the Symbolizer
50+
*/
51+
protected String title
52+
4853
/**
4954
* A Map of Symbolizer options
5055
*/
@@ -128,6 +133,15 @@ class Symbolizer implements Style, Cloneable {
128133
this
129134
}
130135

136+
Symbolizer title(String title) {
137+
this.title = title
138+
this
139+
}
140+
141+
String getTitle() {
142+
this.title
143+
}
144+
131145
/**
132146
* Set composite (copy, destination, source-over, destination-over, source-in, destination-in,
133147
* source-out, destination-out, source-atop, destination-atop, xor) or blending (multiply, screen, overlay, darken,
@@ -361,6 +375,7 @@ class Symbolizer implements Style, Cloneable {
361375
rule.filter = fil.filter
362376

363377
syms.each {Symbolizer sym ->
378+
rule.name = sym.title
364379
sym.prepare(fts, rule)
365380
// Apply FeatureTypeStyle vendor options
366381
if (!sym.styleOptions.isEmpty()) {

src/main/groovy/geoscript/style/UniqueValues.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ class UniqueValues extends Composite {
8686
// Create the Symbolizer
8787
// name: "${field} = ${value}",
8888
// title: "${field} = ${value}",
89-
Symbolizer.getDefault(layer.schema.geom.typ, color).where(new Filter(filterFactory.equals(filterFactory.property(field), filterFactory.literal(value))))
89+
Symbolizer.getDefault(layer.schema.geom.typ, color)
90+
.where(new Filter(filterFactory.equals(filterFactory.property(field), filterFactory.literal(value))))
91+
.title("${value}")
9092
}
9193
}
9294

src/test/groovy/geoscript/carto/LegendItemTest.groovy

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package geoscript.carto
22

3+
import geoscript.layer.GeoTIFF
34
import geoscript.layer.Shapefile
5+
import geoscript.render.Map
46
import geoscript.style.ColorMap
57
import geoscript.style.Fill
68
import geoscript.style.Shape
79
import geoscript.style.Stroke
10+
import geoscript.style.UniqueValues
11+
import org.junit.jupiter.api.io.TempDir
12+
813
import java.awt.Color
914
import org.junit.jupiter.api.Test
1015

@@ -14,6 +19,9 @@ import static org.junit.jupiter.api.Assertions.*
1419

1520
class LegendItemTest {
1621

22+
@TempDir
23+
private File folder
24+
1725
@Test
1826
void create() {
1927

@@ -47,4 +55,42 @@ class LegendItemTest {
4755
assertTrue(item.toString().endsWith(")"))
4856
}
4957

58+
@Test
59+
void drawWithNamedSymbolizer() {
60+
File file = new File(getClass().getClassLoader().getResource("states.shp").toURI())
61+
Shapefile shapefile = new Shapefile(file)
62+
shapefile.style = new Fill("white") + new Stroke("black", 0.1).title("State Outlines")
63+
64+
Map map = new Map(layers: [
65+
shapefile
66+
])
67+
68+
File mapFile = new File("target/carto_legend_symbolizer_name.png")
69+
mapFile.withOutputStream { OutputStream outputStream ->
70+
new ImageCartoBuilder(PageSize.LETTER_LANDSCAPE, ImageCartoBuilder.ImageType.PNG)
71+
.map(new MapItem(30, 120, 742, 470).map(map))
72+
.legend(new LegendItem(640, 500, 180,80).addMap(map))
73+
.build(outputStream)
74+
}
75+
}
76+
77+
@Test
78+
void drawWithNamedUniqueSymbolizer() {
79+
File file = new File(getClass().getClassLoader().getResource("states.shp").toURI())
80+
Shapefile shapefile = new Shapefile(file)
81+
shapefile.style = new UniqueValues(shapefile, "SUB_REGION")
82+
83+
Map map = new Map(layers: [
84+
shapefile
85+
])
86+
87+
File mapFile = new File("target/carto_legend_symbolizer_unique_name.png")
88+
mapFile.withOutputStream { OutputStream outputStream ->
89+
new ImageCartoBuilder(PageSize.LETTER_LANDSCAPE, ImageCartoBuilder.ImageType.PNG)
90+
.map(new MapItem(240, 120, 542, 470).map(map))
91+
.legend(new LegendItem(10, 10, 220,600).addMap(map))
92+
.build(outputStream)
93+
}
94+
}
95+
5096
}

src/test/groovy/geoscript/style/SymbolizerTest.groovy

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,29 @@ class SymbolizerTest {
7575
assertEquals 200, sym.scale[1], 0.1
7676

7777
}
78+
79+
@Test void title() {
80+
// Title on a Symbolizer
81+
Symbolizer symbolizer = new Symbolizer().title("Outline")
82+
assertEquals "Outline", symbolizer.title
83+
84+
// Title on the Composites parts not itself (should return the title of the last part)
85+
Symbolizer composite = new Fill("red").title("Fill") + new Stroke("#ffffff").title("Stroke")
86+
assertEquals "Stroke", composite.title
87+
88+
// Title on the Composites parts not itself (should return the title of the last part)
89+
composite = new Fill("red").title("Fill") + new Stroke("#ffffff").title("Stroke") + new Label("NAME").title("Label")
90+
assertEquals "Label", composite.title
91+
92+
// Title on the Composites parts not itself (should return the title of the last part that has a title)
93+
composite = new Fill("red") + new Stroke("#ffffff").title("Stroke") + new Label("NAME")
94+
assertEquals "Stroke", composite.title
95+
96+
// Title is on the Composite which is used instead of titles on it's parts
97+
composite = new Fill("red") + new Stroke("#ffffff").title("Stroke") + new Label("NAME")
98+
composite.title = "Outlines"
99+
assertEquals "Outlines", composite.title
100+
}
78101

79102
@Test void plus() {
80103
def composite = new Fill("red") + new Stroke("#ffffff")

0 commit comments

Comments
 (0)