Beispiel #1
0
        public static Canvas RenderLabelLayer(IViewport viewport, LabelLayer layer)
        {
            var canvas = new Canvas { Opacity = layer.Opacity };

            // todo: take into account the priority 
            var features = layer.GetFeaturesInView(viewport.Extent, viewport.Resolution).ToList();

            var layerStyles = BaseLayer.GetLayerStyles(layer);
            
            foreach (var layerStyle in layerStyles)
            {
                foreach (var feature in features)
                {
                    var style = (layerStyle is IThemeStyle) ? (layerStyle as IThemeStyle).GetStyle(feature) : layerStyle;

                    if ((style == null) || 
                        (style.Enabled == false) || 
                        (style.MinVisible > viewport.Resolution) || 
                        (style.MaxVisible < viewport.Resolution)) continue;

                    if (!(style is LabelStyle)) throw new Exception("Style of label is not a LabelStyle");
                    var labelStyle = style as LabelStyle;

                    labelStyle.Text = layer.GetLabelText(feature);

                    var postion = feature.Geometry.GetBoundingBox().GetCentroid();
                    var labelText = labelStyle.GetLabelText(feature);
                    canvas.Children.Add(SingleLabelRenderer.RenderLabel(postion, labelStyle, viewport, labelText));
                }
            }
            return canvas;
        }
 private static ILayer CreateCityLabelLayer(IProvider citiesProvider)
 {
     var cityLabelLayer = new LabelLayer("City labels");
     cityLabelLayer.DataSource = citiesProvider;
     cityLabelLayer.DataSource.SRID = 3785;
     cityLabelLayer.Enabled = true;
     cityLabelLayer.LabelColumn = "NAME";
     cityLabelLayer.Styles.Add(CreateCityLabelTheme());
     cityLabelLayer.LabelFilter = LabelCollisionDetection.ThoroughCollisionDetection;
     return cityLabelLayer;
 }
 private static LabelLayer CreateCountryLabelLayer(IProvider countryProvider)
 {
     var countryLabelLayer = new LabelLayer("Country labels");
     countryLabelLayer.DataSource = countryProvider;
     countryLabelLayer.DataSource.SRID = 3785;
     countryLabelLayer.Enabled = true;
     countryLabelLayer.LabelColumn = "NAME";
     countryLabelLayer.MaxVisible = double.MaxValue;
     countryLabelLayer.MinVisible = double.MinValue;
     countryLabelLayer.MultipartGeometryBehaviour = LabelLayer.MultipartGeometryBehaviourEnum.Largest;
     countryLabelLayer.Styles.Add(CreateCountryLabelTheme());
     return countryLabelLayer;
 }
        public static Canvas RenderStackedLabelLayer(IViewport viewport, LabelLayer layer)
        {
            var canvas = new Canvas();
            canvas.Opacity = layer.Opacity;

            //todo: take into account the priority 
            var features = layer.GetFeaturesInView(viewport.Extent, viewport.Resolution);
            var margin = viewport.Resolution * 50;

            foreach (var layerStyle in layer.Styles)
            {
                var style = layerStyle;

                var clusters = new List<Cluster>();
                //todo: repeat until there are no more merges
                ClusterFeatures(clusters, features, margin, layerStyle, viewport.Resolution);

                foreach (var cluster in clusters)
                {
                    Offset stackOffset = null;
                    
                    foreach (var feature in cluster.Features.OrderBy(f => f.Geometry.GetBoundingBox().GetCentroid().Y))
                    {
                        if (layerStyle is IThemeStyle) style = (layerStyle as IThemeStyle).GetStyle(feature);
                        if ((style == null) || (style.Enabled == false) || (style.MinVisible > viewport.Resolution) || (style.MaxVisible < viewport.Resolution)) continue;

                        if (stackOffset == null) //first time
                        {
                            stackOffset = new Offset();
                            if (cluster.Features.Count > 1)
                                canvas.Children.Add(RenderBox(cluster.Box, viewport));
                        }
                        else stackOffset.Y += 18; //todo: get size from text, (or just pass stack nr)
                                                
                        if (!(style is LabelStyle)) throw new Exception("Style of label is not a LabelStyle");
                        var labelStyle = style as LabelStyle;
                        string labelText = layer.GetLabel(feature);
                        var position = new Mapsui.Geometries.Point(cluster.Box.GetCentroid().X, cluster.Box.Bottom);
                        canvas.Children.Add(RenderLabel(position, stackOffset, labelStyle, viewport, labelText));
                    }
                }
            }

            return canvas;
        }
        public static Canvas Render(IViewport viewport, LabelLayer layer)
        {
            // todo: Move stack functionality to Mapsui core.
            // step 1) Split RenderStackedLabelLayer into a method
            // GetFeaturesInViewStacked en a RenderStackedLabel 
            // which can later be replace by normal label rendering.
            // The method GetFeaturesInViewStacked 
            // returns a style with an offset determined by the stackoffset
            // and a position determined by CenterX en Cluster.Box.Bottom.
            // step 2) Move GetFeaturesInViewStacked to a GetFeaturesInView
            // method of a new StackedLabelLayed.

            var canvas = new Canvas { Opacity = layer.Opacity };

            // todo: take into account the priority 
            var features = layer.GetFeaturesInView(viewport.Extent, viewport.Resolution).ToArray();
            var margin = viewport.Resolution * 50;

            const int symbolSize = 32; // todo: determine margin by symbol size
            const int boxMargin = symbolSize / 2;

            var clusters = new List<Cluster>();
            //todo: repeat until there are no more merges
            ClusterFeatures(clusters, features, margin, layer.Style, viewport.Resolution);
            const int textHeight = 18;
            foreach (var cluster in clusters)
            {
                var stackOffsetY = double.NaN;

                var orderedFeatures = cluster.Features.OrderBy(f => f.Geometry.GetBoundingBox().GetCentroid().Y);

                if (cluster.Features.Count > 1) canvas.Children.Add(RenderBox(cluster.Box, viewport));

                foreach (var feature in orderedFeatures)
                {
                    if (double.IsNaN(stackOffsetY)) // first time
                        stackOffsetY = textHeight * 0.5 + boxMargin;
                    else
                        stackOffsetY += textHeight; //todo: get size from text (or just pass stack nr)

                    LabelStyle style;
                    if (layer.Style is IThemeStyle)
                    {
                        style = (LabelStyle)((IThemeStyle)layer.Style).GetStyle(feature);
                    }
                    else
                    {
                        style = (LabelStyle)layer.Style;
                    }

                    var labelStyle = new LabelStyle(style)
                    {
                        Text = layer.GetLabelText(feature) //we only use the layer for the text, this should be returned by style
                    };
                    labelStyle.Offset.Y += stackOffsetY;

                    // since the box can be rotated, find the minimal Y value of all 4 corners
                    var rotatedBox = cluster.Box.Rotate(-viewport.Rotation);
                    var minY = rotatedBox.Vertices.Select(v => v.Y).Min();
                    var position = new Geometries.Point(cluster.Box.GetCentroid().X, minY);

                    var labelText = labelStyle.GetLabelText(feature);
                    canvas.Children.Add(SingleLabelRenderer.RenderLabel(position, labelStyle, viewport, labelText));
                }
            }
            return canvas;
        }
        public static Map InitializeMap()
        {
            //Initialize a new map based on the simple map
            var map = new Map();

            //Layer osm = new Layer("OSM");
            //string url = "http://labs.metacarta.com/wms-c/tilecache.py?version=1.1.1&amp;request=GetCapabilities&amp;service=wms-c";
            //var tileSources = TileSourceWmsC.TileSourceBuilder(new Uri(url), null);
            //var tileSource = new List<ITileSource>(tileSources).Find(source => source.Schema.Name == "osm-map");
            //osm.DataSource = new TileProvider(tileSource, "OSM");
            //map.Layers.Add(osm);

            //Set up countries layer
            var countryLayer = new Layer("Countries");
            //Set the datasource to a shapefile in the App_data folder
            countryLayer.DataSource = new ShapeFile("GeoData/World/countries.shp", true);
            countryLayer.DataSource.SRID = 4326;
            
            var style = new VectorStyle
            {
                Fill = new Brush { Color = Color.Green },
                Outline = new Pen { Color = Color.Black }
            };
            countryLayer.Styles.Add(style);
            map.Layers.Add(countryLayer);

            //set up cities layer
            var cityLayer = new Layer("Cities");
            //Set the datasource to a shapefile in the App_data folder
            cityLayer.DataSource = new ShapeFile("GeoData/World/cities.shp", true);
            cityLayer.DataSource.SRID = 4326;
            cityLayer.MaxVisible = 0.09;
            map.Layers.Add(cityLayer);

            //Set up a country label layer
            var countryLabelLayer = new LabelLayer("Country labels");
            countryLabelLayer.DataSource = countryLayer.DataSource;
            countryLabelLayer.DataSource.SRID = 4326;
            countryLabelLayer.Enabled = true;
            countryLabelLayer.MaxVisible = 0.18;
            countryLabelLayer.MinVisible = 0.054;
            countryLabelLayer.LabelColumn = "NAME";
            var labelStyle = new LabelStyle();
            labelStyle.ForeColor = Color.Black;
            labelStyle.Font = new Font { FontFamily = "GenericSerif", Size = 12 };
            labelStyle.BackColor = new Brush { Color = new Color { A = 128, R = 255, G = 255, B = 255 } };
            labelStyle.HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Center;
            countryLabelLayer.MultipartGeometryBehaviour = LabelLayer.MultipartGeometryBehaviourEnum.Largest;
            countryLabelLayer.Styles.Add(labelStyle);
            map.Layers.Add(countryLabelLayer);

            //Set up a city label layer
            var cityLabelLayer = new LabelLayer("City labels");
            cityLabelLayer.DataSource = cityLayer.DataSource;
            cityLabelLayer.DataSource.SRID = 4326;
            cityLabelLayer.Enabled = true;
            cityLabelLayer.LabelColumn = "NAME";
            cityLabelLayer.MaxVisible = countryLabelLayer.MinVisible;
            cityLabelLayer.MinVisible = 0;
            cityLabelLayer.LabelFilter = LabelCollisionDetection.ThoroughCollisionDetection;
            var cityLabelStyle = new LabelStyle();
            cityLabelStyle.ForeColor = Color.Black;
            cityLabelStyle.Font = new Font { FontFamily = "GenericSerif", Size = 11 };
            cityLabelStyle.HorizontalAlignment = LabelStyle.HorizontalAlignmentEnum.Left;
            cityLabelStyle.VerticalAlignment = LabelStyle.VerticalAlignmentEnum.Bottom;
            cityLabelStyle.Offset = new Offset { X = 3, Y = 3 };
            cityLabelStyle.Halo = new Pen { Color = Color.Yellow, Width = 2 };
            cityLabelStyle.CollisionDetection = true;
            cityLabelLayer.Styles.Add(cityLabelStyle);
            map.Layers.Add(cityLabelLayer);

            //Set a gradient theme on the countries layer, based on Population density
            //First create two styles that specify min and max styles
            //In this case we will just use the default values and override the fill-colors
            //using a colorblender. If different line-widths, line- and fill-colors where used
            //in the min and max styles, these would automatically get linearly interpolated.
            IStyle min = new Style();
            IStyle max = new Style();
            //Create theme using a density from 0 (min) to 400 (max)
            var popdens = new GradientTheme("PopDens", 0, 400, min, max);
            //We can make more advanced coloring using the ColorBlend'er.
            //Setting the FillColorBlend will override any fill-style in the min and max fills.
            //In this case we just use the predefined Rainbow colorscale
            popdens.FillColorBlend = ColorBlend.Rainbow5;
            countryLayer.Styles.Add(popdens);

            //Lets scale the labels so that big countries have larger texts as well
            var lblMin = new LabelStyle();
            var lblMax = new LabelStyle();
            lblMin.ForeColor = Color.Black;
            lblMin.Font = new Font { FontFamily = "Sans Serif", Size = 6 };
            lblMax.ForeColor = Color.Black;
            lblMax.BackColor = new Brush { Color = new Color { A = 128, R = 255, G = 255, B = 255 } };
            lblMin.BackColor = lblMax.BackColor;
            lblMax.Font = new Font { FontFamily = "Sans Serif", Size = 9 };
            countryLabelLayer.Styles.Add(new GradientTheme("PopDens", 0, 400, lblMin, lblMax));

            //Lets scale city icons based on city population
            //cities below 1.000.000 gets the smallest symbol, and cities with more than 5.000.000 the largest symbol
            var citymin = new SymbolStyle();
            var citymax = new SymbolStyle();
            const string iconPath = "Images/icon.png";
            if (!File.Exists(iconPath))
            {
                throw new Exception(
                    String.Format("Error file '{0}' could not be found, make sure it is at the expected location",
                                  iconPath));
            }

            citymin.Symbol = new Bitmap { Data = new FileStream(iconPath, FileMode.Open, FileAccess.Read) };
            citymin.SymbolScale = 0.5f;
            citymax.Symbol = new Bitmap { Data = new FileStream(iconPath, FileMode.Open, FileAccess.Read) };
            citymax.SymbolScale = 1f;
            cityLayer.Styles.Add(new GradientTheme("Population", 1000000, 5000000, citymin, citymax));

            var geodanLayer = new Layer("Geodan");
            geodanLayer.DataSource = new MemoryProvider(new Point(4.9130567, 52.3422033));
            geodanLayer.Styles.Add(new SymbolStyle { Symbol = new Bitmap { Data = new FileStream(iconPath, FileMode.Open, FileAccess.Read) } });
            map.Layers.Add(geodanLayer);

            //limit the zoom to 360 degrees width
            map.BackColor = Color.White;

            return map;
        }
 public static Canvas Render(IViewport viewport, LabelLayer layer)
 {
     throw new NotImplementedException();
 }
        public static void Render(Graphics graphics, IViewport viewport, LabelLayer labelLayer)
        {
            var layerStyles = BaseLayer.GetLayerStyles(labelLayer);
            foreach (var layerStyle in layerStyles)
            {
                if (layerStyle.Enabled && labelLayer.MaxVisible >= viewport.Resolution && labelLayer.MinVisible < viewport.Resolution)
                {
                    if (labelLayer.DataSource == null)
                        throw (new ApplicationException("DataSource property not set"));

                    graphics.SmoothingMode = SmoothingMode.AntiAlias;

                    var features = labelLayer.GetFeaturesInView(viewport.Extent, viewport.Resolution);

                    //Initialize label collection
                    var labels = new List<Label>();

                    var style = layerStyle as LabelStyle;

                    //List<System.Drawing.Rectangle> LabelBoxes; //Used for collision detection
                    //Render labels
                    foreach (IFeature feature in features)
                    {
                        if (layerStyle is IThemeStyle) style = (layerStyle as IThemeStyle).GetStyle(feature) as LabelStyle;

                        float rotation = 0;
                        if (!String.IsNullOrEmpty(labelLayer.RotationColumn))
                            rotation = float.Parse(feature[labelLayer.RotationColumn].ToString(), NumberStyles.Any, CultureInfo.InvariantCulture);

                        int priority = labelLayer.Priority;
                        if (labelLayer.PriorityDelegate != null)
                            priority = labelLayer.PriorityDelegate(feature);
                        else if (!String.IsNullOrEmpty(labelLayer.PriorityColumn))
                            priority = int.Parse(feature[labelLayer.PriorityColumn].ToString(), NumberStyles.Any, CultureInfo.InvariantCulture);

                        string text;

                        if (labelLayer.LabelStringDelegate != null)
                        {
                            text = labelLayer.LabelStringDelegate(feature);
                        }
                        else
                        {
                            text = feature[labelLayer.LabelColumn].ToString();
                        }

                        if (!string.IsNullOrEmpty(text))
                        {
                            if (feature.Geometry is GeometryCollection)
                            {
                                var geometryCollection = feature.Geometry as GeometryCollection;
                                if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.All)
                                {
                                    foreach (var geometry in geometryCollection)
                                    {
                                        var label = CreateLabel(geometry, text, rotation, priority, style, viewport, graphics);
                                        if (label != null) labels.Add(label);
                                    }
                                }
                                else if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.CommonCenter)
                                {
                                    var label = CreateLabel(feature.Geometry, text, rotation, priority, style, viewport, graphics);
                                    if (label != null) labels.Add(label);
                                }
                                else if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.First)
                                {
                                    if ((feature.Geometry as GeometryCollection).Collection.Count > 0)
                                    {
                                        Label label = CreateLabel(geometryCollection.Collection[0], text, rotation, 0,
                                            style, viewport, graphics);
                                        if (label != null) labels.Add(label);
                                    }
                                }
                                else if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.Largest)
                                {
                                    var coll = (feature.Geometry as GeometryCollection);
                                    if (coll.NumGeometries > 0)
                                    {
                                        double largestVal = 0;
                                        int idxOfLargest = 0;
                                        for (var j = 0; j < coll.NumGeometries; j++)
                                        {
                                            Geometry geom = coll.Geometry(j);
                                            if (geom is LineString && ((LineString)geom).Length > largestVal)
                                            {
                                                largestVal = ((LineString)geom).Length;
                                                idxOfLargest = j;
                                            }
                                            if (geom is MultiLineString && ((MultiLineString)geom).Length > largestVal)
                                            {
                                                largestVal = ((MultiLineString)geom).Length;
                                                idxOfLargest = j;
                                            }
                                            if (geom is Polygon && ((Polygon)geom).Area > largestVal)
                                            {
                                                largestVal = ((Polygon)geom).Area;
                                                idxOfLargest = j;
                                            }
                                            if (geom is MultiPolygon && ((MultiPolygon)geom).Area > largestVal)
                                            {
                                                largestVal = ((MultiPolygon)geom).Area;
                                                idxOfLargest = j;
                                            }
                                        }

                                        var label = CreateLabel(coll.Geometry(idxOfLargest), text, rotation, priority, style,
                                                                viewport, graphics);
                                        if (label != null) labels.Add(label);
                                    }
                                }
                            }
                            else
                            {
                                var label = CreateLabel(feature.Geometry, text, rotation, priority, style, viewport, graphics);
                                if (label != null) labels.Add(label);
                            }
                        }
                    }

                    if (labels.Count > 0) //We have labels to render...
                    {
                        if ((layerStyle is LabelStyle) && (layerStyle as LabelStyle).CollisionDetection && labelLayer.LabelFilter != null)
                            labelLayer.LabelFilter(labels);
                        foreach (Label label in labels)
                        {
                            if (!label.Show) continue;
                            LabelRenderer.DrawLabel(graphics, label.LabelPoint, label.Style.Offset, label.Style.Font,
                                label.Style.ForeColor, label.Style.BackColor, label.Halo, label.Rotation, label.Text, viewport);
                        }
                    }
                }
            }
        }
