func (p Polygon) AsGeometry() Geometry {
	return Geometry{TypePolygon, unsafe.Pointer(&p)}
}
AsGeometry converts this Polygon into a Geometry.
package geom
import (
	"database/sql/driver"
	"fmt"
	"math"
	"unsafe"
	"github.com/peterstace/simplefeatures/rtree"
)
type Polygon struct {
	rings []LineString
	ctype CoordinatesType
}
func NewPolygon(rings []LineString, opts ...ConstructorOption) (Polygon, error) {
	if len(rings) == 0 {
		return Polygon{}, nil
	}
	ctype := DimXYZM
	for _, r := range rings {
		ctype &= r.CoordinatesType()
	}
	rings = append([]LineString(nil), rings...)
	for i := range rings {
		rings[i] = rings[i].ForceCoordinatesType(ctype)
	}
	ctorOpts := newOptionSet(opts)
	if err := validatePolygon(rings, ctorOpts); err != nil {
		if ctorOpts.omitInvalid {
			return Polygon{}, nil
		}
		return Polygon{}, err
	}
	return Polygon{rings, ctype}, nil
}
func validatePolygon(rings []LineString, opts ctorOptionSet) error {
	if len(rings) == 0 || opts.skipValidations {
		return nil
	}
	for _, r := range rings {
		if !r.IsClosed() {
			return validationError{"polygon ring not closed"}
		}
		if !r.IsSimple() {
			return validationError{"polygon ring not simple"}
		}
	}
	nextInterVert := len(rings)
	interVerts := make(map[XY]int)
	graph := newGraph()
	boxes := make([]rtree.Box, len(rings))
	items := make([]rtree.BulkItem, len(rings))
	for i, r := range rings {
		box, ok := r.Envelope().box()
		if !ok {
			panic("unexpected empty ring")
		}
		boxes[i] = box
		items[i] = rtree.BulkItem{Box: boxes[i], RecordID: i}
	}
	tree := rtree.BulkLoad(items)
	for i := range rings {
		if err := tree.RangeSearch(boxes[i], func(j int) error {
			if i <= j {
				return nil
			}
			if i > 0 && j > 0 {  
				iStart := rings[i].Coordinates().GetXY(0)
				jStart := rings[j].Coordinates().GetXY(0)
				nestedFwd := relatePointToRing(iStart, rings[j]) == interior
				nestedRev := relatePointToRing(jStart, rings[i]) == interior
				if nestedFwd || nestedRev {
					return validationError{"polygon has nested rings"}
				}
			}
			intersects, ext := hasIntersectionLineStringWithLineString(rings[i], rings[j], true)
			if !intersects {
				return nil
			}
			if ext.multiplePoints {
				return validationError{"polygon rings intersect at multiple points"}
			}
			interVert, ok := interVerts[ext.singlePoint]
			if !ok {
				interVert = nextInterVert
				nextInterVert++
				interVerts[ext.singlePoint] = interVert
			}
			graph.addEdge(interVert, i)
			graph.addEdge(interVert, j)
			return nil
		}); err != nil {
			return err
		}
	}
	for _, hole := range rings[1:] {
		xy, ok := hole.StartPoint().XY()
		if !ok {
			continue
		}
		if relatePointToRing(xy, rings[0]) == exterior {
			return validationError{"polygon interior ring outside of exterior ring"}
		}
	}
	if graph.hasCycle() {
		return validationError{"polygon has disconnected interior"}
	}
	return nil
}
func (p Polygon) Type() GeometryType {
	return TypePolygon
}