func (p Point) PointOnSurface() Point {
	return p.Force2D()
}
PointOnSurface returns the original Point.
package geom
import (
	"database/sql/driver"
	"fmt"
	"math"
	"unsafe"
)
type Point struct {
	coords Coordinates
	full   bool
}
func NewPoint(c Coordinates, opts ...ConstructorOption) (Point, error) {
	os := newOptionSet(opts)
	if os.skipValidations {
		return newUncheckedPoint(c), nil
	}
	if err := c.XY.validate(); err != nil {
		if os.omitInvalid {
			return NewEmptyPoint(c.Type), nil
		}
		return Point{}, validationError{err.Error()}
	}
	return newUncheckedPoint(c), nil
}
func newUncheckedPoint(c Coordinates) Point {
	return Point{c, true}
}
func NewEmptyPoint(ctype CoordinatesType) Point {
	return Point{Coordinates{Type: ctype}, false}
}
func (p Point) Type() GeometryType {
	return TypePoint
}
func (p Point) AsGeometry() Geometry {
	return Geometry{TypePoint, unsafe.Pointer(&p)}
}
func (p Point) XY() (XY, bool) {
	return p.coords.XY, p.full
}
func (p Point) Coordinates() (Coordinates, bool) {
	return p.coords, p.full
}
func (p Point) AsText() string {
	return string(p.AppendWKT(nil))
}
func (p Point) AppendWKT(dst []byte) []byte {
	dst = appendWKTHeader(dst, "POINT", p.coords.Type)
	return p.appendWKTBody(dst)
}
func (p Point) appendWKTBody(dst []byte) []byte {
	if !p.full {
		return appendWKTEmpty(dst)
	}
	return appendWKTCoords(dst, p.coords, true)
}
func (p Point) IsEmpty() bool {
	return !p.full
}
func (p Point) IsSimple() bool {
	return true
}
func (p Point) Envelope() Envelope {
	if xy, ok := p.XY(); ok {
		return Envelope{}.uncheckedExtend(xy)
	}
	return Envelope{}
}
func (p Point) Boundary() GeometryCollection {
	return GeometryCollection{}
}
func (p Point) Value() (driver.Value, error) {
	return p.AsBinary(), nil
}
func (p *Point) Scan(src interface{}) error {
	return scanAsType(src, p, TypePoint)
}
func (p Point) AsBinary() []byte {
	return p.AppendWKB(nil)
}
func (p Point) AppendWKB(dst []byte) []byte {
	marsh := newWKBMarshaller(dst)
	marsh.writeByteOrder()
	marsh.writeGeomType(TypePoint, p.CoordinatesType())
	if !p.full {
		p.coords.X = math.NaN()
		p.coords.Y = math.NaN()
		p.coords.Z = math.NaN()
		p.coords.M = math.NaN()
	}
	marsh.writeCoordinates(p.coords)
	return marsh.buf
}
func (p Point) ConvexHull() Geometry {
	return convexHull(p.AsGeometry())
}
func (p Point) MarshalJSON() ([]byte, error) {
	var dst []byte
	dst = append(dst, `{"type":"Point","coordinates":`...)
	if p.full {
		dst = appendGeoJSONCoordinate(dst, p.coords)
	} else {
		dst = append(dst, '[', ']')
	}
	return append(dst, '}'), nil
}
func (p Point) TransformXY(fn func(XY) XY, opts ...ConstructorOption) (Point, error) {
	if !p.full {
		return p, nil
	}
	newC := p.coords
	newC.XY = fn(newC.XY)
	return NewPoint(newC, opts...)
}
func (p Point) Centroid() Point {
	return p.Force2D()
}
func (p Point) Reverse() Point {
	return p
}
func (p Point) AsMultiPoint() MultiPoint {
	return NewMultiPoint([]Point{p})
}
func (p Point) CoordinatesType() CoordinatesType {
	return p.coords.Type
}
func (p Point) ForceCoordinatesType(newCType CoordinatesType) Point {
	if !p.full {
		return NewEmptyPoint(newCType)
	}
	if newCType.Is3D() != p.coords.Type.Is3D() {
		p.coords.Z = 0
	}
	if newCType.IsMeasured() != p.coords.Type.IsMeasured() {
		p.coords.M = 0
	}
	p.coords.Type = newCType
	return p
}
func (p Point) Force2D() Point {
	return p.ForceCoordinatesType(DimXY)
}