Beispiel #9
0
		public static List<IFeature> RenderStackedLabelLayer(IViewport viewport, LabelLayer layer)
		{
			var renderedFeatures = new List<IFeature> ();
			var canvas = new CALayer ();
			canvas.Opacity = (float)layer.Opacity;

			//todo: take into account the priority 
			var features = layer.GetFeaturesInView(viewport.Extent, viewport.Resolution);
			var margin = viewport.Resolution * 50;

			if(layer.Style != null)
			{
				var clusters = new List<Cluster>();
				//todo: repeat until there are no more merges
				ClusterFeatures(clusters, features, margin, layer.Style, viewport.Resolution);

				foreach (var cluster in clusters)
				{
					var feature = cluster.Features.OrderBy(f => f.Geometry.GetBoundingBox().GetCentroid().Y).FirstOrDefault();
					//SetFeatureOutline (feature, layer.Name, cluster.Features.Count);
					//var bb = RenderBox(cluster.Box, viewport);

					//Zorg dat dit ALTIJD decimal zelfde ISet als ViewChanged is
					//var feature = cluster.Features.FirstOrDefault ();

					var styles = feature.Styles ?? Enumerable.Empty<IStyle>();
					foreach (var style in styles)
					{
						if (feature.Styles != null && style.Enabled)
						{
							var styleKey = layer.Name; //feature.GetHashCode ().ToString ();
							var renderedGeometry = (feature[styleKey] != null) ? (CALayer)feature[styleKey] : null;
							var labelText = layer.GetLabelText(feature);

							if (renderedGeometry == null) {
							//Mapsui.Geometries.Point point, Offset stackOffset, LabelStyle style, IFeature feature, IViewport viewport, string text)
								renderedGeometry = RenderLabel(feature.Geometry as Mapsui.Geometries.Point,
								                               style as LabelStyle, feature, viewport, labelText);

								feature [styleKey] = renderedGeometry;
								feature ["first"] = true;

							} else {
								feature ["first"] = false;
							}
						}
					}
					renderedFeatures.Add (feature);

					/*
					Offset stackOffset = null;

					foreach (var feature in cluster.Features.OrderBy(f => f.Geometry.GetBoundingBox().GetCentroid().Y))
					{
						if (layerStyle is IThemeStyle) style = (layerStyle as IThemeStyle).GetStyle(feature);
						if ((style == null) || (style.Enabled == false) || (style.MinVisible > viewport.Resolution) || (style.MaxVisible < viewport.Resolution)) continue;

						if (stackOffset == null) //first time
						{
							stackOffset = new Offset();
							if (cluster.Features.Count > 1)
								canvas.AddSublayer (RenderBox(cluster.Box, viewport));
						}
						else stackOffset.Y += 18; //todo: get size from text, (or just pass stack nr)

						if (!(style is LabelStyle)) throw new Exception("Style of label is not a LabelStyle");
						var labelStyle = style as LabelStyle;
						string labelText = layer.GetLabel(feature);
						var position = new Mapsui.Geometries.Point(cluster.Box.GetCentroid().X, cluster.Box.Bottom);
						canvas.AddSublayer(RenderLabel(position, stackOffset, labelStyle, feature, viewport, labelText));
					}
					*/
				}
			}

			return renderedFeatures;
		}
