large-image-source-rasterio 1.32.12.dev39__tar.gz → 1.32.12.dev45__tar.gz

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.
Files changed (15) hide show
  1. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/PKG-INFO +3 -3
  2. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/large_image_source_rasterio/__init__.py +89 -25
  3. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/large_image_source_rasterio/girder_source.py +2 -0
  4. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/large_image_source_rasterio.egg-info/PKG-INFO +3 -3
  5. large_image_source_rasterio-1.32.12.dev45/large_image_source_rasterio.egg-info/requires.txt +9 -0
  6. large_image_source_rasterio-1.32.12.dev39/large_image_source_rasterio.egg-info/requires.txt +0 -9
  7. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/LICENSE +0 -0
  8. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/README.rst +0 -0
  9. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/large_image_source_rasterio.egg-info/SOURCES.txt +0 -0
  10. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/large_image_source_rasterio.egg-info/dependency_links.txt +0 -0
  11. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/large_image_source_rasterio.egg-info/entry_points.txt +0 -0
  12. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/large_image_source_rasterio.egg-info/top_level.txt +0 -0
  13. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/pyproject.toml +0 -0
  14. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/setup.cfg +0 -0
  15. {large_image_source_rasterio-1.32.12.dev39 → large_image_source_rasterio-1.32.12.dev45}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: large-image-source-rasterio
3
- Version: 1.32.12.dev39
3
+ Version: 1.32.12.dev45
4
4
  Summary: A rasterio tilesource for large_image.
5
5
  Home-page: https://github.com/girder/large_image
6
6
  Author: Kitware, Inc.
@@ -17,11 +17,11 @@ Classifier: Programming Language :: Python :: 3.13
17
17
  Requires-Python: >=3.9
18
18
  Description-Content-Type: text/x-rst
19
19
  License-File: LICENSE
20
- Requires-Dist: large-image>=1.32.12.dev39
20
+ Requires-Dist: large-image>=1.32.12.dev45
21
21
  Requires-Dist: rasterio>=1.3
22
22
  Requires-Dist: packaging
23
23
  Provides-Extra: girder
24
- Requires-Dist: girder-large-image>=1.32.12.dev39; extra == "girder"
24
+ Requires-Dist: girder-large-image>=1.32.12.dev45; extra == "girder"
25
25
  Provides-Extra: all
26
26
  Requires-Dist: rio-cogeo; extra == "all"
27
27
  Dynamic: author
@@ -36,7 +36,8 @@ from large_image.constants import (PROJECTION_SENTINEL, TILE_FORMAT_IMAGE,
36
36
  TileOutputMimeTypes)
37
37
  from large_image.exceptions import (TileSourceError,
38
38
  TileSourceFileNotFoundError,
39
- TileSourceInefficientError)
39
+ TileSourceInefficientError,
40
+ TileSourceXYZRangeError)
40
41
  from large_image.tilesource.geo import (GDALBaseFileTileSource,
41
42
  ProjUnitsAcrossLevel0,
42
43
  ProjUnitsAcrossLevel0_MaxSize)
@@ -93,7 +94,7 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
93
94
  cacheName = 'tilesource'
94
95
  name = 'rasterio'
95
96
 
