-
71.63%
Rate
-
149
Hits
-
59
Missed
- 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
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
-
-
-
-
-
- 1x
- 1x
- 1x
- 1x
- 1x
- 1x
- 1x
- 1x
-
- 1x
-
-
-
-
-
- 1x
-
-
- 1x
-
-
- 6x
-
-
-
-
-
-
- 6x
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 6x
- 6x
-
- 6x
-
-
-
-
-
-
- 6x
- 4x
- 4x
- 4x
- 4x
- 2x
-
- 2x
-
-
- 2x
-
-
-
-
- 13x
-
-
-
-
-
- 13x
- 68x
- 55x
- 55x
-
-
-
- 13x
-
-
- 1x
- 1x
-
- 1x
- 89x
- 5x
- 84x
- 13x
- 71x
- 6x
- 65x
- 34x
- 31x
- 31x
-
-
-
-
-
-
- 1x
- 2x
- 1x
-
-
-
-
- 1x
- 1x
-
- 1x
- 1x
-
-
-
- 1x
- 2x
- 1x
-
-
-
-
-
-
-
-
-
-
-
-
-
- 6x
- 12x
- 6x
-
- 6x
-
-
-
-
-
-
-
-
-
- 1x
-
- 1x
- 1x
-
-
-
-
-
-
-
-
-
- 4x
-
- 4x
- 4x
-
-
-
-
-
-
-
- 4x
-
-
-
- 36x
-
- 36x
-
- 36x
- 36x
- 15x
- 15x
-
-
-
-
- 15x
-
-
-
-
-
-
-
-
- 15x
- 15x
- 15x
- 15x
- 15x
- 15x
-
- 15x
-
-
-
-
- 15x
- 15x
- 21x
- 19x
-
-
-
-
- 19x
- 19x
- 19x
- 2x
- 6x
- 2x
- 1x
-
-
-
-
- 1x
-
- 2x
-
-
-
-
-
- 34x
-
- 34x
-
-
- 1x
-
-
-
-
-
-
- 1x
-
-
-
- 4x
-
- 6x
- 8x
-
-
- 2x
-
-
- 1x
-
- 1x
- 1x
-
-
-
- 1x
- 9x
-
-
-
-
- 1x
-
-
-
- 1x
- 3x
- 6x
-
-
- 1x
-
-
-
-
- 2x
-
-
-
-
- 3x
- 6x
- 3x
-
-
-
-
- 1x
-
-
-
-
- 1x
-
-
- 1x
- 1x
- 1x
-
- 1x
- 65x
- 60x
- 5x
- 1x
- 4x
- 1x
- 3x
- 2x
- 1x
- 1x
-
-
-
-
-
- 1x
-
-
-
-
-
-
-
-
-
- 1x
-
-
- 9x
- 9x
-
-
-
- 9x
- 9x
-
-
- 33x
- 23x
- 23x
- 2x
- 6x
- 21x
- 20x
- 40x
- 1x
- 2x
-
-
-
-
-
-
-
-
-
- 9x
-
- 9x
-
-
-
- 1x
-
-
-
-
-
-
- 1x
- -------------------------------------------------------------------------------
- -- Wrapper for topography data
- -- Author: Valentin Niess
- -- License: GNU LGPL-3.0
- -------------------------------------------------------------------------------
- local ffi = require('ffi')
- local lfs = require('lfs')
- local call = require('pumas.call')
- local clib = require('pumas.clib')
- local compat = require('pumas.compat')
- local error = require('pumas.error')
- local metatype = require('pumas.metatype')
- local type_ = require('pumas.coordinates.type')
-
- local topography = {}
-
-
- -------------------------------------------------------------------------------
- -- The topography data metatypes
- -------------------------------------------------------------------------------
- local TopographyData = {}
-
- do
- local pumas_geodetic_point_t = ffi.typeof('struct pumas_geodetic_point')
-
- local function elevation (self, x, y)
- if (self == nil) or (x == nil) then
- local args = {self, x, y}
- error.raise{
- fname = 'elevation', argnum = 'bad', expected = '2 or 3',
- got = #args}
- end
-
- if y == nil then
- local geodetic
- if ffi.istype(pumas_geodetic_point_t, x) then
- geodetic = x
- elseif (metatype(x) == 'Coordinates') or
- ffi.istype('double [3]', x) then
- geodetic = type_.GeodeticPoint():set(x)
- else
- error.raise{
- fname = 'elevation', argnum = 2,
- expected = 'a Coordinates ctype', got = metatype.a(x)}
- end
- x, y = geodetic.latitude, geodetic.longitude
- else
- local argnum, argval
- if type(x) ~= 'number' then argnum, argval = 2, x end
- if type(y) ~= 'number' then argnum, argval = 3, y end
-
- if argnum then
- error.raise{
- fname = 'elevation', argnum = argnum,
- expected = 'a number', got = metatype.a(argval)}
- end
- end
-
- if self._elevation then
- local z = ffi.new('double [1]')
- local inside = ffi.new('int [1]')
- call(self._elevation, self._c, x, y, z, inside)
- if inside[0] == 1 then
- return z[0] + self._offset
- else
- return nil
- end
- else
- return self._offset
- end
- end
-
- local function clone (self)
- if not self then
- error.raise{
- fname = 'clone', argnum = 1,
- expected = 'a TopographyData table', got = metatype.a(self)}
- end
-
- local new = {}
- for k, v in pairs(self) do
- if k ~= '_geometry' then
- new[k] = v
- end
- end
-
- return setmetatable(new, TopographyData)
- end
-
- error.register('TopographyData.__index.clone', clone)
- error.register('TopographyData.__index.elevation', elevation)
-
- function TopographyData:__index (k)
- if k == '__metatype' then
- return 'TopographyData'
- elseif k == 'clone' then
- return clone
- elseif k == 'elevation' then
- return elevation
- elseif k == 'offset' then
- return rawget(self, '_offset')
- elseif k == 'path' then
- return rawget(self, '_path')
- else
- error.raise{
- ['type'] = 'TopographyData', bad_member = k}
- end
- end
-
- function TopographyData:__newindex (k, v)
- if k == 'offset' then
- if type(v) ~= 'number' then
- error.raise{fname = 'offset', expected = 'a number',
- got = metatype.a(v)}
- end
-
- if v ~= self._offset then
- self._offset = v
-
- local geometry = rawget(self, '_geometry')
- if geometry then
- geometry:_invalidate()
- end
- end
- elseif (k == 'path') or (k == 'elevation') then
- error.raise{
- ['type'] = 'TopographyData', not_mutable = k}
- else
- error.raise{
- ['type'] = 'TopographyData', bad_member = k}
- end
- end
- end
-
-
- -------------------------------------------------------------------------------
- -- Addition and subtraction operators
- -------------------------------------------------------------------------------
- do
- local function add (t, v)
- if type(v) == 'number' then
- local c = t:clone()
- c._offset = c._offset + v
-
- return c
- else
- error.raise{
- fname = 'TopographyData.__add',
- expected = 'a number',
- got = metatype.a(v)
- }
- end
- end
-
- TopographyData.__add = add
-
- function TopographyData:__sub (v)
- return add(self, -v)
- end
- end
-
-
- -------------------------------------------------------------------------------
- -- The topography data constructor
- -------------------------------------------------------------------------------
- do
- local function map_elevation (self, x, y, z, inside)
- local projection = clib.turtle_map_projection(self)
-
- if projection == nil then
- x, y = y, x
- else
- local xmap = ffi.new('double [1]')
- local ymap = ffi.new('double [1]')
- clib.turtle_projection_project(projection, x, y, xmap, ymap)
- x, y = xmap[0], ymap[0]
- end
-
- return clib.turtle_map_elevation(self, x, y, z, inside)
- end
-
- local function new (cls, data, offset)
- if data == nil then data = 0 end
-
- local self = {}
- local c, ptr
- local data_type = metatype(data)
- if data_type == 'string' then
- local mode, errmsg = lfs.attributes(data, 'mode')
- if mode == nil then
- error.raise{
- fname = 'TopographyData',
- description = errmsg
- }
- elseif mode == 'directory' then
- ptr = ffi.new('struct turtle_stack *[1]')
- call(clib.turtle_stack_create, ptr, data, 0, nil, nil)
- c = ptr[0]
- ffi.gc(c, function () clib.turtle_stack_destroy(ptr) end)
- call(clib.turtle_stack_load, c)
- self._stepper_add = clib.turtle_stepper_add_stack
- self._elevation = clib.turtle_stack_elevation
- else
- ptr = ffi.new('struct turtle_map *[1]')
- call(clib.turtle_map_load, ptr, data)
- c = ptr[0]
- ffi.gc(c, function () clib.turtle_map_destroy(ptr) end)
- self._stepper_add = clib.turtle_stepper_add_map
- self._elevation = map_elevation
- end
- if offset and type(offset) ~= 'number' then
- error.raise{
- fname = 'TopographyData', argnum = 3,
- expected = ' a number', got = metatype.a(offset)}
- end
- self._offset = offset or 0
- self._path = data
- elseif data_type == 'number' then
- if offset then
- error.raise{
- fname = 'TopographyData', argnum = 'bad', expected = 1,
- got = 2}
- end
- self._offset = data
- self._stepper_add = clib.turtle_stepper_add_flat
- self._elevation = false
- elseif data_type == 'TopographyData' then
- self = data:clone()
- if offset then
- if type(offset) ~= 'number' then
- error.raise{
- fname = 'TopographyData', argnum = 3,
- expected = ' a number', got = metatype.a(offset)}
- end
- self._offset = offset
- end
- return self
- else
- error.raise{
- fname = 'TopographyData', argnum = 1,
- expected = 'a number or a string', got = metatype.a(data)}
- end
- self._c = c
-
- return setmetatable(self, cls)
- end
-
- topography.TopographyData = setmetatable(TopographyData, {__call = new})
- end
-
-
- -------------------------------------------------------------------------------
- -- Topography data set
- -------------------------------------------------------------------------------
- local TopographyDataset = {__index = {}}
-
- do
- local function add (self, t)
- local new = compat.table_new(#self, 0)
-
- for i, v in ipairs(self._set) do
- new[i] = v + t
- end
-
- return setmetatable({_set = new}, TopographyDataset)
- end
-
- TopographyDataset.__add = add
-
- function TopographyDataset:__sub (t)
- return add(self, -t)
- end
- end
-
- function TopographyDataset:__len ()
- return #self._set
- end
-
- do
- local function clone (self)
- if not self then
- error.raise{fname = 'clone', argnum = 1,
- expected = 'a TopographyDataset table', got = metatype.a(self)}
- else
- local new = {}
- for k, v in pairs(self._set) do
- new[k] = v:clone()
- end
-
- return setmetatable({_set = new}, TopographyDataset)
- end
- end
-
- local function elevation (self, x, y)
- if not self then
- error.raise{fname = 'elevation', argnum = 1,
- expected = 'a TopographyDataset', got = metatype.a(self)}
- end
-
- for _, v in ipairs(self._set) do
- local z = v:elevation(x, y)
- if z then return z end
- end
- end
-
- local function ipairs_ (self)
- if not self then
- error.raise{fname = 'ipairs', argnum = 1,
- expected = 'a TopographyDataset', got = metatype.a(self)}
- end
-
- return ipairs(self._set)
- end
-
- error.register('TopographyDataset.__index.clone', clone)
- error.register('TopographyDataset.__index.elevation', elevation)
- error.register('TopographyDataset.__index.ipairs', ipairs_)
-
- function TopographyDataset:__index (k)
- if type(k) == 'number' then
- return self._set[k]
- elseif k == '__metatype' then
- return 'TopographyDataset'
- elseif k == 'clone' then
- return clone
- elseif k == 'elevation' then
- return elevation
- elseif k == 'ipairs' then
- return ipairs_
- else
- error.raise{['type'] = 'TopographyDataset', bad_member = k}
- end
- end
-
- function TopographyDataset.__newindex (_, k)
- if (type(k) == 'number') or (k == 'clone') or (k == 'elevation') then
- error.raise{['type'] = 'TopographyDataset', not_mutable = k}
- else
- error.raise{['type'] = 'TopographyDataset', bad_member = k}
- end
- end
- end
-
- do
- local raise_error = error.ErrorFunction{fname = 'TopographyDataset'}
-
- local function new (cls, ...)
- local nargs = select('#', ...)
- if nargs == 0 then
- raise_error{argnum = 'bad', expected = '1 or more', got = 0}
- end
-
- local set = compat.table_new(nargs, 0)
- local iarg = 0
-
- local function add (args, index)
- for i, arg in ipairs(args) do
- local mt = metatype(arg)
- if mt == 'TopographyData' then
- iarg = iarg + 1
- set[iarg] = arg:clone()
- elseif (mt == 'string') or (mt == 'number') then
- iarg = iarg + 1
- set[iarg] = TopographyData(arg)
- elseif mt == 'table' then
- add(arg, index or i)
- else
- raise_error{argnum = index or i,
- expected = 'a (TopographyData) table, a string or \z
- a number',
- got = metatype.a(arg)}
- end
- end
- end
-
- add({...})
-
- return setmetatable({_set = set}, cls)
- end
-
- topography.TopographyDataset =
- setmetatable(TopographyDataset, {__call = new})
- end
-
-
- -------------------------------------------------------------------------------
- -- Return the package
- -------------------------------------------------------------------------------
- return topography