Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding GeoTIFF support #61

Closed
wants to merge 1 commit into from
Closed

Conversation

mjstevens777
Copy link

It was hard for me to find a ruby library that allowed for reading GeoTIFF metadata that didn't require a lot of dependencies to be installed first, and your library looked like a good tool for achieving that. It wasn't too much work to add basic GeoTIFF parsing. On a related note, it might be nice if there was a way to specify custom tags that you want to extract so that people can extend the library without having to modify the source. Please let me know what you think of my approach, and thanks for your time.

@remvee
Copy link
Owner

remvee commented Mar 14, 2019

That's cool, I never heard about GeoTIFF before but I am reluctant to merge this. I want to keep the focus of this lib on standard EXIF only and this is a TIFF related thing. The only reason this lib decodes TIFF is because EXIF is encoded using that standard.

What I can do is merge the support for floats and doubles you've added, and allow access to unknown IFD fields so you can build a separate lib on top of EXIFR. The main code for your lib would roughly look as follows:

class GeoTIFF
  KEY_IDS = {
    1024 => "GTModelTypeGeoKey", # TODO these values are used as methods, Ruby convention is to use snake_case
    1025 => "GTRasterTypeGeoKey",
    ..
  }

  def initialize(file)
    @tiff = EXIFR::TIFF.new(file)

    @data = {}
    return if geo_key_directory && geo_key_directory.length < 4

    number_of_keys = geo_key_directory[3]
    if (1 + number_of_keys) * 4 != geo_key_directory.length
      throw "Malformed GeoKeyDirectoryTag" # TODO define your own exception and throw that, easier to catch
    end

    (4...geo_key_directory.length).step(4) do |i|
      # populate @data instead of params in your original code
      ..
    end

    # Ensure callers won't change my internal state.
    @data.freeze
  end

  def geo_key_directory    ; @tiff[0x87af]; end
  def geo_double_params    ; @tiff[0x87b0]; end
  def geo_ascii_params     ; @tiff[0x87b1]; end
  def model_transformation ; @tiff[34264]; end
  def model_tiepoint       ; @tiff[33922]; end
  def model_pixel_scale    ; @tiff[33550]; end

  def method_missing(method, *args)
    super unless args.empty? || !KEY_IDS.values.include?(method.to_s)
    @params[method.to_s]
  end

  def to_hash
    @params
  end
end

Note: the above will not work (yet) because @tiff[0x87b1] will return nil and floats and doubles are not supported yet.

Let me know what you think, if you like this approach, I'll make the necessary changes for you. I can also help or give feedback on making your own gem if you want.

@mjstevens777
Copy link
Author

Okay thank you! That sounds like the right compromise. I was also concerned that adding the GeoTIFF-specific code would make things too bloated. Please let me know if there is anything I can help out with.

@remvee
Copy link
Owner

remvee commented Mar 14, 2019

I've just pushed a branch with the changes you'll need. Accessing unknown ifds works slightly different from what I proposed earlier (see tests/tiff_test.rb:211 for an example).

Given the code I posted earlier

@tiff = EXIFR::TIFF.new(file)

should become

@ifd = EXIFR::TIFF.new(file).first

and instead of @tiff[..] you'd use @ifd.raw_fields[..]. You'll also need check for @ifd not being nil somewhere.

Please let me know if this works for you. If it does, I'll merge it. When you are ready for a lib release, I'll do a release too and point to your geotiff code in the README of this repo, like I did for XMP.

@mjstevens777
Copy link
Author

Thanks for working on this, that sounds perfect. Hopefully people won’t mind making the fields -> mapped_fields change. Let me know if there is anything I can help with, and I will let you know if I make a gem.

@remvee
Copy link
Owner

remvee commented Mar 15, 2019

Ah, yes.. That's a problem because that's part of the YAML dump output. I've added a commit to fix that; a634e55.

Also I'm closing this PR and making a new one for the extension points (#62).

@remvee remvee closed this Mar 15, 2019
ombr pushed a commit to ombr/exifr that referenced this pull request Jun 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants