Mar 02

World MapYesterday,  Following Foursquare’s announcement of their decision to switch to OpenStreetMap,  I had a long discussion on Twitter about the merits of open and “closed” map systems.

I am a big fan of Google maps. I like using the website both from my pc and my iPhone.
The only interaction I have had with OpenStreetMap has been through the Skobbler navigation app for the iPhone. I had even paid to get the offline maps. My experience was a thoroughly disappointing one. Partly because of the maps not being very accurate but mainly because of the frustration with the application. After spending the money to get the offline maps the app kept telling me to connect to the internet to navigate – which entirely defeats the purpose of paying for the offline maps.

Normally I’m a big supporter of openness. However, in this particular care, I find myself thinking that a “closed” system is probably better. I am using the word close losely here as what I mean is not a system unaccessible to developers but rather a system maintained and paid for by a private corporation.
My reasons are the following:

  1. “Mapping” is an expensive business – A private corporation fully invested in this business is likely to spend considerable sums of money making sure its maps are accurate and reliable, globally. Globally here is a keyword for me. OpenStreetMap is not likely to get very accurate data in areas which are not easily reachable or don’t have easy access to the internet (and that’s where I like to travel and use my maps)
  2. People are lazy – We see it all the time. Wikipedia (which I love) is updated only by a handful of users  while being consumed by billions – Creating content on Wikipedia requires relatively little (physical) effort, on the other hand creating content for OpenStreetMaps includes going out, driving and therefore spending money. Granted there will always be a handful of people eager to create and share this information, but is that enough to keep a world atlas up to date?
  3. Being popular online is expensive – OpenStreetMap to keep growing in popularity will have to raise an ever larger amount of money to keep its hosting facilities up to scratch to deal with the demand. Of course a business has the same issue, but they make money out of it and this money is invested in keeping the facilities up-to-date.

I love the idea of OpenStreetMap being an open data source and API rather than a product (like Google maps). I love how customisable it is and how easy it is for developers to integrate. Nevertheless I am not sure it will be able to stay accurate in the long run. Yesterday Skobbler’s creator claimed that OpenStreetMap is already better than Google maps in Germany. Just out of curiosity I went to google maps, picked a random small town in the middle of Germany then went to have a look at it on OpenStreetMap – quite a few roads where missing (especially dead end roads) – Urgh.

What do you think?

Tagged with:
Jun 14

The new version of MapKit in iOS 4 supports polylines, finally. MKPolyline to be precise.

I have been working with the Google Maps API for a while and now I’m learning Objective-C and writing an iPhone app ro Route.ly

Since the best way to send around the net the data to draw a polyline on a map is in encoded format I decided to write a small Objective-C function to decode the encoded string. Since I couldn’t find this anywhere on the net I decided to publish the code here.

You’ll notice that at the beginning of the function I replace “\\\\” with “\\”. This is because I use the encoded data both in web pages with javascript and my iPhone app. In javascript “\\” would be considered an escape and would therefore break my array of points. This is not the case in Objective-C so I switch back to the normal “\\”.

- (NSMutableArray *) decodePolyline:(NSString *)encodedPoints {
        NSString escapedEncodedPoints = [encodedPoints stringByReplacingOccurrencesOfString:@"\\\\" withString:@"\\"];
        int len = [escapedEncodedPoints length];
        NSMutableArray waypoints = [[NSMutableArray alloc] init];
        int index = 0;
        float lat = 0;
        float lng = 0;
               
        while (index < len) {
                char b;
                int shift = 0;
                int result = 0;
                do {
                        b = [escapedEncodedPoints characterAtIndex:index++] - 63;
                        result |= (b & 0x1f) << shift;
                        shift += 5;
                } while (b >= 0×20);
                   
                float dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
                lat += dlat;
                       
                shift = 0;
                result = 0;
                do {
                        b = [escapedEncodedPoints characterAtIndex:index++] - 63;
                        result |= (b & 0x1f) << shift;
                        shift += 5;
                } while (b >= 0×20);
                   
                float dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
                lng += dlng;
               
                float finalLat = lat * 1e-5;
                float finalLong = lng * 1e-5;
               
                Waypoint *newPoint = [[Waypoint alloc] init];
                newPoint.lat = [[NSString alloc] initWithFormat:@"%f", finalLat];
                newPoint.lng = [[NSString alloc] initWithFormat:@"%f", finalLong];
                [waypoints addObject:newPoint];
                [newPoint release];
        }
        return waypoints;
}

Waypoints is a simple model class I’ve written with two NSString properties: lat and lng.

Tagged with:
Mar 09

I love calculating driving directions on Google Maps and then drag the blue line marking my directions to change the route. Everything is updated automatically on the page and the directions are re-calculated to go through the new point I defined.

I’ve been playing around with the Google Maps APIs recently and imagine my disappointment when I found out that Google does not allow directions calculated through the APIs to be dragged around.

