Adding Google Maps into Mobile Atlas Creator

Mobile Atlas Creator is an awesome tool for generating offline maps for mapping applications, such as the equally awesome RMaps for Android. Unfortunately, due to restrictions from many map providers, Mobile Atlas Creator no longer provides access to many map sources.

However, it is able to read user-customised map sources. So with the help of httpfox, I have managed to get google maps hooked up again. Just unzip the following files into the “mapsources” subdirectory of your Mobile Atlas Creator installation location, and then restart it.

Enjoy!

Google Maps (google_map)

<?xml version="1.0" encoding="UTF-8"?>
<customMapSource>
	<name>Google Maps</name>
	<minZoom>0</minZoom>
	<maxZoom>19</maxZoom>
	<tileType>png</tileType>
	<tileUpdate>None</tileUpdate>
	<url>http://mt0.google.com/vt/lyrs=m@156000000&amp;hl={$lang}&amp;x={$x}&amp;y={$y}&amp;z={$z}</url>
	<backgroundColor>#000000</backgroundColor>
</customMapSource>

Google Satellite (google_satellite)

<?xml version="1.0" encoding="UTF-8"?>
<customMapSource>
	<name>Google Satellite
</name>
	<minZoom>0</minZoom>
	<maxZoom>19</maxZoom>
	<tileType>PNG</tileType>
	<tileUpdate>None</tileUpdate>
	<url>http://khm0.google.com/kh/v=88&amp;x={$x}&amp;y={$y}&amp;z={$z}</url>
	<backgroundColor>#000000</backgroundColor>
</customMapSource>

Google Satellite + Overlay Hybrid (google_satellite_hybrid)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customMultiLayerMapSource>
    <name>Google Satellite Hybrid</name>
    <tileType>PNG</tileType>
    <layers>
        <customMapSource>
            <name>Google Earth</name>
            <minZoom>0</minZoom>
            <maxZoom>19</maxZoom>
            <tileType>PNG</tileType>
            <tileUpdate>None</tileUpdate>
            <url>http://khm0.google.com/kh/v=88&amp;x={$x}&amp;y={$y}&amp;z={$z}</url>
            <backgroundColor>#000000</backgroundColor>
        </customMapSource>
        <customMapSource>
			<name>Google Earth Maps Overlay</name>
			<minZoom>0</minZoom>
			<maxZoom>19</maxZoom>
			<tileType>png</tileType>
			<tileUpdate>None</tileUpdate>
			<url>http://mt0.google.com/vt/lyrs=h@145&amp;hl={$lang}&amp;x={$x}&amp;y={$y}&amp;z={$z}</url>
        </customMapSource>
    </layers>
</customMultiLayerMapSource>

Google Terrain (google_terrain)

<?xml version="1.0" encoding="UTF-8"?>
<customMapSource>
	<name>Google Terrain</name>
	<minZoom>0</minZoom>
	<maxZoom>19</maxZoom>
	<tileType>png</tileType>
	<tileUpdate>None</tileUpdate>
	<url>http://mt0.google.com/vt/lyrs=t@127,r@156000000&amp;hl={$lang}&amp;x={$x}&amp;y={$y}&amp;z={$z}</url>
	<backgroundColor>#000000</backgroundColor>
</customMapSource>

If you look at the url in the files, you can see that all the map tiles are downloaded from 1 google server mt0, when in google maps, tiles are downloaded from mt1 as well for load distribution. I don’t know if Mobile Atlas Creator supports this or not.

If I ever get to figure out how Bing or Yahoo map tiles are named, then I’ll probably post about them. But it is likely I won’t get to that :-P

Directly deleting files in OS X

In OS X, I’m so not used to having to send files to Trash first before emptying it, just to get rid of files I no longer want. In the end, I created an Automator service that does the job for me.

(File download at the bottom of this post)

How To Use

1. Select the files to delete, and right-click:

 

 

 

 

 

 

2. Confirmation Prompt:

 

 

Simple as that.

How It Is Done

Here is how it is done in Automator:

The guid in the text box of the “Ask for Confirmation” step is a hack to insert the file names into the prompt dialog (step 2 above). It is the guid of the variable “Files” in “Set Value of Variable”, obtained by opening the document.wflow file of this Automator service in a text editor and searching for it there. It is unfortunate that Automator doesn’t support variables in the text of the confirmation dialog.

So if the user clicks “Yes” to the dialog, the shell script will do our favourite rm -r on each file. Why “-r”? Because the file could be a folder too, which we delete -recursively.

Download and Install

The Automator Service bundle can be downloaded here: delete_Files_Mac.zip It is just a bunch of xml in a Mac bundle which you can freely examine in Automator or any text editor.

