-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy paths2cell.h
143 lines (117 loc) · 5.55 KB
/
s2cell.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// Copyright 2005 Google Inc. All Rights Reserved.
#ifndef UTIL_GEOMETRY_S2CELL_H_
#define UTIL_GEOMETRY_S2CELL_H_
#include "base/basictypes.h"
#include "base/logging.h"
#include "s2.h"
#include "s2cellid.h"
#include "s2region.h"
#include "util/math/vector2.h"
// An S2Cell is an S2Region object that represents a cell. Unlike S2CellIds,
// it supports efficient containment and intersection tests. However, it is
// also a more expensive representation (currently 48 bytes rather than 8).
// This class is intended to be copied by value as desired. It uses
// the default copy constructor and assignment operator, however it is
// not a "plain old datatype" (POD) because it has virtual functions.
class S2Cell : public S2Region {
public:
// The default constructor is required in order to use freelists.
// Cells should otherwise always be constructed explicitly.
S2Cell() {}
// An S2Cell always corresponds to a particular S2CellId. The other
// constructors are just convenience methods.
explicit S2Cell(S2CellId const& id) { Init(id); }
static S2Cell FromFacePosLevel(int face, uint64 pos, int level) {
// This is a static method in order to provide named parameters.
return S2Cell(S2CellId::FromFacePosLevel(face, pos, level));
}
// Convenience methods. The S2LatLng must be normalized.
explicit S2Cell(S2Point const& p) { Init(S2CellId::FromPoint(p)); }
explicit S2Cell(S2LatLng const& ll) { Init(S2CellId::FromLatLng(ll)); }
inline S2CellId id() const { return id_; }
inline int face() const { return face_; }
inline int level() const { return level_; }
inline int orientation() const { return orientation_; }
inline bool is_leaf() const { return level_ == S2CellId::kMaxLevel; }
// These are equivalent to the S2CellId methods, but have a more efficient
// implementation since the level has been precomputed.
int GetSizeIJ() const;
double GetSizeST() const;
// Return the k-th vertex of the cell (k = 0,1,2,3). Vertices are returned
// in CCW order. The points returned by GetVertexRaw are not necessarily
// unit length.
S2Point GetVertex(int k) const { return GetVertexRaw(k).Normalize(); }
S2Point GetVertexRaw(int k) const;
// Return the inward-facing normal of the great circle passing through
// the edge from vertex k to vertex k+1 (mod 4). The normals returned
// by GetEdgeRaw are not necessarily unit length.
S2Point GetEdge(int k) const { return GetEdgeRaw(k).Normalize(); }
S2Point GetEdgeRaw(int k) const;
// If this is not a leaf cell, set children[0..3] to the four children of
// this cell (in traversal order) and return true. Otherwise returns false.
// This method is equivalent to the following:
//
// for (pos=0, id=child_begin(); id != child_end(); id = id.next(), ++pos)
// children[i] = S2Cell(id);
//
// except that it is more than two times faster.
bool Subdivide(S2Cell children[4]) const;
// Return the direction vector corresponding to the center in (s,t)-space of
// the given cell. This is the point at which the cell is divided into four
// subcells; it is not necessarily the centroid of the cell in (u,v)-space
// or (x,y,z)-space. The point returned by GetCenterRaw is not necessarily
// unit length.
S2Point GetCenter() const { return GetCenterRaw().Normalize(); }
S2Point GetCenterRaw() const;
// Return the average area for cells at the given level.
static double AverageArea(int level);
// Return the average area of cells at this level. This is accurate to
// within a factor of 1.7 (for S2_QUADRATIC_PROJECTION) and is extremely
// cheap to compute.
double AverageArea() const { return AverageArea(level_); }
// Return the approximate area of this cell. This method is accurate to
// within 3% percent for all cell sizes and accurate to within 0.1% for
// cells at level 5 or higher (i.e. squares 350km to a side or smaller
// on the Earth's surface). It is moderately cheap to compute.
double ApproxArea() const;
// Return the area of this cell as accurately as possible. This method is
// more expensive but it is accurate to 6 digits of precision even for leaf
// cells (whose area is approximately 1e-18).
double ExactArea() const;
////////////////////////////////////////////////////////////////////////
// S2Region interface (see s2region.h for details):
virtual S2Cell* Clone() const;
virtual S2Cap GetCapBound() const;
virtual S2LatLngRect GetRectBound() const;
virtual bool Contains(S2Cell const& cell) const;
virtual bool MayIntersect(S2Cell const& cell) const;
virtual bool VirtualContainsPoint(S2Point const& p) const {
return Contains(p); // The same as Contains() below, just virtual.
}
// The point 'p' does not need to be normalized.
bool Contains(S2Point const& p) const;
virtual void Encode(Encoder* const encoder) const {
LOG(FATAL) << "Unimplemented";
}
virtual bool Decode(Decoder* const decoder) { return false; }
private:
// Internal method that does the actual work in the constructors.
void Init(S2CellId const& id);
// Return the latitude or longitude of the cell vertex given by (i,j),
// where "i" and "j" are either 0 or 1.
inline double GetLatitude(int i, int j) const;
inline double GetLongitude(int i, int j) const;
// This structure occupies 44 bytes plus one pointer for the vtable.
int8 face_;
int8 level_;
int8 orientation_;
S2CellId id_;
double uv_[2][2];
};
inline int S2Cell::GetSizeIJ() const {
return S2CellId::GetSizeIJ(level());
}
inline double S2Cell::GetSizeST() const {
return S2CellId::GetSizeST(level());
}
#endif // UTIL_GEOMETRY_S2CELL_H_