Monday, December 14, 2015

Nerdy Mapping Fun with Faerun and Google Earth, Part IV, KML Files

In Part I, I discussed the process of getting this awesome and massively detailed map of Northern Faerun by Mike Schley, onto Google Earth.

Going a little further than in previous posts, I wanted to see if I could display different maps at different zooms. For this I needed to create a KML file. This is actually easy to do manually, just create an xml file with a KML extension. You can get a lot of information on what is possible from KML files on Google Maps. Also, KML files use decimal degrees so I had to use the translated coordinates from previous posts.

I created two KML files. You can probably do it in one, but I had some issues with properly nesting the xml, so I separated them. The first file just positions the same four maps (though I'm using versions I created without text overlays) I used in my other posts. Getting the "href" path in the xml right on a Windows machine took a while to sort out, but otherwise this was fairly straightforward.

Then I created a second KML to bring in a detailed view of the Dessarin Valley and set the zoom level so it would only show up when you were in close. For this, I used another one of Mike Schley's maps. It took some work to get the edges more or less lined up and the scale to match, and I could delete the borders, to clean it up a bit, but in this case I was just testing out creating KML files so I wasn't overthinking it. Clearly, it would also be easier with maps designed for this purpose (Mike!?)

Here is the view zoomed out:

And zoomed in just a little:

I also added a placemark for Neverwinter, just to experiment with adding individual elements on the page. You can of course swap out the icons, position the text more elegantly but this was enough for a test.

Here is the first KML file.

<kml xmlns="http://www.opengis.net/kml/2.2">
  <folder>
    <name>Northwest Faerun</name>
    <description></description>
    <groundoverlay>
      <name>Faerun SW Corner</name>
      <description></description>
      <icon>
        <href>D:\[filepath]\nw-faerun-sw.jpg</href>
      </icon>
      <latlonbox>
        <north>41.250</north>
        <south>26.0000</south>
        <east>-118.475</east>
        <west>-150.000</west>
        <rotation>0</rotation>
      </latlonbox>
    </groundoverlay>
    <groundoverlay>
      <name>Faerun SE Corner</name>
      <description></description>
      <icon>
        <href>D:\[filepath]\nw-faerun-se.jpg</href>
      </icon>
      <latlonbox>
        <north>41.250</north>
        <south>26.0000</south>
        <east>-89.950</east>
        <west>-118.475</west>
        <rotation>0</rotation>
      </latlonbox>
    </groundoverlay>
     <groundoverlay>
      <name>Faerun NE Corner</name>
      <description></description>
      <icon>
        <href>D:\[filepath]\nw-faerun-ne.jpg</href>
      </icon>
      <latlonbox>
        <north>56.500</north>
        <south>41.250</south>
        <east>-89.950</east>
        <west>-118.475</west>
        <rotation>0</rotation>
      </latlonbox>
    </groundoverlay>
     <groundoverlay>
      <name>Faerun NW Corner</name>
      <description></description>
      <icon>
        <href>D:\[filepath]\nw-faerun-nw.jpg</href>
      </icon>
      <latlonbox>
        <north>56.500</north>
        <south>41.250</south>
        <east>-150.000</east>
        <west>-118.475</west>
        <rotation>0</rotation>
      </latlonbox>
    </groundoverlay>
    <placemark>
      <name>Neverwinter</name>
      <description>A city.</description>
      <point>
        <coordinates>-124.92085,50.227359,0</coordinates>
      </point>
    </placemark>
  </folder>
</kml>

And here is the Dessarin Valley KML file.

<kml xmlns="http://www.opengis.net/kml/2.2">
    <folder>
          <name>Dessarin Valley</name>
        <description></description>
      <groundoverlay>
        <name>Dessarin Valley</name>
        <description></description>
        <icon>
          <href>D:\[FilePath]\dessarin-valley.jpg</href>
        </icon>
        <region>
          <latlonbox>
            <north>50.400</north>
            <south>45.8</south>
            <east>-117.640</east>
            <west>-122.150</west>
            <rotation>0</rotation>
          </latlonbox>
          <lod>
              <minlodpixels>65000</minlodpixels>
              <maxlodpixels>-1</maxlodpixels>
            </lod>
        </region>
           <latlonbox>
               <north>50.400</north>
            <south>45.8</south>
            <east>-117.640</east>
            <west>-122.150</west>
            <rotation>0</rotation>
          </latlonbox>
      </groundoverlay>
    </folder>
</kml>

Getting this into Google Earth is now just a matter of File | Open and select each KML file. KML files can be used in other mapping software as well.

Nerdy Mapping Fun
  1. In Part I I overlay a map of Faerun on Google Earth.
  2. In Part II, Stitching it Together I repeat this process with the 34 part PDF map.
  3. Part III, Higher Resolution and now moving it around.
  4. In Part IV, KML Files I use KML files to display maps at different zoom levels.

Thursday, October 29, 2015

Nerdy Mapping Fun with Faerun and Google Earth, Part III, Higher Resolution

In Part I, I discussed the process of getting this this awesome and massively detailed map of Northern Faerun by Mike Schley, onto Google Earth.

Anonymous commented on Part I that he thought the map should be shifted North. My position was based on trying to keep the Jungle of Chult within the tropics. However, various older maps of Faerun have considerable variations in distances. Pending new updated maps from Mike / WoTC, I thought it would be reasonable to shift the whole map at least 4 degrees North, putting the Southern edge at 28N and the Northern edge at 56N. You could probably shift at least another 4 degrees depending on which map you use as a reference.

This also moves Baldur's Gate to about San Francisco, Neverwinter to Portland, and Neverwinter to a bit North of Vancouver, BC.

So in this version — I'm using the higher resolution tiled image from Part II — you get the following corners:

  • 150° 0'0.00"W 28° 0'0.00"N
  • 89°42'0.00"W 28° 0'0.00"N
  • 89°42'0.00"W 56°14'0.00"N
  • 150° 0'0.00"W 56°14'0.00"N

The midpoint for calculating the width is at 42° 7'0.00"N.

And here is how it looks.

Northwest Faerun on Google Earth
Nerdy Mapping Fun
  1. In Part I I overlay a map of Faerun on Google Earth.
  2. In Part II, Stitching it Together I repeat this process with the 34 part PDF map.
  3. Part III, Higher Resolution and now moving it around.
  4. In Part IV, KML Files I use KML files to display maps at different zoom levels.

Wednesday, October 28, 2015

Nerdy Mapping Fun with Faerun and Google Earth, Part II, Stitching it Together

In Part I, I discussed the process of getting this this awesome and massively detailed map of Northern Faerun by Mike Schley, onto Google Earth.

In addition to the map I originally used there is a ~34 part PDF version at about 2x the resolution of the JPG image. So, I decided to try using this and adding multiple image maps that I could tile together.

For this, I copied each PDF page into Paint.NET and alligned them. This turned out to be a bit of work as, in some cases, some of the images were off by a pixel or two. I'm not sure if this is an artifact of the conversion to and from the PDF or maybe my accidentally nudging pixels around as I worked. However, after some effort I had a nice 645 MB Paint file.

I then stripped the borders and cut the image into 4 equal 9735x6175 pngs. Before being optimized each image was about 140MB, after about MB.

I then ran a similar process as in Part I, bringing in the image, converting the coordinates to radians, measuring the distance between points and adjusting until they matched the map dimensions. As before, the North–South dimensions match the map, but only the mid-point line is accurate, with the Southern border stretched and the Northern border compressed.

For this version the combined tiles ran from Longitude 150° 0'0.00"W to 93°12'0.00"W and Latitude 24° 0'0.00"N to 52°14'0.00"N.

And looks good with double the resolution of the map in Part I.

Nerdy Mapping Fun
  1. In Part I I overlay a map of Faerun on Google Earth.
  2. In Part II, Stitching it Together I repeat this process with the 34 part PDF map.
  3. Part III, Higher Resolution and now moving it around.
  4. In Part IV, KML Files I use KML files to display maps at different zoom levels.

Nerdy Mapping Fun with Faerun and Google Earth, Part I

Updated with a few math fixes

I purchased this awesome and massive detailed map of Northern Faerun by Mike Schley, a digital version of the one included in the Dungeons & Dragons Sword Coast Adventurer's Guide.

The map weighs in at 10200 x 6600 px — a little less if you shave the borders — and also comes with a 34 page even higher detail PDF version. If I get ambitious I might stitch that together and use that instead.

However, at this scale the map really needs to be on a globe, for which Google Earth will do nicely. Now, some literature suggests Toril is slightly larger than Earth, some literature says the same size, but as far as I know Google Earth doesn't allow for rolling out your own planets, so our Earth will have to do.

First off, it is easy enough to overlay an image in Google Earth. In the menu bar: Add | Image Overlay. Wait a bit for the image to load. Then, change to the Location tab in the New Image Overlay popup and click the "Convert to LatLonQuad" button. This will give you the ability to set the four corners independently.

The Edit Image Overlay dialog's Location tab then lists four corners with Longitude and Latitude. The 1st corner is Southwest (bottom left) then Southeast (bottom right), Northeast (top right) then Northwest (top left).

The map legend is about 1820px = 500 miles. After shaving the borders I ended up with a map that was about 2674 x 1696 miles. Further, I assumed that this is actually a Mercator projection and so the distances are accurate North-South, but that East-West the scale is only accurate at the middle of the map.

Given those assumptions, everything is nicely parallel, with the Southern edge of the map ending up at about 3,124 nautical miles while the Northern edge is only 2,074 nautical miles.

I picked a starting point where Baldur's Gate will end up roughly on top of Los Angeles, CA (Waterdeep at Ashland, OR and Neverwinter at Seattle, WA). Using formulas from Allen Wyatt's ExcelTips I started plugging numbers into Excel.

I converted each LAT/LNG pair into radians using this formula:

=RADIANS((DEGREES*3600+MINUTES*60+SECONDS)/3600)

Then plugged a N-S pair into Excel, and adjusted, to get one edge using this forumula:

=ACOS(SIN(LAT1)*SIN(LAT2)+COS(LAT1)*COS(LAT2)*COS(LON2-LON1))*3443.89849

With that done, I took the mid-point between the North South edges, and plugged those into the same formulas to get the East West coordinates. I plugged those numbers back into the Google Earth location tab on the image overlay. And success!

Hard to see here but if you look close you can see the latitude and longitude markings.

The final values I used were:

  1. 1st Corner: 150° 0'0.00"W Longitude and 24° 0'0.00"N Latitude
  2. 2nd Corner: 92°12'0.00"W Longitude and 24° 0'0.00"N Latitude
  3. 3rd Corner: 92°12'0.00"W Longitude and 52°16'0.00"N Latitude
  4. 4th Corner: 150° 0'0.00"W Longitude and 52°16'0.00"N Latitude
Nerdy Mapping Fun
  1. In Part I I overlay a map of Faerun on Google Earth.
  2. In Part II, Stitching it Together I repeat this process with the 34 part PDF map.
  3. Part III, Higher Resolution and now moving it around.
  4. In Part IV, KML Files I use KML files to display maps at different zoom levels.

Saturday, April 27, 2013

First days with Google Glass

On this past Wednesday, April 24, after 11 months of — I'll admit to anxiously — waiting I was invited to come down to Google and pick them up (after forking over the cash of course). I was surprised at the level of attention I got from two Googlers who spent 30 minutes teaching me to use the device and getting the fit right. They followed this with a campus tour. They are definitely putting out the red carpet for Glass developers and it was low key but still fun and exciting.

With Glass the first thing I noticed was how high the build quality was and how comfortable they were to wear. The weight becomes noticeable to me only after having them on for several hours. And, though I wear contacts (or at least I do since I got the invite) after three days of on and off use, I have not felt any eye strain or issues. While I had trouble hearing the speaker if there was a lot of ambient noise, in other conditions it is loud enough.

Like many others, I think it would benefit from a less bulky and more aesthetically pleasing frame but I find the appearance less jarring than it appears in pictures, especially with (optional) sun glass lenses in place. The biggest issue I have had was setting the vertical adjustment of the screen. I had to twist the frame and the nose pads to get it to stay consistently in my FOV. Also, the battery life seems less than the all-day they suggested and, if participating in a hangout have your charger nearby. Making it work with existing glasses or the ability to add prescription lenses is also an obvious need.

Meanwhile, the deluge of anti-glass articles, some bordering on hysteria, and the "glasshole" meme have certainly managed to get the word out. I brought them to work and the existing level of knowledge and curiosity was crazy — better than any other product I've ever seen (including the Segway).

Of course, curiosity doesn't mean love, and I think many of the points that are being raised about the negative social implications and issues such as with using a voice as a primary interface in public, are real. I can recall the backlash against cell phones (long before smartphones) when they first began to encroach on daily life. It took years before a still-rough social etiquette developed. I will not be at all surprised if Glass and similar wearable computing devices' initial usage ends up being somewhat limited rather than in broad public and social settings. Although the dork factor is quite capable of doing serious damage. Just look at what happened to Segway and cell phone belt clips — hopefully Google will take this issue seriously.

Still, the naysayers seem to be primarily focused on the potential negative social aspects without giving thought to the utility. For me, I became a convert when my son asked me who the president of India was, and I said: "OK Glass, Google: who is the president of India?" and it whispered the answer in my ear. And to say I could take out my phone and look up the answer is like saying I can go to my desktop and look up the answer which is like saying I can get the answer by calling my local librarian — which is to say, not even close. The immediacy is amazing and almost shocking. Want to translate something? "OK Glass, Google: how do I say 'where is is the bathroom' in Turkish?" Want to know if it is raining outside just ask. Need to call your spouse, just say so.

I think this is a revolutionary product and the beginning of a trend that will be nearly unstoppable. While I expect social backlash and for many to reject these devices or at least be slow to adopt, and who knows what interface or products finally win out. The borg meme actually seems fitting here so, in the end, resistance is futile, you will be assimilated.

Friday, November 30, 2012

A knockout binding handler to update dynamically loaded Facebook plugins

When you are loading Facebook social plugins, Facebook takes the values, such as for the "data-href" value for a comments box, when the page is initially created.

Sometimes, you want to update the plugin after an observable has been updated or based on dynamic values coming in from a knockout template.

Here is a simple knockout binding handler that will call FB.XFBML.parse() to update the page after an element is bound.


ko.bindingHandlers.updateFacebook = {     
    init: function (element) {
        FB.XFBML.parse();
    }
};

And you can can use it like this, overwriting the initial value with the attr value:


<div class="fb-comments" data-bind="attr: { 'data-href': viewModelUrl  }, updateFacebook: true" data-href="@Request.Url" data-num-posts="10" data-width="400">
</div>

The FB.XFBML.parse() method will allow you update either the whole page or an element by id, so you could also do:


ko.bindingHandlers.updateFacebook = {     
    init: function (element) {
         var id = $(element).attr('id');
         FB.XFBML.parse( document.getElementById(id) );
    }
};

This is put together from Facebook's parse function, Ryan Niemeyer and from this post

Friday, September 21, 2012

Set KeyTips z-index

Because I pretty much just do whatever Hanselman tells me to do, I was trying to get some keyboard shortcuts set up on my website.

While testing with Damien Edwards KeyTips I could get the keyboard commands to work, but the popup would not display. It is a complex site, lots of css, ajax loaded objects, etc. Long story, short, I needed to set the z-index in the .KeyTips__popup class to be higher than the surrounding elements. .KeyTips__popup { //removed for clarity z-index: 1000; }