/**
         * Create a surface polygon from a KML GroundOverlay.
         *
         * @param tc      the current {@link KMLTraversalContext}.
         * @param overlay the {@link SharpEarth.ogc.kml.KMLGroundOverlay} to render as a polygon.
         *
         * @throws NullPointerException     if the geometry is null.
         * @throws ArgumentException if the parent placemark or the traversal context is null.
         */
        public KMLSurfacePolygonImpl(KMLTraversalContext tc, KMLGroundOverlay overlay)
        {
            if (tc == null)
            {
                String msg = Logging.getMessage("nullValue.TraversalContextIsNull");
                Logging.logger().severe(msg);
                throw new ArgumentException(msg);
            }

            if (overlay == null)
            {
                String msg = Logging.getMessage("nullValue.ParentIsNull");
                Logging.logger().severe(msg);
                throw new ArgumentException(msg);
            }

            this.parent = overlay;

            // Positions are specified either as a kml:LatLonBox or a gx:LatLonQuad
            Position.PositionList corners = overlay.getPositions();
            this.setOuterBoundary(corners.list);

            // Check to see if a rotation is provided. The rotation will be applied when the image is rendered, because
            // how the rotation is performed depends on the globe.
            KMLLatLonBox box = overlay.getLatLonBox();

            if (box != null && box.getRotation() != null)
            {
                this.mustApplyRotation = true;
            }

            if (overlay.getName() != null)
            {
                this.setValue(AVKey.DISPLAY_NAME, overlay.getName());
            }

            if (overlay.getDescription() != null)
            {
                this.setValue(AVKey.BALLOON_TEXT, overlay.getDescription());
            }

            if (overlay.getSnippetText() != null)
            {
                this.setValue(AVKey.SHORT_DESCRIPTION, overlay.getSnippetText());
            }

            String colorStr = overlay.getColor();

            if (!WWUtil.isEmpty(colorStr))
            {
                Color color = WWUtil.decodeColorABGR(colorStr);

                ShapeAttributes attributes = new BasicShapeAttributes();
                attributes.setDrawInterior(true);
                attributes.setInteriorMaterial(new Material(color));
                this.setAttributes(attributes);
            }
        }
        protected ShapeAttributes getInitialAttributes(String attrType)
        {
            ShapeAttributes attrs = new BasicShapeAttributes();

            if (KMLConstants.HIGHLIGHT.Equals(attrType))
            {
                attrs.setOutlineMaterial(Material.RED);
                attrs.setInteriorMaterial(Material.PINK);
            }
            else
            {
                attrs.setOutlineMaterial(Material.WHITE);
                attrs.setInteriorMaterial(Material.LIGHT_GRAY);
            }

            return(attrs);
        }
        /**
         * Create an instance.
         *
         * @param tc      the current {@link KMLTraversalContext}.
         * @param overlay the {@link SharpEarth.ogc.kml.KMLGroundOverlay} to render as a polygon.
         *
         * @throws NullPointerException     if the geomtry is null.
         * @throws ArgumentException if the parent placemark or the traversal context is null.
         */
        public KMLGroundOverlayPolygonImpl(KMLTraversalContext tc, KMLGroundOverlay overlay)
        {
            if (tc == null)
            {
                String msg = Logging.getMessage("nullValue.TraversalContextIsNull");
                Logging.logger().severe(msg);
                throw new ArgumentException(msg);
            }

            if (overlay == null)
            {
                String msg = Logging.getMessage("nullValue.ParentIsNull");
                Logging.logger().severe(msg);
                throw new ArgumentException(msg);
            }

            this.parent = overlay;

            String altMode = overlay.getAltitudeMode();

            if (!WWUtil.isEmpty(altMode))
            {
                if ("relativeToGround".Equals(altMode))
                {
                    this.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND);
                }
                else if ("absolute".Equals(altMode))
                {
                    this.setAltitudeMode(WorldWind.ABSOLUTE);
                }
            }

            // Positions are specified either as a kml:LatLonBox or a gx:LatLonQuad
            Position.PositionList corners = overlay.getPositions();
            this.setOuterBoundary(corners.list);

            // Apply rotation if the overlay includes a LatLonBox
            KMLLatLonBox box = overlay.getLatLonBox();

            if (box != null)
            {
                this.setRotation(box.getRotation());
            }

            if (overlay.getName() != null)
            {
                this.setValue(AVKey.DISPLAY_NAME, overlay.getName());
            }

            if (overlay.getDescription() != null)
            {
                this.setValue(AVKey.BALLOON_TEXT, overlay.getDescription());
            }

            if (overlay.getSnippetText() != null)
            {
                this.setValue(AVKey.SHORT_DESCRIPTION, overlay.getSnippetText());
            }

            // If no image is specified, draw a filled rectangle
            if (this.parent.getIcon() == null || this.parent.getIcon().getHref() == null)
            {
                String colorStr = overlay.getColor();
                if (!WWUtil.isEmpty(colorStr))
                {
                    Color color = WWUtil.decodeColorABGR(colorStr);

                    ShapeAttributes attributes = new BasicShapeAttributes();
                    attributes.setDrawInterior(true);
                    attributes.setInteriorMaterial(new Material(color));
                    this.setAttributes(attributes);
                }
            }
        }