Расширение KML Geometry — Circle

Опубликовано Июн 7, 2010 в .NET, Google Earth | Нет комментариев

В стандарте KML нет геометрии круга или окружности. Небольшой пример на C#, как программно нарисовать окружность с помощью LineString (примеры на других языках есть, а вот для C# не гугляться — этот будет первый).


Если добавить к полигону элемент innerBoundaryIs с окружностью меньшего радиуса, то мы получим кольцо. Если Placemark должен иметь значок, то в MultiGeometry необходимо добавить элемент Point.

    // radius - в метрах
    public static void WriteCirclePlacemark(XmlTextWriter writer, Point p, string name, string description, double radius)
    {
        writer.WriteStartElement("Placemark");
        writer.WriteElementString("name", name);
        writer.WriteStartElement("description");
        writer.WriteCData(description);
        writer.WriteEndElement(); // description

        writer.WriteStartElement("Style");
        writer.WriteStartElement("LineStyle");
        writer.WriteElementString("color", "998080ff");
        writer.WriteElementString("width", "3");
        writer.WriteEndElement(); // LineStyle
        writer.WriteStartElement("PolyStyle");
        writer.WriteElementString("color", "9980ff80");
        writer.WriteEndElement(); // PolyStyle
        writer.WriteEndElement(); // Style

        //writer.WriteStartElement("MultiGeometry");

        writer.WriteStartElement("Polygon");
        writer.WriteStartElement("outerBoundaryIs");
        writer.WriteStartElement("LinearRing");
        writer.WriteElementString("tessellate", "1");
        writer.WriteStartElement("coordinates");

        double M_PI = Math.PI;
        double lat_center = DegToRad(p.Lat);
        double lon_center = DegToRad(p.Lng);
        double d_rad = radius / 6378137d;

        CultureInfo EnUsCi = new CultureInfo("en-US");
        for (int i = 0; i <= 360; i += 5)
        {
            double radial = DegToRad(i);
            double lat_rad = Math.Asin(Math.Sin(lat_center) * Math.Cos(d_rad) + Math.Cos(lat_center) * Math.Sin(d_rad) * Math.Cos(radial));
            double lon_rad_tmp = Math.Atan2(Math.Sin(radial) * Math.Sin(d_rad) * Math.Cos(lat_center), Math.Cos(d_rad) - Math.Sin(lat_center) * Math.Sin(lat_rad));
            double lon_rad = ((lon_center + lon_rad_tmp + M_PI) % (2 * M_PI)) - M_PI;

            writer.WriteString(RadToDeg(lon_rad).ToString(EnUsCi) + "," + RadToDeg(lat_rad).ToString(EnUsCi) + ",0 ");
        }

        writer.WriteEndElement(); // coordinates
        writer.WriteEndElement(); // LinearRing
        writer.WriteEndElement(); // outerBoundaryIs
        writer.WriteEndElement(); // Polygon

        //writer.WriteEndElement(); // MultiGeometry

        writer.WriteEndElement(); // Placemark
    }

    private static double DegToRad(double deg)
    {
        return deg * (Math.PI / 180d);
    }

    private static double RadToDeg(double rad)
    {
        return rad * (180d / Math.PI);
    }

Оставить комментарий