private void RenderPointLabel(TextSymbolizer textSymbolizer, Feature feature) { //TODO labels could be not strings var str = feature.Attributes.Exists(textSymbolizer.LabelAttribute) ? feature.Attributes[textSymbolizer.LabelAttribute] as string : null; if (string.IsNullOrWhiteSpace(str)) { return; } var emSize = Graphics.DpiY * textSymbolizer.FontSize / 72; //ref http://msdn.microsoft.com/en-us/library/xwf9s90b(v=vs.110).aspx var font = FontCache[textSymbolizer]; var ascent = emSize * font.FontFamily.GetCellAscent(FontStyle.Bold) / font.FontFamily.GetEmHeight(FontStyle.Bold); var coord = Project(feature.Geometry.Coordinates)[0]; var size = new SizeF(Graphics.MeasureString(str, font).Width, ascent); var offset = new SizeF(); switch (textSymbolizer.Alignment) { case ContentAlignment.MiddleCenter: //no offset break; case ContentAlignment.TopRight: offset = new SizeF(size.Width * 0.5f, -size.Height * 0.5f); break; default: throw new NotImplementedException(); } TryRenderText(textSymbolizer, feature, emSize, str, coord, offset, size, -Config.Angle); }
private TextSymbolizer CreateTextSymbolizer(NodePropertyValue[] properties) { TextSymbolizer symText = new TextSymbolizer(); symText.Clip = true; symText.TextLayout.Alignment = TextAlignment.CenterAligned; GeometryTransformInfo geomTrans = new GeometryTransformInfo(); LabelPlacementInfo lpi = new LabelPlacementInfo(); lpi.Symbolizer = (int)SymbolizerType.Text; TextLayoutBlock textBlock = new TextLayoutBlock(); string textTransform = null; int blockIndex = -1; int nProps = properties.Length; NodePropertyValue pv = null; try { for (int i = 0; i < nProps; i++) { pv = properties[i]; switch (pv.Name) { case "text-name": if (pv.Value != null) { string textExpr = ToExpression(pv.Value); if (!string.IsNullOrEmpty(textTransform)) textExpr = GetTextTransform(textExpr, textTransform); textBlock.TextExpression = textExpr; // TODO if (textBlock.TextExpression == string.Empty) symText.Enabled = false; blockIndex++; if (blockIndex > 0) textBlock = new TextLayoutBlock(); symText.TextLayout.Blocks.Add(textBlock); } break; case "text-face-name": SetFontName(textBlock, pv.Value); break; case "text-transform": if (string.IsNullOrEmpty(textBlock.TextExpression)) textTransform = pv.Value; else textBlock.TextExpression = GetTextTransform(textBlock.TextExpression, pv.Value); break; case "text-fill": Color clr = ColorUtility.FromHtml(pv.Value); textBlock.TextFormat.TextStyle.Color = clr; if (clr.A != 255) textBlock.TextFormat.TextStyle.Opacity = clr.A / 255.0F; break; case "text-opacity": textBlock.TextFormat.TextStyle.Opacity = Convert.ToSingle(pv.Value); break; case "text-size": textBlock.TextFormat.TextStyle.Font.Size = Convert.ToSingle(pv.Value); break; case "text-halo-radius": textBlock.TextFormat.TextStyle.Halo.Radius = Convert.ToSingle(pv.Value); break; case "text-halo-fill": Color clr2 = ColorUtility.FromHtml(pv.Value); textBlock.TextFormat.TextStyle.Halo.Color = clr2; if (clr2.A != 255) textBlock.TextFormat.TextStyle.Halo.Opacity = clr2.A / 255F; break; case "text-halo-opacity": // This property does not exist in the specification. textBlock.TextFormat.TextStyle.Halo.Opacity = Convert.ToSingle(pv.Value); break; case "text-halo-rasterizer": // TODO break; case "text-ratio": //TODO break; case "text-clip": symText.Clip = Convert.ToBoolean(pv.Value); break; case "text-align": textBlock.TextFormat.TextAlignment = ToTextAlignment(pv.Value); break; case "text-horizontal-alignment": // TODO break; case "text-vertical-alignment": // TODO break; case "text-wrap-width": textBlock.TextFormat.TextWrapping.MaxWidth = Convert.ToUInt32(pv.Value); textBlock.TextFormat.TextWrapping.Mode = Drawing.Text.TextWrapMode.WrapByMaxWidthPixels; break; case "text-wrap-before": TextWrapping tw = textBlock.TextFormat.TextWrapping; if (tw.Characters == null || tw.Characters.Length == 0) tw.Characters = new WrapCharacter[] { new WrapCharacter() }; tw.Characters[0].WrapType = CharacterWrapType.Before; break; case "text-wrap-character": TextWrapping tw2 = textBlock.TextFormat.TextWrapping; if (tw2.Characters == null || tw2.Characters.Length == 0) tw2.Characters = new WrapCharacter[] { new WrapCharacter() }; tw2.Characters[0].Character = pv.Value; break; case "text-character-spacing": textBlock.TextFormat.TextSpacing.CharacterSpacing = Convert.ToSingle(pv.Value); break; case "text-line-spacing": textBlock.TextFormat.TextSpacing.Leading = Convert.ToSingle(pv.Value); break; case "text-allow-overlap": symText.LabelBehaviour.AllowOverlap = Convert.ToBoolean(pv.Value); break; case "text-min-distance": symText.LabelBehaviour.CollisionMeasures.Add(string.Format("MinimumDistance({0})", pv.Value)); break; case "text-avoid-edges": symText.LabelBehaviour.AvoidEdges = Convert.ToBoolean(pv.Value); break; case "text-spacing": lpi.Properties.Add(new KeyValuePair<string, string>(pv.Name, pv.Value)); break; case "text-max-char-angle-delta": lpi.Properties.Add(new KeyValuePair<string, string>(pv.Name, pv.Value)); break; case "text-label-position-tolerance": lpi.Properties.Add(new KeyValuePair<string, string>(pv.Name, pv.Value)); break; case "text-min-padding": UnsupportedProperty(pv); break; case "text-min-path-length": lpi.Properties.Add(new KeyValuePair<string, string>(pv.Name, pv.Value)); break; case "text-orientation": lpi.Properties.Add(new KeyValuePair<string, string>(pv.Name, pv.Value)); break; case "text-placement": lpi.Placement = pv.Value; if (lpi.Placement == "line") geomTrans.OffsetCurve = true; break; case "text-placement-type": lpi.Properties.Add(new KeyValuePair<string, string>(pv.Name, pv.Value)); break; case "text-placements": lpi.Properties.Add(new KeyValuePair<string, string>(pv.Name, pv.Value)); break; case "text-dx": geomTrans.DisplacementX = pv.Value; lpi.Properties.Add(new KeyValuePair<string, string>(pv.Name, pv.Value)); break; case "text-dy": geomTrans.DisplacementY = pv.Value; lpi.Properties.Add(new KeyValuePair<string, string>(pv.Name, pv.Value)); break; case "text-comp-op": UnsupportedProperty(pv); break; default: break; } } } catch (Exception ex) { ThrowParsingException(ex, pv); } ApplyTextBlockFormat(symText.TextLayout); symText.LabelPlacement = CreateLabelPlacement(lpi); if ("point".Equals(lpi.Placement)) geomTrans.DisplacementX = geomTrans.DisplacementY = string.Empty; symText.GeometryExpression = ToGeometryExpression(geomTrans); return symText; }
public void ExerciseWmcFromCodeTest() { ViewContext context = new ViewContext(); // Context -> General context.General.Window.Width = 500; context.General.Window.Height = 300; context.General.BoundingBox.SRS = "EPSG:4326"; context.General.BoundingBox.MinX = -180; context.General.BoundingBox.MinY = -90; context.General.BoundingBox.MaxX = 180; context.General.BoundingBox.MaxY = 90; context.General.Title = "EOS Data Gateways"; context.General.KeywordList.Add("EOS"); context.General.KeywordList.Add("EOSDIS"); context.General.KeywordList.Add("NASA"); context.General.KeywordList.Add("CCRS"); context.General.KeywordList.Add("CEOS"); context.General.KeywordList.Add("OGC"); context.General.Abstract = "Map View of EOSDIS partners locations"; context.General.LogoURL.Width = 130; context.General.LogoURL.Height = 74; context.General.LogoURL.Format = "image/gif"; context.General.LogoURL.OnlineResource.Type = "simple"; context.General.LogoURL.OnlineResource.Href = "http://redhook.gsfc.nasa.gov/~imswww/pub/icons/logo.gif"; context.General.DescriptionURL.Format = "text/html"; context.General.DescriptionURL.OnlineResource.Type = "simple"; context.General.DescriptionURL.OnlineResource.Href = "http://eos.nasa.gov/imswelcome"; context.General.ContactInformation.ContactPersonPrimary.ContactPerson = "Tom Kralidis"; context.General.ContactInformation.ContactPersonPrimary.ContactOrganisation = "Canada Centre for Remote Sensing"; context.General.ContactInformation.ContactPosition = "Systems Scientist"; context.General.ContactInformation.ContactAddress.AddressType = "postal"; context.General.ContactInformation.ContactAddress.Address = "615 Booth Street, room 650"; context.General.ContactInformation.ContactAddress.City = "Ottawa"; context.General.ContactInformation.ContactAddress.StateOrProvince = "Ontario"; context.General.ContactInformation.ContactAddress.Country = "Canada"; context.General.ContactInformation.ContactVoiceTelephone = "+01 613 947 1828"; context.General.ContactInformation.ContactFacsimileTelephone = "+01 613 947 2410"; context.General.ContactInformation.ContactElectronicMailAddress = "*****@*****.**"; context.Version = "1.0"; context.Id = "TEST"; // Context -> Layer Layer layer = new Layer(); layer.Queryable = 1; layer.Hidden = 0; layer.Server.Service = GeospatialServices.Ogc.Common.ServiceNames.WMS; layer.Server.Version = "1.0.7"; layer.Title = "The GLOBE Program Visualization Server"; layer.Server.OnlineResource.Type = "simple"; layer.Server.OnlineResource.Href = "http://globe.digitalearth.gov/viz-bin/wmt.cgi"; layer.Name = "NATIONAL"; layer.Title = "National Boundaries"; layer.Abstract = "Context layer: National Boundaries"; layer.SRS = "EPSG:4326"; // Context -> Layer -> Format layer.FormatList.Add(new Format("GIF", 1)); // Context -> Layer -> Style Style style1 = new Style(); style1.Current = 1; style1.Name = "default"; style1.LegendURL.Width = 16; style1.LegendURL.Height = 16; style1.LegendURL.Format = "image/gif"; style1.LegendURL.OnlineResource.Type = "simple"; style1.LegendURL.OnlineResource.Href = "http://mapserv2.esrin.esa.it/cubestor/cubeserv.cgi?VERSION=1.1.0&REQUEST=GetLegendIcon&LAYER=WORLD_MODIS_1KM:MapAdmin&SPATIAL_TYPE=RASTER&STYLE=default&FORMAT=image//gif"; // Context -> Layer -> Style -> Named Layer NamedLayer namedLayer = new NamedLayer(); namedLayer.Name = "Roads"; // Context -> Layer -> Style -> Named Layer -> Named Styles namedLayer.NamedStyles.Add(new NamedStyle("Casing")); namedLayer.NamedStyles.Add(new NamedStyle("Centerline")); // Context -> Layer -> Style -> Named Layer -> User Style UserStyle userStyle1 = new UserStyle(); // Context -> Layer -> Style -> Named Layer -> User Style -> FeatureTypeStyle FeatureTypeStyle featureTypeStyle1 = new FeatureTypeStyle(); Rule rule1 = new Rule(); // Context -> Layer -> Style -> Named Layer -> User Style -> FeatureTypeStyle -> Rule -> Symbolizers BaseSymbolizer[] symbolizers = new BaseSymbolizer[6]; SymbolizerTypes[] symbolizerSelections = new SymbolizerTypes[6]; // Line Symbolizer LineSymbolizer lineSymbolizer = new LineSymbolizer(); lineSymbolizer.Geometry.PropertyName = "center-line"; lineSymbolizer.Stroke.SvgParameters.Add(new SvgParameter("stroke", "#0000ff")); lineSymbolizer.Stroke.SvgParameters.Add(new SvgParameter("stroke-width", "2")); symbolizers[0] = lineSymbolizer; symbolizerSelections[0] = SymbolizerTypes.LineSymbolizer; // Polygon Symbolizer PolygonSymbolizer polygonSymbolizer = new PolygonSymbolizer(); polygonSymbolizer.Geometry.PropertyName = "the_area"; polygonSymbolizer.Fill.SvgParameters.Add(new SvgParameter("fill", "#aaaaff")); polygonSymbolizer.Stroke.SvgParameters.Add(new SvgParameter("stroke", "#0000aa")); symbolizers[1] = polygonSymbolizer; symbolizerSelections[1] = SymbolizerTypes.PolygonSymbolizer; // Point Symbolizer PointSymbolizer pointSymbolizer = new PointSymbolizer(); // Point Symbolizer - > External Graphic 1 ExternalGraphic externalGraphic1 = new ExternalGraphic(); externalGraphic1.OnlineResource.Type = "simple"; externalGraphic1.OnlineResource.Href = "http://www.vendor.com/geosym/2267.svg"; externalGraphic1.Format = "image/svg+xml"; pointSymbolizer.Graphic.ExternalGraphics.Add(externalGraphic1); // Point Symbolizer - > External Graphic 2 ExternalGraphic externalGraphic2 = new ExternalGraphic(); externalGraphic2.OnlineResource.Type = "simple"; externalGraphic2.OnlineResource.Href = "http://www.vendor.com/geosym/2267.png"; externalGraphic2.Format = "image/png"; pointSymbolizer.Graphic.ExternalGraphics.Add(externalGraphic2); pointSymbolizer.Graphic.Size = 15.0; symbolizers[2] = pointSymbolizer; symbolizerSelections[2] = SymbolizerTypes.PointSymbolizer; // Text Symbolizer TextSymbolizer textSymbolizer = new TextSymbolizer(); textSymbolizer.Geometry.PropertyName = "locatedAt"; textSymbolizer.Label = @"ogc:PropertyName[hospitalName]"; textSymbolizer.Font.SvgParameters.Add(new SvgParameter("font-family", "Arial")); textSymbolizer.Font.SvgParameters.Add(new SvgParameter("font-family", "Sans-Serif")); textSymbolizer.Font.SvgParameters.Add(new SvgParameter("font-style", "italic")); textSymbolizer.Font.SvgParameters.Add(new SvgParameter("font-size", "10")); textSymbolizer.Fill.SvgParameters.Add(new SvgParameter("fill", "#000000")); textSymbolizer.LabelPlacement.PointPlacement = new PointPlacement(); textSymbolizer.LabelPlacement.PointPlacement.AnchorPoint.AnchorPointX = 456; textSymbolizer.LabelPlacement.PointPlacement.AnchorPoint.AnchorPointY = 123; textSymbolizer.LabelPlacement.PointPlacement.Rotation = 180; textSymbolizer.LabelPlacement.PointPlacement.Displacement.DisplacementX = 111; textSymbolizer.LabelPlacement.PointPlacement.Displacement.DisplacementY = 222; textSymbolizer.LabelPlacement.LinePlacement = new LinePlacement(); textSymbolizer.LabelPlacement.LinePlacement.Gap = 12; textSymbolizer.LabelPlacement.LinePlacement.GeneraliseLine = 3; textSymbolizer.LabelPlacement.LinePlacement.InitialGap = 3; textSymbolizer.LabelPlacement.LinePlacement.IsAligned = 0; textSymbolizer.LabelPlacement.LinePlacement.IsRepeated = 1; textSymbolizer.LabelPlacement.LinePlacement.PerpendicularOffset = 5; textSymbolizer.Halo.Fill = new Fill(); textSymbolizer.Halo.Fill.SvgParameters.Add(new SvgParameter("fill", "#000000")); textSymbolizer.Halo.Radius = 3; symbolizers[3] = textSymbolizer; symbolizerSelections[3] = SymbolizerTypes.TextSymbolizer; // Raster Symbolizer 1 RasterSymbolizer rasterSymbolizer1 = new RasterSymbolizer(); rasterSymbolizer1.Opacity = 1.0; rasterSymbolizer1.OverlapBehaviour = OverlapBehaviourTypes.Average; rasterSymbolizer1.ColourMap.Categorize.LookupValue = "Rasterdata"; rasterSymbolizer1.ColourMap.Categorize.Values.Add("#00ff00"); rasterSymbolizer1.ColourMap.Categorize.Thresholds.Add(-417); rasterSymbolizer1.ColourMap.Categorize.Values.Add("#00fa00"); rasterSymbolizer1.ColourMap.Categorize.Thresholds.Add(-333); symbolizers[4] = rasterSymbolizer1; symbolizerSelections[4] = SymbolizerTypes.RasterSymbolizer; // Raster Symbolizer 2 RasterSymbolizer rasterSymbolizer2 = new RasterSymbolizer(); rasterSymbolizer2.Opacity = 1.0; rasterSymbolizer2.OverlapBehaviour = OverlapBehaviourTypes.LatestOnTop; rasterSymbolizer2.ChannelSelection.RedChannel.SourceChannelName = "1"; rasterSymbolizer2.ChannelSelection.GreenChannel.SourceChannelName = "2"; rasterSymbolizer2.ChannelSelection.GreenChannel.ContrastEnhancement.GammaValue = 2.5; rasterSymbolizer2.ChannelSelection.BlueChannel.SourceChannelName = "3"; rasterSymbolizer2.ColourMap.Interpolate.FallBackValue = "#dddddd"; rasterSymbolizer2.ColourMap.Interpolate.LookupValue = "Rasterdata"; rasterSymbolizer2.ColourMap.Interpolate.InterpolationPoints.Add(new InterpolationPoint(0, "#000000")); rasterSymbolizer2.ColourMap.Interpolate.InterpolationPoints.Add(new InterpolationPoint(255, "#ffffff")); rasterSymbolizer2.ContrastEnhancement.GammaValue = 1; rasterSymbolizer2.Geometry.PropertyName = "Coastlines"; symbolizers[5] = rasterSymbolizer2; symbolizerSelections[5] = SymbolizerTypes.RasterSymbolizer; rule1.SymbolizerSelections = symbolizerSelections; rule1.Symbolizers = symbolizers; featureTypeStyle1.Rules.Add(rule1); Rule rule2 = new Rule(); rule2.ElseFilter = new ElseFilter(); featureTypeStyle1.Rules.Add(rule2); Rule rule3 = new Rule(); GeospatialServices.Ogc.Wmc.PropertyIsEqualTo propEqualTo = new PropertyIsEqualTo(); propEqualTo.Literal.Value = "NEW YORK"; propEqualTo.PropertyName = "SALES_AREA"; //BaseComparisonOps ComparisonOps[] = new BaseComparisonOps[2]; rule3.Filter.FilterExpression = propEqualTo; featureTypeStyle1.Rules.Add(rule3); userStyle1.FeatureTypeStyles.Add(featureTypeStyle1); namedLayer.UserStyles.Add(userStyle1); // Context - > Layer -> Style -> User Layer UserLayer userLayer = new UserLayer(); userLayer.Name = "Lakes and Rivers"; UserStyle userStyle = new UserStyle("Default"); userStyle.FeatureTypeStyles.Add(featureTypeStyle1); userLayer.UserStyles = new List <UserStyle>(); userLayer.UserStyles.Add(userStyle); style1.SLD.StyledLayerDescriptor.NamedLayers.Add(namedLayer); style1.SLD.StyledLayerDescriptor.UserLayers.Add(userLayer); layer.StyleList.Add(style1); context.Layers.Add(layer); }
private void RenderLineLabel(TextSymbolizer textSymbolizer, Feature feature) { //TODO labels could be not strings var str = feature.Attributes.Exists(textSymbolizer.LabelAttribute) ? feature.Attributes[textSymbolizer.LabelAttribute] as string : null; if (string.IsNullOrWhiteSpace(str)) { return; } var emSize = Graphics.DpiY * textSymbolizer.FontSize / 72; //ref http://msdn.microsoft.com/en-us/library/xwf9s90b(v=vs.110).aspx var font = FontCache[textSymbolizer]; var ascent = emSize * font.FontFamily.GetCellAscent(FontStyle.Bold) / font.FontFamily.GetEmHeight(FontStyle.Bold); Graphics.SmoothingMode = SmoothingMode.HighQuality; var size = Graphics.MeasureString(str, font); float spacing = textSymbolizer.Spacing; var coords = ProjectToCoordinate(feature.Geometry.Coordinates); var coordsAsLine = new LineString(coords); var lengthIndexed = new NetTopologySuite.LinearReferencing.LengthIndexedLine(coordsAsLine); var labelCount = (int)((coordsAsLine.Length - spacing) / (size.Width + spacing)); if (labelCount < 1 || textSymbolizer.Spacing == 0) { labelCount = 1; } //work out spacing based on the amount of labels we'll be putting on spacing = ((float)coordsAsLine.Length / labelCount) - size.Width; for (var i = 0; i < labelCount; i++) { var labelCenterLength = (spacing + size.Width) * (0.5f + i); var subLine = lengthIndexed.ExtractLine(labelCenterLength - (size.Width / 2), labelCenterLength + (size.Width / 2)); if (subLine.Coordinates.Length < 2) { continue; } var firstCoord = subLine.Coordinates[0]; var lastCoord = subLine.Coordinates[subLine.Coordinates.Length - 1]; var middleOfLabelLinePoint = lengthIndexed.ExtractPoint(labelCenterLength); var midPoint = new PointF((float)(firstCoord.X + lastCoord.X + middleOfLabelLinePoint.X + middleOfLabelLinePoint.X) * 0.25f, (float)(firstCoord.Y + lastCoord.Y + middleOfLabelLinePoint.Y + middleOfLabelLinePoint.Y) * 0.25f); var angle = (float)(Math.Atan2(lastCoord.Y - firstCoord.Y, lastCoord.X - firstCoord.X) * 180 / Math.PI); //Keep the text up the right way while (angle + Config.Angle > 90) { angle -= 180; } while (angle + Config.Angle < -90) { angle += 180; } TryRenderText(textSymbolizer, feature, emSize, str, midPoint, SizeF.Empty, new SizeF(size.Width, ascent), angle); } }