SyntaxHighlighter

Wednesday, December 3, 2008

Creating JPG's and other formats with Python and GDAL

Ok for some daft reason the driver.Create() method is not supported by all image drivers, but the driver.CreateCopy() is. The main difference being that Create() actually creates the format from scratch whereas CreateCopy() makes a copy of another existing image. I'm sure they have their reasons, but I don't understand why everything isn't created in a generic image type and then converted to the destintation image format through CreateCopy().

Anyhow, this is how I created a JPEG with GDAL. The same approach can be followed for multiple image formats. See this link for a complete list of supported formats.
# Import libs
import numpy, os
from osgeo import osr, gdal

# Set file vars
output_file = "out.jpg"
output_file_root = os.path.splitext(output_file)[0]
output_file_ext = os.path.splitext(output_file)[1]
output_file_tmp = output_file_root + ".tmp"

# Create tmp gtif
driver = gdal.GetDriverByName("GTiff")
dst_ds = driver.Create(output_file_tmp, 512, 512, 1, gdal.GDT_Byte )
raster = numpy.zeros( (512, 512) )
dst_ds.GetRasterBand(1).WriteArray(raster)

# Create jpeg or rename tmp file
if (cmp(output_file_ext.lower(),"jpg" ) == 0 or cmp(output_file_ext.lower(),"jpeg") == 0):
jpg_driver = gdal.GetDriverByName("JPEG")
jpg_driver.CreateCopy( output_file, dst_ds, 0 )
os.remove(output_file_tmp)
else:
os.rename(output_file_tmp, output_file)

Create a GeoTiff with Python and GDAL

It looks like the GDAL tutorial on creating GeoTiff's is slightly outdated (2008/05). I received this error with Python 2.5.2, GDAL 1.53 and NumPy 1.0.4:
Traceback (most recent call last):
File "test.py", line 9, in <module>
dst_ds.GetRasterBand(1).WriteArray(raster)
File "/usr/lib/python2.5/site-packages/gdal.py", line 796, in WriteArray

File "usr/lib/python2.5/site-packages/osgeo/gdal_array.py", line 154, in BandWriteArray
AttributeError: dtype

As far as I can tell this occurs because the matrix raster doesn't have the attribute (property) dtype. Something must have changed, but I managed to get it going by using the numpy lib rather than Numeric.

The code that worked for me looks like this:
import numpy
from osgeo import osr, gdal
format = "GTiff"
driver = gdal.GetDriverByName( format )
dst_ds = driver.Create("out.tif", 512, 512, 1, gdal.GDT_Byte )
raster = numpy.zeros( (512, 512) )
dst_ds.GetRasterBand(1).WriteArray(raster)

One can also explicitly state the matrix's data type by adding the dtype attribute:
raster = numpy.zeros( (512, 512), dtype = numpy.uint8)

Tuesday, November 18, 2008

PHP: move_uploaded_file, Permission denied

If you ever receive the failed to open stream: Permission denied error in Linux on the move_uploaded_file function, try changing the upload folder's permissions through the chmod command:
chmod 0777 upload_dir

Monday, November 17, 2008

Nesting floating DIV overflow problem

I had an issue with non-IE browsers where a floating div would oveflow its parent container.

Here's an example:
<div id="Container" style="background-color: Blue; width: 400px; padding: 10px;">
<div id="Image" style="float: left;">
<img src="http://www.google.com/images/logo.gif" />
</div>
Some text yada yada. Some more text yada dada.
</div>

One can solve this issue by simply adding a div that places a break after the floating div:
<div style="clear: both; font: 1px/1px sans-serif;">&nbsp;</div>

So in the end, it should look something like this:
<div id="Container" style="background-color: Blue; width: 400px; padding: 10px;">
<div id="Image" style="float: left;">
<img src="http://www.google.com/images/logo.gif" />
</div>
Some text yada yada. Some more text yada dada.
<div style="clear: both; font: 1px/1px sans-serif;">&nbsp;</div>
</div>

Tuesday, October 28, 2008

PHP Web Application Root URL

I wrote this little function to return a PHP applicaiton's root url. It is very quick and dirty, but I thought I'd still share it:
function get_app_root_url()
{
$app_root_dir_name = getcwd();
$idx = strripos($app_root_dir_name, '/');

if($idx >= 0)
$app_root_dir_name = substr($app_root_dir_name, $idx + 1);

$app_root_url = get_page_url();

$idx = strpos($app_root_url, $app_root_dir_name);

if($idx >= 0)
$app_root_url = substr($app_root_url, 0, $idx + strlen($app_root_dir_name));

return $app_root_url;
}

// Curtosy of http://www.webcheatsheet.com/PHP/get_current_page_url.php
function get_page_url()
{
$page_url = 'http';

if ($_SERVER["HTTPS"] == "on")
$page_url .= "s";

$page_url .= "://";

if ($_SERVER["SERVER_PORT"] != "80")
$page_url .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
else
$page_url .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];

return $page_url;
}

Friday, October 24, 2008

So long Java!

I've been struggling on and off for over two weeks to get my development environment up and running for Java web apps. I went with the JBoss Seam framework, since it was supposedly lightweight; Eclipse because it had a lot of plugins and seamed to be the most popular free IDE; Tomcat, since its what our web server is running.

In the end I had to ditch Eclipse because it has major issues with plugins cross versions. It's near impossible to get the right jar files and versions for all the Tomcat, Seam and Debugging plugins to play together. So I went with NetBeans, which seemed to be miles simpler to use, but with less functionality and a smaller community.

Even with the simpler NetBeans it was still a mission to get everything working. Finally I was ready to start doing some real coding, but oh my, what a mess!! Perhaps I'm just an idiot, but Seam doesn't have any logical (/www/myproject/...) structure and there's hundreds of XML files all over the shop. Phew... I tried to follow a few tutorials, but I was unable to find a good one. There isn't a single one that just says 1. Here is all the crazy config files, 2. Here is the code, 3. This is how it it all is structured, 4. This is how you deploy... bla bla. Come on people! Keep it simple!

After getting the examples going I read somewhere that I would need JBoss AS in order to run Enterprise Java Beans and it seemed like Seam used EJB for session management or something. Aaargh!!!! The Seam website explicitly states that you can run Seam on Tomcat, but fails to mention that you wouldn't have all the functionalities. What a load of rubbish!! Our web server only runs Apache 2 and Tomcat, so this is a bit of an issue.

I could see that ease of web development in Java is still VERY mush inferior to the likes of Asp.Net or RoR. It's almost impossible for a noob to create a simple website that queries a db with an IDE that supports debugging.

I had a quick look at PHP and it took me two days (which is also far too long for my liking) to get a full dev environment setup with Apache 2, MySql, Eclipse, PDT and Zend. After that my first application was up and running within minutes. PHP is logical, very well documented and has a huge dev community. It seems brilliant!

So that was the final blow to the head for Java. I can't understand why Java is so popular in big enterprises. Well at least for the web side of things. It's like using C++ to run a web app. It simply isn't geared for that purpose. Or perhaps I'm just missing something.

Thursday, October 16, 2008

Facelets Support in NetBeans 6.1

After getting Seam working by manually deploying a .war, I moved onto the next step of integrating Seam into an IDE. Eclipse is a clunky heap of rubbish. I'd say its problem is that it is too flexible. There's a million ways to do one simple thing, but no single way to do one simple thing properly.

After serveral hours wasted on Eclipse, I moved over to NetBeans (6.1). There's a great little tutorial on getting your NetBeans environment setup over at Edem Morny's tech blog. Everything went smoothely, up to the part where one installs Facelets Support, where I get this nasty little message:
Missing required modules for Plugin Facelets Support:
JSP Parser [module org.netbeans.modules.web.jspparser/3 = 200805300101]
This can be avoided by not updating NetBeans. Fortunately there is a bit of a hack to get around this issue:
1. Go to your netbeans-6.1/enterprise5/modules directory
2. Unjar the org-netbeans-modules-web-jspparser.jar file
jar xf org-netbeans-modules-web-jspparser.jar
3. Create a backup of the orignal org-netbeans-modules-web-jspparser.jar just in case.
4. Edit the META-INF/MANIFEST.MF file.
5. Change the OpenIDE-Module-Implementation-Version: to match the verion the facelet is complaining about. In this instance 200805300101.
6. Save the file and jar the whole thing again (by explicitly adding the modified manifest file)
jar cfm org-netbeans-modules-web-jspparser.jar META-INF/MANIFEST.MF org