/// <summary> /// Translates a way. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="way"></param> private void TranslateWay(Scene2D scene, IProjection projection, CompleteWay way) { // build the rules. List <MapCSSRuleProperties> rules = this.BuildRules(new MapCSSObject(way)); // validate what's there. if (rules.Count == 0) { return; } // get x/y. double[] x = null, y = null; if (x == null) { // pre-calculate x/y. x = new double[way.Nodes.Count]; y = new double[way.Nodes.Count]; for (int idx = 0; idx < way.Nodes.Count; idx++) { x[idx] = projection.LongitudeToX( way.Nodes[idx].Coordinate.Longitude); y[idx] = projection.LatitudeToY( way.Nodes[idx].Coordinate.Latitude); } // simplify. if (x.Length > 2) { double[][] simplified = SimplifyCurve.Simplify(new double[][] { x, y }, 0.0001); x = simplified[0]; y = simplified[1]; } } // add the z-index. foreach (var rule in rules) { float minZoom = (float)projection.ToZoomFactor(rule.MinZoom); float maxZoom = (float)projection.ToZoomFactor(rule.MaxZoom); int zIndex; if (!rule.TryGetProperty <int>("zIndex", out zIndex)) { zIndex = 0; } // interpret the results. if (x != null) { // there is a valid interpretation of this way. int color; if (way.IsOfType(MapCSSTypes.Area)) { // the way is an area. check if it can be rendered as an area. int fillColor; if (rule.TryGetProperty("fillColor", out fillColor)) { // render as an area. scene.AddPolygon(this.CalculateSceneLayer(OffsetArea, zIndex), minZoom, maxZoom, x, y, fillColor, 1, true); if (rule.TryGetProperty("color", out color)) { scene.AddPolygon(this.CalculateSceneLayer(OffsetCasing, zIndex), minZoom, maxZoom, x, y, color, 1, false); } } } // the way has to rendered as a line. LineJoin lineJoin; if (!rule.TryGetProperty("lineJoin", out lineJoin)) { lineJoin = LineJoin.Miter; } int[] dashes; if (!rule.TryGetProperty("dashes", out dashes)) { dashes = null; } if (rule.TryGetProperty("color", out color)) { float casingWidth; int casingColor; if (!rule.TryGetProperty("casingWidth", out casingWidth)) { casingWidth = 0; } if (!rule.TryGetProperty("casingColor", out casingColor)) { // casing: use the casing layer. casingColor = -1; } float width; if (!rule.TryGetProperty("width", out width)) { width = 1; } if (casingWidth > 0) { // adds the casing scene.AddLine(this.CalculateSceneLayer(OffsetCasing, zIndex), minZoom, maxZoom, x, y, casingColor, width + (casingWidth * 2), lineJoin, dashes); } if (dashes == null) { // dashes not set, use line offset. scene.AddLine(this.CalculateSceneLayer(OffsetLine, zIndex), minZoom, maxZoom, x, y, color, width, lineJoin, dashes); } else { // dashes set, use line pattern offset. scene.AddLine(this.CalculateSceneLayer(OffsetLinePattern, zIndex), minZoom, maxZoom, x, y, color, width, lineJoin, dashes); } int textColor; int fontSize; string nameTag; if (!rule.TryGetProperty("fontSize", out fontSize)) { fontSize = 10; } if (rule.TryGetProperty("text", out nameTag) && rule.TryGetProperty("textColor", out textColor)) { int haloColor; int?haloColorNullable = null; if (rule.TryGetProperty("textHaloColor", out haloColor)) { haloColorNullable = haloColor; } int haloRadius; int?haloRadiusNullable = null; if (rule.TryGetProperty("textHaloRadius", out haloRadius)) { haloRadiusNullable = haloRadius; } string name; if (way.Tags.TryGetValue(nameTag, out name)) { scene.AddTextLine(this.CalculateSceneLayer(OffsetLineText, zIndex), minZoom, maxZoom, x, y, textColor, fontSize, name, haloColorNullable, haloRadiusNullable); } } } } } }