Thread: Time Zone map data

  1. #1
    Registered User
    Join Date
    Jan 2013
    Posts
    106

    Time Zone map data

    Hi Guys,
    I posted here because the question isnít specifically C, but my current project is.
    Iíve recently been working on a GPS (NMEA) parser,
    and discovered if you want to convert UTC to display local time and date,
    you need access to a complete calendar.
    If UTC time is 22:00 on a given date, and you have to add 10 hours,
    any possible increment of hours could potentially add to every other date variable depending on what the date is.
    I imagine this is usually solved with a calendar, and I have solved that issue.

    Now the only thing that is not automated is setting the time zone.
    Is there a free data for a world map of polygons or something like that
    to determine the time zone based on location?
    I realise youíd pull it from some system settings on most platforms,
    but Iím out of luck there.
    Cheers, Art.

  2. #2
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    The IANA Time Zone Database is actively maintained and contains both data and code on how to convert UTC to and from local time, given you know the name of the region you're in.

    To find out the name of the region you're in, check the Global Administrative Areas database. It is huge (333 megabytes in a zipped shapefile format), but you'll only need the outlines of each timezone region in GPS coordinates, so your dataset will be much, much smaller.

    (Note that the boundaries of a country are not guaranteed to form just one polygon, but may actually be composed of more than one? Like United States for example? And in international waters, like in the middle of the Pacific Ocean, there is no strictly defined timezone anyway; most travellers simply picking one based on their previous or next ports, even if they did cross into local waters?)

    You do realize that all this is subject to change, and does change on a regular basis? Countries move their borders, switch timezones (often just to highlight their political stance), and so on. I recommend you automate the process of parsing and massaging the timezone and administrative areas databases to whatever format you'll need, because you will be doing so every year or so for the lifetime of your gadget.

    There is a reason most systems just ask the user to select a city in the country or state they're in, and determine the local time from that, even if you did have GPS coordinates. It's not automatic, but it avoids all that hassle. If all you need is the Continent-City-Timezone mapping, you can easily process/optimize the TZ database into a binary format used by your gadget, and just update that when it changes, once or twice a year.

    I bet you didn't realize it was this nasty.

  3. #3
    Registered User
    Join Date
    Jan 2013
    Posts
    106
    Hi again
    I remember you answered me about the Moon percentage Illumination code.

    It’s all about that, and other Sun/Moon astronomy that requires a time zone offset to display correct local times.
    Yes I realise it’s a PITA, I did it with the Sony PSP, but the whole Earth was a 520x272 bitmap,
    so if it were ever represented in a real projection it would look very Atari 2600.
    http://pdroms.de/wp-content/uploads/...plication).png

    being a dsPic, I’m not going to have huge memory, but maybe if I can figure how to use the shape file It could be dumbed down a bit.

    You suggested I upgrade my LCD, so I have got a monochrome dot matrix LCD display, still a bit old school by today’s standards,
    but enough to draw a vector current continent, and I thought time zone data would be more appropriate to begin with for a clock
    than actual vector polygons of the continents which would possibly just waste time & memory.

  4. #4
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by xArt View Post
    dsPic, Iím not going to have huge memory, but maybe if I can figure how to use the shape file It could be dumbed down a bit.
    If you have a spare chip select pin to use with the SPI on that, how about sticking a micro-SD card socket on it, and use that for the data? No need for a file system, either, just make sure you have good tools to massage that data to store to the card. (In particular, this should not be at all difficult in Linux.)

    A "pixel map" should work for this quite well. Truncated mercator projection is okay, too, because the data outside 83N to 70S (i.e. near the poles) is pretty ambiguous anyway.

    The shapefile format is not too difficult to handle, and there are libraries like shapelib. You do need some code to render the shapefile data to one or more pixel maps (at different resolutions), and combine it with the timezone database, but all this can definitely be automated (and should).

    Might make an interesting programming topic on the C or C++ subforums, whichever you are more comfortable with outside microcontrollers.

    Quote Originally Posted by xArt View Post
    draw a vector current continent, and I thought time zone data would be more appropriate to begin with for a clock than actual vector polygons of the continents which would possibly just waste time & memory.
    Oh, absolutely; no need for vectors in your application.

    Fortunately, vector formats are not at all hard to render to pixmaps. (If you don't want to render the images yourself, you can always convert the vector data to SVG, then use existing tools like ImageMagick to render the SVG images to portable pixmap (PPM) format, which is real easy to work with. Modular tools for the win!)

    Note that your display data and your internal timezone data are, and should, be separate.

    If I were you, I'd definitely use a micro-SD card for storage. They use SPI at 3.3VDC levels, and it allows you to use desktop tools to generate -- and update -- the geo+timezone database, and there are tons of examples on how to do this on any microcontroller. (If you use 3.3V logic, you don't necessarily need any extra components other than a microSD card socket; for 5V logic microcontroller, you'll need a level shifter or something like this.)

    For this use case, forget about using a filesystem like FAT, just access the sectors directly. In Linux, for example, you can access the card directly, just by opening and using the device node (/dev/sdX) as if it were a file (assuming you have the necessary privileges). Just make sure you don't overwrite your hard drive by accident. You can make that a lot easier in Linux, if you use a "dedicated" microSD-to-USB adapter for this, and add an udev rule for that adapter to adjust the device access rights and create a symlink (like /dev/microSD) you can read and write to as a normal user.

    For the timezone database, I'd start by finding out exactly how many unique timezone rules there are, and what kinds of variations they have (in relation to your use case and needs). I think, but have not verified, that there are somewhat fewer than 256, so that a single byte per "pixel" (GPS coordinates at whatever resolution you choose) should be enough to describe the timezone. If not, I'm pretty sure there are fewer than 65536, so in the worst case you still need just two bytes for the index per GPS coordinate cell at your desired resolution.

    (I don't know how many different rules there are for the Daylight Savings time, but I think they are all nasty -- something like "the last Funkyday of Junkmonth, twirl your minute hand clockwise until it points to Saturn" -- and it'd take a bit of thinking to decide how to handle all those rules efficiently with little memory but relatively fast microcontroller.)

    I'd then have a fixed structure to describe each timezone, and stick these in known sectors on the SD card. The timezone selector map I'd put at ridiculously big resolution, maybe 16384◊8192 or something like that (covering a full Mercator projection), as the microcontroller would only access one byte of it anyway, whenever the location changes enough. That would yield roughly a 2.5 km per pixel timezone resolution, and require 128 MB or 256 MB of storage space, depending on whether 256 timezone rules sufficies.

    To draw the screen, I'd use separate images for each timezone, and probably at multiple zoom levels. Yes, that makes for a buttload of images, but it's okay; the microSD cards have room. I'd choose the format for the images based on the display module used, so that I could just "stream" the data from the microSD card to the display module, without having to manipulate it much. Having each image fixed size (in sectors) would make it easy to locate the images (without a filesystem or even a logical directory -- each image would just start at specific sector).

    A nice gigabyte or two microSD card costs maybe five bucks, so there is no need to go for a smaller card. If power consumption is important, you might wish to check a few different makes, to see if some of them need less power.

  5. #5
    Registered User
    Join Date
    Jan 2013
    Posts
    106
    Quote Originally Posted by Nominal Animal View Post
    (I don't know how many different rules there are for the Daylight Savings time, but I think they are all nasty -- something like "the last Funkyday of Junkmonth, twirl your minute hand clockwise until it points to Saturn" -- and it'd take a bit of thinking to decide how to handle all those rules efficiently with little memory but relatively fast microcontroller.)
    That one totally slipped my mind. By the time I’m done there I’ll be down to the individual time dilation offset gained from velocity and elevation.

    I was planning to project to a scaleable 2D pixel based screen, yes. Something like rotating around centre origin, or following longitude of the greyline.
    I’ve done a more full on one with iOS, but I think doing it for a micro is about getting code working out of iOS. Similar story with the Astronomy.
    Using an SD card is not out of the question. I do have a working filesystem example, so it’s possible to go either way.
    In fact, the dsPic board I followed the design of a dev board that had SD card but no LCD. I did leave the SD card pins vacant so that the code
    could and hardware could be dropped in later without changing even the pin definitions

  6. #6
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by xArt View Post
    That one totally slipped my mind.
    Having slept on it, I think it might make most sense to have your internal time (converted from GPS data) in seconds in UTC since some epoch, say 2000-01-01 00:00:00 or whatever works well. I'd just calculate the moments in UTC when the UTC offset for each unique timezone changes, and form an array of UTC time, localtime offset in seconds pairs, in ascending order, for the next 128 years or so -- 32-bit unsigned integer is sufficient to cover a bit over 136 years. Since the timezone changes at most twice per year, you'd have an array of at most 256 pairs, each pair 8 bytes, for a total of 2048 bytes per unique timezone. To find out the current offset to UTC, you'd just read the 2048 bytes relevant to the current timezone, and use the offset from the last pair where the UTC time is not after this particular moment.

    If you have eeprom or battery-packed cache, you'd obviously stick some of those there (current timezone, current offset to UTC, UTC time of next change of the offset to UTC time), so you don't need to keep reading from the SD card all the time.

    Quote Originally Posted by xArt View Post
    I was planning to project to a scaleable 2D pixel based screen, yes. Something like rotating around centre origin, or following longitude of the greyline.
    The amount of RAM available on these tiny microcontrollers is a limiting factor. Also, SD cards read and write data in 512 byte blocks -- that is, you always transfer blocks of 512 bytes, even if you end up using only a few bytes of it.

    Quote Originally Posted by xArt View Post
    I did leave the SD card pins vacant so that the code
    could and hardware could be dropped in later without changing even the pin definitions
    It is amazing what you can make an 8-bit microcontroller do, if you just have storage or RAM to keep the data in. Reminds me of the 6502 days, and the demoscene in the early nineties..

  7. #7
    Registered User
    Join Date
    Jan 2013
    Posts
    106
    Itís a 16 bit dsPic doing the drawing to LCD, should have more RAM than low range pics.
    I do at least know SD card filesystem routines exist, and do work for it.
    People I know on the microcontroller forums have used SD cards in the raw fashion,
    and I would also have access to those examples.


    Iím sad now I discovered my code to check if inside a polygon is not my code,
    but probably the only iOSsy code I used. So Iíll have to scrounge the way to do that.


    Code:
    if (shapeContainsPoint == TRUE) {inboundsnp = 1;} // check if in National Park polygon

    I do have distance to point, bearing to point, foot of perpendicular worked out in C,
    and have also been limited to 4 Mb of data RAM before where I had to pre-index the file.


    This one is a vector map if you take away the bitmap background.
    There was enough memory here to store the entire map in RAM,
    and cycle for closest topographic contour (3D elevation with no need for GPS),
    and keep the cartoon hiker on track (foot of perpendicular)....
    all at the same cycle as drawing the lines.
    The red line is where the GPS is, and the cartoon hiker is where the GPS should
    ideally be (on the nearest point of a track).


    https://www.youtube.com/watch?v=B2nHh8s985M


    This is kind of what Iím looking to port, not so fancy, but all of the C that drives it,
    but for the time zone map, Iíll really have to find how to check in bounds of a polygon.
    Iíll really have to go check how much RAM I have and also look at other chip options.


    Iíll come back when I at least have GFX display and some storage connected to a chip

  8. #8
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    How about using the elevation data instead of the topographic contour lines, and generate the contour lines on demand?

    You might need to resample the topographic data available, to get a regular rectangular grid. A regular rectangular grid is ugly, but I'm not suggesting that; the end result would be a triangular/hexagonal grid, see below. If the distance between height samples is L, you can use a regular rectangular grid cells L wide and 2Lsin60į ≈ 1.732L tall (or vice versa); just have one sample at the corner of the cell, and one at the center. A 16-bit unsigned integer would work -- either feet, or thirds of a meter, so you can cover everything from Mariana Trench to top of Mount Everest -- so that'd be 4 bytes per 1.732L2, or about 2.31 bytes per L squared. Given that the total surface area of the Earth is about 510,072,000 km2, the dataset is about 1.1GiB at 1km resolution. Only 30% of that is land, however. I'd probably go for something like 20-30 meter resolution; should be enough for hiking.

    Time Zone map data-grid-png

    Within each triangle, using data from one, two, or three cells, you can interpolate the height at given point trivially, because the relative distances to the three defining points are always constant. (I can derive the exact equations, if you like.)

    Furthermore, you can draw any contour curve or curves you want. Within each triangle, there can be at most one line belonging to a topographic contour curve.

    Consider the leftmost, red, triangle above. It is defined by three points: corner point of cell (1,2), A12, and center points of cells (1,1) and (1,2), B11 and B12 respectively. The center cell in the above image is cell (1,2). If one or two of those points are at or below the contour curve, and one or two is above the contour curve, then the curve passes through this triangle, and is approximated by a line. Let's say that C is our contour level -- remember, we can pick these freely (which might come in very handy when hiking, and considering different paths, if the data was detailed enough) --, and that
    A12C
    B11 > C
    B12 > C
    then we know for a fact that the contour line crosses the triangle sides A12B11 and A12B12. You can trivially compute the intersection points using linear interpolation:
    t1 = (C - A12) / (B11 - A12), 0 ≤ t1 < 1
    t2 = (C - A12) / (B12 - A12), 0 ≤ t2 < 1
    If the 2D coordinates for the points are PA12, PB11, and PB12, then the contour line is drawn between P1 and P2,
    P1 = (1 - t1) PA12 + t1 PB11
    P2 = (1 - t2) PA12 + t2 PB12
    There are a total of six cases how the contour line might intersect the triangle, plus another six cases where the contour line is an edge of the triangle (because two were equal to C and the third was not), but it's all symmetrical to above.

    If you rotated the display, only the PA12, PB11, and PB12 are rotated above -- and since they are just the regular rectangular grid points (corner and center points), they can be trivially derived just from your orientation and relative position.

    If you had a color display, many microcontrollers are fast enough to calculate the interpolated elevation at every pixel in any orientation or scaling if you use a regular rectangular grid, but for contour lines, you definitely want the center point too, to make the contours look more natural.

    If you draw more than one contour line, as in the video displayed, do note that there often are more than one contour line within each triangle. The restriction here is that a single contour line only passes through a triangle once; every contour line you have could very well pass through the same triangle. So the resolution you should target is basically determined by how precise data you can get your mittens on, and how much storage you can devote to it.

    For example, if B12 was the highest elevation compared to the six surrounding points, you'd have a six-sided polygon around it, approximating the contour.

    For different zoom levels, just store additional datasets with L doubled every step. You only need at most 1/3 more storage space (1/4 + 1/16 + 1/64 + 1/256 + ... ≤ 1/3).

    It would also make sense to clip all paths to sub-paths that fit within a cell. That way all your path considerations are limited to sub-paths in four cells or fewer (to consider everything closer than L/2), or eight cells or fewer (to consider everything closer than L).

    A full planetary map could start with an icosahedron (20-sided regular polyhedron with triangular faces), then recursively subdivide each triangle into four sub-triangles, down to desired detail. (Yes, you can use this approach to specify a direction or position on a spherical shell using a single integer, at arbitrary precision.) In this case, you'd have for example average elevation stored for each triangle. Unfortunately, the calculations between subdivided icosahedral coordinates and standard latitude-longitude coordinates are so nasty I don't think anyone has seriously even considered this approach. The nice thing in this approach with relation to Earth is that there are several orientations in which land masses are nicely contained within the triangles, and even on the highest level, the distortion between a flat triangle and the spherical surface is very small; nothing like for example a Mercator projection, which is ridiculously stretched.

    If anyone is interested in the math involved here, I'd be happy to elaborate. I had a hobby project in late nineties involving elevation data and contour curves for Pyhš-Luosto National Park, but at that time, the elevation data was not freely available in Finland. In fact, just the elevation data for the region involved would have cost the price of a new computer. So that was that. I did scan some maps, extracted the contour curves, but the ensuing reconstructed elevation data was unnatural; it'd have needed serious filtering to make it resemble the actual data (some erosion modeling, maybe?). Or maybe my home-grown data extraction functions were just incorrect..

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. making a time zone converter
    By haru31773 in forum C Programming
    Replies: 2
    Last Post: 03-09-2010, 11:11 AM
  2. Time Zone
    By fragrax in forum C Programming
    Replies: 3
    Last Post: 07-10-2008, 07:53 AM
  3. need help in time zone
    By Gong in forum C++ Programming
    Replies: 2
    Last Post: 01-03-2007, 04:44 AM
  4. question on how to get different time zone
    By godhand in forum C Programming
    Replies: 5
    Last Post: 04-13-2004, 01:00 PM
  5. Time Zone Bias?
    By EdwardKoo in forum Windows Programming
    Replies: 0
    Last Post: 11-27-2002, 04:28 AM