96
- def __init__(self, path, projection=PROJECTION_SENTINEL, unitsPerPixel=None, **kwargs):
97
+ def __init__(self, path, projection=PROJECTION_SENTINEL, unitsPerPixel=None, **kwargs): # noqa
97
98
  """Initialize the tile class.
98
99
 
99
100
  See the base class for other available parameters.
@@ -178,7 +179,32 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
178
179
  logY = math.log(float(self.sizeY) / self.tileHeight)
179
180
  computedLevel = math.ceil(max(logX, logY) / math.log(2))
180
181
  self.sourceLevels = self.levels = int(max(0, computedLevel) + 1)
181
-
182
+ with self._getDatasetLock:
183
+ try:
184
+ subdatasets = self.dataset.subdatasets
185
+ except (RuntimeError, ZeroDivisionError):
186
+ subdatasets = None
187
+ if subdatasets and len(subdatasets) > 1:
188
+ self._frames = []
189
+ for sdsrecord in subdatasets:
190
+ sdspath = os.path.join(os.path.dirname(self._largeImagePath), sdsrecord)
191
+ try:
192
+ sds = rio.open(sdspath)
193
+ except Exception:
194
+ sdspath = sdsrecord
195
+ try:
196
+ sds = rio.open(sdspath)
197
+ except Exception:
198
+ sds = None
199
+ try:
200
+ if (sds and sds.width == self.sourceSizeX and
201
+ sds.height == self.sourceSizeY and
202
+ self.dataset.indexes == sds.indexes):
203
+ self._frames.append(sdspath)
204
+ except Exception:
205
+ pass
206
+ if len(self._frames) <= 1:
207
+ delattr(self, '_frames')
182
208
  self._unitsPerPixel = unitsPerPixel
183
209
  self.projection is None or self._initWithProjection(unitsPerPixel)
184
210
  self._getPopulatedLevels()
@@ -206,19 +232,19 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
206
232
  :param analysisSize: optional default to 1024
207
233
  :param onlyMinMax: optional default to True
208
234
  """
209
- # default frame to 0 in case it is set to None from outside
210
- frame = frame or 0
235
+ frame = self._getFrame(frame=frame or 0)
236
+ ds = self._getFrameDataset(frame)
211
237
 
212
238
  # read band information
213
- bandInfo = self.getBandInformation()
239
+ bandInfo = self.getBandInformation(dataset=ds)
214
240
 
215
241
  # get the minmax value from the band
216
242
  hasMin = all(b.get('min') is not None for b in bandInfo.values())
217
243
  hasMax = all(b.get('max') is not None for b in bandInfo.values())
218
- if not frame and onlyMinMax and hasMax and hasMin:
244
+ if onlyMinMax and hasMax and hasMin:
219
245
  with self._getDatasetLock:
220
246
  dtype = self.dataset.profile['dtype']
221
- self._bandRanges[0] = {
247
+ self._bandRanges[frame] = {
222
248
  'min': np.array([b['min'] for b in bandInfo.values()], dtype=dtype),
223
249
  'max': np.array([b['max'] for b in bandInfo.values()], dtype=dtype),
224
250
  }
@@ -478,7 +504,7 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
478
504
  return self._bandInfo
479
505
 
480
506
  # check if the dataset is cached
481
- cache = not dataset
507
+ cache = not dataset or dataset == self.dataset
482
508
 
483
509
  # do everything inside the dataset lock to avoid multiple read
484
510
  with self._getDatasetLock:
@@ -551,6 +577,9 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
551
577
  'sourceBounds': self.getBounds(),
552
578
  'bands': self.getBandInformation(),
553
579
  })
580
+ if hasattr(self, '_frames'):
581
+ metadata['frames'] = [{} for _ in self._frames]
582
+ self._addMetadataFrameInformation(metadata)
554
583
  return metadata
555
584
 
556
585
  def getInternalMetadata(self, **kwargs):
@@ -591,8 +620,30 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
591
620
 
592
621
  return result
593
622
 
623
+ def _getFrameDataset(self, frame):
624
+ ds = self.dataset
625
+ if frame or hasattr(self, '_frames'):
626
+ if frame < 0 or not hasattr(self, '_frames') or frame >= len(self._frames):
627
+ msg = 'Frame does not exist'
628
+ raise TileSourceXYZRangeError(msg)
629
+ if not hasattr(self, '_frameCache') or not hasattr(self, '_frameCacheMaxSize'):
630
+ self._frameCache = {}
631
+ self._frameCacheMaxSize = 10
632
+ if frame in self._frameCache:
633
+ ds = self._frameCache[frame]
634
+ else:
635
+ with self._getDatasetLock:
636
+ if len(self._frameCache) >= self._frameCacheMaxSize:
637
+ self._frameCache = {}
638
+ ds = rio.open(self._frames[frame])
639
+ self._frameCache[frame] = ds
640
+ return ds
641
+
594
642
  @methodcache()
