or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdcore-lookup.mdgeometry.mdglobal-functions.mdindex.md

core-lookup.mddocs/

0

# Core Timezone Lookup

1

2

Primary timezone determination classes providing both full-featured polygon-based precision checking and lightweight approximation modes. These classes form the foundation of timezonefinder's timezone lookup capabilities.

3

4

## Capabilities

5

6

### TimezoneFinder Class

7

8

Full-featured timezone finder with polygon-based precision checking. Uses precomputed shortcuts to reduce polygon testing while maintaining accuracy through precise point-in-polygon algorithms.

9

10

```python { .api }

11

class TimezoneFinder:

12

def __init__(self, bin_file_location: Optional[str] = None, in_memory: bool = False):

13

"""

14

Initialize TimezoneFinder instance.

15

16

Parameters:

17

- bin_file_location: Path to binary data files, None for package data

18

- in_memory: Whether to load coordinate data into memory for faster access

19

"""

20

21

def timezone_at(self, *, lng: float, lat: float) -> Optional[str]:

22

"""

23

Find timezone for given coordinates, including ocean timezones.

24

25

Parameters:

26

- lng: Longitude in degrees (-180.0 to 180.0)

27

- lat: Latitude in degrees (-90.0 to 90.0)

28

29

Returns:

30

- Timezone name (e.g., 'Europe/Berlin', 'Etc/GMT+5') or None

31

"""

32

33

def timezone_at_land(self, *, lng: float, lat: float) -> Optional[str]:

34

"""

35

Find land timezone only, excluding ocean timezones.

36

37

Parameters:

38

- lng: Longitude in degrees (-180.0 to 180.0)

39

- lat: Latitude in degrees (-90.0 to 90.0)

40

41

Returns:

42

- Land timezone name or None for ocean locations

43

"""

44

45

def unique_timezone_at(self, *, lng: float, lat: float) -> Optional[str]:

46

"""

47

Find timezone if unique within the shortcut area.

48

49

Parameters:

50

- lng: Longitude in degrees (-180.0 to 180.0)

51

- lat: Latitude in degrees (-90.0 to 90.0)

52

53

Returns:

54

- Timezone name if unique in area, None if multiple or no zones

55

"""

56

57

def certain_timezone_at(self, *, lng: float, lat: float) -> Optional[str]:

58

"""

59

Find timezone with exhaustive polygon checking.

60

61

Note: Less performant than timezone_at(), only useful for custom timezone data

62

with incomplete coverage.

63

64

Parameters:

65

- lng: Longitude in degrees (-180.0 to 180.0)

66

- lat: Latitude in degrees (-90.0 to 90.0)

67

68

Returns:

69

- Timezone name if point is certainly within a polygon, None otherwise

70

"""

71

```

72

73

#### Properties and Utility Methods

74

75

```python { .api }

76

@property

77

def nr_of_zones(self) -> int:

78

"""Number of timezones in the dataset."""

79

80

@property

81

def nr_of_polygons(self) -> int:

82

"""Number of boundary polygons in the dataset."""

83

84

@property

85

def nr_of_holes(self) -> int:

86

"""Number of hole polygons in the dataset."""

87

88

def zone_name_from_id(self, zone_id: int) -> str:

89

"""

90

Get timezone name from zone ID.

91

92

Parameters:

93

- zone_id: Zone identifier (0 to nr_of_zones-1)

94

95

Returns:

96

- Timezone name

97

98

Raises:

99

- ValueError: If zone_id is invalid

100

"""

101

102

def zone_id_of(self, boundary_id: int) -> int:

103

"""

104

Get the zone ID that a boundary polygon belongs to.

105

106

Parameters:

107

- boundary_id: ID of the boundary polygon

108

109

Returns:

110

- Zone ID (index in timezone_names)

111

112

Raises:

113

- ValueError: If zone_ids data is not available

114

"""

115

116

def zone_ids_of(self, boundary_ids: np.ndarray) -> np.ndarray:

117

"""

118

Get zone IDs for multiple boundary polygons.

119

120

Parameters:

121

- boundary_ids: Array of boundary polygon IDs

122

123

Returns:

124

- Array of corresponding zone IDs

125

"""

126

127

def zone_name_from_boundary_id(self, boundary_id: int) -> str:

128

"""

129

Get timezone name from boundary polygon ID.

130

131

Parameters:

132

- boundary_id: ID of the boundary polygon

133

134

Returns:

135

- Timezone name

136

"""

137

138

def coords_of(self, boundary_id: int = 0) -> np.ndarray:

139

"""

140

Get coordinates of a boundary polygon from the FlatBuffers collection.

141

142

Parameters:

143

- boundary_id: Index of the polygon (default: 0)

144

145

Returns:

146

- Array of coordinates

147

"""

148

149

def get_boundaries_in_shortcut(self, *, lng: float, lat: float) -> np.ndarray:

150

"""

151

Get boundary polygon IDs in the shortcut area for given coordinates.

152

153

Parameters:

154

- lng: Longitude in degrees (-180.0 to 180.0)

155

- lat: Latitude in degrees (-90.0 to 90.0)

156

157

Returns:

158

- Array of boundary polygon IDs

159

"""

160

161

def most_common_zone_id(self, *, lng: float, lat: float) -> Optional[int]:

162

"""

163

Get the most common zone ID in the shortcut area for given coordinates.

164

165

Note: Boundary polygons are sorted by zone, with zones having more polygon

166

coordinates coming last.

167

168

Parameters:

169

- lng: Longitude in degrees (-180.0 to 180.0)

170

- lat: Latitude in degrees (-90.0 to 90.0)

171

172

Returns:

173

- Most common zone ID or None if no polygons exist in shortcut

174

"""

175

176

def unique_zone_id(self, *, lng: float, lat: float) -> Optional[int]:

177

"""

178

Get unique zone ID in shortcut area if only one zone exists.

179

180

Parameters:

181

- lng: Longitude in degrees (-180.0 to 180.0)

182

- lat: Latitude in degrees (-90.0 to 90.0)

183

184

Returns:

185

- Unique zone ID or None if no polygons or multiple zones exist

186

"""

187

188

def inside_of_polygon(self, boundary_id: int, x: int, y: int) -> bool:

189

"""

190

Check if a point is inside a boundary polygon.

191

192

Note: Checks bounding boxes first for efficiency, then holes, then boundary.

193

194

Parameters:

195

- boundary_id: ID of the boundary polygon

196

- x: X-coordinate of the point

197

- y: Y-coordinate of the point

198

199

Returns:

200

- True if point is inside boundary polygon, False if outside or in hole

201

"""

202

203

@staticmethod

204

def using_numba() -> bool:

205

"""Check if Numba JIT compilation is being used."""

206

207

@staticmethod

208

def using_clang_pip() -> bool:

209

"""Check if compiled C point-in-polygon implementation is being used."""

210

```

