read method

  1. @override
void read([
  1. int? imageIndex
])
override

Read the raster accessing the file.

The optional imageIndex defines the image to open.

Implementation

@override
void read([int? imageIndex]) {
  if (imageIndex == null) {
    imageIndex = 0;
  }

  // right now geotiff ad esri ascii grids are supported
  if (GeoimageUtils.isTiff(_file!.path)) {
    var bytes = _file!.readAsBytesSync();
    var tiffDecoder = TiffDecoder();
    _raster = tiffDecoder.decode(bytes, frame: imageIndex);
    _tiffInfo = tiffDecoder.info;
    _tiffImage = _tiffInfo?.images[imageIndex];

    if (_raster == null) {
      throw StateError("Unable to decode tiff.");
    }
    // even in this case there might be worldfile info. In case use them.
    var wesnxyValues = GeoimageUtils.parseWorldFile(
        _file!.path, _raster!.width, _raster!.height);
    var prjWkt = GeoimageUtils.getPrjWkt(_file!.path);
    if (wesnxyValues != null) {
      // has worldfile
      _geoInfo = GeoInfo.fromValues(
          _raster!.width,
          _raster!.height,
          wesnxyValues[4],
          -wesnxyValues[5],
          wesnxyValues[0],
          wesnxyValues[3],
          prjWkt);
    } else {
      _geoInfo = GeoInfo(_tiffImage!);
    }
    _rows = _geoInfo!.rows;
    _cols = _geoInfo!.cols;
    isTiff = true;
  } else if (GeoimageUtils.isAsc(_file!.path)) {
    var prjWkt = GeoimageUtils.getPrjWkt(_file!.path);
    var fileLines = GeoimageUtils.readFileToList(_file!.path);

    // ncols         4
    // nrows         6
    // xllcorner     0.0
    // yllcorner     0.0
    // cellsize      50.0
    // NODATA_value  -9999

    int cols = 0;
    int rows = 0;
    double west = 0.0;
    double south = 0.0;
    double novalue = 0.0;
    double res = 0.0;
    dataList = [];
    bool dataStarted = false;
    for (var i = 0; i < fileLines.length; i++) {
      var line = fileLines[i].trim();
      if (line.isEmpty) {
        continue;
      }
      if (!dataStarted &&
          double.tryParse(line.substring(0, 1)) == null &&
          line.substring(0, 1) != "-") {
        // starts with letter -> header
        line = line.toLowerCase();
        var split = line.split(RegExp(r'\s+'));
        if (split.length == 2) {
          if (split[0] == "ncols") {
            cols = int.parse(split[1]);
          } else if (split[0] == "nrows") {
            rows = int.parse(split[1]);
          } else if (split[0] == "xllcorner") {
            west = double.parse(split[1]);
          } else if (split[0] == "yllcorner") {
            south = double.parse(split[1]);
          } else if (split[0] == "cellsize") {
            res = double.parse(split[1]);
          } else if (split[0] == "nodata_value") {
            novalue = double.parse(split[1]);
          }
        }
      } else {
        dataStarted = true;
        List<double> rowData = [];
        var split = line.split(RegExp(r'\s+'));
        if (split.length != cols) {
          throw ArgumentError(
              "The values in the row are of different number than the one defined in the header: ${split.length} vs $cols");
        }
        split.forEach((element) {
          rowData.add(double.parse(element));
        });
        dataList.add(rowData);
      }
    }
    if (dataList.length != rows) {
      throw ArgumentError(
          "The row number if different from the one defined in the header: ${dataList.length} vs $rows");
    }
    _geoInfo = GeoInfo.fromValues(
        cols, rows, res, -res, west, south + rows * res, prjWkt);
    _rows = _geoInfo!.rows;
    _cols = _geoInfo!.cols;
    _geoInfo!.noValue = novalue;
    isEsriAsc = true;
  }
}