public static List <MGLPaint> ConvertLineLayer(JsonStyleLayer jsonStyleLayer, MGLSpriteAtlas spriteAtlas) { var layout = jsonStyleLayer?.Layout; var paint = jsonStyleLayer?.Paint; var line = new MGLPaint(); // Set defaults line.SetFixColor(new SKColor(0, 0, 0, 0)); line.SetFixStyle(SKPaintStyle.Stroke); line.SetFixStrokeWidth(0); line.SetFixStrokeCap(SKStrokeCap.Butt); line.SetFixStrokeJoin(SKStrokeJoin.Miter); // If we don't have a paint, than there isn't anything that we could do if (paint == null) { return(new List <MGLPaint>() { line }); } // line-cap // Optional enum. One of butt, round, square. Defaults to butt. Interval. // The display of line endings. if (layout?.LineCap != null) { if (layout.LineCap.Stops != null) { line.SetVariableStrokeCap((context) => { switch (layout.LineCap.Evaluate(context.Zoom)) { case "butt": return(SKStrokeCap.Butt); case "round": return(SKStrokeCap.Round); case "square": return(SKStrokeCap.Square); default: return(SKStrokeCap.Butt); } }); } else { switch (layout.LineCap.SingleVal) { case "butt": line.SetFixStrokeCap(SKStrokeCap.Butt); break; case "round": line.SetFixStrokeCap(SKStrokeCap.Round); break; case "square": line.SetFixStrokeCap(SKStrokeCap.Square); break; default: line.SetFixStrokeCap(SKStrokeCap.Butt); break; } } } // line-join // Optional enum. One of bevel, round, miter. Defaults to miter. Interval. // The display of lines when joining. if (layout?.LineJoin != null) { if (layout.LineJoin.Stops != null) { line.SetVariableStrokeJoin((context) => { switch (layout.LineJoin.Evaluate(context.Zoom)) { case "bevel": return(SKStrokeJoin.Bevel); case "round": return(SKStrokeJoin.Round); case "mitter": return(SKStrokeJoin.Miter); default: return(SKStrokeJoin.Miter); } }); } else { switch (layout.LineJoin.SingleVal) { case "bevel": line.SetFixStrokeJoin(SKStrokeJoin.Bevel); break; case "round": line.SetFixStrokeJoin(SKStrokeJoin.Round); break; case "mitter": line.SetFixStrokeJoin(SKStrokeJoin.Miter); break; default: line.SetFixStrokeJoin(SKStrokeJoin.Miter); break; } } } // line-color // Optional color. Defaults to #000000. Disabled by line-pattern. Exponential. // The color with which the line will be drawn. if (paint?.LineColor != null) { if (paint.LineColor.Stops != null) { line.SetVariableColor((context) => jsonStyleLayer.Paint.LineColor.Evaluate(context.Zoom)); } else { line.SetFixColor(jsonStyleLayer.Paint.LineColor.SingleVal); } } // line-width // Optional number.Units in pixels.Defaults to 1. Exponential. // Stroke thickness. if (paint?.LineWidth != null) { if (paint.LineWidth.Stops != null) { line.SetVariableStrokeWidth((context) => jsonStyleLayer.Paint.LineWidth.Evaluate(context.Zoom)); } else { line.SetFixStrokeWidth(jsonStyleLayer.Paint.LineWidth.SingleVal); } } // line-opacity // Optional number. Defaults to 1. Exponential. // The opacity at which the line will be drawn. if (paint?.LineOpacity != null) { if (paint.LineOpacity.Stops != null) { line.SetVariableOpacity((context) => jsonStyleLayer.Paint.LineOpacity.Evaluate(context.Zoom)); } else { line.SetFixOpacity(jsonStyleLayer.Paint.LineOpacity.SingleVal); } } // line-dasharray // Optional array. Units in line widths. Disabled by line-pattern. Interval. // Specifies the lengths of the alternating dashes and gaps that form the dash pattern. // The lengths are later scaled by the line width.To convert a dash length to pixels, // multiply the length by the current line width. if (paint?.LineDashArray != null) { if (paint.LineDashArray.Stops != null) { line.SetVariableDashArray((context) => jsonStyleLayer.Paint.LineDashArray.Evaluate(context.Zoom)); } else { line.SetFixDashArray(jsonStyleLayer.Paint.LineDashArray.SingleVal); } } // line-miter-limit // Optional number. Defaults to 2. Requires line-join = miter. Exponential. // Used to automatically convert miter joins to bevel joins for sharp angles. // line-round-limit // Optional number. Defaults to 1.05. Requires line-join = round. Exponential. // Used to automatically convert round joins to miter joins for shallow angles. // line-translate // Optional array. Units in pixels.Defaults to 0,0. Exponential. // The geometry's offset. Values are [x, y] where negatives indicate left and up, // respectively. // line-translate-anchor // Optional enum. One of map, viewport.Defaults to map. Requires line-translate. Interval. // Control whether the translation is relative to the map (north) or viewport (screen) // line-gap-width // Optional number.Units in pixels.Defaults to 0. Exponential. // Draws a line casing outside of a line's actual path.Value indicates the width of // the inner gap. // line-offset // Optional number. Units in pixels. Defaults to 0. Exponential. // The line's offset perpendicular to its direction. Values may be positive or negative, // where positive indicates "rightwards" (if you were moving in the direction of the line) // and negative indicates "leftwards". // line-blur // Optional number. Units in pixels.Defaults to 0. Exponential. // Blur applied to the line, in pixels. // line-pattern // Optional string. Interval. // Name of image in sprite to use for drawing image lines. For seamless patterns, image // width must be a factor of two (2, 4, 8, …, 512). return(new List <MGLPaint>() { line }); }
public static List <MGLPaint> ConvertFillLayer(JsonStyleLayer jsonStyleLayer, MGLSpriteAtlas spriteAtlas) { var layout = jsonStyleLayer?.Layout; var paint = jsonStyleLayer?.Paint; var area = new MGLPaint(); var line = new MGLPaint(); // Set defaults area.SetFixColor(new SKColor(0, 0, 0, 0)); area.SetFixOpacity(1); area.SetFixStyle(SKPaintStyle.Fill); line.SetFixColor(new SKColor(0, 0, 0, 0)); line.SetFixOpacity(1); line.SetFixStyle(SKPaintStyle.Stroke); line.SetFixStrokeWidth(0); // If we don't have a paint, than there isn't anything that we could do if (paint == null) { return(new List <MGLPaint>() { area, line }); } // fill-color // Optional color. Defaults to #000000. Disabled by fill-pattern. Exponential. // The color of the filled part of this layer. This color can be specified as // rgba with an alpha component and the color's opacity will not affect the // opacity of the 1px stroke, if it is used. if (paint.FillColor != null) { if (paint.FillColor.Stops != null) { area.SetVariableColor((context) => jsonStyleLayer.Paint.FillColor.Evaluate(context.Zoom)); line.SetVariableColor((context) => jsonStyleLayer.Paint.FillColor.Evaluate(context.Zoom)); } else { area.SetFixColor(jsonStyleLayer.Paint.FillColor.SingleVal); line.SetFixColor(jsonStyleLayer.Paint.FillColor.SingleVal); } } // fill-outline-color // Optional color. Disabled by fill-pattern. Requires fill-antialias = true. Exponential. // The outline color of the fill. Matches the value of fill-color if unspecified. if (paint.FillOutlineColor != null && paint.FillAntialias != null) { if (paint.FillOutlineColor.Stops != null) { line.SetVariableColor((context) => jsonStyleLayer.Paint.FillOutlineColor.Evaluate(context.Zoom)); } else { line.SetFixColor(jsonStyleLayer.Paint.FillOutlineColor.SingleVal); } } // fill-opacity // Optional number. Defaults to 1. Exponential. // The opacity of the entire fill layer. In contrast to the fill-color, this // value will also affect the 1px stroke around the fill, if the stroke is used. if (paint.FillOpacity != null) { if (paint.FillOpacity.Stops != null) { area.SetVariableOpacity((context) => jsonStyleLayer.Paint.FillOpacity.Evaluate(context.Zoom)); line.SetVariableOpacity((context) => jsonStyleLayer.Paint.FillOpacity.Evaluate(context.Zoom)); } else { area.SetFixOpacity(jsonStyleLayer.Paint.FillOpacity.SingleVal); line.SetFixOpacity(jsonStyleLayer.Paint.FillOpacity.SingleVal); } } // fill-antialias // Optional boolean. Defaults to true. Interval. // Whether or not the fill should be antialiased. if (paint.FillAntialias != null) { if (paint.FillAntialias.Stops != null) { area.SetVariableAntialias((context) => jsonStyleLayer.Paint.FillAntialias.Evaluate(context.Zoom)); line.SetVariableAntialias((context) => jsonStyleLayer.Paint.FillAntialias.Evaluate(context.Zoom)); } else { area.SetFixAntialias(jsonStyleLayer.Paint.FillAntialias.SingleVal == null ? false : (bool)jsonStyleLayer.Paint.FillAntialias.SingleVal); line.SetFixAntialias(jsonStyleLayer.Paint.FillAntialias.SingleVal == null ? false : (bool)jsonStyleLayer.Paint.FillAntialias.SingleVal); } } // fill-translate // Optional array. Units in pixels. Defaults to 0,0. Exponential. // The geometry's offset. Values are [x, y] where negatives indicate left and up, // respectively. // TODO: Use matrix of paint object for this // fill-translate-anchor // Optional enum. One of map, viewport. Defaults to map. Requires fill-translate. Interval. // Control whether the translation is relative to the map (north) or viewport (screen) // TODO: Use matrix of paint object for this // fill-pattern // Optional string. Interval. // Name of image in sprite to use for drawing image fills. For seamless patterns, // image width and height must be a factor of two (2, 4, 8, …, 512). if (paint.FillPattern != null) { // FillPattern needs a color. Instead no pattern is drawn. area.SetFixColor(SKColors.Black); if (paint.FillPattern.Stops == null && !paint.FillPattern.SingleVal.Contains("{")) { area.SetVariableShader((context) => { var name = paint.FillPattern.SingleVal; var sprite = spriteAtlas.GetSprite(name); if (sprite != null && sprite.Image != null) { return(sprite.Image.ToShader(SKShaderTileMode.Repeat, SKShaderTileMode.Repeat, SKMatrix.MakeScale(context.Scale, context.Scale))); } else { // Log information, that no sprite is found // TODO // Logging.Logger.Log(Logging.LogLevel.Information, $"Fill pattern {name} not found"); return(null); } }); } else { area.SetVariableShader((context) => { var name = ReplaceFields(jsonStyleLayer.Paint.FillPattern.Evaluate(context.Zoom), context.Tags); var sprite = spriteAtlas.GetSprite(name); if (sprite != null && sprite.Image != null) { return(sprite.Image.ToShader(SKShaderTileMode.Repeat, SKShaderTileMode.Repeat, SKMatrix.MakeScale(context.Scale, context.Scale))); } else { // Log information, that no sprite is found // TODO // Logging.Logger.Log(Logging.LogLevel.Information, $"Fill pattern {name} not found"); return(null); } }); } } return(new List <MGLPaint>() { area, line }); }