595
643
  def getTile(self, x, y, z, pilImageAllowed=False, numpyAllowed=False, **kwargs):
644
+ frame = self._getFrame(**kwargs)
645
+ ds = self._getFrameDataset(frame)
646
+ tile = None
596
647
  if not self.projection:
597
648
  self._xyzInRange(x, y, z)
598
649
  factor = int(2 ** (self.levels - 1 - z))
@@ -605,13 +656,20 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
605
656
 
606
657
  with self._getDatasetLock:
607
658
  window = rio.windows.Window(xmin, ymin, xmax - xmin, ymax - ymin)
608
- count = self.dataset.count
609
- tile = self.dataset.read(
610
- window=window,
611
- out_shape=(count, h, w),
612
- resampling=rio.enums.Resampling.nearest,
613
- )
614
-
659
+ count = ds.count
660
+ try:
661
+ tile = ds.read(
662
+ window=window,
663
+ out_shape=(count, h, w),
664
+ resampling=rio.enums.Resampling.nearest,
665
+ )
666
+ except Exception:
667
+ tile = None
668
+ self.logger.exception('Failed to getTile')
669
+ if hasattr(self, '_frameCache'):
670
+ self._frameCache = {}
671
+ else:
672
+ self.dataset = rio.open(self._largeImagePath)
615
673
  else:
616
674
  xmin, ymin, xmax, ymax = self.getTileCorners(z, x, y)
617
675
  bounds = self.getBounds(self.projection)
@@ -635,7 +693,7 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
635
693
  # Adding an alpha band when the source has one is trouble.
636
694
  # It will result in surprisingly unmasked data.
637
695
  src_alpha_band = 0
638
- for i, interp in enumerate(self.dataset.colorinterp):
696
+ for i, interp in enumerate(ds.colorinterp):
639
697
  if interp == rio.enums.ColorInterp.alpha:
640
698
  src_alpha_band = i
641
699
  add_alpha = not src_alpha_band
@@ -643,7 +701,7 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
643
701
  # read the image as a warp vrt
644
702
  with self._getDatasetLock:
645
703
  with rio.vrt.WarpedVRT(
646
- self.dataset,
704
+ ds,
647
705
  resampling=rio.enums.Resampling.nearest,
648
706
  crs=self.projection,
649
707
  transform=dst_transform,
@@ -655,8 +713,10 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
655
713
  tile = vrt.read(resampling=rio.enums.Resampling.nearest)
656
714
  except Exception:
657
715
  self.logger.exception('Failed to getTile')
658
- tile = np.zeros((1, 1))
716
+ tile = None
659
717
 
718
+ if tile is None:
719
+ tile = np.zeros((1, 1))
660
720
  # necessary for multispectral images:
661
721
  # set the coordinates first and the bands at the end
662
722
  if len(tile.shape) == 3:
@@ -925,11 +985,13 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
925
985
  x, y = self.toNativePixelCoordinates(x, y)
926
986
 
927
987
  if 0 <= int(x) < self.sizeX and 0 <= int(y) < self.sizeY:
988
+ frame = self._getFrame(**kwargs)
989
+ ds = self._getFrameDataset(frame)
928
990
  with self._getDatasetLock:
929
- for i in self.dataset.indexes:
991
+ for i in ds.indexes:
930
992
  window = rio.windows.Window(int(x), int(y), 1, 1)
931
993
  try:
932
- value = self.dataset.read(
994
+ value = ds.read(
933
995
  i, window=window, resampling=rio.enums.Resampling.nearest,
934
996
  )
935
997
  value = value[0][0] # there should be 1 single pixel
@@ -958,6 +1020,8 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
958
1020
  :returns: regionData, formatOrRegionMime: the image data and either the
959
1021
  mime type, if the format is TILE_FORMAT_IMAGE, or the format.
960
1022
  """
1023
+ frame = self._getFrame(**kwargs)
1024
+ ds = self._getFrameDataset(frame)
961
1025
  # cast format as a tuple if needed
962
1026
  format = format if isinstance(format, (tuple, set, list)) else (format,)
963
1027
 
@@ -1002,7 +1066,7 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
1002
1066
  dst_transform = Affine(xres, 0.0, left, 0.0, -yres, top)
1003
1067
 
1004
1068
  with rio.vrt.WarpedVRT(
1005
- self.dataset,
1069
+ ds,
1006
1070
  resampling=rio.enums.Resampling.nearest,
1007
1071
  crs=self.projection,
1008
1072
  transform=dst_transform,
@@ -1011,7 +1075,7 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
1011
1075
  ) as vrt:
1012
1076
  data = vrt.read(resampling=rio.enums.Resampling.nearest)
1013
1077
 
1014
- profile = self.dataset.meta.copy()
1078
+ profile = ds.meta.copy()
1015
1079
  profile.update(
1016
1080
  large_image.tilesource.utilities._rasterioParameters(
1017
1081
  defaultCompression='lzw', **kwargs,
@@ -1027,8 +1091,8 @@ class RasterioFileTileSource(GDALBaseFileTileSource, metaclass=LruCacheMetaclass
1027
1091
  dst.write(data)
1028
1092
  # Write colormaps if available
1029
1093
  for i in range(data.shape[0]):
1030
- if self.dataset.colorinterp[i].name.lower() == 'palette':
1031
- dst.write_colormap(i + 1, self.dataset.colormap(i + 1))
1094
+ if ds.colorinterp[i].name.lower() == 'palette':
1095
+ dst.write_colormap(i + 1, ds.colormap(i + 1))
1032
1096
 
1033
1097
  return outputPath, TileOutputMimeTypes['TILED']
1034
1098
 
@@ -30,6 +30,8 @@ class RasterioGirderTileSource(RasterioFileTileSource, GirderTileSource):
30
30
  name = 'rasterio'
31
31
  cacheName = 'tilesource'
32
32
 
33
+ _mayHaveAdjacentFiles = True
34
+
33
35
  @staticmethod
34
36
  def getLRUHash(*args, **kwargs):
35
37
  projection = kwargs.get(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: large-image-source-rasterio
3
- Version: 1.32.12.dev39
3
+ Version: 1.32.12.dev45
4
4
  Summary: A rasterio tilesource for large_image.
5
5
  Home-page: https://github.com/girder/large_image
6
6
  Author: Kitware, Inc.
@@ -17,11 +17,11 @@ Classifier: Programming Language :: Python :: 3.13
17
17
  Requires-Python: >=3.9
18
18
  Description-Content-Type: text/x-rst
19
19
  License-File: LICENSE
20
- Requires-Dist: large-image>=1.32.12.dev39
20
+ Requires-Dist: large-image>=1.32.12.dev45
21
21
  Requires-Dist: rasterio>=1.3
22
22
  Requires-Dist: packaging
23
23
  Provides-Extra: girder
24
- Requires-Dist: girder-large-image>=1.32.12.dev39; extra == "girder"
24
+ Requires-Dist: girder-large-image>=1.32.12.dev45; extra == "girder"
25
25
  Provides-Extra: all
26
26
  Requires-Dist: rio-cogeo; extra == "all"
27
27
  Dynamic: author
@@ -0,0 +1,9 @@
1
+ large-image>=1.32.12.dev45
2
+ rasterio>=1.3
3
+ packaging
4
+
5
+ [all]
6
+ rio-cogeo
7
+
8
+ [girder]
9
+ girder-large-image>=1.32.12.dev45
@@ -1,9 +0,0 @@
1
- large-image>=1.32.12.dev39
2
- rasterio>=1.3
3
- packaging
4
-
5
- [all]
6
- rio-cogeo
7
-
8
- [girder]
9
- girder-large-image>=1.32.12.dev39