Archive for the 'default' Category

Phone Hacking (7 years later)

Posted in default on October 24th, 2011 at 21:09:53

Nearly 7 years ago, I first started hacking software on phones. This blog was started in part to track my interest in topics around mobile hacking, a desire that I’ve never given up on.

Amusingly enough, when I joined Nokia as an employee, I was able to actually find references to some of these early works as being important in the space of the Symbian Python developments. It was kinda cool to see my name in some PowerPoint presentation that had been put together 6 years before by someone I’d never met or even heard of.

But you’ll notice that since then, I’ve had a serious dropping off; there’s been a dearth of development in that space for a lot of years. The reason for this is simple: on the platform that I used the most for many years, development was a pain. Shipping applications to users was not possible, and as time went on, the number of people who even used the same OS or platform as I did was shrinking drastically, due to Nokia’s tiny marketshare in the US.

Up until two weeks ago, I had never owned a non-Nokia phone. Sure, when we were acquired by Nokia, I got an opportunity to use other phones — both to test out our software on them, and to compare how they succeeded and failed — but I never owned anything but a Nokia phone, from summer of 2003 when I got my first 3650, to April of 2010 when MetaCarta was acquired and I still had my N95 (with a 6600 in the middle).

That’s not true anymore, though.

I recently attended a Microsoft Windows Phone developer event, and I’m — almost 7 years later — hacking phones again. While there still isn’t anything quite as easy as Symbian Python — it’s really hard to beat something in a programming language I speak all the time, presenting a beautiful API to the widget sets that the platform makes available with almost no need for platform specific knowledge — the Windows Phone platform combines a strong toolkit, extremely broad set of documentation and examples, and another key thing that I never had in the Symbian world: the ability to get the applications that I write to users.

Nine days ago, just three days after getting Visual Studio installed in my Windows 7 VM, I was able to not only build, but deploy to my phone and upload to the Windows Phone Marketplace — where just a few days later, my app was available for all to download (well, at least everybody on Mango).

Windows Phone development is *fun*. The tools are helpful, intuitive, and a breeze to get started with. The documentation and support community is huge — building on top of one of the things Microsoft does best. And thanks to the developer event, I now own my first ever non-Nokia phone: an LG Quantum, won in a raffle among people who were able to build and demo an app in just a day at the Microsoft developer event.

While nothing can compete with Symbian Python for pure quick-hack ability — at least, nothing I’ve seen yet — the Windows Phone platform provides a great development ecosystem, with a strong community backing, and the ability to quickly and easily get together apps that do things. Once you do — not only to put them on your phone, but you can also get them in a store so everyone else can install them… and that’s just damn cool.

Many thanks to Joe Healy, and the whole MS Events team who were able to put together the Mango Boston event a couple weeks ago. It was pretty awesome to not only be able to learn about Windows Phone — but to be able to *do* Windows Phone development, and really get my hands dirty, and ship an app less than a week after I even got the dev tools installed on my system.

Tablet: The Bad that comes with the Good

Posted in default on September 11th, 2011 at 16:58:28

Of course, in addition to the good — solid OS, and overall positive experience from all sides — there is some bad that comes with the owning of my new tablet.

