/// <summary> /// Converts this tile definition into a projected box. /// </summary> /// <param name="projection"></param> /// <returns></returns> public BoxF2D ToBox(IProjection projection) { double left = projection.LongitudeToX(this.TopLeft[0]); double right = projection.LongitudeToX(this.BottomRight[0]); double bottom = projection.LatitudeToY(this.BottomRight[1]); double top = projection.LatitudeToY(this.TopLeft[1]); return(new BoxF2D(left, bottom, right, top)); }
public BoxF2D ToBox(IProjection projection) { double x1 = projection.LongitudeToX(this.TopLeft[0]); double x2 = projection.LongitudeToX(this.BottomRight[0]); double y1 = projection.LatitudeToY(this.BottomRight[1]); double y2 = projection.LatitudeToY(this.TopLeft[1]); double y1_1 = y1; double x2_1 = x2; double y2_1 = y2; return(new BoxF2D(x1, y1_1, x2_1, y2_1)); }
/// <summary> /// Adds a new OsmSharpRoute. /// </summary> /// <param name="route">Stream.</param> /// <param name="argb">Stream.</param> public void AddRoute(OsmSharpRoute route, int argb) { if (route.Entries != null && route.Entries.Length > 0) { // there are entries. // get x/y. var x = new double[route.Entries.Length]; var y = new double[route.Entries.Length]; for (int idx = 0; idx < route.Entries.Length; idx++) { x[idx] = _projection.LongitudeToX( route.Entries[idx].Longitude); y[idx] = _projection.LatitudeToY( route.Entries[idx].Latitude); } // set the default color if none is given. SimpleColor blue = new SimpleColor() { Value = argb }; SimpleColor color = SimpleColor.FromArgb(argb); this.Scene.AddLine(float.MinValue, float.MaxValue, x, y, color.Value, 4); } }
/// <summary> /// Adds a new OsmSharpRoute. /// </summary> /// <param name="route">Stream.</param> /// <param name="argb">Stream.</param> /// <param name="width"></param> public void AddRoute(Route route, int argb, double width) { if (route != null && route.Segments != null && route.Segments.Length > 0) { // there are entries. // get x/y. var x = new double[route.Segments.Length]; var y = new double[route.Segments.Length]; for (int idx = 0; idx < route.Segments.Length; idx++) { x[idx] = _projection.LongitudeToX( route.Segments[idx].Longitude); y[idx] = _projection.LatitudeToY( route.Segments[idx].Latitude); } // set the default color if none is given. var color = SimpleColor.FromArgb(argb); var pointsId = _scene.AddPoints(x, y); if (pointsId.HasValue) { _scene.AddStyleLine(pointsId.Value, 0, float.MinValue, float.MaxValue, color.Value, (float)width, Renderer.Primitives.LineJoin.Round, null); } } this.RaiseLayerChanged(); }
/// <summary> /// Adds a new OsmSharpRoute. /// </summary> /// <param name="route">Stream.</param> /// <param name="argb">Stream.</param> /// <param name="width"></param> public void AddRoute(Route route, int argb, double width) { if (route != null && route.Segments != null && route.Segments.Length > 0) { // there are entries. // get x/y. var x = new double[route.Segments.Length]; var y = new double[route.Segments.Length]; for (int idx = 0; idx < route.Segments.Length; idx++) { x[idx] = _projection.LongitudeToX( route.Segments[idx].Longitude); y[idx] = _projection.LatitudeToY( route.Segments[idx].Latitude); // update envelope. if (_envelope == null) { // create initial envelope. _envelope = new GeoCoordinateBox( new GeoCoordinate(route.Segments[idx].Latitude, route.Segments[idx].Longitude), new GeoCoordinate(route.Segments[idx].Latitude, route.Segments[idx].Longitude)); } // also include the current point. _envelope.ExpandWith(new GeoCoordinate(route.Segments[idx].Latitude, route.Segments[idx].Longitude)); } // set the default color if none is given. var color = SimpleColor.FromArgb(argb); var pointsId = _scene.AddPoints(x, y); if (pointsId.HasValue) { _scene.AddStyleLine(pointsId.Value, 0, float.MinValue, float.MaxValue, color.Value, (float)width, Renderer.Primitives.LineJoin.Round, null); } } this.RaiseLayerChanged(); }
/// <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; bool renderAsLine = true; 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. uint?pointsId = scene.AddPoints(x, y); if (pointsId.HasValue) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetArea, zIndex), minZoom, maxZoom, fillColor, 1, true); if (rule.TryGetProperty("color", out color)) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetCasing, zIndex), minZoom, maxZoom, color, 1, false); } } renderAsLine = false; // was validly rendered als a line. } } if (renderAsLine) { // was not rendered as an area. // 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; } uint?pointsId = scene.AddPoints(x, y); if (pointsId.HasValue) { if (casingWidth > 0) { // adds the casing scene.AddStyleLine(pointsId.Value, this.CalculateSceneLayer(OffsetCasing, zIndex), minZoom, maxZoom, casingColor, width + (casingWidth * 2), lineJoin, dashes); } if (dashes == null) { // dashes not set, use line offset. scene.AddStyleLine(pointsId.Value, this.CalculateSceneLayer(OffsetLine, zIndex), minZoom, maxZoom, color, width, lineJoin, dashes); } else { // dashes set, use line pattern offset. scene.AddStyleLine(pointsId.Value, this.CalculateSceneLayer(OffsetLinePattern, zIndex), minZoom, maxZoom, 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 fontFamily; if (!rule.TryGetProperty("fontFamily", out fontFamily)) { fontFamily = "Arial"; // just some default font. } string name; if (way.Tags.TryGetValue(nameTag, out name)) { scene.AddStyleLineText(pointsId.Value, this.CalculateSceneLayer(OffsetLineText, zIndex), minZoom, maxZoom, textColor, fontSize, name, fontFamily, haloColorNullable, haloRadiusNullable); } } } } } } } }
/// <summary> /// Converts this tile definition into a projected box. /// </summary> /// <param name="projection"></param> /// <returns></returns> public BoxF2D ToBox(IProjection projection) { double left = projection.LongitudeToX(this.TopLeft[0]); double right = projection.LongitudeToX(this.BottomRight[0]); double bottom = projection.LatitudeToY(this.BottomRight[1]); double top = projection.LatitudeToY(this.TopLeft[1]); return new BoxF2D(left, bottom, right, top); }
/// <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> /// <param name="relevantTags"></param> private bool TranslateWay(Scene2D scene, IProjection projection, CompleteWay way, TagsCollectionBase relevantTags) { // build the rules. List<MapCSSRuleProperties> rules = null; if (!_succesfullWays.TryGetValue(relevantTags, out rules)) { rules = this.BuildRules(new MapCSSObject(way)); _succesfullWays.Add(relevantTags, rules); } // validate what's there. if (rules.Count == 0) { return false; } bool success = false; // 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 && x.Length > 1) { // there is a valid interpretation of this way. int color; bool renderAsLine = true; 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. uint? pointsId = scene.AddPoints(x, y); if (pointsId.HasValue) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetArea, zIndex), minZoom, maxZoom, fillColor, 1, true); success = true; if (rule.TryGetProperty("color", out color)) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetCasing, zIndex), minZoom, maxZoom, color, 1, false); success = true; } } renderAsLine = false; // was validly rendered als a line. } } if (renderAsLine) { // was not rendered as an area. // 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; } uint? pointsId = scene.AddPoints(x, y); success = true; if (pointsId.HasValue) { if (casingWidth > 0) { // adds the casing scene.AddStyleLine(pointsId.Value, this.CalculateSceneLayer(OffsetCasing, zIndex), minZoom, maxZoom, casingColor, width + (casingWidth * 2), lineJoin, dashes); } if (dashes == null) { // dashes not set, use line offset. scene.AddStyleLine(pointsId.Value, this.CalculateSceneLayer(OffsetLine, zIndex), minZoom, maxZoom, color, width, lineJoin, dashes); } else { // dashes set, use line pattern offset. scene.AddStyleLine(pointsId.Value, this.CalculateSceneLayer(OffsetLinePattern, zIndex), minZoom, maxZoom, 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 fontFamily; if (!rule.TryGetProperty("fontFamily", out fontFamily)) { fontFamily = "Arial"; // just some default font. } string name; if (way.Tags.TryGetValue(nameTag, out name)) { scene.AddStyleLineText(pointsId.Value, this.CalculateSceneLayer(OffsetLineText, zIndex), minZoom, maxZoom, textColor, fontSize, name, fontFamily, haloColorNullable, haloRadiusNullable); } } } } } } else { // don't report as an error when no nodes. success = true; } } if(!success) { // make sure this sucess is stored. _succesfullWays[relevantTags] = null; } return success; }
/// <summary> /// Translates a node. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="node"></param> private void TranslateNode(Scene2D scene, IProjection projection, Node node) { // build the rules. IEnumerable<MapCSSRuleProperties> rules = this.BuildRules(new MapCSSObject(node)); // interpret the results. foreach (var rule in rules) { int zIndex; if (!rule.TryGetProperty<int>("zIndex", out zIndex)) { zIndex = 0; } float minZoom = (float)projection.ToZoomFactor(rule.MinZoom); float maxZoom = (float)projection.ToZoomFactor(rule.MaxZoom); uint? pointId = null; int color; if (rule.TryGetProperty<int>("color", out color)) { float width; if (rule.TryGetProperty<float>("width", out width)) { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); scene.AddStylePoint(pointId.Value, this.CalculateSceneLayer(OffsetPoint, zIndex), minZoom, maxZoom, color, width); } else { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); scene.AddStylePoint(pointId.Value, this.CalculateSceneLayer(OffsetPoint, zIndex), minZoom, maxZoom, color, 1); } } byte[] iconImage; if (rule.TryGetProperty("iconImage", out iconImage)) { if (!pointId.HasValue) { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); } // an icon is to be drawn! ushort imageId = scene.AddImage(iconImage); scene.AddIcon(pointId.Value, this.CalculateSceneLayer(OffsetPoint, zIndex), minZoom, maxZoom, imageId); } string text; if (rule.TryGetProperty("text", out text)) { int textColor; if(!rule.TryGetProperty("textColor", out textColor)) { textColor = SimpleColor.FromKnownColor(KnownColor.Black).Value; } 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; } int fontSize; if (!rule.TryGetProperty("fontSize", out fontSize)) { fontSize = 10; } string fontFamily; if (!rule.TryGetProperty ("fontFamily", out fontFamily)) { fontFamily = "Arial"; // just some default font. } // a text is to be drawn. string value; if (node.Tags.TryGetValue(text, out value)) { if (!pointId.HasValue) { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); } scene.AddText(pointId.Value, this.CalculateSceneLayer(OffsetPointText, zIndex), minZoom, maxZoom, fontSize, value, textColor, haloColorNullable, haloRadiusNullable, fontFamily); } } } }
/// <summary> /// Translates a lineair ring. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="lineairRing"></param> private void TranslateLineairRing(Scene2D scene, IProjection projection, LineairRing lineairRing) { // build the rules. List<MapCSSRuleProperties> rules = this.BuildRules(new MapCSSObject(lineairRing)); // validate what's there. if (rules.Count == 0) { return; } // get x/y. double[] x = null, y = null; if (lineairRing.Coordinates != null && lineairRing.Coordinates.Count > 0) { // pre-calculate x/y. x = new double[lineairRing.Coordinates.Count]; y = new double[lineairRing.Coordinates.Count]; for (int idx = 0; idx < lineairRing.Coordinates.Count; idx++) { x[idx] = projection.LongitudeToX( lineairRing.Coordinates[idx].Longitude); y[idx] = projection.LatitudeToY( lineairRing.Coordinates[idx].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; int fillColor; if (rule.TryGetProperty("fillColor", out fillColor)) { // render as an area. float fillOpacity; if(rule.TryGetProperty("fillOpacity", out fillOpacity)) { SimpleColor simpleFillColor = new SimpleColor() { Value = fillColor }; fillColor = SimpleColor.FromArgb((int)(255 * fillOpacity), simpleFillColor.R, simpleFillColor.G, simpleFillColor.B).Value; } uint? pointsId = scene.AddPoints(x, y); if (pointsId.HasValue) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetArea, zIndex), minZoom, maxZoom, fillColor, 1, true); if (rule.TryGetProperty("color", out color)) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetCasing, zIndex), minZoom, maxZoom, color, 1, false); } } } } } }
/// <summary> /// Translates OSM objects into basic renderable primitives. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="osmGeo">The osm object.</param> /// <returns></returns> public override void Translate(Scene2D scene, IProjection projection, ICompleteOsmGeo osmGeo) { // set the scene backcolor. scene.BackColor = this.GetCanvasColor().Value; if (osmGeo == null) { return; } if (_mapCSSFile == null) { return; } // store the object count. int countBefore = scene.Count; // interpret the osm-objects. switch (osmGeo.Type) { case CompleteOsmType.Node: if (!_mapCSSFile.HasNodeIdSelector && osmGeo.Tags.Count == 0) { // this node can never be selected, no tags and no id selectors. break; } if (!_mapCSSFile.HasNodeIdSelector && _keysForNodes != null && !osmGeo.Tags.ContainsOneOfKeys(_keysForNodes)) { // no good keys present. break; } this.TranslateNode(scene, projection, osmGeo as Node); break; case CompleteOsmType.Way: var relevantWayTags = osmGeo.Tags; if (_keysForWays != null) { // filter the collection. relevantWayTags = relevantWayTags.KeepKeysOf(_keysForWays); } if (!_mapCSSFile.HasWayIdSelector && _keysForWays != null && relevantWayTags.Count == 0) { // no good keys present. break; } if (!_unsuccesfullWays.Contains(relevantWayTags)) { // way has some potential. var completeWay = osmGeo as CompleteWay; if (completeWay.Nodes.Count > 0 && !this.TranslateWay(scene, projection, completeWay, relevantWayTags)) { // ... but translate was unsuccesfull. _unsuccesfullWays.Add(relevantWayTags); } } break; case CompleteOsmType.Relation: if (!_mapCSSFile.HasRelationIdSelector && _keysForRelations != null && !osmGeo.Tags.ContainsOneOfKeys(_keysForRelations)) { // no good keys present. break; } this.TranslateRelation(scene, projection, osmGeo as CompleteRelation); break; } // interpret the osmGeo object and check if it makes up an area. if (osmGeo.Type != CompleteOsmType.Node) { // nodes cannot lead to a geometry for MapCSS. if (_keysForLines == null || osmGeo.Tags.ContainsOneOfKeys(_keysForLines) || _keysForAreas == null || osmGeo.Tags.ContainsOneOfKeys(_keysForAreas)) { // good keys present. var collection = _geometryInterpreter.Interpret(osmGeo); foreach (Geometry geometry in collection) { if (geometry is LineairRing) { // a simple lineair ring. this.TranslateLineairRing(scene, projection, geometry as LineairRing); } else if (geometry is Polygon) { // a simple polygon. this.TranslatePolygon(scene, projection, geometry as Polygon); } else if (geometry is MultiPolygon) { // a multipolygon. this.TranslateMultiPolygon(scene, projection, geometry as MultiPolygon); } } } } // check if any objects have been added to the scene. if (scene.Count <= countBefore) { // no objects have been added. Apply default styles if needed. if (osmGeo.Type == CompleteOsmType.Node && _mapCSSFile != null && _mapCSSFile.DefaultPoints) { // apply default points style. Node node = (osmGeo as Node); uint pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); scene.AddStylePoint(pointId, this.CalculateSceneLayer(OffsetPoint, 0), float.MinValue, float.MaxValue, SimpleColor.FromKnownColor(KnownColor.Black).Value, 2); } else if (osmGeo.Type == CompleteOsmType.Way && _mapCSSFile != null && _mapCSSFile.DefaultLines) { // apply default lines style. CompleteWay way = (osmGeo as CompleteWay); // 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]; } } uint? points = scene.AddPoints(x, y); if (points.HasValue) { scene.AddStyleLine(points.Value, this.CalculateSceneLayer(OffsetLine, 0), float.MinValue, float.MaxValue, SimpleColor.FromKnownColor(KnownColor.Red).Value, 1, LineJoin.Round, null); } } } }
/// <summary> /// Translates a lineair ring. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="lineairRing"></param> private void TranslateLineairRing(Scene2D scene, IProjection projection, LineairRing lineairRing) { // build the rules. List <MapCSSRuleProperties> rules = this.BuildRules(new MapCSSObject(lineairRing)); // validate what's there. if (rules.Count == 0) { return; } // get x/y. double[] x = null, y = null; if (lineairRing.Coordinates != null && lineairRing.Coordinates.Count > 0) { // pre-calculate x/y. x = new double[lineairRing.Coordinates.Count]; y = new double[lineairRing.Coordinates.Count]; for (int idx = 0; idx < lineairRing.Coordinates.Count; idx++) { x[idx] = projection.LongitudeToX( lineairRing.Coordinates[idx].Longitude); y[idx] = projection.LatitudeToY( lineairRing.Coordinates[idx].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; int fillColor; if (rule.TryGetProperty("fillColor", out fillColor)) { // render as an area. float fillOpacity; if (rule.TryGetProperty("fillOpacity", out fillOpacity)) { SimpleColor simpleFillColor = new SimpleColor() { Value = fillColor }; fillColor = SimpleColor.FromArgb((int)(255 * fillOpacity), simpleFillColor.R, simpleFillColor.G, simpleFillColor.B).Value; } uint?pointsId = scene.AddPoints(x, y); if (pointsId.HasValue) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetArea, zIndex), minZoom, maxZoom, fillColor, 1, true); if (rule.TryGetProperty("color", out color)) { scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetCasing, zIndex), minZoom, maxZoom, color, 1, false); } } } } } }
/// <summary> /// Loads the tiles. /// </summary> private void TilesLoading(object projectionParam) { IProjection projection = null; if (projectionParam is IProjection) { // the argument has to a projection. projection = projectionParam as IProjection; } if (projection == null) { throw new ArgumentException("Argument not of type IProjection."); } while (true) { for (int idx = 0; idx < 10; idx++) { Tile tile = null; lock (_tilesStack) { // load the stacked tiles. if (_tilesStack.Count > 0) { // the tiles stack contains at least some tiles. tile = _tilesStack.Pop(); } } // load the tile if (tile != null) { // a tile was found to load. string url = string.Format(_tilesURL, tile.Zoom, tile.X, tile.Y); // get file from tile server. var request = (HttpWebRequest)HttpWebRequest.Create( url); request.Accept = "text/html, image/png, image/jpeg, image/gif, */*"; request.UserAgent = "OsmSharp/4.0"; request.Timeout = 1000; WebResponse myResp = request.GetResponse(); Stream stream = myResp.GetResponseStream(); byte[] image = null; if (stream != null) { // there is data: read it. var memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); image = memoryStream.ToArray(); } if (image != null) { // data was read create the scene object. lock (this.Scene) { float minZoom = (float)projection.ToZoomFactor(tile.Zoom - 0.5f); float maxZoom = (float)projection.ToZoomFactor(tile.Zoom + 0.5f); float left = (float)projection.LongitudeToX(tile.TopLeft.Longitude); float right = (float)projection.LongitudeToX(tile.BottomRight.Longitude); float bottom = (float)projection.LatitudeToY(tile.BottomRight.Latitude); float top = (float)projection.LatitudeToY(tile.TopLeft.Latitude); this.Scene.AddImage(0, minZoom, maxZoom, left, top, right, bottom, image); } if (this.LayerChanged != null) { this.LayerChanged(this); } } } } System.Threading.Thread.Sleep(100); } }
/// <summary> /// Translates a node. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="node"></param> private void TranslateNode(Scene2D scene, IProjection projection, CompleteNode node) { // build the rules. IEnumerable <MapCSSRuleProperties> rules = this.BuildRules(new MapCSSObject(node)); // interpret the results. foreach (var rule in rules) { int zIndex; if (!rule.TryGetProperty <int>("zIndex", out zIndex)) { zIndex = 0; } float minZoom = (float)projection.ToZoomFactor(rule.MinZoom); float maxZoom = (float)projection.ToZoomFactor(rule.MaxZoom); uint?pointId = null; int color; if (rule.TryGetProperty <int>("color", out color)) { float width; if (rule.TryGetProperty <float>("width", out width)) { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); scene.AddStylePoint(pointId.Value, this.CalculateSceneLayer(OffsetPoint, zIndex), minZoom, maxZoom, color, width); } else { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); scene.AddStylePoint(pointId.Value, this.CalculateSceneLayer(OffsetPoint, zIndex), minZoom, maxZoom, color, 1); } } byte[] iconImage; if (rule.TryGetProperty("iconImage", out iconImage)) { if (!pointId.HasValue) { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); } // an icon is to be drawn! ushort imageId = scene.AddImage(iconImage); scene.AddIcon(pointId.Value, this.CalculateSceneLayer(OffsetPoint, zIndex), minZoom, maxZoom, imageId); } string text; if (rule.TryGetProperty("text", out text)) { int textColor; if (!rule.TryGetProperty("textColor", out textColor)) { textColor = SimpleColor.FromKnownColor(KnownColor.Black).Value; } 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; } int fontSize; if (!rule.TryGetProperty("fontSize", out fontSize)) { fontSize = 10; } string fontFamily; if (!rule.TryGetProperty("fontFamily", out fontFamily)) { fontFamily = "Arial"; // just some default font. } // a text is to be drawn. string value; if (node.Tags.TryGetValue(text, out value)) { if (!pointId.HasValue) { pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); } scene.AddText(pointId.Value, this.CalculateSceneLayer(OffsetPointText, zIndex), minZoom, maxZoom, fontSize, value, textColor, haloColorNullable, haloRadiusNullable, fontFamily); } } } }
/// <summary> /// Translates OSM objects into basic renderable primitives. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="osmGeo">The osm object.</param> /// <returns></returns> public override void Translate(Scene2D scene, IProjection projection, CompleteOsmGeo osmGeo) { // set the scene backcolor. scene.BackColor = this.GetCanvasColor().Value; if (osmGeo == null) { return; } // store the object count. int countBefore = scene.Count; // interpret the osm-objects. switch (osmGeo.Type) { case CompleteOsmType.Node: this.TranslateNode(scene, projection, osmGeo as CompleteNode); break; case CompleteOsmType.Way: this.TranslateWay(scene, projection, osmGeo as CompleteWay); break; case CompleteOsmType.Relation: this.TranslateRelation(scene, projection, osmGeo as CompleteRelation); break; case CompleteOsmType.ChangeSet: break; default: throw new ArgumentOutOfRangeException(); } // interpret the osmGeo object and check if it makes up an area. GeometryCollection collection = _geometryInterpreter.Interpret(osmGeo); foreach (Geometry geometry in collection) { if (geometry is LineairRing) { // a simple lineair ring. this.TranslateLineairRing(scene, projection, geometry as LineairRing); } else if (geometry is Polygon) { // a simple polygon. this.TranslatePolygon(scene, projection, geometry as Polygon); } else if (geometry is MultiPolygon) { // a multipolygon. this.TranslateMultiPolygon(scene, projection, geometry as MultiPolygon); } } // check if any objects have been added to the scene. if (scene.Count <= countBefore) { // no objects have been added. Apply default styles if needed. if (osmGeo.Type == CompleteOsmType.Node && _mapCSSFile != null && _mapCSSFile.DefaultPoints) { // apply default points style. CompleteNode node = (osmGeo as CompleteNode); uint pointId = scene.AddPoint(projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude)); scene.AddStylePoint(pointId, this.CalculateSceneLayer(OffsetPoint, 0), float.MinValue, float.MaxValue, SimpleColor.FromKnownColor(KnownColor.Black).Value, 2); } else if (osmGeo.Type == CompleteOsmType.Way && _mapCSSFile != null && _mapCSSFile.DefaultLines) { // apply default lines style. CompleteWay way = (osmGeo as CompleteWay); // 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]; } } uint?points = scene.AddPoints(x, y); if (points.HasValue) { scene.AddStyleLine(points.Value, this.CalculateSceneLayer(OffsetLine, 0), float.MinValue, float.MaxValue, SimpleColor.FromKnownColor(KnownColor.Red).Value, 1, LineJoin.Round, null); } } } }
/// <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); } } } } } }
/// <summary> /// Translates OSM objects into basic renderable primitives. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="osmGeo">The osm object.</param> /// <returns></returns> public override void Translate(Scene2D scene, IProjection projection, CompleteOsmGeo osmGeo) { // set the scene backcolor. scene.BackColor = this.GetCanvasColor().Value; if (osmGeo == null) { return; } // store the object count. int countBefore = scene.Count; // interpret the osm-objects. switch (osmGeo.Type) { case CompleteOsmType.Node: this.TranslateNode(scene, projection, osmGeo as CompleteNode); break; case CompleteOsmType.Way: this.TranslateWay(scene, projection, osmGeo as CompleteWay); break; case CompleteOsmType.Relation: this.TranslateRelation(scene, projection, osmGeo as CompleteRelation); break; case CompleteOsmType.ChangeSet: break; default: throw new ArgumentOutOfRangeException(); } // interpret the osmGeo object and check if it makes up an area. GeometryCollection collection = _geometryInterpreter.Interpret(osmGeo); foreach (Geometry geometry in collection) { if (geometry is LineairRing) { // a simple lineair ring. this.TranslateLineairRing(scene, projection, geometry as LineairRing); } else if (geometry is Polygon) { // a simple polygon. this.TranslatePolygon(scene, projection, geometry as Polygon); } else if (geometry is MultiPolygon) { // a multipolygon. this.TranslateMultiPolygon(scene, projection, geometry as MultiPolygon); } } // check if any objects have been added to the scene. if (scene.Count <= countBefore) { // no objects have been added. Apply default styles if needed. if (osmGeo.Type == CompleteOsmType.Node && _mapCSSFile != null && _mapCSSFile.DefaultPoints) { // apply default points style. CompleteNode node = (osmGeo as CompleteNode); scene.AddPoint(this.CalculateSceneLayer(OffsetPoint, 0), float.MinValue, float.MaxValue, projection.LongitudeToX(node.Coordinate.Longitude), projection.LatitudeToY(node.Coordinate.Latitude), SimpleColor.FromKnownColor(KnownColor.Black).Value, 2); } else if (osmGeo.Type == CompleteOsmType.Way && _mapCSSFile != null && _mapCSSFile.DefaultLines) { // apply default lines style. CompleteWay way = (osmGeo as CompleteWay); // 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]; } } scene.AddLine(this.CalculateSceneLayer(OffsetLine, 0), float.MinValue, float.MaxValue, x, y, SimpleColor.FromKnownColor(KnownColor.Red).Value, 1, LineJoin.Round, null); } } }
/// <summary> /// Adds a new GPX. /// </summary> /// <param name="stream">Stream.</param> public GeoCoordinateBox AddGpx(Stream stream) { GeoCoordinateBox bounds = null; var gpxStream = new GpxGeoStreamSource(stream); foreach (var geometry in gpxStream) { if (geometry is Point) { // add the point. var point = (geometry as Point); // get x/y. var x = _projection.LongitudeToX(point.Coordinate.Longitude); var y = _projection.LatitudeToY(point.Coordinate.Latitude); // set the default color if none is given. SimpleColor blue = SimpleColor.FromKnownColor(KnownColor.Blue); SimpleColor transparantBlue = SimpleColor.FromArgb(128, blue.R, blue.G, blue.B); uint pointId = _scene.AddPoint(x, y); _scene.AddStylePoint(pointId, 0, float.MinValue, float.MaxValue, transparantBlue.Value, 8); if (bounds == null) { // create box. bounds = point.Box; } else { // add to the current box. bounds = bounds + point.Box; } } else if (geometry is LineString) { // add the lineString. var lineString = (geometry as LineString); // get x/y. var x = new double[lineString.Coordinates.Count]; var y = new double[lineString.Coordinates.Count]; for (int idx = 0; idx < lineString.Coordinates.Count; idx++) { x[idx] = _projection.LongitudeToX( lineString.Coordinates[idx].Longitude); y[idx] = _projection.LatitudeToY( lineString.Coordinates[idx].Latitude); } // set the default color if none is given. SimpleColor blue = SimpleColor.FromKnownColor(KnownColor.Blue); SimpleColor transparantBlue = SimpleColor.FromArgb(128, blue.R, blue.G, blue.B); uint?pointsId = _scene.AddPoints(x, y); if (pointsId.HasValue) { _scene.AddStyleLine(pointsId.Value, 0, float.MinValue, float.MaxValue, transparantBlue.Value, 8, Renderer.Primitives.LineJoin.Round, null); if (bounds == null) { // create box. bounds = lineString.Box; } else { // add to the current box. bounds = bounds + lineString.Box; } } } } return(bounds); }