211

212

### TimezoneFinderL Class

213

214

Lightweight timezone finder for fast approximations. Uses only precomputed shortcuts without polygon checking, providing the most common timezone in each area.

215

216

```python { .api }

217

class TimezoneFinderL:

218

def __init__(self, bin_file_location: Optional[Union[str, Path]] = None, in_memory: bool = False):

219

"""

220

Initialize TimezoneFinderL instance.

221

222

Note: Inherits constructor from AbstractTimezoneFinder.

223

224

Parameters:

225

- bin_file_location: Path to binary data files, None for package data

226

- in_memory: Ignored for TimezoneFinderL, exists for compatibility

227

"""

228

229

def timezone_at(self, *, lng: float, lat: float) -> Optional[str]:

230

"""

231

Instantly return the most common timezone in the shortcut area.

232

233

Note: 'Most common' means the zone with boundary polygons having the most

234

coordinates in the corresponding shortcut area.

235

236

Parameters:

237

- lng: Longitude in degrees (-180.0 to 180.0)

238

- lat: Latitude in degrees (-90.0 to 90.0)

239

240

Returns:

241

- Most common timezone name in area or None if no polygons exist

242

"""

243

244

def timezone_at_land(self, *, lng: float, lat: float) -> Optional[str]:

245

"""

246

Find land timezone only, excluding ocean timezones.

247

248

Inherited from AbstractTimezoneFinder. Returns None when an ocean

249

timezone would be matched.

250

251

Parameters:

252

- lng: Longitude in degrees (-180.0 to 180.0)

253

- lat: Latitude in degrees (-90.0 to 90.0)

254

255

Returns:

256

- Land timezone name or None for ocean locations

257

"""

258

```

259

260

## Usage Examples

261

262

### Basic Instance Usage

263

264

```python

265

from timezonefinder import TimezoneFinder

266

267

# Create instance

268

tf = TimezoneFinder()

269

270

# Single lookup

271

tz = tf.timezone_at(lng=13.358, lat=52.5061)

272

print(tz) # 'Europe/Berlin'

273

274

# Land timezone only

275

land_tz = tf.timezone_at_land(lng=0.0, lat=0.0)

276

print(land_tz) # None (ocean location)

277

```

278

279

### High-Performance Usage

280

281

```python

282

from timezonefinder import TimezoneFinder

283

284

# Load data into memory for faster repeated queries

285

tf = TimezoneFinder(in_memory=True)

286

287

# Check performance capabilities

288

print(f"Using Numba: {tf.using_numba()}")

289

print(f"Using C extension: {tf.using_clang_pip()}")

290

291

# Batch processing

292

coordinates = [

293

(13.358, 52.5061), # Berlin

294

(-74.0060, 40.7128), # New York

295

(139.6917, 35.6895) # Tokyo

296

]

297

298

for lng, lat in coordinates:

299

tz = tf.timezone_at(lng=lng, lat=lat)

300

print(f"({lat:.3f}, {lng:.3f}) -> {tz}")

301

```

302

303

### Lightweight Approximation

304

305

```python

306

from timezonefinder import TimezoneFinderL

307

308

# Fast approximation without polygon checking

309

tfl = TimezoneFinderL()

310

311

# Quick timezone suggestion

312

tz = tfl.timezone_at(lng=13.358, lat=52.5061)

313

print(tz) # 'Europe/Berlin' (most common in area)

314

```

315

316

### Thread-Safe Usage

317

318

```python

319

import threading

320

from timezonefinder import TimezoneFinder

321

322

def worker(coordinates, results, thread_id):

323

# Each thread gets its own instance

324

tf = TimezoneFinder(in_memory=True)

325

326

for i, (lng, lat) in enumerate(coordinates):

327

tz = tf.timezone_at(lng=lng, lat=lat)

328

results[thread_id][i] = tz

329

330

# Prepare data for multiple threads

331

all_coords = [(lng, lat) for lng in range(-180, 180, 10)

332

for lat in range(-90, 90, 10)]

333

334

threads = []

335

results = [{} for _ in range(4)]

336

337

# Split work across threads

338

chunk_size = len(all_coords) // 4

339

for i in range(4):

340

start = i * chunk_size

341

end = start + chunk_size if i < 3 else len(all_coords)

342

coords_chunk = all_coords[start:end]

343

344

thread = threading.Thread(

345

target=worker,

346

args=(coords_chunk, results, i)

347

)

348

threads.append(thread)

349

thread.start()

350

351

# Wait for completion

352

for thread in threads:

353

thread.join()

354

```