GEOS Bindings Maintainer

Posted by Charlie Mon, 17 Apr 2006 04:55:00 GMT

I seem to have officially inherited the job of maintaining the GEOS language bindings from Sean :)

For those who don't know, GEOS is an open source C++ library that contains a lot of functionality for analyzing and manipulating geometries. It is also one of the key parts of PostGIS. Sandros and Mateusz have been doing a ton of refactoring and adding functionality in preparation for a Geos 3.0 release (no date yet determined).

Besides providing a C and C++ api, there are also Python and Ruby bindings (the Ruby bindings will be new with the upcoming 2.2.2 release). This is the bit I now maintain. So check it out, and any ideas/suggestions are welcome - send them to the geos-devel list.

Thanks to Sean, Sandro and Paul for setting this up.

Posted in ,  | no comments | no trackbacks

Disappointed in Firefox 1.5

Posted by Charlie Thu, 13 Apr 2006 23:17:00 GMT

I have to join the ranks of those unhappy with Firefox 1.5. I've been using Mozilla browsers forever - long, long before Firefox. I switched over to Firefox right around the time it was called Firebird.

At Smallworld/GE we put great focus on making sure our clients would run in IE 5/5.5/6.0 and Mozilla 0.8/0.9. Most people at the time thought we were nuts - why bother with a browser that no one used. But Mozilla was much more standards compliant and offered good debugging tools (Venkman). It was the right thing to do, and since I was in charge of the development group, I made sure it happened.

Fast forward four years - I was quite excited by the release of Firefox 1.5. It was great to finally see SVG make it into a mainline browser and the canvas functionality also looked intriguing.

However, when I upgraded I was met with disappointment. First, Venkman didn't work and it took a non-Mozilla employee to fix it. Talk about a marketing blunder - it sends totally the wrong message to the large numbers of developers who love to work with Mozilla/Firefox because of its openess.

And of course there is the obnoxious memory usage, which is explained away using the tried-and-trued trick of as designed. I’ve used that one once or twice before :)

I suppose you could consider the above nitpicks, but the most damming bit is that Firefox just doesn’t work well on Windows. I tend to open a large number of browser windows with a large number of embedded tabs – so at any given time I’ll have 15 or 20 pages open. This has always worked in previous versions of Firefox and Mozilla. With 1.5, within half an hour I’ll try to load a page and Firefox will spike the CPU at 100% and hang. As far as I can tell this is random, but it always happens, and some websites are worse than others. If you wait about 20 seconds, the CPU usage may drop and Firefox will once again become responsive. But every page you load after that will have the excruciating CPU spike and wait. And more often than not, Firefox will never return and the CPU usage will remain at 100%. Thus I find myself killing off Firefox with Ctrl+Alt+Del multiple times a day.

Remembering that I've used Firefox for 3 plus years now, I thought maybe the problem was caused by cruft in my profile. So I backed it up, wiped it clean, and started with a fresh slate. I even uninstalled Firefox, cleaned everything out, and reinstalled. No difference.

From talking to people, and from my observations, these problems don't seem to happen on Linux (no idea about the Mac). But that’s still no excuse for not delivering a quality product on the most widely deployed operating system.

I fear that 2.0 will be no better, since it is based on the same underlying 1.8 Gecko rendering engine. I hope I’m wrong.

Posted in  | 9 comments | no trackbacks

Updated Rails Plugins

Posted by Charlie Thu, 13 Apr 2006 19:18:00 GMT

Tom Fakes was kind enough to point out that the Rails Rest controller and content negotiation plugins I posted a couple of weeks ago can no longer be downloaded. They unfortunately were deleted when my server crashed last week.

So I've uploaded new versions of the plugins that work with Rails 1.1.1.

If you're interesetd in the Rest controller, I'd recommend looking at this one on RubyForge. It was written by Dan Kubb and then modified based on feedback from Peter and myself. This post to the microformats rest mailing list provides a bit of the technical background.

Posted in ,  | no comments | no trackbacks

Dynamically Scoped Variables

Posted by Charlie Thu, 13 Apr 2006 09:35:00 GMT

Just as Peter continues to be amazed by Wikipedia, so do I. Today I noticed that David Jenkins, who I used to work with, wrote an article about a programming language called Magik that forms the basis of Smallworld GIS.

