Following Label coordinate position of Grid lines explanations I was able to create latitude lines every 10 degrees with labels. The values of the latitudes are drawn following the prime meridian (0 longitude).
Is there a way to display the labels along meridians 30W and 30E without displaying them at the prime meridian?
How could I label latitudes every 30 degrees starting at 0 while keeping the latitude lines (parallels) drawn every 10 degrees?
I have looked in various articles about filters and rules, but I have not been able to find the answer to my questions.
New version of code creating lat/lon graticule and labeling :
public Layer getGraticuleLayer(MapContent map, ReferencedEnvelope bounds) {
CoordinateReferenceSystem crs1 = map.getCoordinateReferenceSystem();
SimpleFeatureType type = (SimpleFeatureType) GridUtilities.buildType(crs1);
List<OrthoLineDef> lineDefs = Arrays.asList(
new OrthoLineDef(LineOrientation.VERTICAL, 2, 10.0),
new OrthoLineDef(LineOrientation.HORIZONTAL, 2,10.0));
double vertexSpacing = 0.1;
SimpleFeatureSource grid =
Lines.createOrthoLines(bounds, lineDefs, vertexSpacing,
new LineFeatureBuilder(type));
Style blueStyle = SLD.createLineStyle(Color.blue, 1.0f);
((LineSymbolizer)blueStyle.featureTypeStyles().get(0).rules()
.get(0).symbolizers().get(0)).getStroke().setOpacity(ff.literal(0.5));
FeatureLayer layer = new FeatureLayer(grid, blueStyle);
ReferencedEnvelope gridBounds = layer.getBounds();
StyleBuilder sb = new StyleBuilder();
java.awt.Font font = java.awt.Font.decode("Arial");
TextSymbolizer text = sb.createTextSymbolizer(Color.white,
sb.createFont(font), "label");
// every 30 instead of 10
String localElement = "element";
for (OrthoLineDef lineDef : lineDefs) {
switch (lineDef.getOrientation()) {
case HORIZONTAL:
Rule rule = blueStyle.featureTypeStyles().get(0).rules().get(0);
Function startPoint = ff.function("startPoint", ff.property(localElement)); // name = localName var in orig code
Function endPoint = ff.function("endPoint", ff.property(localElement)); // name = localName var in orig code.
text.setGeometry(endPoint);
Filter filter = ff.and(ff.equals(ff.function("getY", startPoint), ff.function("getY", endPoint)), ff.equals(ff.function("IEEEremainder", ff.function("parseDouble", ff.property("value")), ff.literal(30)),
ff.literal(0)));
rule.setFilter(filter);
LabelPlacement lp = sb.createPointPlacement(.5, .5, 0, -10, 0);
text.setLabelPlacement(lp);
rule.symbolizers().add(text);
break;
case VERTICAL:
Rule ruleLon = blueStyle.featureTypeStyles().get(0).rules().get(0);
startPoint = ff.function("startPoint", ff.property(localElement));
endPoint = ff.function("endPoint", ff.property(localElement));
text.setGeometry(endPoint);
filter = ff.and(ff.equals(ff.function("getX", startPoint), ff.function("getX", endPoint)), ff.equals(ff.function("IEEEremainder", ff.function("parseDouble", ff.property("value")), ff.literal(30)),
ff.literal(0)));
ruleLon.setFilter(filter);
// text.setLabelPlacement(lp);
lp = sb.createPointPlacement(.5, .5, -10, 0, 90.0);
text.setLabelPlacement(lp);
ruleLon.symbolizers().add(text);
break;
}
}
Layer gridLayer = new FeatureLayer(grid, blueStyle);
return gridLayer;
}
UPDATED CODE
FeatureTypeStyle featureTypeStyle = sf.createFeatureTypeStyle();
String geometryName = LineFeatureBuilder.DEFAULT_GEOMETRY_ATTRIBUTE_NAME;
String labelName = LineFeatureBuilder.VALUE_LABEL_NAME;
String valueName = LineFeatureBuilder.VALUE_ATTRIBUTE_NAME;
Function startPoint = ff.function("startPoint", ff.property(geometryName));
Function endPoint = ff.function("endPoint", ff.property(geometryName));
// Set up how the labels are drawn
TextSymbolizer htext = sb.createTextSymbolizer(Color.red, sb.createFont(font), labelName);
TextSymbolizer vtext = sb.createTextSymbolizer(Color.red, sb.createFont(font), labelName);
htext.setGeometry(endPoint);
vtext.setGeometry(endPoint);
LabelPlacement hlp = sb.createPointPlacement(.5, .5, 10, 0, 0);
LabelPlacement vlp = sb.createPointPlacement(.5, .5, 0, -50, 0);
htext.setLabelPlacement(hlp);
vtext.setLabelPlacement(vlp);
// create a rule for Horizontal Labels
Rule rule = sb.createRule(htext);
Filter hFilter = ff.and(ff.equals(ff.function("getY", startPoint), ff.function("getY", endPoint)), ff.equals(
ff.function("IEEEremainder", ff.function("parseInt", ff.property(valueName)), ff.literal(30)), ff.literal(0)));
rule.setFilter(hFilter);
featureTypeStyle.rules().add(rule);
Filter vFilter = ff.and(ff.equals(ff.function("getX", startPoint), ff.function("getX", endPoint)), ff.equals(
ff.function("IEEEremainder", ff.function("parseInt", ff.property(valueName)), ff.literal(30)), ff.literal(0)));
Rule ruleLon = sb.createRule(vtext);
ruleLon.setFilter(vFilter);
featureTypeStyle.rules().add(ruleLon);
// blueStyle.featureTypeStyles().get(0).rules().get(0).symbolizers().add(text); // replaced by rule.symbolizers(text)
**blueStyle.featureTypeStyles().add(featureTypeStyle);**
Layer gridLayer = new FeatureLayer(grid, blueStyle);