Quantcast
Channel: DotSpatial
Viewing all articles
Browse latest Browse all 3973

New Post: Draw Circle on a Map.Drawing layer

$
0
0
Hi,
I worked on a project back in 2013 and there was no way to insert a circle on a map using a dotSpatial embedded function back then. The way I did it was to calculate the circumference points of a circle given a center, a radius and a number of segments. The number of segments defines the number of points to be calculated that will be inserted in a Polygon to create the circle. The larger the number of segments the more smoother the circle. For my project a segment number of 60 point was more than enough.

I hereby give two classes the ShapePolygon and the deriving ShapeCircle, to give you an idea:
 public class ShapePolygon :Shape,IShape{
        protected double m_lineWidth = 1.0;

        public double LineStroke {
            get {
                return m_lineWidth;
            }
            set {
                m_lineWidth = value;
                (ShapeSymbolizer as PolygonSymbolizer).SetOutline(m_outlineColor, m_lineWidth);
            }
        }

        public ShapePolygon(Map map,IList<Coordinate> vertices, Color? fillColor = null, Color? outlineColor =null, string name = "new polygon", double lineStroke = 1.0)
            : base(map, name) {
                m_shapeType = TYPE.POLYGON;
                Vertices = vertices;
                OutlineColor = outlineColor.HasValue ? outlineColor.Value : m_outlineColor;

                if (fillColor.HasValue) {
                    FillColor = fillColor.Value;
                }

                
                Add(ShapeMapLayer);

                DataColumn distCol = new DataColumn("Name");
                distCol.DataType = typeof(string);
                ShapeFeatureSet.DataTable.Columns.Add(distCol);
                ReDraw();
                m_shapeLabelLayer = createLabelLayer(ShapeFeatureSet, "Name");
                Add(m_shapeLabelLayer);
                if (vertices != null) {
                    m_map.MapFrame.DrawingLayers.AddRange(this);
                }
        }


        public IFeatureSymbolizer ShapeSymbolizer {
                get {
                    if (m_shapeSymbolizer == null) {
                        m_shapeSymbolizer = new PolygonSymbolizer( FillColor, OutlineColor);
                    }
                    return m_shapeSymbolizer;
                }
                set {
                    m_shapeSymbolizer = value;
                    //Rfreshh tbd
            }
        }


        public IMapLayer ShapeMapLayer {
                get {
                    if (m_shapeLayer == null) {
                        m_shapeLayer = new MapPolygonLayer(ShapeFeatureSet);
                        m_shapeLayer.Projection = ShapeFeatureSet.Projection;
                        m_shapeLayer.LegendText = "Point";
                        (m_shapeLayer as MapPolygonLayer).Symbolizer = ShapeSymbolizer as IPolygonSymbolizer;
                    }
                    return m_shapeLayer;
                }

                set {
                    m_shapeLayer = value;
            }
        }


        public virtual FeatureSet ShapeFeatureSet {
                get {
                    if (m_shapeFeatureSet == null) {
                        m_shapeFeatureSet = new FeatureSet(FeatureType.Polygon);
                        m_shapeFeatureSet.Projection = m_map.Projection;
                    }
                    return m_shapeFeatureSet;
                }

                set {
                    m_shapeFeatureSet = value;
                }
        }

        public  IMapLayer GetMapLayer() { return ShapeMapLayer; }

        

        public Shape.TYPE Type {
            get {
                return ShapeType;
            }
            set { }
        }

        public override Color OutlineColor {
            get {
                return m_outlineColor;
            }
            set {
                m_outlineColor = value;
                (ShapeSymbolizer as PolygonSymbolizer).SetOutline(m_outlineColor, m_lineWidth);
            }
        }

        public override Color FillColor {
            get {
                return m_fillColor;
            }
            set {
                m_fillColor = value;
                if(m_fillColor!=Color.Transparent){
                    m_fillColor = m_fillColor.ToTransparent(0.3f);
                }

                (ShapeSymbolizer as PolygonSymbolizer).SetFillColor(m_fillColor);
            }
        }


        public virtual void ReDraw() {
            ShapeFeatureSet.Features.Clear();
            List<Coordinate> temp = new List<Coordinate>();

            //if projection is webmercator re-project vertices appropriately since they come always in WGS1984
            if (m_map.Projection.Equals(KnownCoordinateSystems.Projected.World.WebMercator)) {
                foreach (Coordinate c in Vertices) {
                    temp.Add(MapManipulator.ConvertToWebMercator(c));
                }
            }
            else {
                temp = Vertices as List<Coordinate>;
            }
           

            LinearRing lr = new LinearRing(temp);
            Polygon obj = new Polygon(lr);
            IFeature f = ShapeFeatureSet.AddFeature(obj);
            DataRow dr = f.DataRow;
            dr.BeginEdit();
            dr["Name"] = Name;
            dr.EndEdit();

            ShapeFeatureSet.LockDispose();
            ShapeFeatureSet.InvalidateVertices();
            ShapeFeatureSet.UnlockDispose();
        }
    }
