Windows > Software Development for Windows Client Forums > Windows Imaging Component (WIC) > Writing latitude and longitude using policies
Ask a questionAsk a question
 

QuestionWriting latitude and longitude using policies

  • Thursday, February 12, 2009 5:43 PMATGardner Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I am trying to write the above values, using the "System.GPS.Latitude" and "System.GPS.Longitude" policies.
    First, I tried using the "Numerator"/"Denominator" option to write URational data, but since I have a URational[3] in here, it doesn't seem reasonable.
    I couldn't find a way to write a coordinate using the policies. Only using the direct xmp or exif query strings.
    with xmp, I should use a string, with exif, I use a ulong[3] array.

    this.metadata.SetQuery("/xmp/exif:GPSLatitude", "3223");

    or

    this.metadata.SetQuery("/app1/ifd/gps/{ushort=2}", new ulong[]{1, 2, 3});

    seem to work, but I am looking for something like

    this.metadata.SetQuery("System.GPS.Latitude", value)

    where value is ulong[3] or string (or whatever else it can be...), and it would set both the xmp and the exif to the proper values.

    Am I hoping for too much?

All Replies

  • Friday, February 20, 2009 11:37 PMElliott Prechter Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    First of all, are you using Win7 Beta or Vista? On Win7 Beta, these keys should work just fine, but they are currently are not enabled on Vista (so you have to write directly to the gps ifd). For Win7 Beta, you should be able to use a string value for the numerator and denominator via a proxy key, i.e. this.metadata.SetQuery("System.GPS.Latitude.Proxy", "1/2").

  • Saturday, February 21, 2009 3:21 PMATGardner Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I am trying this on Vista.
    The main problem with Latitude and Longitude is that it contains three URational values, not just one. At least in the exif container. It can contain just one rational for degrees (with minutes and seconds as fraction of degrees), I guess.

    Yesterday I managed to execute the following code with some success:

    this.metadata.SetQuery("System.GPS.Latitude", new ULong[]{ 30, 40, 20 });

    and this did put the 30 40 20 values in the exif ULong array, but when I later try to read with
    this.metadata.GetQuery("/xmp/exif:GPSLatitude")
    or
    this.metadata.GetQuery("System.GPS.Latitude.Proxy")

    all I get is
    "-2147483648,0.#INFN"

    which is quite odd
    I tried putting different values in the ULong array. they all ran alright (no exception, at least), and reading with
    this.metadata.GetQuery("/app1/ifd/gps/{ushort=2}")
    just gives me back exactly what I put in. the xmp and proxy strings got me more strange results, like
    "-2147483648,-2147483648.#INDN"

    Is it all just not supported by Vista? Should I try sticking to reading and writing from exif, for lat and long?
  • Tuesday, March 03, 2009 6:56 PMElliott Prechter Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    You're almost there. Each rational type is actually composed of two 32-bit numbers -- the upper 32-bits is a numerator, and the bottom 32-bits is a denominator. The rational is interpreted by dividing these two numbers. So if you with write "30", you need to write "30/1", which means you create a 64-bit ULong by taking 30 and shifting it up by 32 bits and then adding one.
  • Wednesday, November 04, 2009 6:20 AMBen Vincent [Hotmail] Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Did you solve your problem? I've just finishing up a blog on this. The code you need for reading is:

    // Grab GpsAltitude as a ulong
    ulong rational = (ulong)bitmapMetadata.GetQuery("/app1/ifd/Gps/subifd:{uint=6}");

    // Now shift & mask out the upper and lower parts to get the numerator and the denominator
    uint numerator = (uint)(rational & 0xFFFFFFFFL);
    uint denominator = (uint)((rational & 0xFFFFFFFF00000000L) >> 32);

    // And finally turn it into a double
    double altitude = Math.Round(Convert.ToDouble(numerator) / Convert.ToDouble(denominator), 3);

    I'll post the blog here in the next week or so:

    http://www.tassography.com/blog.aspx?tag=Windows+Imaging+Component