1package geojson
2
3import (
4	"github.com/tidwall/tile38/geojson/geo"
5	"github.com/tidwall/tile38/geojson/geohash"
6	"github.com/tidwall/tile38/geojson/poly"
7)
8
9// SimplePoint is a geojson object with the type "Point" and where there coordinate is 2D and there is no bbox.
10type SimplePoint struct {
11	X, Y float64
12}
13
14// New2DPoint creates a SimplePoint
15func New2DPoint(x, y float64) SimplePoint {
16	return SimplePoint{x, y}
17}
18
19func fillSimplePoint(coordinates Position, bbox *BBox, err error) (SimplePoint, error) {
20	return SimplePoint{X: coordinates.X, Y: coordinates.Y}, err
21}
22
23// CalculatedBBox is exterior bbox containing the object.
24func (g SimplePoint) CalculatedBBox() BBox {
25	return BBox{
26		Min: Position{X: g.X, Y: g.Y, Z: 0},
27		Max: Position{X: g.X, Y: g.Y, Z: 0},
28	}
29}
30
31// CalculatedPoint is a point representation of the object.
32func (g SimplePoint) CalculatedPoint() Position {
33	return Position{X: g.X, Y: g.Y, Z: 0}
34}
35
36// Geohash converts the object to a geohash value.
37func (g SimplePoint) Geohash(precision int) (string, error) {
38	p := g.CalculatedPoint()
39	return geohash.Encode(p.Y, p.X, precision)
40}
41
42// PositionCount return the number of coordinates.
43func (g SimplePoint) PositionCount() int {
44	return 1
45}
46
47// Weight returns the in-memory size of the object.
48func (g SimplePoint) Weight() int {
49	return 2 * 8
50}
51
52// MarshalJSON allows the object to be encoded in json.Marshal calls.
53func (g SimplePoint) MarshalJSON() ([]byte, error) {
54	return g.appendJSON(nil), nil
55}
56
57func (g SimplePoint) appendJSON(json []byte) []byte {
58	return appendLevel1JSON(json, "Point", Position{X: g.X, Y: g.Y, Z: 0}, nil, false)
59}
60
61// JSON is the json representation of the object. This might not be exactly the same as the original.
62func (g SimplePoint) JSON() string {
63	return string(g.appendJSON(nil))
64}
65
66// String returns a string representation of the object. This might be JSON or something else.
67func (g SimplePoint) String() string {
68	return g.JSON()
69}
70
71func (g SimplePoint) bboxPtr() *BBox {
72	return nil
73}
74func (g SimplePoint) hasPositions() bool {
75	return true
76}
77
78// WithinBBox detects if the object is fully contained inside a bbox.
79func (g SimplePoint) WithinBBox(bbox BBox) bool {
80	return poly.Point(Position{X: g.X, Y: g.Y, Z: 0}).InsideRect(rectBBox(bbox))
81}
82
83// IntersectsBBox detects if the object intersects a bbox.
84func (g SimplePoint) IntersectsBBox(bbox BBox) bool {
85	return poly.Point(Position{X: g.X, Y: g.Y, Z: 0}).InsideRect(rectBBox(bbox))
86}
87
88// Within detects if the object is fully contained inside another object.
89func (g SimplePoint) Within(o Object) bool {
90	return withinObjectShared(g, o,
91		func(v Polygon) bool {
92			return poly.Point(Position{X: g.X, Y: g.Y, Z: 0}).Inside(polyExteriorHoles(v.Coordinates))
93		},
94	)
95}
96
97// Intersects detects if the object intersects another object.
98func (g SimplePoint) Intersects(o Object) bool {
99	return intersectsObjectShared(g, o,
100		func(v Polygon) bool {
101			return poly.Point(Position{X: g.X, Y: g.Y, Z: 0}).Intersects(polyExteriorHoles(v.Coordinates))
102		},
103	)
104}
105
106// Nearby detects if the object is nearby a position.
107func (g SimplePoint) Nearby(center Position, meters float64) bool {
108	return geo.DistanceTo(center.Y, center.X, g.Y, g.X) <= meters
109}
110
111// IsBBoxDefined returns true if the object has a defined bbox.
112func (g SimplePoint) IsBBoxDefined() bool {
113	return false
114}
115
116// IsGeometry return true if the object is a geojson geometry object. false if it something else.
117func (g SimplePoint) IsGeometry() bool {
118	return true
119}
120