public class ShapeCircle :ShapePolygon,IShape{
        protected double m_radius = 10.0;

        public double Radius {
            get { 
                return Unit.RadToDeg(m_radius); 
            }
            set {
                m_radius = Unit.DegToRad(value);             
            }
        }

        protected double m_radiusToMapProj;
        protected int m_segments = 60;

        public int Segments {
            get {
                return m_segments;
            }
            set {
                m_segments = value;
            }
        }

        public Coordinate Center {get;set;}


        public ShapeCircle(Map map, Coordinate center, double radius, Color? fillColor = null, Color? outlineColor = null, string name = "new circle", double lineStroke = 0.0)
            : base(map,null,fillColor,outlineColor, name) {
                m_shapeType = TYPE.CIRCLE;
                Center = center;
                Radius = radius;
                ReDraw();
                m_map.MapFrame.DrawingLayers.AddRange(this);
        }


        public override void ReDraw() {
            if (Center != null) {
                ShapeFeatureSet.Features.Clear();
                List<Coordinate> circlePoints = new List<Coordinate>();
                double arcSegment = 360.0 / m_segments;

                Coordinate center = new Coordinate(Center);
                Coordinate radius = new Coordinate(m_radius, 0);
                //if projection is webmercator re-project vertices appropriately since they come always in WGS1984
                if (Projection.Equals(KnownCoordinateSystems.Projected.World.WebMercator)) {
                    center = MapManipulator.ConvertToWebMercator(Center);
                    radius = MapManipulator.ConvertToWebMercator(radius);
                }

//I create the circle segment points
                for (int i = 0; i < m_segments; i++) {
                    PointD c = PointOnCircle(arcSegment * i, center, radius.X);
                    circlePoints.Add(new Coordinate(c.X, c.Y));
                }

//I put the circle points into a Polygon

                LinearRing lr = new LinearRing(circlePoints);
                Polygon obj = new Polygon(lr);

                IFeature f = ShapeFeatureSet.AddFeature(obj);
                DataRow dr = f.DataRow;
                dr.BeginEdit();
                dr["Name"] = Name;
                dr.EndEdit();

                ShapeFeatureSet.LockDispose();
                ShapeFeatureSet.InvalidateVertices();
                ShapeFeatureSet.UnlockDispose();
            }

        }

//Each point of the circle is calculated via this function I am passing the center, radius, 
//and the arc in degrees of the point for instance for 60 segments the arc in degrees 
//should be 360/60 = 6 degrees so the values I am passing in this function will be 6,12,18, ....,354
//the function will return the x,y value of the circle point each time._ 
        private PointD PointOnCircle(double angleInDegrees, Coordinate center, double radius) {
            // Convert from degrees to radians via multiplication by PI/180                          
            double x = radius * Math.Cos(angleInDegrees * Math.PI / 180.0) + center.X;
            double y = radius * Math.Sin(angleInDegrees * Math.PI / 180.0) + center.Y;

            return new PointD(x, y);
        }
    }
When I want to draw a circle I do something like:
 Shape.ShapeCircle circle = new ShapeCircle(m_map, center, radius, null, lineColor, circleNameStr);
 m_shapes.Add(circle);
I hope that these will be helpful!

Viewing all articles
Browse latest Browse all 3973

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>