Create a circle or ellipse

Topics: Algorithms, Español, Italiano, SharpMap v0.9 / v1.x
Mar 8, 2011 at 8:40 AM

Hi,

Could someone help me to create a simple layer with a circle or ellipse. I need a simple example please!

Thanks so much.

Coordinator
Mar 8, 2011 at 10:33 AM

Hello javiermorata,

first you need some class that creates your geometries e.g.

 

public static class ShapeFactory
{
public static SharpMap.Geometries.LinearRing CreateRectangle(SharpMap.Geometries.Point leftTop, SharpMap.Geometries.Point rightBottom)
{
    var pts = new[]
                    {
                        leftTop, 
                        new Point(rightBottom.X, leftTop.Y), 
                        rightBottom,
                        new Point(leftTop.X, rightBottom.Y), 
                        leftTop
                    };
    return new LinearRing(pts);
}

public static SharpMap.Geometries.LinearRing CreateRectangle(SharpMap.Geometries.Point center, System.Drawing.SizeF size)
{
    var wh = new System.Drawing.SizeF(size.Width*0.5f, size.Height*0.5f);
    var lt = new SharpMap.Geometries.Point(center.X - wh.Width, center.Y + wh.Height);
    var rb = new SharpMap.Geometries.Point(center.X + wh.Width, center.Y - wh.Height);

    return CreateRectangle(lt, rb);
}

public static SharpMap.Geometries.LinearRing CreateEllipse(SharpMap.Geometries.Point center, System.Drawing.SizeF size)
{
    return CreateEllipse(center, size, 12);
}
        
public static SharpMap.Geometries.LinearRing CreateEllipse(SharpMap.Geometries.Point center, 
                                                            System.Drawing.SizeF size, 
                                                            int segmentsPerQuadrant)
{
    const double piHalf = System.Math.PI*0.5d;

    var step = piHalf/segmentsPerQuadrant;

    var pts = new SharpMap.Geometries.Point[4*segmentsPerQuadrant + 1];
    var angle = 0d;
    for (var i = 0; i < 4*segmentsPerQuadrant; i++)
    {
        pts[i] = new Point(center.X + Math.Cos(angle) * size.Width, 
                            center.Y + Math.Sin(angle) * size.Height);
        angle += step;
    }
    pts[pts.Length - 1] = pts[0];
    return new SharpMap.Geometries.LinearRing(pts);
}
}

Then you need to setup some SharpMap.Layer.VectorLayer with a SharpMap.Data.Providers.GeometryProvider as datasource:

var map = new SharpMap.Map(new Size(500, 500));
var gp = new SharpMap.Data.Providers.GeometryProvider(
    new SharpMap.Geometries.Geometry[]
        {
            new SharpMap.Geometries.Polygon(ShapeFactory.CreateEllipse(new Point(0, 0), new SizeF(40, 30))),
            ShapeFactory.CreateEllipse(new Point(90, 55), new SizeF(40, 30)),
            ShapeFactory.CreateEllipse(new Point(77, 24), new SizeF(40, 30)),
            ShapeFactory.CreateEllipse(new Point(-80, 41), new SizeF(40, 30)),
            ShapeFactory.CreateEllipse(new Point(-45, -36), new SizeF(40, 30)),
        });
var gl = new SharpMap.Layers.VectorLayer("GeometryLayer", gp);
map.Layers.Add(gl);
map.ZoomToExtents();
var mapimage = map.GetMap();
mapimage.Save("ellipse.png", ImageFormat.Png);

Hth FObermaier

Mar 8, 2011 at 11:14 AM

Thanks for your prompt attention FObermaier, I am going to try it ;)

Mar 8, 2011 at 3:01 PM

The code is good! Thanks a lot.

I just needed change the variable var because I do not use C# 3.0. But it not was easy for me because I am a junior developer in C#

and unexperienced in sharpmaps. My code was:

class MiElipse
{
public static SharpMap.Geometries.LinearRing CreateEllipse(SharpMap.Geometries.Point center, System.Drawing.SizeF size)
{
return CreateEllipse(center, size, 12);
}

public static SharpMap.Geometries.LinearRing CreateEllipse(SharpMap.Geometries.Point center,
System.Drawing.SizeF size,
int segmentsPerQuadrant)
{
const double piHalf = System.Math.PI * 0.5d;

double step = piHalf / segmentsPerQuadrant;

System.Collections.ObjectModel.Collection pts =
new System.Collections.ObjectModel.Collection();

double angle = 0d;
for (int i = 0; i < 4 * segmentsPerQuadrant; i++)
{
pts.Add(new SharpMap.Geometries.Point((int)(center.X + Math.Cos(angle) * size.Width),
(int)(center.Y + Math.Sin(angle) * size.Height)));
angle += step;
}
pts[pts.Count - 1] = pts[0];
return new SharpMap.Geometries.LinearRing(pts);
}
}

######## Then I create de Layer ######

SharpMap.Data.Providers.GeometryProvider gp = new SharpMap.Data.Providers.GeometryProvider(
new SharpMap.Geometries.Polygon(MiElipse.CreateEllipse(new SharpMap.Geometries.Point(375000, 4672000), new SizeF(5000, 5000))));

SharpMap.Layers.VectorLayer VLayer = new VectorLayer("SismoLayer",gp);
mapa.Layers.Add(VLayer);
ReasignarMapa(); // Is like map.ZoomToExtents() and more...