/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2017, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. * */ package org.geotools.mbstyle.layer; import org.geotools.mbstyle.MBStyle; import org.geotools.mbstyle.parse.MBFilter; import org.geotools.mbstyle.parse.MBObjectParser; import org.geotools.styling.*; import org.geotools.text.Text; import org.json.simple.JSONObject; import org.opengis.filter.expression.Expression; import org.opengis.style.ContrastMethod; import org.opengis.style.Rule; import org.opengis.style.SemanticType; import javax.measure.unit.NonSI; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; public class RasterMBLayer extends MBLayer { private JSONObject paintJson; private static String TYPE = "raster"; public RasterMBLayer(JSONObject json) { super(json, new MBObjectParser(RasterMBLayer.class)); if (json.get("paint") != null) { paintJson = (JSONObject) json.get("paint"); } else { paintJson = new JSONObject(); } } @Override protected SemanticType defaultSemanticType() { return SemanticType.RASTER; } /** * (Optional) The opacity (Number) at which the image will be drawn. * * Defaults to 1. Range: [0, 1] * * @return The opacity of this raster layer. */ public Expression opacity() { return parse.percentage(paintJson, "raster-opacity", 1); } /** * (Optional) The opacity (Number) at which the image will be drawn. * * Defaults to 1. Range: [0, 1] * * @return The opacity of this raster layer. */ public Number getOpacity() { return parse.optional(Number.class , paintJson, "raster-opacity", 1); } /** * (Optional) Rotates hues around the color wheel. * * Number. Units in degrees. Defaults to 0. * * @return The angle to rotate the hue of the raster image by. */ public Expression hueRotate() { return parse.number(paintJson, "raster-hue-rotate", 0); } /** * (Optional) Rotates hues around the color wheel. * * Number. Units in degrees. Defaults to 0. * * @return The angle to rotate the hue of the raster image by. */ public Number getHueRotate() { return parse.optional(Number.class, paintJson, "raster-hue-rotate", 0); } /** * (Optional) Scale the brightness of the image. The value is the minimum brightness. * * Number. Defaults to 0. Range: [0, 1] * * @return The minimum magnitude of the brightness. */ public Expression brightnessMin() { return parse.number(paintJson, "raster-brightness-min", 0); } /** * (Optional) Scale the brightness of the image. The value is the minimum brightness. * * Number. Defaults to 0. Range: [0, 1] * * @return The minimum magnitude of the brightness. */ public Number getBrightnessMin() { return parse.optional(Number.class, paintJson, "raster-brightness-min", 0); } /** * (Optional) Scale the brightness of the image. The value is the maximum brightness. * * Number. Defaults to 1. Range: [0, 1] * * @return The maximum magnitude of the brightness. */ public Expression brightnessMax() { return parse.number(paintJson, "raster-brightness-max", 1); } /** * (Optional) Scale the brightness of the image. The value is the maximum brightness. * * Number. Defaults to 1. Range: [0, 1] * * @return The maximum magnitude of the brightness. */ public Number getBrightnessMax() { return parse.optional(Number.class, paintJson, "raster-brightness-max", 1); } /** * (Optional) Increase or reduce the saturation of the image. * * Number. Defaults to 0. Range: [-1, 1] * * @return The change in saturation */ public Expression saturation() { return parse.number(paintJson, "raster-saturation", 0); } /** * (Optional) Increase or reduce the saturation of the image. * * Number. Defaults to 0. Range: [-1, 1] * * @return The change in saturation */ public Number getSaturation() { return parse.optional(Number.class, paintJson, "raster-saturation", 0); } /** * (Optional) Increase or reduce the contrast of the image. * * Number. Defaults to 0. Range: [-1, 1] * * @return The change in contrast */ public Expression contrast() { return parse.number(paintJson, "raster-contrast", 0); } /** * (Optional) Increase or reduce the contrast of the image. * * Number. Defaults to 0. Range: [-1, 1] * * @return The change in contrast */ public Number getContrast() { return parse.optional(Number.class, paintJson, "raster-contrast", 0); } /** * (Optional) Fade duration when a new tile is added. * * Number. Units in milliseconds. Defaults to 300. * * @return The duration of the fade when a new tile is added. */ public Expression fadeDuration() { return parse.number(paintJson, "raster-fade-duration", 300); } /** * (Optional) Fade duration when a new tile is added. * * Number. Units in milliseconds. Defaults to 300. * * @return The duration of the fade when a new tile is added. */ public Number getFadeDuration() { return parse.optional(Number.class, paintJson, "raster-fade-duration", 300); } /** * Transform {@link RasterMBLayer} to GeoTools FeatureTypeStyle. * <p> * Notes: * </p> * <ul> * <li>Assumes 3-band RGB</li> * </ul> * * @param styleContext The MBStyle to which this layer belongs, used as a context for things like resolving sprite and glyph names to full urls. * @return FeatureTypeStyle */ public List<FeatureTypeStyle> transformInternal(MBStyle styleContext) { ContrastEnhancement ce = sf.contrastEnhancement(ff.literal(1.0), ContrastMethod.NONE); // Use of builder is easier for code examples; but fills in SLD defaults // Currently only applies the opacity. RasterSymbolizer symbolizer = sf.rasterSymbolizer(getId(), null, sf.description(Text.text("raster"), null), NonSI.PIXEL, opacity(), null, null, null, ce, null, null); List<Rule> rules = new ArrayList<>(); MBFilter filter = getFilter(); org.geotools.styling.Rule rule = sf.rule(getId(), null, null, 0.0, Double.MAX_VALUE, Arrays.asList(symbolizer), filter.filter()); rules.add(rule); rule.setLegendGraphic(new Graphic[0]); return Collections.singletonList(sf.featureTypeStyle(getId(), sf.description(Text.text("MBStyle " + getId()), Text.text("Generated for " + getSourceLayer())), null, Collections.emptySet(), filter.semanticTypeIdentifiers(), rules)); } /** * Rendering type of this layer. * * @return {@link #TYPE} */ public String getType() { return TYPE; } }