I don’t know if any install step is needed.

  • Unzip it and copy the app bundle to /Users/YourUserHome/Library/Services.
  • Try right-clicking on any unwanted files in Finder, and see if the “Delete File(s)” option appears at the bottom of the context menu.
  • If not, maybe try to open and save it via Automator and try again.

2 API differences between iOS and Android

These are just 2 differences that I’ve encountered recently, and I’m sure there’ll be more to come. Points to note when doing cross-platform coding.

Signed-ness of char type

char type is signed in iOS, but unsigned in Android NDK. For the latter, I’ve just discovered this post, which suggests that its an ARM code generation behaviour for gcc that can be handled by passing LOCAL_CFLAGS := -fsigned-char. I will give this a try.

Accelerometer reading values

iOS returns accelerometer readings in units of g, while Android returns in ms^-2. So for a device lying screen up on the table, iOS reports z = -1, while Android reports z = -9.81

Android also has a constant defined for the gravitational constant of Death Star.

Debugging release mode code with __asm int 3

Sometimes we have to run release mode code, either because it is what we’re testing, or it just takes too long to run the program in debug mode (I had one level which took > 15 mins to load up in debug mode, and that’s without the debugger attached!). While solving bugs in this case, I would sometimes like to break the process when some invalid situation occurs. I do this way:

if ( _isnan( someNumber )
{
    __asm int 3    // semi-colon not necessary
}

int 3 is a software interrupt that, in this example, gets triggered when someNumber is invalid, which means most likely the latter is an uninitialised variable. This is quite useful when logging to output is not an option.

Notes:

  • This is definitely not cross-platform
  • DebugBreak() and __debugbreak() should do the same thing, but its more l337 to use asm when debugging :-P

Actionscript TransitionManager Class

Actionscript 3 has a rather useful TransitionManager class to provide transition effects to movie clips. It provides a convenient function static TransitionManager.start() that we can use for adding effects (e.g. blinds, fly, zoom, etc). Whats missing from the documentation though is that the class that the effect is being applied on must be declared a dynamic class. This is something to note if you’re using it on a custom MovieClip sub-class. The MovieClip class itself is dynamic, so its not a problem. Doesn’t apply as well if you are using the instanced method startTransition(. . .).

Another useful thing to note is that the Transition class provides events for when the transition is completed, those being “transitionInDone” and “transitionOutDone”, depending on the transition direction. This is shown in the documentation example. It is unusual though that, unlike other events, they do not provide a static constant for these events, and we have to quote them as literal strings.

My renderer is cross-platform!

I’ve finally gotten my OpenGL ES code to cross compile and run on both iOS and Android. Have learned lots of things in the process. It’s still an extremely primitive “spinning cube” code, so there’s still heaps more work to be done, but at least most of it should be platform-neutral.

iOS (left), Android (right)

Its quite obvious from the screenshots that the lighting is different on both of them. Still have to figure that out too.

Back to work!

Conditional compile #define for iOS and Android platform

I’m working on a cross platform library for iOS and Android devices. The header files for OpenGL ES are in different folders for these platforms (see end of post), so I need to #include them differently per platform. Took me a while to find the proper one to #define for the iOS platform, so here it is:

#ifdef __APPLE__
    #include "TargetConditionals.h"
#endif
 
#if (defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR))
    #define PLATFORM_IOS
#elif (defined(ANDROID))
    #define PLATFORM_ANDROID
#endif

TargetConditionals.h is where the Target_OS_IPHONE and TARGET_IPHONE_SIMULATOR are defined, and it is only available on a Mac, hence it is wrapped in __APPLE__. The second part, PLATFORM_IOS is the preprocessor macro I’ll use throughout my code.

The #elif clause takes care of Android platform.

The OpenGL ES headers are located here:

  • iOS
    • #include <OpenGLES/ES1/gl.h>
    • #include <OpenGLES/ES1/glext.h>
    • (Swap ES1 for ES2 if you’re using that)
  • Android
    • #include <GLES/gl.h>
    • #include <GLES/glext.h>
    • #include <GLES/glplatform.h>
    • #include <GLES2/gl2.h>
    • #include <GLES2/gl2ext.h>
    • #include <GLES2/gl2ext.h>

My first post

Been hesitating about what to write for my first post. Should it be an introduction? There’s already an “about” page for that. Something to warm up the theme of this blog? Hmm…

The lack of creative writing faculty in me is preventing the opening of the floodgates for more posts to come. Ok, so here’s the solution:

*Reserved for future updates*

Voilà! Now I can properly start blogging! :-P