I don’t mind if I’m incomprehensible

Campus Map Part II (of I): Nothing is Ever Simple

leave a comment »

I received a bit of feedback on my previous post.  Based on that, I’ll write more about some stuff we did because we had to.

There wasn’t an introduction to the project last time, so here’s a quickie.  Store GIS data in MySQL, deliver that data to the Google Maps API with PHP, profit!

Whining Mode: On.

The first issue wasn’t so much that there was no existent solution, but more why the hell was it so hard to find.  I’ve already mentioned in the previous post that we need to generate map tiles, and since we are stacking images, these tiles need transparent backgrounds.  And I don’t mean your one color transparency with ImageColorTransparent, but fit for the 21st century alpha channel transparency.  (Partly because IE6 requires it; amazingly one color transparency backgrounds worked in the modern browsers.)

This should be easy.  And it is once you figured out the right functions to call, but getting there was a pain.  I don’t know if it was the poor documentation in the PHP manual, the bad examples I saw, or I was just sleep deprived and really dumb.  It was probably all three ingredients with some weak sauce thrown in for that extra FAIL flavor.

At the beginning when I was just learning the GD functions by creating simple sample images, I’d manage to get PHP segfault on me.  Not an error message, not an exception, but segfault!  Just for calling a certain combination of GD functions.  (Not sure if order mattered.)

Anyway, I just wanted to bitch.

After I had the tiles working, I wanted to add anti-aliasing to them.  Luckily, GD’s ImageAntiAlias “does not support alpha components”.  Did I say “luckily”?  I mean “WTF, FINE!”  Learning from a user comment in the PHP doc, I made the original “master” image much bigger, and then used ImageCopyResampled to create the scaled down, pseudo-anti-aliased tiles.

They look much better.  But of course now the tile generation process is even slower (while keeping the memory footprint the same).

MySQL stores the GIS data in some sort of binary format.  There are no corresponding native PHP types.  That means whenever we retrieve data, we’d need to wrap AsText around the appropriate fields.  And then parse the returned text into something useful with regular expressions.  Now I have two problems.

Actually, I’ve got three.  CakePHP doesn’t provide a way to wrap a MySQL function around a column for its built-in find methods, nor does it offer a way to register callbacks on the records returned, so I can have CakePHP automatically perform the parsing.  (We’re using CakePHP, because, um, it’s the kind of the default around the office.  It’s far better than no framework at all.  But not awesome enough for me not to curse at it.)

Yep, had to cheesy hack that stuff in.

In the previous post I said one of the consequences of using tiles was having to move the click handling to PHP, i.e. whenever someone clicks on the map, send the latitude/longitude back to the server to check if she clicked on something (building, parking lot, whatever).  Since MySQL already has functions that test relationships between geometries, I can just use it for this purpose.

O Reader, surely you’ve noticed the pattern and know what’s coming…

Not if I RTFM!  “Currently, MySQL does not implement these functions according to the specification. Those that are implemented return the same result as the corresponding MBR-based functions.”  OMG wut good iz u then!?  A solution was implemented in PHP instead.

No choice really.


Written by Barry

December 28, 2007 at 6:07 am

Posted in Nerdy

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: