yirgacheffe 1.6.1__py3-none-any.whl → 1.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of yirgacheffe might be problematic. Click here for more details.
- yirgacheffe/__init__.py +9 -2
- yirgacheffe/_core.py +10 -12
- yirgacheffe/layers/area.py +4 -4
- yirgacheffe/layers/base.py +99 -62
- yirgacheffe/layers/constant.py +3 -3
- yirgacheffe/layers/group.py +5 -7
- yirgacheffe/layers/h3layer.py +17 -17
- yirgacheffe/layers/rasters.py +14 -15
- yirgacheffe/layers/rescaled.py +12 -9
- yirgacheffe/layers/vectors.py +126 -45
- yirgacheffe/operators.py +152 -39
- yirgacheffe/window.py +41 -0
- {yirgacheffe-1.6.1.dist-info → yirgacheffe-1.7.0.dist-info}/METADATA +11 -9
- yirgacheffe-1.7.0.dist-info/RECORD +25 -0
- yirgacheffe-1.6.1.dist-info/RECORD +0 -25
- {yirgacheffe-1.6.1.dist-info → yirgacheffe-1.7.0.dist-info}/WHEEL +0 -0
- {yirgacheffe-1.6.1.dist-info → yirgacheffe-1.7.0.dist-info}/entry_points.txt +0 -0
- {yirgacheffe-1.6.1.dist-info → yirgacheffe-1.7.0.dist-info}/licenses/LICENSE +0 -0
- {yirgacheffe-1.6.1.dist-info → yirgacheffe-1.7.0.dist-info}/top_level.txt +0 -0
yirgacheffe/operators.py
CHANGED
|
@@ -12,14 +12,15 @@ from multiprocessing.managers import SharedMemoryManager
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from typing import Callable, Dict, Optional, Union
|
|
14
14
|
|
|
15
|
+
import deprecation
|
|
15
16
|
import numpy as np
|
|
16
17
|
import numpy.typing as npt
|
|
17
18
|
from osgeo import gdal
|
|
18
19
|
from dill import dumps, loads # type: ignore
|
|
19
20
|
|
|
20
|
-
from . import constants
|
|
21
|
-
from .rounding import
|
|
22
|
-
from .window import Area, PixelScale, Window
|
|
21
|
+
from . import constants, __version__
|
|
22
|
+
from .rounding import round_up_pixels, round_down_pixels
|
|
23
|
+
from .window import Area, PixelScale, MapProjection, Window
|
|
23
24
|
from ._backends import backend
|
|
24
25
|
from ._backends.enumeration import operators as op
|
|
25
26
|
from ._backends.enumeration import dtype as DataType
|
|
@@ -38,14 +39,17 @@ class LayerConstant:
|
|
|
38
39
|
def __init__(self, val):
|
|
39
40
|
self.val = val
|
|
40
41
|
|
|
41
|
-
def __str__(self):
|
|
42
|
+
def __str__(self) -> str:
|
|
42
43
|
return str(self.val)
|
|
43
44
|
|
|
44
|
-
def _eval(self, _area, _index, _step, _target_window):
|
|
45
|
+
def _eval(self, _area, _projection, _index, _step, _target_window):
|
|
45
46
|
return self.val
|
|
46
47
|
|
|
47
48
|
@property
|
|
48
|
-
def area(self):
|
|
49
|
+
def area(self) -> Area:
|
|
50
|
+
return Area.world()
|
|
51
|
+
|
|
52
|
+
def _get_operation_area(self, _projection) -> Area:
|
|
49
53
|
return Area.world()
|
|
50
54
|
|
|
51
55
|
class LayerMathMixin:
|
|
@@ -95,12 +99,26 @@ class LayerMathMixin:
|
|
|
95
99
|
def __or__(self, other):
|
|
96
100
|
return LayerOperation(self, op.OR, other, window_op=WindowOperation.UNION)
|
|
97
101
|
|
|
98
|
-
def _eval(
|
|
102
|
+
def _eval(
|
|
103
|
+
self,
|
|
104
|
+
area,
|
|
105
|
+
projection,
|
|
106
|
+
index,
|
|
107
|
+
step,
|
|
108
|
+
target_window=None
|
|
109
|
+
):
|
|
99
110
|
try:
|
|
100
111
|
window = self.window if target_window is None else target_window
|
|
101
|
-
return self._read_array_for_area(area, 0, index, window.xsize, step)
|
|
112
|
+
return self._read_array_for_area(area, projection, 0, index, window.xsize, step)
|
|
102
113
|
except AttributeError:
|
|
103
|
-
return self._read_array_for_area(
|
|
114
|
+
return self._read_array_for_area(
|
|
115
|
+
area,
|
|
116
|
+
projection,
|
|
117
|
+
0,
|
|
118
|
+
index,
|
|
119
|
+
target_window.xsize if target_window else 1,
|
|
120
|
+
step
|
|
121
|
+
)
|
|
104
122
|
|
|
105
123
|
def nan_to_num(self, nan=0, posinf=None, neginf=None):
|
|
106
124
|
return LayerOperation(
|
|
@@ -314,7 +332,7 @@ class LayerOperation(LayerMathMixin):
|
|
|
314
332
|
else:
|
|
315
333
|
raise ValueError("Numpy arrays are no allowed")
|
|
316
334
|
else:
|
|
317
|
-
if not
|
|
335
|
+
if not lhs.map_projection == rhs.map_projection:
|
|
318
336
|
raise ValueError("Not all layers are at the same pixel scale")
|
|
319
337
|
self.rhs = rhs
|
|
320
338
|
else:
|
|
@@ -329,7 +347,7 @@ class LayerOperation(LayerMathMixin):
|
|
|
329
347
|
else:
|
|
330
348
|
raise ValueError("Numpy arrays are no allowed")
|
|
331
349
|
else:
|
|
332
|
-
if not
|
|
350
|
+
if not lhs.map_projection == other.map_projection:
|
|
333
351
|
raise ValueError("Not all layers are at the same pixel scale")
|
|
334
352
|
self.other = other
|
|
335
353
|
else:
|
|
@@ -403,7 +421,56 @@ class LayerOperation(LayerMathMixin):
|
|
|
403
421
|
case _:
|
|
404
422
|
assert False, "Should not be reached"
|
|
405
423
|
|
|
424
|
+
def _get_operation_area(self, projection: Optional[MapProjection]) -> Area:
|
|
425
|
+
|
|
426
|
+
# The type().__name__ here is to avoid a circular import dependancy
|
|
427
|
+
lhs_area = self.lhs._get_operation_area(projection)
|
|
428
|
+
try:
|
|
429
|
+
rhs_area = self.rhs._get_operation_area(projection)
|
|
430
|
+
except AttributeError:
|
|
431
|
+
rhs_area = None
|
|
432
|
+
try:
|
|
433
|
+
other_area = self.other._get_operation_area(projection)
|
|
434
|
+
except AttributeError:
|
|
435
|
+
other_area = None
|
|
436
|
+
|
|
437
|
+
all_areas = [x for x in [lhs_area, rhs_area, other_area] if (x is not None) and (not x.is_world)]
|
|
438
|
+
|
|
439
|
+
match self.window_op:
|
|
440
|
+
case WindowOperation.NONE:
|
|
441
|
+
return all_areas[0]
|
|
442
|
+
case WindowOperation.LEFT:
|
|
443
|
+
return lhs_area
|
|
444
|
+
case WindowOperation.RIGHT:
|
|
445
|
+
assert rhs_area is not None
|
|
446
|
+
return rhs_area
|
|
447
|
+
case WindowOperation.INTERSECTION:
|
|
448
|
+
intersection = Area(
|
|
449
|
+
left=max(x.left for x in all_areas),
|
|
450
|
+
top=min(x.top for x in all_areas),
|
|
451
|
+
right=min(x.right for x in all_areas),
|
|
452
|
+
bottom=max(x.bottom for x in all_areas)
|
|
453
|
+
)
|
|
454
|
+
if (intersection.left >= intersection.right) or (intersection.bottom >= intersection.top):
|
|
455
|
+
raise ValueError('No intersection possible')
|
|
456
|
+
return intersection
|
|
457
|
+
case WindowOperation.UNION:
|
|
458
|
+
return Area(
|
|
459
|
+
left=min(x.left for x in all_areas),
|
|
460
|
+
top=max(x.top for x in all_areas),
|
|
461
|
+
right=max(x.right for x in all_areas),
|
|
462
|
+
bottom=min(x.bottom for x in all_areas)
|
|
463
|
+
)
|
|
464
|
+
case _:
|
|
465
|
+
assert False, "Should not be reached"
|
|
466
|
+
|
|
406
467
|
@property
|
|
468
|
+
@deprecation.deprecated(
|
|
469
|
+
deprecated_in="1.7",
|
|
470
|
+
removed_in="2.0",
|
|
471
|
+
current_version=__version__,
|
|
472
|
+
details="Use `map_projection` instead."
|
|
473
|
+
)
|
|
407
474
|
def pixel_scale(self) -> PixelScale:
|
|
408
475
|
# Because we test at construction that pixel scales for RHS/other are roughly equal,
|
|
409
476
|
# I believe this should be sufficient...
|
|
@@ -418,19 +485,22 @@ class LayerOperation(LayerMathMixin):
|
|
|
418
485
|
|
|
419
486
|
@property
|
|
420
487
|
def window(self) -> Window:
|
|
421
|
-
|
|
422
|
-
|
|
488
|
+
projection = self.map_projection
|
|
489
|
+
if projection is None:
|
|
490
|
+
# This can happen if your source layers are say just constants
|
|
491
|
+
raise AttributeError("No window without projection")
|
|
492
|
+
area = self._get_operation_area(projection)
|
|
423
493
|
assert area is not None
|
|
424
494
|
|
|
425
495
|
return Window(
|
|
426
|
-
xoff=round_down_pixels(area.left /
|
|
427
|
-
yoff=round_down_pixels(area.top / (
|
|
496
|
+
xoff=round_down_pixels(area.left / projection.xstep, projection.xstep),
|
|
497
|
+
yoff=round_down_pixels(area.top / (projection.ystep * -1.0), projection.ystep * -1.0),
|
|
428
498
|
xsize=round_up_pixels(
|
|
429
|
-
(area.right - area.left) /
|
|
499
|
+
(area.right - area.left) / projection.xstep, projection.xstep
|
|
430
500
|
),
|
|
431
501
|
ysize=round_up_pixels(
|
|
432
|
-
(area.top - area.bottom) / (
|
|
433
|
-
(
|
|
502
|
+
(area.top - area.bottom) / (projection.ystep * -1.0),
|
|
503
|
+
(projection.ystep * -1.0)
|
|
434
504
|
),
|
|
435
505
|
)
|
|
436
506
|
|
|
@@ -440,23 +510,53 @@ class LayerOperation(LayerMathMixin):
|
|
|
440
510
|
return self.lhs.datatype
|
|
441
511
|
|
|
442
512
|
@property
|
|
513
|
+
@deprecation.deprecated(
|
|
514
|
+
deprecated_in="1.7",
|
|
515
|
+
removed_in="2.0",
|
|
516
|
+
current_version=__version__,
|
|
517
|
+
details="Use `map_projection` instead."
|
|
518
|
+
)
|
|
443
519
|
def projection(self):
|
|
444
520
|
try:
|
|
445
|
-
|
|
521
|
+
projection = self.lhs.projection
|
|
446
522
|
except AttributeError:
|
|
447
|
-
|
|
523
|
+
projection = None
|
|
448
524
|
|
|
449
|
-
|
|
525
|
+
if projection is None:
|
|
526
|
+
projection = self.rhs.projection
|
|
527
|
+
return projection
|
|
528
|
+
|
|
529
|
+
@property
|
|
530
|
+
def map_projection(self) -> Optional[MapProjection]:
|
|
531
|
+
try:
|
|
532
|
+
projection = self.lhs.map_projection
|
|
533
|
+
except AttributeError:
|
|
534
|
+
projection = None
|
|
535
|
+
|
|
536
|
+
if projection is None:
|
|
537
|
+
try:
|
|
538
|
+
projection = self.rhs.map_projection
|
|
539
|
+
except AttributeError:
|
|
540
|
+
pass
|
|
541
|
+
return projection
|
|
542
|
+
|
|
543
|
+
def _eval(
|
|
544
|
+
self,
|
|
545
|
+
area: Area,
|
|
546
|
+
projection: MapProjection,
|
|
547
|
+
index: int,
|
|
548
|
+
step: int,
|
|
549
|
+
target_window:Optional[Window]=None
|
|
550
|
+
):
|
|
450
551
|
|
|
451
552
|
if self.buffer_padding:
|
|
452
553
|
if target_window:
|
|
453
554
|
target_window = target_window.grow(self.buffer_padding)
|
|
454
|
-
|
|
455
|
-
area = area.grow(self.buffer_padding * pixel_scale.xstep)
|
|
555
|
+
area = area.grow(self.buffer_padding * projection.xstep)
|
|
456
556
|
# The index doesn't need updating because we updated area/window
|
|
457
557
|
step += (2 * self.buffer_padding)
|
|
458
558
|
|
|
459
|
-
lhs_data = self.lhs._eval(area, index, step, target_window)
|
|
559
|
+
lhs_data = self.lhs._eval(area, projection, index, step, target_window)
|
|
460
560
|
|
|
461
561
|
if self.operator is None:
|
|
462
562
|
return lhs_data
|
|
@@ -469,12 +569,12 @@ class LayerOperation(LayerMathMixin):
|
|
|
469
569
|
|
|
470
570
|
if self.other is not None:
|
|
471
571
|
assert self.rhs is not None
|
|
472
|
-
rhs_data = self.rhs._eval(area, index, step, target_window)
|
|
473
|
-
other_data = self.other._eval(area, index, step, target_window)
|
|
572
|
+
rhs_data = self.rhs._eval(area, projection, index, step, target_window)
|
|
573
|
+
other_data = self.other._eval(area, projection, index, step, target_window)
|
|
474
574
|
return operator(lhs_data, rhs_data, other_data, **self.kwargs)
|
|
475
575
|
|
|
476
576
|
if self.rhs is not None:
|
|
477
|
-
rhs_data = self.rhs._eval(area, index, step, target_window)
|
|
577
|
+
rhs_data = self.rhs._eval(area, projection, index, step, target_window)
|
|
478
578
|
return operator(lhs_data, rhs_data, **self.kwargs)
|
|
479
579
|
|
|
480
580
|
return operator(lhs_data, **self.kwargs)
|
|
@@ -486,22 +586,24 @@ class LayerOperation(LayerMathMixin):
|
|
|
486
586
|
# of the sum are done in different types.
|
|
487
587
|
res = 0.0
|
|
488
588
|
computation_window = self.window
|
|
589
|
+
projection = self.map_projection
|
|
489
590
|
for yoffset in range(0, computation_window.ysize, self.ystep):
|
|
490
591
|
step=self.ystep
|
|
491
592
|
if yoffset+step > computation_window.ysize:
|
|
492
593
|
step = computation_window.ysize - yoffset
|
|
493
|
-
chunk = self._eval(self.
|
|
594
|
+
chunk = self._eval(self._get_operation_area(projection), projection, yoffset, step, computation_window)
|
|
494
595
|
res += backend.sum_op(chunk)
|
|
495
596
|
return res
|
|
496
597
|
|
|
497
598
|
def min(self):
|
|
498
599
|
res = None
|
|
499
600
|
computation_window = self.window
|
|
601
|
+
projection = self.map_projection
|
|
500
602
|
for yoffset in range(0, computation_window.ysize, self.ystep):
|
|
501
603
|
step=self.ystep
|
|
502
604
|
if yoffset+step > computation_window.ysize:
|
|
503
605
|
step = computation_window.ysize - yoffset
|
|
504
|
-
chunk = self._eval(self.
|
|
606
|
+
chunk = self._eval(self._get_operation_area(projection), projection, yoffset, step, computation_window)
|
|
505
607
|
chunk_min = backend.min_op(chunk)
|
|
506
608
|
if (res is None) or (res > chunk_min):
|
|
507
609
|
res = chunk_min
|
|
@@ -510,11 +612,12 @@ class LayerOperation(LayerMathMixin):
|
|
|
510
612
|
def max(self):
|
|
511
613
|
res = None
|
|
512
614
|
computation_window = self.window
|
|
615
|
+
projection = self.map_projection
|
|
513
616
|
for yoffset in range(0, computation_window.ysize, self.ystep):
|
|
514
617
|
step=self.ystep
|
|
515
618
|
if yoffset+step > computation_window.ysize:
|
|
516
619
|
step = computation_window.ysize - yoffset
|
|
517
|
-
chunk = self._eval(self.
|
|
620
|
+
chunk = self._eval(self._get_operation_area(projection), projection, yoffset, step, computation_window)
|
|
518
621
|
chunk_max = backend.max_op(chunk)
|
|
519
622
|
if (res is None) or (chunk_max > res):
|
|
520
623
|
res = chunk_max
|
|
@@ -533,14 +636,24 @@ class LayerOperation(LayerMathMixin):
|
|
|
533
636
|
except AttributeError as exc:
|
|
534
637
|
raise ValueError("Layer must be a raster backed layer") from exc
|
|
535
638
|
|
|
639
|
+
projection = self.map_projection
|
|
640
|
+
|
|
536
641
|
destination_window = destination_layer.window
|
|
642
|
+
destination_projection = destination_layer.map_projection
|
|
643
|
+
assert destination_projection is not None
|
|
644
|
+
|
|
645
|
+
if projection is None:
|
|
646
|
+
projection = destination_projection
|
|
647
|
+
else:
|
|
648
|
+
if projection != destination_projection:
|
|
649
|
+
raise ValueError("Destination layer and input layers have different projection/scale")
|
|
537
650
|
|
|
538
651
|
# If we're calculating purely from a constant layer, then we don't have a window or area
|
|
539
652
|
# so we should use the destination raster details.
|
|
540
653
|
try:
|
|
541
654
|
computation_window = self.window
|
|
542
|
-
computation_area = self.
|
|
543
|
-
except AttributeError:
|
|
655
|
+
computation_area = self._get_operation_area(projection)
|
|
656
|
+
except (AttributeError, IndexError):
|
|
544
657
|
computation_window = destination_window
|
|
545
658
|
computation_area = destination_layer.area
|
|
546
659
|
|
|
@@ -556,7 +669,7 @@ class LayerOperation(LayerMathMixin):
|
|
|
556
669
|
step=self.ystep
|
|
557
670
|
if yoffset+step > computation_window.ysize:
|
|
558
671
|
step = computation_window.ysize - yoffset
|
|
559
|
-
chunk = self._eval(computation_area, yoffset, step, computation_window)
|
|
672
|
+
chunk = self._eval(computation_area, projection, yoffset, step, computation_window)
|
|
560
673
|
if isinstance(chunk, (float, int)):
|
|
561
674
|
chunk = backend.full((step, destination_window.xsize), chunk)
|
|
562
675
|
band.WriteArray(
|
|
@@ -573,7 +686,7 @@ class LayerOperation(LayerMathMixin):
|
|
|
573
686
|
|
|
574
687
|
def _parallel_worker(self, index, shared_mem, sem, np_dtype, width, input_queue, output_queue, computation_window):
|
|
575
688
|
arr = np.ndarray((self.ystep, width), dtype=np_dtype, buffer=shared_mem.buf)
|
|
576
|
-
|
|
689
|
+
projection = self.map_projection
|
|
577
690
|
try:
|
|
578
691
|
while True:
|
|
579
692
|
# We acquire the lock so we know we have somewhere to put the
|
|
@@ -591,7 +704,7 @@ class LayerOperation(LayerMathMixin):
|
|
|
591
704
|
break
|
|
592
705
|
yoffset, step = task
|
|
593
706
|
|
|
594
|
-
result = self._eval(self.
|
|
707
|
+
result = self._eval(self._get_operation_area(projection), projection, yoffset, step, computation_window)
|
|
595
708
|
backend.eval_op(result)
|
|
596
709
|
|
|
597
710
|
arr[:step] = backend.demote_array(result)
|
|
@@ -628,7 +741,7 @@ class LayerOperation(LayerMathMixin):
|
|
|
628
741
|
assert (destination_layer is not None) or and_sum
|
|
629
742
|
try:
|
|
630
743
|
computation_window = self.window
|
|
631
|
-
except AttributeError:
|
|
744
|
+
except (AttributeError, IndexError):
|
|
632
745
|
# This is most likely because the calculation is on a constant layer (or combination of only constant
|
|
633
746
|
# layers) and there's no real benefit to parallel saving then, so to keep this code from getting yet
|
|
634
747
|
# more complicated just fall back to the single threaded path
|
|
@@ -828,12 +941,12 @@ class LayerOperation(LayerMathMixin):
|
|
|
828
941
|
|
|
829
942
|
class ShaderStyleOperation(LayerOperation):
|
|
830
943
|
|
|
831
|
-
def _eval(self, area, index, step, target_window=None):
|
|
944
|
+
def _eval(self, area, projection, index, step, target_window=None):
|
|
832
945
|
if target_window is None:
|
|
833
946
|
target_window = self.window
|
|
834
|
-
lhs_data = self.lhs._eval(area, index, step, target_window)
|
|
947
|
+
lhs_data = self.lhs._eval(area, projection, index, step, target_window)
|
|
835
948
|
if self.rhs is not None:
|
|
836
|
-
rhs_data = self.rhs._eval(area, index, step, target_window)
|
|
949
|
+
rhs_data = self.rhs._eval(area, projection, index, step, target_window)
|
|
837
950
|
else:
|
|
838
951
|
rhs_data = None
|
|
839
952
|
|
yirgacheffe/window.py
CHANGED
|
@@ -7,6 +7,47 @@ from typing import List, Optional, Tuple
|
|
|
7
7
|
|
|
8
8
|
PixelScale = namedtuple('PixelScale', ['xstep', 'ystep'])
|
|
9
9
|
|
|
10
|
+
@dataclass
|
|
11
|
+
class MapProjection:
|
|
12
|
+
"""Records the map projection and the size of the pixels in a layer.
|
|
13
|
+
|
|
14
|
+
This superceeeds the old PixelScale class, which will be removed in version 2.0.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
name : str
|
|
19
|
+
The map projection used.
|
|
20
|
+
xstep : float
|
|
21
|
+
The number of units horizontal distance a step of one pixel makes in the map projection.
|
|
22
|
+
ystep : float
|
|
23
|
+
The number of units verticle distance a step of one pixel makes in the map projection.
|
|
24
|
+
|
|
25
|
+
Attributes
|
|
26
|
+
----------
|
|
27
|
+
name : str
|
|
28
|
+
The map projection used.
|
|
29
|
+
xstep : float
|
|
30
|
+
The number of units horizontal distance a step of one pixel makes in the map projection.
|
|
31
|
+
ystep : float
|
|
32
|
+
The number of units verticle distance a step of one pixel makes in the map projection.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
name : str
|
|
36
|
+
xstep : float
|
|
37
|
+
ystep : float
|
|
38
|
+
|
|
39
|
+
def __eq__(self, other) -> bool:
|
|
40
|
+
if other is None:
|
|
41
|
+
return True
|
|
42
|
+
# to avoid circular dependancies
|
|
43
|
+
from .rounding import are_pixel_scales_equal_enough # pylint: disable=C0415
|
|
44
|
+
return (self.name == other.name) and \
|
|
45
|
+
are_pixel_scales_equal_enough([self.scale, other.scale])
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def scale(self) -> PixelScale:
|
|
49
|
+
return PixelScale(self.xstep, self.ystep)
|
|
50
|
+
|
|
10
51
|
@dataclass
|
|
11
52
|
class Area:
|
|
12
53
|
"""Class to hold a geospatial area of data in the given projection.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: yirgacheffe
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.0
|
|
4
4
|
Summary: Abstraction of gdal datasets for doing basic math operations
|
|
5
5
|
Author-email: Michael Dales <mwd24@cam.ac.uk>
|
|
6
6
|
License-Expression: ISC
|
|
@@ -14,6 +14,8 @@ Requires-Dist: gdal[numpy]
|
|
|
14
14
|
Requires-Dist: scikit-image
|
|
15
15
|
Requires-Dist: torch
|
|
16
16
|
Requires-Dist: dill
|
|
17
|
+
Requires-Dist: deprecation
|
|
18
|
+
Requires-Dist: tomli
|
|
17
19
|
Provides-Extra: dev
|
|
18
20
|
Requires-Dist: mypy; extra == "dev"
|
|
19
21
|
Requires-Dist: pylint; extra == "dev"
|
|
@@ -57,7 +59,7 @@ import yirgaceffe as yg
|
|
|
57
59
|
|
|
58
60
|
habitat_map = yg.read_raster("habitats.tif")
|
|
59
61
|
elevation_map = yg.read_raster('elevation.tif')
|
|
60
|
-
range_polygon = yg.
|
|
62
|
+
range_polygon = yg.read_shape('species123.geojson')
|
|
61
63
|
area_per_pixel_map = yg.read_raster('area_per_pixel.tif')
|
|
62
64
|
|
|
63
65
|
refined_habitat = habitat_map.isin([...species habitat codes...])
|
|
@@ -177,22 +179,22 @@ with VectorLayer.layer_from_file('range.gpkg', PixelScale(0.001, -0.001), WGS_84
|
|
|
177
179
|
...
|
|
178
180
|
```
|
|
179
181
|
|
|
180
|
-
The new 2.0 way of doing this is:
|
|
182
|
+
The new 2.0 way of doing this is, if you plan to use the vector layer in calculation with other raster layers that will have projection information:
|
|
181
183
|
|
|
182
184
|
```python
|
|
183
185
|
import yirgacheffe as yg
|
|
184
186
|
|
|
185
|
-
with yg.read_shape('range.gpkg'
|
|
187
|
+
with yg.read_shape('range.gpkg') as layer:
|
|
186
188
|
...
|
|
187
189
|
```
|
|
188
190
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
+
Of if you plan to use the layer on its own and want to specify a rasterisation projection you can do:
|
|
191
192
|
|
|
192
193
|
```python
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
194
|
+
import yirgacheffe as yg
|
|
195
|
+
|
|
196
|
+
with yg.read_shape('range.gpkg', (yg.WGS_84_PROJECTION, (0.001, -0.001))) as layer:
|
|
197
|
+
...
|
|
196
198
|
```
|
|
197
199
|
|
|
198
200
|
### GroupLayer
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
yirgacheffe/__init__.py,sha256=flTXNQQs6k8nboEv9O4eJnlv8kZ11z5zrfWcmUovCLg,537
|
|
2
|
+
yirgacheffe/_core.py,sha256=SjdIqNlIpePo2Ea5A88aqg1WSmqcmrqORRExBPuR-S0,4191
|
|
3
|
+
yirgacheffe/constants.py,sha256=uCWJwec3-ND-zVxYbsk1sdHKANl3ToNCTPg7MZb0j2g,434
|
|
4
|
+
yirgacheffe/operators.py,sha256=fqk61NW_BjNuuBVPx_nvxPbgBs839cx6WztGOxrtiuE,35653
|
|
5
|
+
yirgacheffe/rounding.py,sha256=ggBG4lMyLMtHLW3dBxr3gBCcF2qhRrY5etZiFGlIoqA,2258
|
|
6
|
+
yirgacheffe/window.py,sha256=0Wy3BT4SZLyviDwzLcX8LYOo2MeZ2zXCWAiJNpMbQpc,9505
|
|
7
|
+
yirgacheffe/_backends/__init__.py,sha256=jN-2iRrHStnPI6cNL7XhwhsROtI0EaGfIrbF5c-ECV0,334
|
|
8
|
+
yirgacheffe/_backends/enumeration.py,sha256=pADawllxpW_hW-IVVvZpHWIKzvEMs9aaqfkZRD1zjnY,1003
|
|
9
|
+
yirgacheffe/_backends/mlx.py,sha256=2vOTMqHbQbeqt81Eq_8hxWDXZHaPsDpbXkALRVGEnnw,6130
|
|
10
|
+
yirgacheffe/_backends/numpy.py,sha256=cYO628s4-5K_-Bp3CrnHegzYSZfkt2QC8iE9oOOMtvA,4069
|
|
11
|
+
yirgacheffe/layers/__init__.py,sha256=mYKjw5YTcMNv_hMy7a6K4yRzIuNUbR8WuBTw4WIAmSk,435
|
|
12
|
+
yirgacheffe/layers/area.py,sha256=OFOM1_dMblzXLW29TwEqfdgSecl6aNs04bKJwUydLH0,3914
|
|
13
|
+
yirgacheffe/layers/base.py,sha256=VCqN6oykGeS68IvKZ7my7otZo1lJpymAasIyw_zXY6E,14143
|
|
14
|
+
yirgacheffe/layers/constant.py,sha256=XQ1ibeSckAcUOow-dMUlZiW5S2MKeFquOz_m8Y027GI,1437
|
|
15
|
+
yirgacheffe/layers/group.py,sha256=tSkyJK6sp8VFxB8ieA3hzEeKLkP6cjW6iIOSLmdbL6c,16088
|
|
16
|
+
yirgacheffe/layers/h3layer.py,sha256=Ys6F-e4Jre7lbFBYErF_4oidQx22WkWMKpHpQ7pPDTs,9875
|
|
17
|
+
yirgacheffe/layers/rasters.py,sha256=-yECyz3Odhy1er0ilJ9bfLUseI2cTHfwqhP-H3ImUKo,13365
|
|
18
|
+
yirgacheffe/layers/rescaled.py,sha256=hkvsd7paDCyUViABxrAXdXPOZegdwiphibkdrBuRclk,3366
|
|
19
|
+
yirgacheffe/layers/vectors.py,sha256=40XAgOAmkxY1liGizwgAaeVtYJYdkFCysh9HvzvmNOU,19731
|
|
20
|
+
yirgacheffe-1.7.0.dist-info/licenses/LICENSE,sha256=dNSHwUCJr6axStTKDEdnJtfmDdFqlE3h1NPCveqPfnY,757
|
|
21
|
+
yirgacheffe-1.7.0.dist-info/METADATA,sha256=DORzQDxIzC2lFGZki3xHzOdiCwzTOxJaWIBVjhso6_g,22351
|
|
22
|
+
yirgacheffe-1.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
23
|
+
yirgacheffe-1.7.0.dist-info/entry_points.txt,sha256=j4KgHXbVGbGyfTySc1ypBdERpfihO4WNjppvCdE9HjE,52
|
|
24
|
+
yirgacheffe-1.7.0.dist-info/top_level.txt,sha256=9DBFlKO2Ld3hG6TuE3qOTd3Tt8ugTiXil4AN4Wr9_y0,12
|
|
25
|
+
yirgacheffe-1.7.0.dist-info/RECORD,,
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
yirgacheffe/__init__.py,sha256=n0v998xPOMMS6hdAQ16UNzmJUdnN5612HRtdudwjYa4,302
|
|
2
|
-
yirgacheffe/_core.py,sha256=0E56yP63vUiwi0g6ntUzmKhOuWQWoh3sSD6Ui8SWWRI,4082
|
|
3
|
-
yirgacheffe/constants.py,sha256=uCWJwec3-ND-zVxYbsk1sdHKANl3ToNCTPg7MZb0j2g,434
|
|
4
|
-
yirgacheffe/operators.py,sha256=4REikGD_hDZjY3jfUfo4NmrrCXXu5hn1tYKedbwUlvg,31609
|
|
5
|
-
yirgacheffe/rounding.py,sha256=ggBG4lMyLMtHLW3dBxr3gBCcF2qhRrY5etZiFGlIoqA,2258
|
|
6
|
-
yirgacheffe/window.py,sha256=kR8sHQ6lcixpndOWC18wLRgbgS8y00tq4Fkh8PLESvM,8209
|
|
7
|
-
yirgacheffe/_backends/__init__.py,sha256=jN-2iRrHStnPI6cNL7XhwhsROtI0EaGfIrbF5c-ECV0,334
|
|
8
|
-
yirgacheffe/_backends/enumeration.py,sha256=pADawllxpW_hW-IVVvZpHWIKzvEMs9aaqfkZRD1zjnY,1003
|
|
9
|
-
yirgacheffe/_backends/mlx.py,sha256=2vOTMqHbQbeqt81Eq_8hxWDXZHaPsDpbXkALRVGEnnw,6130
|
|
10
|
-
yirgacheffe/_backends/numpy.py,sha256=cYO628s4-5K_-Bp3CrnHegzYSZfkt2QC8iE9oOOMtvA,4069
|
|
11
|
-
yirgacheffe/layers/__init__.py,sha256=mYKjw5YTcMNv_hMy7a6K4yRzIuNUbR8WuBTw4WIAmSk,435
|
|
12
|
-
yirgacheffe/layers/area.py,sha256=Qs5N5XMrQwk7StE_Rky94X7BhavRxgRmpC6mXLeu2HQ,3905
|
|
13
|
-
yirgacheffe/layers/base.py,sha256=AgFe1HoWNuJWm2z_CgEE5o-3j-5hdC8HuNpYIM_h8HE,12672
|
|
14
|
-
yirgacheffe/layers/constant.py,sha256=PiRiAgcvOE1Li-fFItt6P_cj8IOlwTf_xi5G_iaqHok,1440
|
|
15
|
-
yirgacheffe/layers/group.py,sha256=e3pyQb35Ma-CPqY0dB4xDjMk3m2DQzzKiMGLSbBMY7c,16292
|
|
16
|
-
yirgacheffe/layers/h3layer.py,sha256=Hy8kJF9-EQnLaRbZlj4TLSRfpq2-dJga8x4jiiPUHYo,9919
|
|
17
|
-
yirgacheffe/layers/rasters.py,sha256=stZOi0sojJqMybvtKpvzfXlFJwRUvW7mA77Q3B4nhzA,13296
|
|
18
|
-
yirgacheffe/layers/rescaled.py,sha256=uam0dsidKpP97gQBig34zXefyNruUbwAnQaeuN68KE4,3104
|
|
19
|
-
yirgacheffe/layers/vectors.py,sha256=4BCGRSzbkFfsGZwLsQS9WelMXV5hDCcLmGGW6mf6MjU,15839
|
|
20
|
-
yirgacheffe-1.6.1.dist-info/licenses/LICENSE,sha256=dNSHwUCJr6axStTKDEdnJtfmDdFqlE3h1NPCveqPfnY,757
|
|
21
|
-
yirgacheffe-1.6.1.dist-info/METADATA,sha256=fn6CGfn17HeAcGhGO1YEbBdc_9WUjTsTnTZPZfQFNU8,22402
|
|
22
|
-
yirgacheffe-1.6.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
23
|
-
yirgacheffe-1.6.1.dist-info/entry_points.txt,sha256=j4KgHXbVGbGyfTySc1ypBdERpfihO4WNjppvCdE9HjE,52
|
|
24
|
-
yirgacheffe-1.6.1.dist-info/top_level.txt,sha256=9DBFlKO2Ld3hG6TuE3qOTd3Tt8ugTiXil4AN4Wr9_y0,12
|
|
25
|
-
yirgacheffe-1.6.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|