Magik was revolutionary for its time - a dynamic/strongly typed object-oriented language used to build large mission critical applications. It shares many similarities with Smalltalk and Ruby, including mixins, closures, procs, etc.

And one thing it has that Ruby doesn't is dynamic variables. Dynamic variables have been around a long time, LISP has them as does PERL. But if you've never worked with dynamic variables they are a bit weird. At least I thought so.

The basic idea is that when you set the value of a variable it will override any previous values for the remainder of that scope but then return back to its original value at the end of the scope. Thus a dynamic variable acts just like a stack.

Let's take a look at an example from Wikipedia:

int x = 0;
int f () { return x; }
int g () { int x = 1; return f(); }				

If you call g() what's the result? Well, most people would say 0 which is true for lexically scoped variables. But for dynamically scoped variables it is 1. See why? In g we override the value of x and make it 1. That value remains the current value as g calls f and accesses x. Once we return out of g, x reverts back to its original value of 0.

Reading Paul Graham's On Lisp, it turns out that LISP started with dynamically scoped variables. However, it turns out that lexically scoped variable are generally more useful because they are easier to understand and enable the use of closures. If you think about it for a second, you'll see that dynamic scoping doesn't work well with closures since the whole point of a closure is to capture the current value of a variable.

So, why would you use dynamic variables? For the longest time I didn't see much use for them. But in turns out they are quite useful in multi-threaded applications. Imagine you've written a gis server (ala ArcIMS, MapServer or Smallworld IAS) and each client can request a map in a different projection. That means that your map rendering code has to have access to the current projection. One simple way to do this is via dynamic variables. Set the dynamic variable at the start of the request and have the map rendering code access its value. Something like this (in pseudo Magik no less!):

# Create a global variable
_global current_projection = 'epsg4326'

_method process_request
  # Override the default value as a dynamic variable
  _dynamic current_projection = 'epsg9822'
  
	 # Do some stuff
  ...

	 # Render map
  self.render_map()
_endmethod

_method render_map
  # Access dynamic variable
  _if current_projection == 'epsg4326'
  _endif
_endmethod   
      

Although it looks like the render_map code is accessing a global variable, it in fact is accessing a dynamically set variable. Thus this code is fully thread safe.

For the case above you can fake dynamic variables by using thread-local storage. In fact, Christian Neukirchen has used this technique to implement dynamic variables in Ruby.

Now, let's get back to my post yesterday about Rails and HTML/XHTML generation. If you write an application server, you'll found out sooner or later that just about every piece of code needs access to the request and response objects. I suppose this might seem obvious, but it took me 2 years and 3 release of SIAS to finally see the light. My resistance was from fear of creating too tight a coupling between different parts of the system.

Rails of course has the same issue. The general solution, and the one Rails takes, is to pass around a reference to an object that holds the information you need. For rails, that is the controller object which in turn has references to the request and response objects. However, it doesn't work quite as well as you would like, as I explained yesterday. And woe to you if you want to change it - then you really are touching every part of the system.

In contrast, dynamic variables provide a cleaner solution. All parts of the code have access to the necessary information, and you don't have to pass object references as method parameters all over the place. Thus you end up with less code, and in fact, less inter-module dependencies.

So although a seemingly obscure programming language construct, dynamically scoped variables can come in handy in the right situations.

Posted in , , ,  | 2 comments | no trackbacks

Typo Feeds

Posted by Charlie Wed, 12 Apr 2006 17:50:00 GMT

One of the nice new featues in the HEAD version of Typo is per-category feeds. However, it wasn't quite obvious to me how to access them. A quick look at xml_controller.rb and routes.rb cleared things up.

From routes.rb we can see that you can specify a :type and :id when requesting a feed.

 map.xml 'xml/:format/feed.xml', :controller => 'xml',
         :action => 'feed', :type => 'feed'
  map.xml 'xml/:format/:type/feed.xml', :controller => 'xml',
         :action => 'feed'
  map.xml 'xml/:format/:type/:id/feed.xml', :controller => 'xml',
         :action => 'feed'

Digging through xml_controller.rb we can then see that the allowed types are:

  • comments
  • trackbacks
  • article
  • category
  • tag

 

