Pages

Showing posts with label web. Show all posts
Showing posts with label web. Show all posts

Wednesday, 25 July 2012

Get country name from coordinates or coordinates from search term using Objective-C and Google API

One project I have been working on recently saw me messing around with Objective-C as I created an app using the MKMapView for interacting with Google Maps. I'm only hoping that when I release the app Apple aren't gonna be stupid and reject my app saying I might as well rewrite it using their new APIs as they're doing away with Google maps in iOS6. Oh well, we'll see...

Anyway, this time around I am posting a couple of methods that outline how I retrieve a country name by doing a JSON query passing in the latitude and longitude of a place, and secondly how I get the coordinates to a search term (a string).

As usual I'll let the code speak for itself...

To get the string name of a country from latitude and longitude, also with the ability to specify which language you get the country name back in...
// Do reverse geocode lookup on latitude/longitude to get country name based on specified locale
- (NSString*)getCountryNameFromCoordinates:(CLLocationCoordinate2D)coordinates locale:(NSString*)language;
{
    NSLog(@"Querying Google location API for %@ country name for latitude %f and longitude %f...", language, coordinates.latitude, coordinates.longitude);
    
    // Get JSON contents from Google API
    NSString *url = [[NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=false&language=%@", coordinates.latitude, coordinates.longitude, language] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"Query URL is: %@", url);
    NSError *error = nil;
    NSString *jsonString = [NSString stringWithContentsOfURL:[NSURL URLWithString:url] encoding:NSUTF8StringEncoding error:&error];
    if (error != nil)
    {
        NSLog(@"Error doing reverse geocode lookup on %f, %f, lang=%@: %@", coordinates.latitude, coordinates.longitude, language, error.localizedDescription);
        return nil;
    }

    // Extract country by parsing JSON data
    SBJsonParser *jsonParser = [[SBJsonParser alloc] init];
    error = nil;
    NSDictionary *jsonObjects = [jsonParser objectWithString:jsonString error:&error];
    if (error != nil)
    {
        NSLog(@"Error parsing JSON response to reverse geocode lookup: %@", jsonParser.error);
        
        [jsonParser release];
        [jsonObjects release];

        return nil;
    }
    NSDictionary *results = [jsonObjects objectForKey:@"results"];
    NSString *country = nil;
    for (NSDictionary *item in results)
    {
        if ([[item objectForKey:@"types"] containsObject:@"country"])
        {
            country = [[[item objectForKey:@"address_components"] objectAtIndex:0] objectForKey:@"long_name"];
            NSLog(@"Found matching country name: %@", country);
            [item release];
            break;
        }
        
        [item release];
    }
    if (country == nil) {
        NSLog(@"Couldn't find a matching country name");
        
        [jsonParser release];
        [jsonObjects release];
        [results release];
        [country release];
        
        return nil;
    }
    
    [jsonParser release];
    [jsonObjects release];
    [results release];
    
    return country;
}

And to center your map (or whatever behaviour you so desire) on the coordinates obtained from a search on a specified location string...


- (void)searchCoordinatesForAddress:(NSString *)inAddress
{
    NSLog(@"Querying Google location API for latitude/longitude coordinates for search term %@", inAddress);
    
    // Get JSON contents from Google API
    NSString *url = [[NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?address=%@&sensor=false", inAddress] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"Query URL is: %@", url);
    NSError *error = nil;
    NSString *jsonString = [NSString stringWithContentsOfURL:[NSURL URLWithString:url] encoding:NSUTF8StringEncoding error:&error];
    if (error != nil)
    {
        NSLog(@"Error doing coordinate lookup on %@: %@", inAddress, error.localizedDescription);
        return;
    }
    
    // Extract coordinates by parsing JSON data
    SBJsonParser *jsonParser = [[SBJsonParser alloc] init];
    error = nil;
    NSDictionary *jsonObjects = [jsonParser objectWithString:jsonString error:&error];
    if (error != nil)
    {
        NSLog(@"Error parsing JSON response to extract coordinates: %@", jsonParser.error);

        [jsonParser release];
        [jsonObjects release];
        
        return;
    }
    NSArray *results;
    NSDictionary *location;
    @try {
        results = [jsonObjects objectForKey:@"results"];
        location = [[[results objectAtIndex:0] objectForKey:@"geometry"] objectForKey:@"location"];
    }
    @catch (NSException *exception) {
        NSLog(@"Could not find searched location's coordinates");
        [jsonParser release];
        [jsonObjects release];
        return;
    }

    // Get latitude and longitude as double values
    double longitude = 0.0;
    double latitude = 0.0;   
    NSNumber *lat = [location objectForKey:@"lat"];
    NSNumber *lng = [location objectForKey:@"lng"];
    latitude = [lat doubleValue];
    longitude = [lng doubleValue];
    [lat release];
    [lng release];
    
    [jsonParser release];
    [jsonObjects release];
    [results release];
    
    if (longitude == 0 && latitude == 0) {
        NSLog(@"Could not find searched location's coordinates");
        return;
    }
    NSLog(@"Coordinates found for searched location: %f %f", latitude, longitude);
    
    // I zoom my map to the area in question.
    [self zoomMapAndCenterAtLatitude:latitude andLongitude:longitude];
}

Tuesday, 29 November 2011

Installing Syntax Highlighter on Blogpost

public static void hola() {
    System.out.println("Hola, ¿cómo estás?");
}

Well the above Java code shows it - I got Syntax Highlighter working on my blog. For those of you who don't know, it's the JavaScript library that formats and highlights the Java syntax above making it all nice and easy for you to read. It supports most popular programming languages. There are already a tonne of articles already out there on how to install Syntax Highlighter so I'm kind of reinventing the wheel but below is an outline of the steps and ways I resolved some issues while installing it.

Getting Syntax Highlighter Running on Blogspot/Blogger.com

  1. Go and download Alex's Syntax Highlighter (SH) from here and unzip it once you've got it. Latest version was 3.0.83 at the time I wrote this article. You'll have a directory hierarchy something like:
  2. You need somewhere to save the SH's JS and CSS files on the web seeing as Blogspot doesn't allow you to upload files (or at least not as far as I could figure out). If you don't have a website or server to host them on then sign up for a free site at Google Sites.
    1. After signing up/logging on, go Create button -> enter details such as name and address of your site -> Create button
    2. New page button (top-right icon) -> enter name of folder (page) to store SH files, e.g. "sh" -> Create -> Save. You'll then have a location something like http://sites.google.com/sites/<your site name>/sh
    3. Manage site -> Attachments -> Upload button -> Choose file, select different location, choose page created in step 2 -> Upload.
      * Files to upload are talked about below so read the rest of the steps before uploading.
  3. Now login to your Blogspot dashboard/admin page (http://www.blogger.com/home) and assuming you're using the new interface (as I am as of 30th Nov 2011):
    1. Open top-right  options menu (beside goto post list icon ) -> Template -> Edit HTML button for the template you current use (under the old interface it's Design -> Edit HTML)
    2. Add the following code directly above the </head> tag. I am using the "Simple" template by the way. Read more below for what edits you will need to do before saving.
    3. <link href="http://sites.google.com/site/arohacorp/sh/shCore.css" rel="stylesheet" type="text/css"/>
      <link href="http://sites.google.com/site/arohacorp/sh/shThemeDefault.css" rel="stylesheet" type="text/css"/>
      <link href="http://sites.google.com/site/arohacorp/sh/shCoreEmacs.css" rel="stylesheet" type="text/css"/>
      <link href="http://sites.google.com/site/arohacorp/sh/shThemeEmacs.css" rel="stylesheet" type="text/css"/>
       
      <script src="http://sites.google.com/site/arohacorp/sh/shCore.js" type="text/javascript">
      </script>
      <script src="http://sites.google.com/site/arohacorp/sh/shAutoloader.js" type="text/javascript">
      </script>
      <script src="http://sites.google.com/site/arohacorp/sh/shBrushJava.js" type="text/javascript">
      </script>
      <script src="http://sites.google.com/site/arohacorp/sh/shBrushPhp.js" type="text/javascript">
      </script>
      <script src="http://sites.google.com/site/arohacorp/sh/shBrushPerl.js" type="text/javascript">
      </script>
      <script src="http://sites.google.com/site/arohacorp/sh/shBrushCpp.js" type="text/javascript">
      </script>
      <script src="http://sites.google.com/site/arohacorp/sh/shBrushBash.js" type="text/javascript">
      </script>
      <script src="http://sites.google.com/site/arohacorp/sh/shBrushJScript.js" type="text/javascript">
      </script>
      <script src="http://sites.google.com/site/arohacorp/sh/shBrushCss.js" type="text/javascript">
      </script>
      <script src="http://sites.google.com/site/arohacorp/sh/shBrushXml.js" type="text/javascript">
      </script>
      <script src="http://sites.google.com/site/arohacorp/sh/shBrushSql.js" type="text/javascript">
      </script>
       
      <script type="text/javascript">
      SyntaxHighlighter.config.bloggerMode = true;
      SyntaxHighlighter.all();
      </script>
      
      1. I have included a few extra files (more than the minimum required) to support an Emacs theme and syntax highlighting for a variety of programming languages). Below is a detailed description of the files and their purpose. Read over that.
      2. Once you've decided what files you will require, upload them to the sh folder you created on Google Sites and then modify the appropriate URLs inside the code you will add to your blog's template.
    4. Now SH should be all setup nicely on your blog, here's what you need to do to actually utilise it.
      1. Create a new post
      2. Open the "Edit HTML" box, and to enter your code copy/paste it between the <pre> and </pre> tags. For example the following code:

        <pre class="brush: java">
        class Foo {
            Foo() {
                System.out.println("Hello, world");
            }
        }
        </pre>

        results in formatted code like:
        class Foo {
            Foo() {
                System.out.println("Hello, world");
            }
        }
        
        A few things to note:
        • You replace the "java" with whatever language you're copy/pasting; js, html etc. Make sure you have the corresponding brush JS file installed (see below).
        • The HTML editor may give you errors saying your tags are not closed if you enter something like <link .../>. It will accept <link ...></link> and may even convert it to the former after you save it.
        • Using <pre>...</pre> tags means that right angle brackets (< and >) in your code will need to be HTML escaped, i.e. be entered > as &gt; and < as &lt;. The solution to that is <script>...</script> tags but these break RSS feeds so pre is considered better for blogs. The trick for using pre is not to directly copy/paste any code that will have right angle brackets in it, but run it through this Postable utility which will automatically convert them for you (Note; as of 2011/12/01 I noticed that this script was deleting + characters in my Java code. I've contacted the creator with the bug and have since resorted to manual search-n-replace in Notepad++ for < and >). More info here.
        • The old flash plugin of yonder days of SH used for copying and printing the contents has been done away with. Now to select all code inside a SH formatted box, just double-click a blank area inside it, all text will be selected then Ctrl+C / Edit->Copy.

    Syntax Highlighter files

    Warning: Do not use the files inside the src folder. You only need worry about the scripts and styles folders in the SH zip file. I was using shCore.js from here and getting lots of XRegExp not found errors when loading my blog.

    At a minimum you will need to install (i.e. upload to Google Sites and link from your template's HTML code) shCore.css and shThemeDefault.css from the styles folder. From the scripts folder you will need shCore.js and at least one brush file for highlighting the syntax of a language (for e.g. JavaScript). The code would look like:
    <link href="http://sites.google.com/site/arohacorp/sh/shCore.css" rel="stylesheet" type="text/css"/>
    <link href="http://sites.google.com/site/arohacorp/sh/shThemeDefault.css" rel="stylesheet" type="text/css"/>
     
    <script src="http://sites.google.com/site/arohacorp/sh/shCore.js" type="text/javascript">
    </script>
    <script src="http://sites.google.com/site/arohacorp/sh/shBrushJScript.js" type="text/javascript">
    </script>
    <script type='text/javascript'>
    SyntaxHighlighter.config.bloggerMode = true;
    SyntaxHighlighter.all();
    </script>
    
    If you want to highlight pure HTML then you can use the Xml brush script and enter "html" as the brush class in the pre tag. Add other languages as you require them.

    That's all. I pieced together this tutorial from memory and half re-doing things as I wrote after I first spent a few hours trying to get it all running. If you find some mistake in this article please let me know.