Lacking Apps

  • No Netflix. I said about 2 months ago that I’d run into my first real pain from DRM — not being able to move files from a broken Wii to a new Wii. This Netflix disaster is another one. Apparently there’s some software issues that prevent this, but the biggest reason that things seem to be stuck is simply because ensuring playback remains DRM-safe is harder than it should be. Netflix support exists on certain Android platforms, and there are a bunch of hacks out there to make it work on the tablet I have, but it’s not currently possible without rooting it.
  • No Hulu. Same as above. Hulu just gives a “No streaming support for your device” message when loading it in the browser, and there’s no App for Android. I’ve really enjoyed the fact that over the past year, more and more of my video watching can be done completely legally, and the lack of support for the tablet is forcing me to back off of that position overnight, which is a shame. (I’m happy to watch adverts, let people track me, even give feedback on how much ads appeal to me — if I can actually get my content. Since I can’t…)
  • No Facebook app? Not really sure what’s up with that, since it doesn’t seem like Facebook would be that hard, but there doesn’t seem to be an official Android Tablet app. I did grab a copy of “Friend Me”, which seems like it’s providing a reasonable replacement.
  • No support for DivX video playback out of the box — but easily solved with a number of other video players on the device, it seems. (Sadly, my personal favorite, VLC, isn’t yet publicly available for Android.

Hardware/Tablet Nits

The Tablet doesn’t seem to support USB mass storage. It does support the “MTP”/Media Transfer Protocol, so I was able to use an app called “XNJB” to copy files over to it, but not being able to use the built in filesystem tools in the OS is pretty unfortunate.

It’s not possible to connect to ad-hoc wireless networks, like those created on mobile devices using software like Joikuspot. It seems like there are (again) some workarounds to this — replacing wpa_supplicant on a rooted device — but nothing that you can do out of the box. (I hate turning ‘toys’ into ‘work’, so I’m trying to avoid rooting if I can.)

No charging, not even trickle charging, over USB. I really think this is unacceptable: even if you can’t increase battery power over USB, there is no reason that you can’t prevent my battery from draining as fast if I’m plugged into USB.

I’m sure I’ll run into more; this is just what I’ve run into so far as I go through. Overall, I’m still 100% happy with the purchase; it is so far looking like it will definitely be worth it for me. But I also recognize that it’s not a perfect tool, and there are improvements I wish could be made.

(As an aside: does anyone have any recommendations for a good Flickr *browsing* application, both my photos and others, on Android Tablets? “Flickr Viewer HD” is … suboptimal in the way it navigates, and browsing contacts photos seems hard to impossible.)

Taking the Tablet Dive

Posted in default on September 11th, 2011 at 16:36:37

(Cross-posted from my LiveJournal.)

Yesterday, I bought myself an Android-based tablet.

I’ve been considering this purchase for a long time. Tablets are one of those things that I have always been wary of, because I’m not as much of a media user as a tablet really targets, I think. However, after a recent flight to Berlin, I realized that I have at least one solid use case for a tablet, in the form of a media player on flights. With that in mind, I quickly moved onto others: showing photos I’d taken to family members, an easy way to get computerized video to the TV, etc.

In addition, it would be a chance to explore Android. I’ve played with a lot of other mobile platforms over the past 18 months, but not Android — and although it’s not quite a phone, the Android tablet experience is still an Android experience.

I’ve been biding my time for a while, while the marketplace kind of leveled out. Handily, my coworkers have done my research for me: over the past 3 months, 3 other people in the office have bought the same Tablet, so I joined the crowd yesterday, and bought an Acer Iconia Tab.

So far, I love it.

Using it makes me feel like I’m in Star Trek, or Minority Report. *whoosh* goes the desktop! *Whoosh* Slicing some fruit!

The application support is obviously much broader than WP7 or Symbian’s; more quick toys, more real tools, more access to third party services that make using the thing easier. The OS really feels clean and relatively solid — I’ve used Android on phones before, but not a recent version, and the tablet experience feels so much ‘cleaner’ than any of the phones I’ve used. In the browser, things like OpenLayers support dragging, pinch-zooming, drawing in the browser, which is awesome. (I should really see if I can dig up whether/when that is happening or not happening in the 2.x series… or maybe 4.x will just fix it for everyone.) The browser really feels nice and relatively solid. The desktop, and widgets, are both nifty and useful.

The Acer was what I picked because it was essentially the same as the Xoom and Galaxy Tab 10.1 in functionality, form factor, etc. — but it was $100 less. I still need to explore sleeve/case for it to protect it from my stupidity, but for now: I have a new shiny toy, and it is Nifty.

Demo: Leaflet/OpenLayers Translator

Posted in default on September 4th, 2011 at 08:06:28

икониFor a long time, I’ve seen complaints that the OpenLayers API is ‘too complicated’ — that there are too many options, that it’s too difficult to configure, etc. I’ve said for a long time that although OpenLayers offers a lot of power, it’s also possible to make things simpler with a relatively thin layer on top of OpenLayers — that the power doesn’t necessary have to compete with simplicity, but that maintaining a simple wrapper at the OpenLayers level is probably not ideal, for a lot of reasons.

I’m obviously not a good target for making a simpler API — I don’t consider OpenLayers difficult to use, so it’s really hard for me to be the one to implement an ‘easier’ to use API! Thankfully, only 3.5 years after I started saying someone should write a simpler API, there appears to be a significant competitor to OpenLayers which is being praised for its ease of use: Leaflet, from Cloudmade.

So, after watching people continually praise the Leaflet API, I thought I’d see what it took to make OpenLayers as easy to use as Leaflet. I started with the Quick Start example, and worked my way down the features of the page until I got to the end.

The result is the ol-leaflet-wrapper quick-start — a substantially similar page, which looks the essentially the same as the Leaflet Quick Start guide (minus popups). Total code to implement: 99 lines.

Now, I’m not saying this is a full-fledged wrapper: in fact, anyone with half a brain would be able to observe that this particular example is missing one big feature, in the form of popups. (In fact, I think this kind of demonstration is one very easy way to make it clear where the OpenLayers *library* is deficient: things that are hard to wrap between one library and another are a clear target for API refactoring and cleanup.) Any deeper look would show that I’ve only minimally wrapped Leaflet, and that a more complete wrapper would still be a significant investment.

However, I do think that it’s possible to make the kinds of changes that people desire most from OpenLayers *without* completely reimplementing the library — and even without a refactoring of the (admittedly bulky) core library; instead, approaching a new API as something built on top of the existing is a way to rapidly prototype a new approach, and integration or improvements can move into the core library as needed.

And if people who like OpenLayers really want a simpler API like Leaflet — well, I’m happy to help develop the Leaflet API wrapper into something more real, to help direct what a suitably friendly API for working with OpenLayers might actually look like.

Flying United (or not)

Posted in default on July 3rd, 2011 at 19:14:14

иконописПравославни икониToday, my 13-year old daughter was flying from Manchester to Greenville/Spartanburg, transferring in Dulles. She was flying without the unaccompanied minor service. Her connection time in Dulles was short (only 1hr15m), but should have been sufficient.

At 4:50PM, her flight status was updated, making it clear that her flight was going to be an hour late in arriving, arriving at 4:54PM. (Admittedly, I should have been keeping closer track and making some phone calls earlier, but I doubt it would have helped.) She pocket-dialed me at 5:00, so I knew she was at least somewhere with cell reception; unfortunately, calling her back didn’t get any response.

At 5:05, I called United, and asked if they could confirm her status — whether she made her flight. While navigating their phone menus, I observed that the flight she was supposed to take had taken off, 5 minutes early. I gave United her name + flight information, and they then proceeded to take 5+ minutes to tell me that she had left from Manchester earlier that day. (Thanks for telling me information I gave you.) They also told me her flight was late (thanks again), and that she was rebooked for the next morning at 8:20AM.

Now, for me, cue a bit of panic; I made the decision not to purchase unaccompanied minor service for her trip based on the idea that she could make her flights, and even if she didn’t, there was another flight later in the day she could pick up (still the case here: there were two more flights out of IAD to her destination 30 minutes later). This may have been a mistake, but that was a decision. Having United rebook her on a flight the next day is an entirely different beast, obviously.

I asked the agent whether they could confirm she had *not* made her flight: I was told that she could tell me that she had been rebooked the next morning, which they would not have done if she had made her flight, but she repeated that she could not tell me if she actually made her flight. (What?)

I called a couple other numbers, including the airport traveller assistance number, who told me that they could not do anything other than page in the baggage claim area; we punted on that for the time and kept trying United, still trying to get a confirmation that she had or had not made it on her flight.

In my next call, I got the same basic story: She’s rebooked for tomorrow. Since she is rebooked for tomorrow, United will be putting her up in a hotel tonight. No, I can’t tell you what hotel. No, I can’t tell you a number you can call for that information. No, I can’t tell you whether she made it on the flight. No, I can’t tell you hotels we use for putting passengers up. I can tell you that she was rebooked for tomorrow morning.

At this point, we had her paged in the airport — which ended up producing no response, though they were attempting to be very helpful. They did clarify that they can’t page in the gate area, and we should contact the airline for that.

Again, we called a different United number, only to be shunted back to the main United phone disaster. No, we can’t contact our gate agents because of 9/11. No we can’t page in the gate are. No, we can’t tell you what hotels we use. No, we can’t give you a number to find out where this passenger has gone.

Kristan and I at this point started calling hotels — this is one hour after she has landed in Dulles and we have been told she will be staying overnight in DC and that we could get no information from anyone. We made it through about 10… at which point we got a call from Alicia. She had not answered her cell phone (which she did have on her, and charged)… because she was on her plane.

She was fine, and on her plane, the whole time. United put her on the next flight, but rebooked her anyway. She’s not in IAD, and had no problems… other than our complete lack of ability to communicate with United at all.

The first response to this will naturally be: “You should have paid for unaccompanied minor service.” While this may be true, I’m not convinced that it would have helped: specifically, the problem was not that Alicia did not make her flight — she did. The problem is that *no one could tell us this* — despite the fact that, presumably, someone scanned her boarding pass. Since we did not have a phone number — and I looked for an ‘unaccompanied minor contact number’ on United’s site — and she made her flight on time, I doubt we would have been contacted by United. (In fact, unaccompanied minor service might well have meant the difference between her making her flight and not in this case!)

Overall, I’m not upset that United didn’t know where my daughter was: that’s my fault. I’m not really that upset about most of the question they couldn’t answer in this case — though if she *was* stuck overnight, I’d be damn upset. Instead, I’m only upset about one thing: United told me she missed her flight, rebooked her on a flight tomorrow morning, and was completely unable to tell us that *she actually made her flight*. That has to be seen as a failure somewhere in the system, in my opinion, and I think the complete lack of being able to get to anyone other than reservations via the phone on short notice is completely unreasonable.

I do want to thank people who helped reassure me on twitter and elsewhere, and the IAD Travelers Aid desk, who did everything within their limited power to help us out, and the most important thing is that Alicia is at her destination + safe.

Suggestions for Better Geo In the (dot)Cloud

Posted in default on June 10th, 2011 at 00:47:03

икониOne of the interesting things that I’ve noticed in exploring various cloud providers is the limited amount of support for strong geo integration. This isn’t particularly surprising — Geo on the web is still a niche market, even if it is a niche market I tend to care about a lot. Here are some things that I think that might make people more eager to adopt cloud-y services for geo, specifically in the context of DotCloud, where I’ve been investing most of my time recently.

DotCloud has the idea of ‘services’ — independent units which work together to form an overall operating picture. The idea behind these services is that they are simple to set up, and perform one particular task well. So rather than having a service which combines PostGIS, GeoDjango, and MapServer, you have three separate services: one for PostGIS, one for GeoDjango, and one for MapServer, or map rendering, and you connect between them. This way, if your application needs to scale at the frontend, you can easily simply deploy additional GeoDjango services; if you need more map rendering ‘oomph’, same deal. (Deploying additional service for databases won’t magically scale them, but you do have the ability to use the software’s internal scaling across your multiple instances.)

So, again, using DotCloud, there are three types of ‘services’ that I think would be interesting to users who are working in Geo:

  • PostGIS — Supporting PostGIS on most debian+debian-derivatives platforms is pretty simple; the tools are all easily installable via packages. (pgRouting is another step beyond — something which might actually have some benefit simply because it’s more difficult to get started with, so having it preconfigured could make a big difference in adoption.) Nothing really special needed here other than apt-get install postgis and some wrapper tools to make setting up PostGIS databases easy. There probably isn’t any reason why this couldn’t be included in the default Postgresql service type in DotCloud.
  • GeoDjango — This one is even easier than PostGIS. GeoDjango already comes with the appropriate batteries included. The primary blocker on this is to get the GEOS, proj, and GDAL libraries installed on the Django service type. I don’t think there is any need for a separate service type for GeoDjango.
  • Map Rendering — This one is a big one for a lot of people, and I’m not entirely sure the best way to work it within DotCloud. Map Rendering — taking a set of raster or vector data, and making it available as rendered tiles based on requests via WMS or other protocols — is one of the things that is not pursued as often by the community right now, and I think a lot of that is in the difficulty of setup. As data grows large, coping with it all on the client side becomes more difficult; some applications simply never get built because the jump from ‘small’ to ‘big’ is too expensive.
    There are three different ‘big’ map rendering setups that I can think of that might be worth trying to support:

    • MapServer — MapServer is a tried and true map rendering tool. It primarily exists as a C program with a set of command line tools around it; it is usually run under CGI/FastCGI. Configuration exists as a set of text-based configuration files (mapfiles); rendering uses GDAL/OGR for most data interactions, and GD or AGG (plus more esoteric output formats) for output. MapServer is often combined with TileCache, for caching purposes; TileCache is based on Python.
    • GeoServer — GeoServer is a Java program, which runs inside a servlet container like Tomcat. Like MapServer, it supports a variety of input/output formats; configuration is typically via its internal web interface. Caching is built in (via geowebcache). I think GeoServer would probably run as is under the ‘java’ service type that exists on DotCloud, assuming the appropriate PostGIS support exists for the database side.
    • OSM data rendering — This one is a bit less solid. OpenStreetMap data rendering has a number of different rendering frontend environments, but the primary one that I think people would tend to set up these days is a stack of mod_tile (Apache-side frontend) talking to tirex (renderer backend) which calls out to/depends on Mapnik, the actual software which does tile rendering. Data comes from a PostGIS database — though in the case of OSM, even that requires some additional finagling, since getting a worldwide OSM dump is… pretty big. (It’s probably safe to set that point aside as a starting point, and concentrate instead on targeting localized OSM rendering deployments — solve the little problems first, scale up later.)

One thing that all of these tools have in common is that they really like having fast access to lots of disk for quickly reading and writing small files. I’m not sure what the right way to do that within the DotCloud setup is — I don’t see an obvious service type which is designed for this — so that might be another component in the overall picture. (Things like the redis service try to solve this problem I think, but since the tools primarily intend to write to disk as is, adopting them to support other ways of storing tile data persistently would require modifying the upstream libraries.)

I think that there is room to significantly simplify deployment of some components of geographic applications by centralizing installation in cloud-based services; the above sketches out some of the components that it might make sense to consider as a first pass. These components would let someone create a relatively complex client + server side geographic data application; exploring and expanding on these — especially the OSM data rendering component — could make deploying to the cloud easier than deploying locally, with the net effect of increased adoption of cloud-based services… and more geodata in the world to consume, which is something I’m always in favor of. 🙂

Better GDAL in the Cloud (DotCloud, Round 2)

Posted in default on June 7th, 2011 at 06:59:40

My previous attempts to make GDAL work in the cloud were sort of silly; compiling directly on the instance is sort of counter to the design of DotCloud, which lets you scale primarily by assuming that a ‘push’ to the server establishes all of the configuration you’ll need. (sshing into the machine is certainly possible, but it seems it is designed more for debugging than it is for active work.)

So, with a few suggestions from the folks in #dotcloud, I started exploring how to set up my dotcloud service in a bit more of a repeatable way — such that if I theoretically needed to scale, I could do it more easily. Rather than manually installing packages on the host, I moved all of that configuration into a ‘postinstall’ file — fenceposted so it runs only once.

After a bit of experimentation (and reporting a bug in GDAL), I was able to get a repeatable installation going; this means that I no longer have any manual steps in creating and setting up a new service doing OpenAerialMap thumbnailing; in fact, the entire process — right down to setting up redis as a distributed cache — can now be completed automatically.

The postinstall is pretty simple: download and configure, then install, curl; Download and configure, then install, GDAL. In both cases, use the respective -config tool as a fencepost so we don’t install multiple times.

Once this is done, setting up a new deployment with the appropriate services is trivial: that’s outlined in setup.sh — configure a redis service, grab the config information, and deploy a wsgi service using that config and the rest of the code.

In fact, while I was writing this post, I followed that very set of instructions, running ‘./setup.sh openaerialmap’ — before I finished the post, I had a running www.openaerialmap.dotcloud.com instance, which I could then commit in place of the silly-named ‘pepperoni’ service that oam.osgeo.org was using before.

The big thing for me about these one-off deployments is that by making available better tools for iterative deployment, they allow me to be more disciplined in how I configure services. When I was recently attending a workshop on container orchestration and automated deployments, I learned about several Ontario available options that significantly streamline this exact process. Normally, installing GDAL or curl is a one-time event: without reformatting my system (and inevitably losing track of customizations), it’s challenging to test setups reliably. With these improved tools, deploying software literally becomes seconds of work—it’s all scripted, repeatable, and far more manageable. No more mistakes in one-off apt-get install commands that I’ll never remember if my system goes down. Now, I’ve got the ability to script deployments of software.

This is of course possible with EC2 directly as well — building custom AMIs, redeploying them, etc. For me, though, DotCloud took the pain out of having to do such a thing. They did the hard part for me — and I got to do the more interesting and fun parts.

DotCloud: GDAL in Python in the Cloud

Posted in default on June 5th, 2011 at 15:14:40

One of the key components of the OpenAerialMap design that I have been working on since around FOSS4G of last year is to use distributed services rather than a single service — the goal being to identify a way to avoid a single point of failure, and instead allow the data and infrastructure to be shared among many different people and organizations. This is why OpenAerialMap does not provide hosting for imagery directly — instead, it expects that you will upload images to your own dedicated servers and provide the information about them to the OpenAerialMap repository.

One of the things that many people want from OpenAerialMap is (naturally) a way to see the images in the repository more easily. Since the images themselves are quite large — in some cases, hundreds of megabytes — it’s not as easy as just browsing a directory of files.

Since OAM does not host the imagery itself, there is actually nothing about this type of service that would be better served by hosting it centrally; the meta-information about the images is small, and easily fetched by HTTP, and the images themselves are already remote from the catalog.

As a result, when I saw people were interested in trying to get OpenAerialMap image thumbnails, I decided that I would write it as a separately hosted service. Thankfully, Mike Migurski had already made a branch with the ‘interesting’ parts of the problem solved: Python code using the GDAL library to fetch an overviewed version of the image and return it as a reasonably sized thumbnail. With that in mind, I thought that I would take this as an opportunity to explore setting this code up in the ‘cloud’.

A requirement for such a cloud deployment is that it needs to have support for GDAL: this severely limits the options available. In general, most of the ‘cloud hosting’ that is out there is to host your applications, using pre-installed libraries; very few of the sites out there would let you compile and run code in them, at least that I can find. However, I remembered that during my vacation week, I happened to sign up for an account with ‘DotCloud’, a service which is designed to help you “Assemble your stack from pre-configured and heavily tested components.” — instead of tying you to some specific setup, you’re able to build your own.

At first, I wasn’t convinced that I could do what I needed, but after reading about another migration, I realized that I could get access to the instance I was running on directly via SSH, and investigated more deeply.

I followed the instructions to create a Python deployment; this got me a simple instance running a webserver under uwsgi behind nginx. I was able to quickly SSH in, and with a bit of poking about, was able to compile and run curl and GDAL via the SSH command line into my local home:

$ wget http://curl.haxx.se/download/curl-7.21.6.tar.gz; tar -zvxf curl-7.21.6.tar.gz
$ wget http://download.osgeo.org/gdal/gdal-1.8.0.tar.gz; tar -zvxf gdal-1.8.0.tar.gz
$ cd curl-7.21.6.tar.gz
$ ./configure --prefix=$HOME --bindir=$HOME/env/bin
$ make
$ make install
$ cd ../gdal-1.8.0;
$ ./configure --prefix=$HOME --bindir=$HOME/env/bin --with-curl --without-libtool --with-python
$ make
$ make install
$ cd ..
$ LD_LIBRARY_PATH=lib/ python

So this got me a running python from which I could import the GDAL Python libraries; a great first step. Then I had to figure out how to make the webserver know about that LD_LIBRARY_PATH — a much more difficult step.

After some mucking about and poking in /etc/, I realized that the way that the uwsgi process was actually being run was under ‘supervsisord’; basically, whenever I deployed, my Python process running under supervisord was restarted, and was running my Python code inside it. So then all I had to do was figure out how to tell the supervisor on the DotCloud instance to run with my environment variables.

I found the ‘/etc/supervisor/conf.d/uwsgi.conf’ which was actually running my uwsgi process; after some research, I found that DotCloud will let you append to the supervisor configuration by simply creating a ‘supervisord.conf’ into your application install directory; it hooks this config at the end of all your other configs. So, I copied the contents of uwsgi.conf into my own supervisord.conf, dropped it in my app directory, and added: environment=LD_LIBRARY_PATH=”/home/dotcloud/lib” to the end of it.

Pushed my app to the server, and now, instead of “libgdal.so.1: cannot open shared object file: No such file or directory”, I was able to successfully import GDAL; I then easy_installed PIL, and with a little bit more work, I got the image thumbnailing code working on my DotCloud instance.

I’ve still got some more to do to clean this up — I’m not sure I’m actually using DotCloud ‘right’ in this sense — but I was able to get GDAL 1.8.0 in a Python server running on a DotCloud instance and use it to run a service, without having to install or screw with the running GDAL libraries on any of my production servers, so I’ll consider that a win.

Some things OpenLayers Shouldn’t Do

Posted in default on June 1st, 2011 at 04:16:17

One of the things that sets me apart from other OpenLayers users and contributors at times is the strong belief that it is not the responsibility of OpenLayers to be everything for everyone. I’ve often been faced with a situation where a user will say “Well, OpenLayers doesn’t have this functionality: doesn’t that mean it should?”

Just this morning, Eric made a similar argument: In response to my saying that OpenLayers is not for everyone, h responded if OpenLayers isn’t for everyone we gotta do something to change the situation, I think.

I completely disagree with this statement, and I think that anyone who thought about it would also disagree. There are some things OpenLayers is not meant to do, which other mapping tools are in a better position to do.

  • OpenLayers is not a 3D spinning globe — we will probably never have support for rendering 3D globes inside of OpenLayers itself.
  • OpenLayers is the ideal tool for browsing 3D panoramas: we are likely not the best tool for doing something like Google Streetview.
  • OpenLayers is not a full GIS application: We will likely never ship as part of OpenLayers itself a full UI for doing GIS editing against some server.
  • OpenLayers should not have as one of its primary goals creating user interface elements for complex functionality.

These choices might seem obvious, but I bring them up specifically because they are things that I have seen people state OpenLayers should do, and I think it’s important for any project to identify goals and seek to solve those goals.

There are also other things which are less obvious that I think OpenLayers is unlikely to do, which other mapping APIs have chosen to do.

  • OpenLayers should not abandon support for Internet Explorer: One of the moves I’ve seen recently is to create applications which abandon support for Internet Explorer, since supporting IE takes more effort than supporting other platforms. Although that is reasonable for many platforms, I think it would not be the right path for OpenLayers. Building a library which supports more platforms will have side effects: OpenLayers has IE support baked into some of its core functionality, like event handling, so it will always have some minimal impact on things like download size, and there are some things we may choose not to do because doing so would make supporting IE more difficult. Internet Explorer may be close to becoming a non-majority browser, but it’s still going to be very important to OpenLayers users for years to come.
  • OpenLayers should not remove support for commercial layers, even if supporting these types of layers requires a more complex architecture: Supporting commercial layers is one of the key components of OpenLayers, and I think that it is important to continue to support using commercial layers, even though this does, at times, make the OpenLayers code more complex. This problem is thankfully getting somewhat better with newer APIs from Bing and Google for direct tile access, but there exist other APIs out there that aren’t as advanced, and continuing to support the types of APIs we need to make that happen is something I feel is central to OpenLayers.
  • OpenLayers should not remove support for direct WMS access. One of the things that some other mapping APIs have chosen to do is to limit their target audience, and as a result, they do not worry about adding WMS access or other similar functionality for accessing data through means other than laying out X/Y/Z tiles on a map. Supporting WMS and other OGC web standards is something that takes some non-trivial portion of OpenLayers developer time. If we were to abandon anything other than support for OSM or XYZ style tiled layers and vector layers, we could certainly concentrate on a smaller API — but I don’t think that is something OpenLayers should do, even if it would mean a better overall API.
  • OpenLayers should not remove support for fetching via various protocols, parsing via various formats, and choosing what to do with that data via various strategies: I have seen an argument that the more recent work with formats, strategies, and protocols is confusing to users, and should simply be removed in favor of letting that be handled at the application level. Most of the APIs OpenLayers is being compared to do not have this kind of support. This is another thing I strongly disagree with.
  • OpenLayers should not remove support for dealing with data in projections other than Spherical Mercator. Many other libraries simplify user experience by picking and sticking with a single projection; I think that is impractical for OpenLayers.

Now, I think it is completely true that it would be possible to rip out 80% of the functionality of OpenLayers, create a smaller, easier to maintain library, and hit a use case that could solve interesting problems. I will agree that OpenLayers is a large codebase — after all, we have more than 200 *thousand* lines of code, compared to just under 20,000 in Polymaps, 60,000 in Mapstraction, 9,000 in Leaflet. This is the ‘big daddy’ of mapping frameworks — no one is denying that — and it has a lot of technical debt built up the same way any Open Source project has happen over 6 years of development without a rewrite.

Some of that code is cruft, and should be removed. No one is denying that. In fact, there’s a fair amount of already-deprecated code; controls that have been deprecated or non-default for more than 4 years are still part of the main OpenLayers trunk release. However, I’d put the amount that is cruft at closer to 20% than 80%: the much bigger portion of the OpenLayers code is the broad support for the many different ways of interacting with remote data. In our formats alone — things which are generally designed to do only one thing, read and write from an external string to an OpenLayers resource — we have 69 files with 20,000 lines of code. That’s right, our format parsing — for everything from OSM to GeoJSON, GeoRSS to ArcXML to CQL to KML — is larger than several other entire mapping libraries.

Eric followed up by pointing out that of course he didn’t mean to suggest OpenLayers shouldn’t do everything, but that OpenLayers should have an easier API to hit simple use cases — something which is better documented, easier to use, and less confusing to users. I find it a bit amusing that this is an argument someone feels they need to make to *me*, since I feel like I’ve been pushing that argument for years now within the project. 🙂 However, since it may not have been clear, let me clarify:

The OpenLayers API is difficult to get started with for many simple problems. It can be hard to use, confusing to start, and difficult to understand for solving simple problems. It pushes details that very few users care about in the face of users who don’t know what to do with them. It is crucially important to supporting the future use of the project to make the easy things easy, while maintaining the ability to make the hard things possible.

Some areas where this is most apparent: difficulty in working with projected coordinates for the purposes of interacting with OSM or other spherical mercator layers. Difficulty in setting up a simple request to download a file from a server and render it — even *I* can’t configure that from memory, and I’ve done it dozens of times. These are real problems that users run into all the time and simplifying them would be a huge step forward in usability for solving the simple problems. (Note that I’m saying this in a blog post rather than in code, which also shows that I don’t think this is a trivial problem: the reason these things are not done is in part because coming up with a solid way to do these things in a helpful way is not trivial.)

I just want to clarify that there will always be some things OpenLayers shouldn’t do. Some of the decisions we’ve made have increased our overall technical debt: Maintaining support for IE, even for relatively advanced features like rotated client-side graphics in VML, was a cost that we could have saved if we chose a narrower supported platform range. However, I think that some of these decisions are important: a key component of OpenLayers is its broad support for loading data of any kind, in a wide variety of browsers. That was the core idea when OpenLayers was started, and I think that it is an extremely important to maintain part of our legacy.

Some of the competing mapping frameworks target a narrower use case. As a result, they can concentrate their developer time on better examples and documentation for a subset of functionality that OpenLayers has. This is great for the users of those tools, and will likely make those tools more attractive, short term, to some users. Competition is good: it encourages innovation, and pushes the limits, especially when the competition is open source and can collaborate across teams. If another tool is better for users than OpenLayers, it is in their best interest to use it. In the end, I hope that OpenLayers can continue to expand the set of users for which it is the best tool, and there is a lot of work that can be done there — and I look forward to continuing to see competition and collaboration between the various mapping projects out there to maximize user success.

More On Flaws in OpenLayers

Posted in default on May 30th, 2011 at 17:00:04

Tom MacWright has responded to my previous post about OpenLayers; in the spirit of continuing the conversation, I’ll respond in kind. (Note that this is a conversation that feels disjointed, which is unfortunate; but I’m not sure of a better way to continue the conversation; oh for the days of Usenet, where I feel like this conversation could be so much more effective.)

First, Tom points out that I compared to the wrong mapping libraries. That’s unfortunate, I guess, but I was going entirely from the list that was presented; I don’t have any beef in the argument. Since I’m an OpenLayers user, I don’t end up doing a lot of research on new hotness, so I’ll admit I had a flaw there; I apologize. (In fact, I couldn’t even *find* Leaflet until it was pointed out to me; clear evidence of my flawed knowledge in this regard.) It was suggested that any comparison should include Leaflet, OpenLayers, and Modest Maps.

I reject that statement as simply incorrect. Leaflet, I’ll gladly accept into the ring—I’m especially happy to see that Cloudmade has open-sourced their new efforts, which opens the possibility for collaboration and contribution across projects, a great step forward. However, Modest Maps is not a JavaScript web mapping library—it’s based on Flash and requires developing using the Flash toolchain. For those interested in comparing various mapping libraries, there are comprehensive collections like 토토사이트 모음 that provide a wide range of options tailored to different needs. While Modest Maps may be an interesting choice for a small percentage of the OpenLayers user base, I would argue that I’m content with users whose needs align with Modest Maps to use that library, but it doesn’t offer a relevant comparison for the vast majority of OpenLayers usage. While OpenLayers can certainly learn from Modest Maps, it’s not an interesting comparison for users of the software as an API.

Some questions which are asked:

Where does control of the map come from? The baselayer? The map object? Both?

Ah, a softball! The layer configuration for resolutions, projections, and all other information related to it should come directly from the current baseLayer of the map. The information assigned to the map may occasionally offer a shortcut for that configuration, but it should not be in any case necessary to have that configuration on the map. (Any case where that is untrue — and I’m sure there are some! — is likely a bug.) For other aspects of the overall configuration, the map may be a home, but in almost all cases, configuration options on the map are just a shortcut (and likely a confusing one, because it compounds the possible configuration issues). When configuring options for projection information, the information comes from the layer; as a courtesy, we do our best to copy configuration from the map to the layers to make it easier (since most maps have the same properties on all layers.)

OpenLayers has its own events system … which is different than the $.proxy and other apis in jQuery or anything else (or in pure Javascript) that people are used to.

Well, in actuality, the OpenLayers event system is based almost entirely on the Prototype system. As we have moved on we have incorporated shortcuts very similar to the ExtJS event registration system. But really, we’re talking about one or two functions here, which are consistent throughout the OpenLayers library: on anything with an ‘events’ object, you can call “foo.events.register(‘eventname’, null, function(evt) {});”. So while it may not be particularly familiar — since it’s based on a less commonly used syntax, perhaps — it’s not like this is the most complex part of the library. I’ll also point out that we’re talking about a library which is older than jQuery, and older than ExtJS — it’s hardly a sin to not follow conventions that were invented years after you started your project 🙂

OpenLayers has its own HTML/styling system, that’s just built-out enough to be terribly limiting to anyone who wants controls to look nice, and uses anywhere from 40% to 60% hardcoded styles.

A mistake (largely created by our early development) that we have been slowly paying back ever since we got some external developers. Tim Schaub has been pushing the use of CSS and stylesheets for new controls since 2.4. We added CSS-stylable zoom and pan panels in OpenLayers 2.7, almost 3 years ago. While there are still a limited number of controls that use non-CSS based styling — specifically, the Control.PanZoomBar is probably a big one that will bite people, and the LayerSwitcher — I hardly think that these flaws are something that are the biggest problem with the library.

Now, the LayerSwitcher is a point: it’s *very* difficult to style, and it’s a not a particularly attractive display… but the reason that we haven’t invested in it is precisely because it’s not in the spirit of OpenLayers to solve this problem for users. As an API — not a UI development tool — OpenLayers isn’t seeking to solve all the problems of user interaction. Instead, we have left things like a more clean layer switching interface to third parties like GeoExt — with reasonable success. We’ve seen people create alternative layerswitchers for mobile applications, as well as other similar alternatives, ranging all the way down to just a simple dropdown. For complex usage, these may be insufficient — but that’s where libraries like GeoExt pick up the slack. In fact, Tom makes my argument for me: “See Modest Maps’s controls: there aren’t any, because designers will make prettier ones.” So it’s okay to have *no* controls, but not okay to have *unattractive* controls… that argument seems a bit flawed.

In this vein, there is a followup later in the post:

The configuration of the theme requires a line of straight-imperative code that sets a global variable. What if you want a different imgpath for different maps? Shouldn’t this be a per-map setting?

For panels — that is, for controls developed in the past 3 years, rather than 4 or 5 years ago — styling is entirely via CSS. This includes the Editing toolbars, it includes the panpanel and zoompanel controls, etc. Since these controls are via CSS, you can use different configurations per map, simply by using CSS rules.

Comparing to ModestMaps — which Tom describes as having no controls at all — and Leaflet — which has only a Zoom control — OpenLayers doesn’t appear to be lacking in the ‘easily customizable controls’ department 🙂

Now, Tom describes this as part of a systemic problem: “an assumption that you already know the scope of the library and the parts that you can customize.” This is a criticism that I am totally willing to grant — and feel falls directly under the heading of poor documentation, especially prose documentation, which I feel is a significant lack in OpenLayers for most users.

The growth of OpenLayers is addressed by code compression, not by changing the code, ever. … the bloat of OpenLayers and its ever-more-complex API is the core problem that shows no signs of changing.

This is completely untrue. The OpenLayers project has made significant efforts in three different areas to reduce code size: Compression (via better tools like the Closure compiler), Better build tools (which simplified building build profiles), and reducing interdependencies in code to limit build size. In fact, a significant portion of the most recent release was an attempt to minimize builds — simplifying default controls, pulling various portions that people use most out of the larger components so they could be built separately, and creating alternative build profiles to help users get started with building smaller OpenLayers builds for their applications.

In addition to making the OpenLayers build itself smaller, we have concentrated a large amount of our recent work on improving performance (simplifying operations while dragging to improve responsiveness) and limiting download size (using more sensible defaults, providing more example build profiles, and doing things like shrinking our default images to save space there). Overall, a simplified OSM map designed for a mobile interface, using our documented example profiles, will save over a megabyte of space, due to improved defaults and documentation.

In addition, the description of the OpenLayers API as ‘ever more complex’ feels confusing to me. An OpenLayers 2.0 application works just as well with OpenLayers 2.11 — so the core API can’t have changed much. There is certainly new functionality in the API, but looking at other APIs — like the leaflet quick start example — I just don’t see that much difference in APIs between OpenLayers and its competition.

While Polymaps and Modest Maps are great drawing frameworks, OpenLayers is an abysmal one. Try to get individual tiles from a drawn map? No way. Interact with anything on the map like a DOM element? Nope. “Unbind” the map from the HTML element it “owns”?

This would be what I would consider contrary to the design of OpenLayers, yes 🙂 I can’t think of *any* case where someone has come to the mailing list and asked a question which would be more easily answered if these things are easier — and I read a lot of mailing list posts.

New-style Javascript isn’t there in OpenLayers.

A perfectly reasonable criticism — OpenLayers is a child of the era from which it was born, and I think that if this is important to you, then I expect other tools will be more useful to you. That said, OpenLayers isn’t alone in this regard — Google, for example, follows much the same style of code, so far as I can tell, so at least we’re in good company. (Note that leaflet‘s quick start reads very much like an OpenLayers example, so I’m not sure I see where this comparison is coming from.)

Recommending GeoExt/MapQuery is a good idea for people building RIAs, but it’s the opposite of that for most others. What people want (people, as in, me, and people building things on mapping frameworks) is a lower-level, simpler API, rather than a higher one.

I think that this is simply untrue, based on the types of questions I regularly see. I think that OpenLayers provides a reasonable API for most tasks at the low level — many of the complaints are indeed only about the higher level tasks (like the layerswitcher styling). Given the rapid growth of usage for GeoExt, I see a lot of basis in the argument that OpenLayers was insufficiently providing for that niche — while I don’t see widely used reasonable competition to OpenLayers as a low level API.

The ability to make slim builds of OpenLayers (something we’ve also done, with openlayers_slim[5]) hasn’t been trumpeted nearly to the level that it should have been.

I don’t really know what more we can do. It’s the first response to every question we’ve ever had on speeding up your application, it’s in our deploying documentation, it’s been the first performance increasing technique mentioned every time we’ve talked about OpenLayers.

Short of not providing a pre-built OpenLayers at all, I don’t know what more we can do to help developers understand how important this is.

I’m positive that OpenLayers is not the best tool for all problems. But I think it’s actually a pretty good tool for a lot of problems. And one of the key things that it does — that nothing else does — is provide support for layers that you don’t *get* anywhere else. OpenLayers is designed to make it possible to use Bing, Google, and OSM in the same map — and as far as I can tell, nothing else does that. I still don’t see a library which offers support for parsing OSM, KML, GeoJSON, and GML in Javascript — and in my experience 50%+ of OpenLayers users end up using either the format parsing code or the commercial layer code.

For the few users who will never need to use anything other than OSM and some markers drawn in Javascript — great. But comparing OpenLayers to these other frameworks for anything other than dropping pre-drawn tiles in a map is sort of a non-sequiter for real usage, no matter what the flaws of OpenLayers are.