So to see an atom feed of all the articles you've written categorized under Ruby you'd use this url:

mysite/xml/atom10/category/ruby/feed.xml

Posted in  | 5 comments | 2 trackbacks

Rails and HTML and XHTML

Posted by Charlie Wed, 12 Apr 2006 08:47:00 GMT

Rails support for HTML and XHTML is less than exemplary. For some reason, the 1.1.1 release considers the application/xhtml+xml mime type to be a synonym for text/html. Umm....why?

And it gets stranger still. If you've ever looked at the HTML that Rails generates you'll see markup that looks like this:

<head>
  <link ... />
</head>
<input type="text" value="foo" name="bar" /><br />

Notice the extra "/>" characters? This usage comes from none other than the W3C which recommends it if you want older browsers (at this point only Internet Explorer) to be able to render your XHTML as if it was HTML. Whether this is a good idea or not is long-standing religious debate that's not worth rehashing.

What is worth asking though is why is Rails doing this? Right now it provides the worst of all worlds. First, it serves quasi XHTML to browsers as HTML. This is wrong for Firefox, Safari and Opera which all understand XHTML. And it serves XHTML to Internet Explorer which doesn't understand it. In addition, this quasi XHTML masquerading as HTML doesn't validate against the HTML 4.01 strict standard or the XHTML standard.

Wouldn't it be a whole lot easier to generate HTML 4.01 and be done with it? The alternative solution is to implement content negotiation so that XHTML is served to modern browsers and HTLM to Internet Explorer. However, before you can even take the first step in this direction you have to teach Rails that XHTML is in fact not HTML. Here is the code:

module ActionController
  module MimeResponds
    class Responder
      DEFAULT_BLOCKS = {
        :xhtml    => 'Proc.new { render }'
      }

      for mime_type in %w( xhtml )
        eval <<-EOT
          def #{mime_type}(&block)
            custom(Mime::#{mime_type.upcase}, &block)
          end
        EOT
      end
    end
  end
end

module Mime
  # Fix HTML
  #HTML  = Type.new "text/html", :html, %w( application/xhtml+xml )
  HTML  = Type.new "text/html", :html
  
  # Add XHTML
  XHTML  = Type.new "application/xhtml+xml", :xhtml
  
  # Fix xhtml lookup
  LOOKUP["application/xhtml+xml"] = XHTML
end

Once you've done that, you need to change the ActionView::TagHelper::so that it doesn't add in the "/>" characters. However, at this point you run into a problem. To figure out whether to close the tag or not requires knowing the response content type, which is on the response object. Unfortunately, the tag method is mixed into ActionView::Base as well as ActionView::Helpers::InstanceTag (and maybe others classes also). The problem is that getting the the response object is different in each case. It would be nice if there was a global place to get it from. More about this in a future post.

Posted in , ,  | no comments | no trackbacks

Ruby Bindings for GEOS

Posted by Charlie Wed, 12 Apr 2006 08:08:00 GMT

One of the things I do is help maintain the SWIG bindings for the GEOS project. GEOS, which stands for the Geometry Engine Open Source, is a library for working with 2D geometries. It includes support for various spatial operators and relationships (for some nice pictures that visually explain what these are take a look at the PDF documentation for a closely related project called JTS).

The original SWIG binding was done by Sean Gillies for Python about a year ago. The upcoming GEOS 2.2.2 release will include a Ruby binding that I've put together. Since 2.2.2 is a bug fix release, the new Ruby binding is not part of the standard build process. This has already been fixed in CVS head, and both the Python and Ruby bindings will be fully integrated into the standard build sequence for GEOS 3.

For those intrepid souls who would like to try out this library here are the instructions on how to build it.

If you are using Linux or cygwin or mingW and msys on Windows:

# Change to the directory where you installed geos
$ cd /usr/src/geos/swig/ruby (or wherever you installed geos)


# Download the SWIG interface file or
create it using SWIG 1.3.29 or higher
$ swig -c++ -ruby -autorename -o geos_wrap.cxx ../geos.i

# Compile the SWIG wrapper
$ g++ -c -I../../source/headers/ 
         -I/usr/lib/ruby/1.8/i386-linux geos_wrap.cxx

# Create a shared library
$ g++ -shared -lgeos -lruby geos_wrap.o -o geos.so

# Install the shared library
$ sudo cp geos.so /usr/lib/site_ruby/1.8/i386-linux/

# Test out the new extension
$ irb
# Load the extension in IRB irb(main):004:0> require 'geos'
=> true
irb(main):005:0>

If you are running on Fedora Core 5, you will run into this error when trying to load the geos.so ruby extension:

cannot restore segment prot after reloc: Permission denied

Dan Walsh recently explained that this is caused by SELinux permission checks. To work around it:

$ chcon -t textrel_shlib_t 
   /usr/lib/site-ruby/1.8/i386-linux/geos.so

You can also build GEOS and the Ruby extension with Visual Studio 2005. Unfortunately, the Visual Studio project file that ship with GEOS 2.2.1 does not work and as a result have been removed from the distribution. If people are interested, I'd be happy to post my custom solution files.

Once you've built the extension comes the fun part - using it. To get started, take a look at the test suite I've put together in ruby/test. You'll see examples that show how to use a significant part of GEOS's functionality, including:

  • Importing and exporting geometries using the well know binary and text formats
  • Spatial operators such as buffers, centroids, etc.
  • Spatial relationships such as overlap, within, etc.

 

Good luck and let me know what you find!

Update - Good news. It turns out that Hobu has been maintaining a Visual Studio makefile that works with Geos. Its under geos/source/Makefile.vc. I'll see if I can put together a Makefile.vc for the Ruby bindings.

Posted in , ,  | no comments | no trackbacks

Back Online

Posted by Charlie Sat, 08 Apr 2006 09:44:00 GMT

A couple of days ago I had the good fortune of having a new Dell Dimension 9000 donated to MapBuzz. The plan was to replace an ancient PIII server with the new machine over the weekend. We were a bit worried about the PIII server because of its age and because it was running on a couple of non-RAID hard drives.

Well…the PIII server must have figured out that its days were numbered! Because yesterday one of its hard drives ground to a screeching halt (perhaps more about that in a future post). We didn’t have much valuable data on the machine, web stats mostly, but it was hosting Yue’s blog and my blog.

Since we had to configure the new machine, and were offline, we went ahead and also rebuilt the database server. However, that meant that our blogs disappeared for about 36 hours. It will be interesting to see if the spiders have given up on crawling savagexi.com yet or not.

Anyway, its good to be back online again!

no comments | no trackbacks

On Being a Plumber

Posted by Charlie Mon, 03 Apr 2006 07:30:00 GMT

After my uncle emigrated from Ukraine to the US after World War II, he made his living as a plumber. I think I’ve inherited one or two of his genes.

We live in small bungalow, not far from downtown Denver. The house was built in 1928, and was completely remodeled about five years ago by a previous owner. For the most part we haven’t had to do too much maintenance outside of repainting the house and putting up new gutters. Except for the pipes.

At this point, I think every appliance or pipe attached to the house has broken.

My plumbing career started with the sprinkler system after Yue got fed up after paying one to many repair men to fix. Her ultimatum was either I start fixing it or it was never going to be turned on again. Well, I’ve always liked digging around in the dirt so I was more than happy to give it a go. Perhaps that was a bad idea.

The first trial was fixing a valve that wouldn’t close - thus two stations (a station is a group of sprinkler heads) were on at the same time. We don’t exactly have great water pressure, so that wasn’t working very well. After doing plenty of reading on the Internet (it’s in my nature as an INTP) I found that it’s best to rebuild a valve, as opposed to replacing it. The problem with replacing it is that you have to cut the valve out, put a new one in, and then reconnect it on both sides. Of course, our sprinkler system is ancient, so it took most of a day driving around to small hardware stores to find the right replacement kit. Having found it, I got back home, and immediately took the valve apart. Which of course meant that I had no idea how to put it back together again (yes, I’ve learned this lesson so many times in my life I don’t care to remember, I clearly suffer from an over inflated view of my ability to put things back together). Well, I tried a couple times and failed. I finally had to take apart another valve before I figured it out.

Feeling proud of myself, I tested my handiwork. Station 1 good, station 2 good, station 3 good, station 4 good, station 5 - wait, two stations were on at the same time. Except two different ones. Grrrr. Feeling like an old hand, I traced back the line and figured out which valve wasn’t working and took it apart. And found that someone had stuffed part of a blue towel into our sprinkler system at one point - it was full of cloth. Cleaned it out. Checked another valve, same thing. And another. Finally got all the valves working.

A couple weeks later, when the system automatically turned on water started bubbling up from our backyard. Not good. Time to take out the shovel and see what was up. Turned out there was a spiral fracture along the pipe. Off to Home depot to buy a hack saw, a bit of PVC, some glue, and try my hand at splicing a pipe. Luckily my brother Michael was around that day so it we made it into a fun home repair project.

About six months after that, one Saturday morning, I went downstairs and saw water running out of the ceiling. The only short-term solution I could figure out was to shut off the water supply to the house. And then call a plumber for emergency service - nothing like paying for Saturday repair costs.

That was soon followed one night by the dishwasher not draining. After taking it apart, I quickly saw the problem. The black plastic pipe used as a drain was bent at 90 degrees (pretty much the same as if you took a hose and bent it 90 degrees). Amazing it ever worked at all. Another trip to Home Depot, another few hours lying on my back in a wet damp place getting filthy.

And no, the litany doesn’t stop there. Next up was the upstairs toilet. One day the valve stopped working, so it was always draining. A bit annoying really. Another trip to Home Depot, another few hours chalked up in my new hobby. Then it was the downstairs toiler, same drill.

Not wanting to miss out on the fun, the washing machine decided to pipe up next (pun very much intended). I hadn’t noticed, but amazingly the plastic drain pipe from the washing machine was simply stuffed into another pipe. No clamp, no coupling, no nothing. Well of course one day when the washer was draining it popped out. And sprayed water over everything around it in the basement. For better or worse, we weren’t around so could only survey the damage when we got home. Thankfully there is a drain under the washing machine, so at least all the water was gone by the time we got back.

Then a few blessed months of happiness for our plumbing system - I think it went into hibernation for the winter. Nothing like a false sense of security.

Come spring time, the valve to turn on the sprinkler system broke. Now this valve is about six feet deep under the front yard - you access it by a long valve key. Against our better judgment we decided to fix it. Bad move.

We had to hire a sprinkler repair person that was a certified plumber to fix it since the valve attaches to the water main that runs from the Denver water pipe under the sidewalk to the front of the house. After an all day affair, two guys dug a hole and fixed it. Or so we thought.

Then came Saturday (yes, it’s always Saturday). In the morning I went outside and noticed a wet spot on the lawn about six feet above the sprinkler valve. Uh-oh. This is something I didn’t want to think about. By afternoon the wet spot had turned into a small trickle and by evening a little river. Ok, this did not look good - I had horrible dreams of the pipe bursting, the front yard being blasted away by the water pressure and the basement flooding. Time to figure out how to turn off the water main to our house. Nothing like playing with Denver water main valves. Luckily I managed to find a plumber who talked me through closing it over the phone without charging the obligatory several hundred dollars for coming out on a weekend. It turned out to be quite simple, if you ever need to know drop me a line. So Saturday evening, no water, no hope for water till Monday. Time to go out…all weekend.

Come Monday a plumber tells me that our water main is cast iron, is probably from 1928, and should have broken a long time ago. Probably messing with the sprinkler valve was the last straw. Time to get the back hoe, dig up the front yard, and replace the whole thing. Its really quite fun digging up your front yard, you get lots of attention from the neighbors. Until of course you get the bill - I don’t even want to talk about how much it cost. And none of it covered by insurance (a hard lesson to learn, most home insurance doesn’t cover water pipe/sewers in older homes). And while we were at it, the sprinkler valve was moved to above ground, next to the side of the house so no one ever has to worry about that again.

And that brings us to today. Can’t wait to find out what’s next.

Posted in  | 2 comments | no trackbacks

Restful Rails Revisited

Posted by Charlie Mon, 03 Apr 2006 05:51:00 GMT

Anyone interested in making Rails a bit more restful should check out the current thread on the Microformats Rest mailing archive.

A good place to start is message. You can also find more information on Peter’s blog.

Posted in ,  | no comments | no trackbacks

Older posts: 1 ... 9 10 11 12 13