Beispiel #10
0
		public static CALayer RenderLabelLayer(IViewport viewport, LabelLayer layer, List<IFeature> features)
		{
			var canvas = new CALayer();
			canvas.Opacity = (float)layer.Opacity;

			//todo: take into account the priority 
			var stackOffset = new Offset();

			if (layer.Style != null)
			{
				var style = layer.Style;

				foreach (var feature in features)
				{
					if (style is IThemeStyle) style = (style as IThemeStyle).GetStyle(feature);

					if ((style == null) || (style.Enabled == false) || (style.MinVisible > viewport.Resolution) || (style.MaxVisible < viewport.Resolution)) continue;
					if (!(style is LabelStyle)) throw new Exception("Style of label is not a LabelStyle");
					//var labelStyle = style as LabelStyle;
					string labelText = layer.GetLabelText(feature);

					var label = RenderLabel (feature.Geometry as Mapsui.Geometries.Point,
					                         style as LabelStyle, feature, viewport, labelText);

					canvas.AddSublayer(label);
				}
			}

			return canvas;
		}
        public static void Render(Graphics g, IViewport viewport, LabelLayer labelLayer)
        {
            foreach (var layerStyle in labelLayer.Styles)
            {
                if (layerStyle.Enabled && labelLayer.MaxVisible >= viewport.Resolution && labelLayer.MinVisible < viewport.Resolution)
                {
                    if (labelLayer.DataSource == null)
                        throw (new ApplicationException("DataSource property not set"));

#if !PocketPC
                    g.SmoothingMode = SmoothingMode.AntiAlias;
#endif

                    //!!!BoundingBox envelope = map.Envelope; //View to render
                    //!!!if (CoordinateTransformation != null)
                    //!!!    envelope = GeometryTransform.TransformBox(envelope, CoordinateTransformation.MathTransform.Inverse());

                    labelLayer.DataSource.Open();
                    var features = labelLayer.DataSource.GetFeaturesInView(viewport.Extent, viewport.Resolution);
                    labelLayer.DataSource.Close();

                    //Initialize label collection
                    var labels = new List<Label>();

                    var style = layerStyle as LabelStyle;
                        
                    //List<System.Drawing.Rectangle> LabelBoxes; //Used for collision detection
                    //Render labels
                    foreach (IFeature feature in features)
                    {
                        //!!!if (CoordinateTransformation != null)
                        //!!!    features[i].Geometry = GeometryTransform.TransformGeometry(
                        //!!!   features[i].Geometry, CoordinateTransformation. MathTransform);

                        if (layerStyle is IThemeStyle) style = (layerStyle as ThemeStyle).GetStyle(feature) as LabelStyle;

                        float rotation = 0;
                        if (!String.IsNullOrEmpty(labelLayer.RotationColumn))
                            rotation = float.Parse(feature[labelLayer.RotationColumn].ToString(), NumberStyles.Any, CultureInfo.InvariantCulture);

                        int priority = labelLayer.Priority;
                        if (labelLayer.PriorityDelegate != null)
                            priority = labelLayer.PriorityDelegate(feature);
                        else if (!String.IsNullOrEmpty(labelLayer.PriorityColumn))
                            priority = int.Parse(feature[labelLayer.PriorityColumn].ToString(), NumberStyles.Any, CultureInfo.InvariantCulture);

                        string text;
                        if (labelLayer.LabelStringDelegate != null)
                            text = labelLayer.LabelStringDelegate(feature);
                        else
                            text = feature[labelLayer.LabelColumn].ToString();

                        if (text != null && text != String.Empty)
                        {
                            if (feature.Geometry is GeometryCollection)
                            {
                                if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.All)
                                {
                                    foreach (Geometry geom in (feature.Geometry as GeometryCollection))
                                    {
                                        Label lbl = CreateLabel(geom, text, rotation, priority, style, viewport, g, labelLayer);
                                        if (lbl != null)
                                            labels.Add(lbl);
                                    }
                                }
                                else if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.CommonCenter)
                                {
                                    Label lbl = CreateLabel(feature.Geometry, text, rotation, priority, style, viewport, g, labelLayer);
                                    if (lbl != null)
                                        labels.Add(lbl);
                                }
                                else if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.First)
                                {
                                    //!!!
                                    //if ((feature.Geometry as GeometryCollection).Collection.Count > 0)
                                    //{
                                    //    Label lbl = CreateLabel((feature.Geometry as GeometryCollection).Collection[0], text,
                                    //                            rotation, style, map, g, labelTheme);
                                    //    if (lbl != null)
                                    //        labels.Add(lbl);
                                    //}
                                }
                                else if (labelLayer.MultipartGeometryBehaviour == LabelLayer.MultipartGeometryBehaviourEnum.Largest)
                                {
                                    var coll = (feature.Geometry as GeometryCollection);
                                    if (coll.NumGeometries > 0)
                                    {
                                        double largestVal = 0;
                                        int idxOfLargest = 0;
                                        for (int j = 0; j < coll.NumGeometries; j++)
                                        {
                                            Geometry geom = coll.Geometry(j);
                                            if (geom is LineString && ((LineString)geom).Length > largestVal)
                                            {
                                                largestVal = ((LineString)geom).Length;
                                                idxOfLargest = j;
                                            }
                                            if (geom is MultiLineString && ((MultiLineString)geom).Length > largestVal)
                                            {
                                                largestVal = ((LineString)geom).Length;
                                                idxOfLargest = j;
                                            }
                                            if (geom is Polygon && ((Polygon)geom).Area > largestVal)
                                            {
                                                largestVal = ((Polygon)geom).Area;
                                                idxOfLargest = j;
                                            }
                                            if (geom is MultiPolygon && ((MultiPolygon)geom).Area > largestVal)
                                            {
                                                largestVal = ((MultiPolygon)geom).Area;
                                                idxOfLargest = j;
                                            }
                                        }

                                        Label lbl = CreateLabel(coll.Geometry(idxOfLargest), text, rotation, priority, style,
                                                                viewport, g, labelLayer);
                                        if (lbl != null)
                                            labels.Add(lbl);
                                    }
                                }
                            }
                            else
                            {
                                Label lbl = CreateLabel(feature.Geometry, text, rotation, priority, style, viewport, g, labelLayer);
                                if (lbl != null)
                                    labels.Add(lbl);
                            }
                        }
                    }

                    if (labels.Count > 0) //We have labels to render...
                    {
                        if ((layerStyle as LabelStyle).CollisionDetection && labelLayer.LabelFilter != null)
                            labelLayer.LabelFilter(labels);
                        for (int i = 0; i < labels.Count; i++)
                            if (labels[i].Show)
                                GdiGeometryRenderer.DrawLabel(g, labels[i].LabelPoint, labels[i].Style.Offset,
                                                         labels[i].Style.Font, labels[i].Style.ForeColor,
                                                         labels[i].Style.BackColor, (layerStyle as LabelStyle).Halo, labels[i].Rotation,
                                                         labels[i].Text, viewport);
                    }
                    labels = null;
                }
            }
        }
        private static Label CreateLabel(IGeometry feature, string text, float rotation, int priority, LabelStyle style, IViewport viewport,
                                  Graphics g, LabelLayer labelTheme)
        {
            SizeF gdiSize = g.MeasureString(text, style.Font.Convert());
            var size = new Mapsui.Styles.Size { Width = gdiSize.Width, Height = gdiSize.Height };

            Mapsui.Geometries.Point position = viewport.WorldToScreen(feature.GetBoundingBox().GetCentroid());
            position.X = position.X - size.Width * (short)style.HorizontalAlignment * 0.5f;
            position.Y = position.Y - size.Height * (short)style.VerticalAlignment * 0.5f;
            if (position.X - size.Width > viewport.Width || position.X + size.Width < 0 ||
                position.Y - size.Height > viewport.Height || position.Y + size.Height < 0)
                return null;
            else
            {
                Label lbl;

                if (!style.CollisionDetection)
                    lbl = new Label(text, position, rotation, priority, null, style);
                else
                {
                    //Collision detection is enabled so we need to measure the size of the string
                    lbl = new Label(text, position, rotation, priority,
                                    new LabelBox(position.X - size.Width * 0.5f - style.CollisionBuffer.Width,
                                                 position.Y + size.Height * 0.5f + style.CollisionBuffer.Height,
                                                 size.Width + 2f * style.CollisionBuffer.Width,
                                                 size.Height + style.CollisionBuffer.Height * 2f), style);
                }
                if (feature.GetType() == typeof(LineString))
                {
                    var line = feature as LineString;
                    if (line.Length / viewport.Resolution > size.Width) //Only label feature if it is long enough
                        CalculateLabelOnLinestring(line, ref lbl, viewport);
                    else
                        return null;
                }

                return lbl;
            }
        }
 private static Label CreateLabel(IGeometry feature, string text, float rotation, LabelStyle style, IViewport viewport, Graphics g, LabelLayer labelTheme)
 {
     return CreateLabel(feature, text, rotation, labelTheme.Priority, style, viewport, g, labelTheme);
 }