Not put off by this I decided to try and replicate the directions-dragging myself. How hard can it be?
As it turns out. Very, at least if you want to make it look as smooth as Google’s own solution.

When generating directions Google Maps adds a GPolyline element overlay to your map. You can set the returned line to be editable but this makes an awful lot of vertices appear on it, which makes reading your directions quite hard. Even so, once you dragged one of this vertices around you are not editing the route but just changing the shape of the line.

Mine is not a complete solution and I’m interested in feedback and ideas on how to improve it.

First off calculate your directions:

map = new google.maps.Map2(document.getElementById(‘map_canvas’));
var wayPoints = [];
wayPoints.push(startPoint.getLatLng());
wayPoints.push(endPoint.getLatLng());

var myDir = new google.maps.Directions(map)
myDir.loadFromWaypoints(wayPoints, { travelMode: G_TRAVEL_MODE_DRIVING });

This will calculate your driving directions and plot a GPolyline on your map. The line is easily accessible in the GDirections object once the directions are calculated. To intercept this I have decided to use the addoverlay event on the GMap object. This event is triggered every time something is plotted over the map (says on the tin).

google.maps.Event.addListener(myDir, "addoverlay", function() {
var dirLine = myDir.getPolyline(); // Get the polyline from the directions object
});

At this point we can ask the APIs to make the GPolyline editable. This will make the vertices appear on the line and make then draggable. As I said before this only changes the shape of the line and doesn’t actually affect your directions object. Luckily the GPolyline comes with a nifty event called lineupdated.
This is triggered once the user has finished dragging a vertex. By intercepting this we can look through the vertices and know what’s been changed on the line and where the vertex has been moved to.
In order to do this we must also know the previous position of the vertices (latitude and longitude) to be able to compare the old and the new “edited” line.
Another challenge is the fact that the GDirections object can accept only so many waypoints (25 if I’m not wrong). Which means we’ll have to add only the vertex that has changed to the directions and not all of them.

// In the addoverlay event also save the original vertices of the line
var origLine = [];
for (var i = 0; i &lt; dirLine.getVertexCount(); i++) {
origLine.push(dirLine.getVertex(i));
}
// DONE saving vertices

// Now intercept the lineupdated event and add the new waypoints
google.maps.Event.addListener(dirLine, "lineupdated", function() {
routePoints = [];
for (var i = 0; i &lt; dirLine.getVertexCount(); i++) {
var savedPoint = origLine[i];
if (!savedPoint || (savedPoint.lat() != dirLine.getVertex(i).lat() &amp;&amp; savedPoint.lng() != dirLine.getVertex(i).lng())) {
routePoints.push(dirLine.getVertex(i));
}
}

// Now we remove the previous directions and recalculate the route
map.removeOverlay(dirLine)
calcRoute();
});

This works quite well but does not look as smooth as Google’s solution.
The problem is that while you are dragging a vertex only that bit of the GPolyline moves and the rest stays in its original position. which makes the shape of your directions quite awkward while you are dragging. Unforunately the GPolyline does not come with a “startdragging” event, otherwise we could just recalculate the route every few seconds while the vertex is being dragged.

This is not the most elegant of solutions but it does the job.

Tagged with:
Oct 28

Ever since Schmidt resigned from Apple’s board we all knew that a feud between the two companies was about to start.

Google had just launched Android, a Mobile OS. I’m sure we are all too aware of this.
Android wasn’t, and still isn’t a serious competitor for Apple’s iPhone. Google’s OS still has a long way to go to reach the “slickness” of the iPhone OS. Furthermore Google doesn’t have control over the hardware running its OS. Which means that the brilliancy of the OS can be completely overshadowed by the absurdity of the hardware. Honestly, some of the Android phones look like they have been designed by some boffin called Jenkins who was given complete freedom by their boss, Who should have instead said “No Jenkins you imbecile that’s not a phone. It’s crap. Do it again.”

I’m getting side-tracked. Let’s get back to the point.

Today Google announced Google Map Navigation for Android; and somehow I doubt it will make it to the iPhone. My guess is that Google is repaying Apple in kind for the whole Google Voice debacle. This is a serious blow and Apple will have some work to do to catch up with this.

More importantly Google Maps Navigation runs entirely off the net.
I have an iPhone with the Navigon app. It’s great but on my slim 8GB iPhone 25% of the storage is used for Navigon maps. With mobile internet connectivity becoming ever more ubiquitous this is definitely the way to go.

All I can hope for is that the rumor that came out a while ago about Google developing its own mobile phone is true. Then I might seriously consider giving up my iPhone.

UPDATE: AppleInsider reports that Google is in fact planning to port Google Maps Navigation to iPhone. If Apple approves the application, that is. Just PR or are they actually working on it?

“Apple is a close partner,” a Google spokesperson told AppleInsider Wednesday. “Millions of users experience Google Maps on the iPhone. We will continue to work with Apple to bring innovation, including Latitude and Navigation, to users but you’ll have to speak to Apple about availability.”

Tagged with:
preload preload preload