Как устранить неполадки при разборе xarray.open_rasterio? - PullRequest
0 голосов
/ 05 марта 2020

Я хочу растеризовать меньшие оттенки GeoTIFF с высоким разрешением. xarray.open_rasterio казалось правильным инструментом для получения того, что нужно datashader.transfer_functions.shade. Однако возвращенный DataArray также имеет полосу, которая отключается shade. Возникает несколько вопросов:

  1. Должен ли xarray.open_rasterio возвращать значения, находящиеся в данный момент в "band", просто как значения в массиве?
  2. Как проверить, выглядит ли GeoTIFF как xarray.open_rasterio ожидает?
  3. Позволит ли любой аргумент xarray.open_rasterio указать "band" в качестве "значения"?
  4. Или xarray.open_rasterio просто переупорядочить или перемаркировать координаты таким образом, чтобы так что «band» является третьим (после «x» и «y»)?
  5. Или, если xarray.open_rasterio правильно проанализировал этот GeoTIFF, можно ли вызвать shade так, чтобы это не смущало 2D-массив с 3D-массивом?

MRE: используйте GeoTIFF из карт населения высокого разрешения Facebook, например, с здесь . Код ниже может поместить это на карту 800x800. Вместо этого, после того как я наконец понял, почему shade пожаловался, что в его аргументе color_key было только 22 цвета (по умолчанию), когда он пытался раскрасить 800 категорий, я понял, что координата y понимается как shade как Значение. Я показываю массив ниже.

import rasterio
from rasterio.mask import mask
import os
import datashader as ds
from datashader import transfer_functions as tf
import xarray as xr
from matplotlib.cm import viridis

data_path = 'SOME_PATH/'
file_name = 'HUN_women_of_reproductive_age_15_49.tif'  # reproductive women, e.g.
file_path = os.path.join(data_path, file_name)

da = xr.open_rasterio(file_path)

cvs = ds.Canvas(plot_width=800, plot_height=800)

img = tf.shade(cvs.raster(da), cmap=viridis)

Это не удается, потому что массив da выглядит следующим образом:

<xarray.DataArray (band: 1, y: 10240, x: 24320)> array([[[nan, nan, ..., nan, nan],
        [nan, nan, ..., nan, nan],
        ...,
        [nan, nan, ..., nan, nan],
        [nan, nan, ..., nan, nan]]]) Coordinates:   * band     (band) int64 1   * y        (y) float64 48.59 48.59 48.59 48.59 ... 45.75
45.75 45.75 45.75   * x        (x) float64 16.13 16.14 16.14 16.14 ... 22.89 22.89 22.89 22.89 Attributes:
    transform:      (0.000277777777778, 0.0, 16.13486111111111, 0.0, -0.00027...
    crs:            +init=epsg:4326
    res:            (0.000277777777778, 0.000277777777778)
    is_tiled:       1
    nodatavals:     (nan,)
    scales:         (1.0,)
    offsets:        (0.0,)
    descriptions:   ('Population Count',)
    AREA_OR_POINT:  Area

1 Ответ

1 голос
/ 06 марта 2020

cvs.raster () принимает аргумент layer, чтобы указать, какую из предоставленных полос вы хотите растеризовать; может это поможет?

img = tf.shade(cvs.raster(da,layer=1), cmap=viridis)

В любом случае, обратите внимание, что datashader.transfer_functions.shade не растеризует свой ввод; это делается с помощью вызова Canvas (в частности, cvs.raster, здесь). Тень просто преобразует уже растеризованный массив в цветные пиксели.

...