GeoInfo constructor

GeoInfo(
  1. TiffImage image, [
  2. String? prjWkt
])

Implementation

GeoInfo(TiffImage image, [String? prjWkt]) {
  _prjWkt = prjWkt;
  _rows = image.height;
  _cols = image.width;
  // ModelTransformationTag: 34264
  // [30.0, 0.0, 0.0, 1640650.0,
  //  0.0, -30.0, 0.0, 5140020.0,
  //  0.0, 0.0, 0.0, 0.0,
  //  0.0, 0.0, 0.0, 1.0]
  var modelTransformationTag = image.tags[TiffTags.MODEL_TRANSFORMATION_TAG];
  if (modelTransformationTag != null) {
    var transformationMatrix = GeoTiffEntry(modelTransformationTag).read();

    //  |  xScale      0  dx | => m00, m01, m02
    //  |  0      yScale  dy | => m10, m11, m12
    //  |  0           0   1 |
    var m00 = transformationMatrix[0];
    var m01 = 0.0;
    var m02 = transformationMatrix[3];
    var m10 = 0.0;
    var m11 = transformationMatrix[5];
    var m12 = transformationMatrix[7];
    _pixelToWorldTransform =
        AffineTransformation.fromMatrixValues(m00, m01, m02, m10, m11, m12);
    _worldToPixelTransform = _pixelToWorldTransform!.getInverse();

    _xResolution = m00;
    _yResolution = m11.abs();

    var llCoord = _pixelToWorldTransform!
        .transform(Coordinate(0, 0), Coordinate.empty2D());
    var urCoord = _pixelToWorldTransform!.transform(
        Coordinate(_cols!.toDouble(), _rows!.toDouble()),
        Coordinate.empty2D());

    _worldEnvelope = Envelope.fromCoordinates(llCoord, urCoord);
  } else {
    // ModelTiepointTag: 33922 -> needs to be there if 34264 is not
    // needs ModelPixelScaleTag: 33550 ->  = (ScaleX, ScaleY, ScaleZ)

    //  ModelTiepointTag (2,3):
    //    0.5              0.5              0
    //    -3683154.58      4212096.53       0
    // ModelPixelScaleTag (1,3):
    //    10000            10000            0
    var modelPixelScaleTag = image.tags[TiffTags.MODEL_PIXELSCALE_TAG];
    if (modelPixelScaleTag != null) {
      var modelPixelScale = GeoTiffEntry(modelPixelScaleTag).read();
      var m00 = modelPixelScale[0];
      var m11 = -modelPixelScale[1];

      var modelTiepointTag = image.tags[TiffTags.MODEL_TIEPOINT_TAG];
      if (modelTiepointTag != null) {
        var modelTiepoint = GeoTiffEntry(modelTiepointTag).read();
        var m01 = 0.0;
        var m02 = modelTiepoint[3];
        var m10 = 0.0;
        var m12 = modelTiepoint[4];

        _pixelToWorldTransform = AffineTransformation.fromMatrixValues(
            m00, m01, m02, m10, m11, m12);
        _worldToPixelTransform = _pixelToWorldTransform!.getInverse();

        _xResolution = m00;
        _yResolution = m11.abs();

        var llCoord = _pixelToWorldTransform!
            .transform(Coordinate(0, 0), Coordinate.empty2D());
        var urCoord = _pixelToWorldTransform!.transform(
            Coordinate(_cols!.toDouble(), _rows!.toDouble()),
            Coordinate.empty2D());

        _worldEnvelope = Envelope.fromCoordinates(llCoord, urCoord);
      }
    }
  }

  // GeoKeyDirectoryTag: 34735 -> also 'ProjectionInfoTag' and 'CoordSystemInfoTag'
  // [1, 1, 2, 3,
  //  1024, 0, 1, 1,
  //  1025, 0, 1, 1,
  //  3072, 0, 1, 32632]

  // [1, 1, 0, 7,
  // 1024, 0, 1, 2,
  // 1025, 0, 1, 2,
  // 2048, 0, 1, 4326,
  // 2049, 34737, 7, 0,
  // 2054, 0, 1, 9102,
  // 2057, 34736, 1, 2,
  // 2059, 34736, 1, 1]
  var projInfoTag = image.tags[TiffTags.GEOKEY_DIRECTORY_TAG];
  if (projInfoTag != null) {
    var projInfovalues = GeoTiffEntry(projInfoTag).readValues();

    // look for an epsg code
    //
    // GeographicTypeGeoKey         = 2048
    // ProjectedCSTypeGeoKey          = 3072
    //
    // TODO this part needs more love and knowledge
    for (var i = 4; i < projInfovalues.length; i += 4) {
      var value = projInfovalues[i];
      if (value == 2048 || value == 3072) {
        _srid = projInfovalues[i + 3];
        break;
      }
    }
  }

  var gdalNovalueTag = image.tags[TiffTags.TAG_GDAL_NODATA];
  if (gdalNovalueTag != null) {
    var gdalNovalueBytes = GeoTiffEntry(gdalNovalueTag).readValues();
    var gdalNovaleString = String.fromCharCodes(gdalNovalueBytes);
    if (gdalNovaleString.startsWith("nan")) {
      noValue = double.nan;
    } else {
      noValue = double.tryParse(gdalNovaleString);
      if (noValue == null) {
        noValue = double.tryParse(
            gdalNovaleString.substring(0, gdalNovaleString.length - 1));
      }
    }
  }
}