Click here to Skip to main content
15,888,527 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello Everybody,


i need a little help from you, im trying to draw a circle around a point (lat/long) in Google Earth, i found some php examples of a circle generator where they use a formula to get te linestring points for the circle by radius. in the php example, it draws a perfect circle but i need the formula implemented in a c# winform app. so i adapted it, and its draws, but it dras an elipse :confused: not a circle.

here is my code:

C#
  public void Save()
        {
            string FullFilePath = _KMLFilePath + _KMLFileName;

            XmlTextWriter xtr = new XmlTextWriter(FullFilePath, Encoding.UTF8);

            xtr.WriteStartDocument();

            xtr.WriteStartElement("kml");//start kml
            xtr.WriteStartAttribute("xmlns");
            xtr.WriteString("http://earth.google.com/kml/2.2");
            xtr.WriteEndAttribute();
            //xtr.WriteString();

            {
                xtr.WriteStartElement("Document");//start document
                {
                    
                        xtr.WriteStartElement("name");//start name
                        {
                            xtr.WriteString("Posiciones Fijas");
                        }
                        xtr.WriteEndElement();//end name


                        #region calcular cada punto con su circulo
                        for (int i = 0; i < _Coords.Count; i++)
                        {
                            xtr.WriteStartElement("Placemark");//start placemark
                            {
                                xtr.WriteStartElement("name");//start name
                                {
                                    xtr.WriteString(_Names[i]);
                                }
                                xtr.WriteEndElement();//end name
                                xtr.WriteStartElement("description");//start description
                                {
                                    xtr.WriteString(_Description[i]);
                                }
                                xtr.WriteEndElement();//end description
                                xtr.WriteStartElement("visibility");//start vis
                                {
                                    xtr.WriteString("1");
                                }
                                xtr.WriteEndElement();//end vis
                                xtr.WriteStartElement("Style");//start Style
                                {

                                    xtr.WriteStartElement("geomColor");//start
                                    {
                                        xtr.WriteString("FFffffFF");
                                    }
                                    xtr.WriteEndElement();//end
                                    xtr.WriteStartElement("geomScale");//start
                                    {
                                        xtr.WriteString("1");
                                    }
                                    xtr.WriteEndElement();//end
                                }
                                xtr.WriteEndElement();//end Style
                                xtr.WriteStartElement("LineString");
                                {
                                    xtr.WriteStartElement("coordinates");
                                    {
                                        #region calcular circulo
                                        double Latitud = deg2rad(double.Parse(_Coords[i].Latitude.Replace(".", ",")));
                                        double Longitud = deg2rad(double.Parse(_Coords[i].Longitude.Replace(".", ",")));
                                        double d_rad = (_radius / 6378137);
                                        for (int j = 0; j <= 360; j++)
                                        {
                                            double radial = (Math.PI*j) / 180;
                                            double lat_rad = Math.Asin((Math.Sin(Latitud) * Math.Cos(d_rad)) + (Math.Cos(Latitud) * Math.Sin(d_rad) * Math.Cos(radial)));
                                            double dlon_rad = Math.Atan2(Math.Sin(radial) * Math.Sin(d_rad) * Math.Cos(Latitud), Math.Cos(d_rad) - Math.Sin(Latitud) * Math.Sin(lat_rad));
                                            double lon_rad = ((Longitud + dlon_rad + Math.PI) %( 2 * Math.PI)) - Math.PI;
                                            xtr.WriteString(rad2deg(lat_rad).ToString().Replace(",", ".") + ", " + rad2deg(lon_rad).ToString().Replace(",", ".") + ", 0 ");
                                        }
                                        #endregion
                                    }
                                    xtr.WriteEndElement();//end coordinates
                                }
                                xtr.WriteEndElement();//end linestring
                            }
                            xtr.WriteEndElement();//end placemark
                        }
                        #endregion
                
                }
                xtr.WriteEndElement(); //end document
            }
            xtr.WriteEndElement();//end kml

            xtr.WriteEndDocument();

            xtr.Close();
            
        }


private double deg2rad(double deg)
       {
           return Math.PI* deg / 180;
       }
       private double rad2deg(double rad)
       {
           return rad *(180 / Math.PI);
       }


i dont know what exactly is going wrong

can anybody help me im a little bit blind,

The original source code for php is located here:

http://dev.bt23.org/keyhole/circlegen/output.phps[^]
Posted

Hi,

The degrees at shorter distance is more or less Cartesian coordinates. If big circles then need to worry about spherical.

From you code it seems your radius is small. The you can use normal circle drawing equation.

if StartX and startY is your reference decimal degrees (center point) then

C#
for (int j = 0; j <= 360; j++)
{
    endX = startX + radius * Math.Cos(deg2rad(j));
    endY = startY + radius * Math.Sin(deg2rad(j));
}


endX and endY (in decimal degrees) are 360 points in the circumference. Here radius also in decimal degrees.

However this will not work if your circle is more than approx 0.1 dec degrees (>1000 meters). It could work for smaller radius
 
Share this answer
 
I have not done a complete analysis of your code but it would appear that you are doing this by drawing 360 dots on the screen. Don't forget that on most screens the pixel distances are not the same in both axes so you need to adjust the point locations to take account of that fact. I would expect a simpler solution would be to use the Ellipse[^] class, which will draw the circle for you.
 
Share this answer
 
Tried both Solution, even with big(100km) and smal circles (150m) and still drawing an elipse, what bugs me is that the PHP code works perfectly, i dont know what i´ve done wrong adapting it.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900