thingsinjars

  • 7 Oct 2012

    Proximity Search

    Now that geolocated posts are beginning to show up around app.net, I found myself wondering about proximity search. Twitter provides one themselves for geotagged tweets. What a proximity search does, essentially, is provide results from a data set ordered by increasing distance from a given location. This can be further enhanced by combining it with a text search either before or after the distance sorting. This would give you a way to search for a certain query within a certain area.

    Here, for example, is a proximity search centred on Berlin including any tweet in 1000 miles containing the word 'toast'.

    When I first started thinking about the tech required for a proximity search, I remembered Lukas Nowacki back in our old Whitespace days implementing the Haversine formula in MySQL (Alexander Rubin has a good overview of how to do this). As much as I love my trigonometry and logarithms, I must admit, I was looking around for a simpler solution. Actually, I was looking around for a copy-paste solution, to be honest. I may even have spent some time going down that route if Max hadn't pointed me in the direction of MongoDB.

    I'd been putting off digging into NoSQL databases for a while because, well, I had no real reason to. Recently, I've either been focused on front-end dev or hacking away at Java and never really had any good reason to investigate any of these new-fangled technologies get off my lawn you kids.

    MongoDB

    After 10 minutes of messing around with Mongo, I pretty much just found myself saying “No... way. There's no way that's actually working” I'm sure those of you experience with document-oriented databases are rolling your eyes right now but for those few of us left with an entirely relational concept of databases, let me just explain it like this: you know those things you want to do with a database that are just a hassle of multiple joins and confusing references? Document databases do some of those things really really well.

    The biggest selling point for me, however was the native geospatial indexing. That pretty much made the majority of my proximity search complete. All I needed to do was wrap it in a nice interface and call it a day...

    I'll follow up tomorrow with a more detailed 'How-to' guide.

    Development, Geek

  • 29 Sep 2012

    CoverMap - Nokia Maps on Facebook

    I'm almost managing to keep to my intended schedule of one map-based web experiment per week. Unfortunately, I've mostly been working on internal Nokia Maps projects over the weekends recently so I've not had much to post here.

    I can share my latest toy, though: CoverMap.me

    Using just the public APIs over a couple of hours last Sunday afternoon, I made this to allow you to set a Nokia Map as your Facebook Timeline cover. The whole process is really straightforward so I thought I'd go over the main parts.

    The exact aim of CoverMap.me is to allow the user to position a map exactly, choose from any of the available map styles and set the image as their cover image.

    Make a Facebook App

    Go to developers.facebook.com/apps/ and click 'Create New App', fill in the basic details – name of the app, URL it will be hosted on, etc – and you're done.

    Facebook login

    I've used the Facebook JS SDK extensively over the summer for various projects but I wanted to try out the PHP one for this. Super, super simple. Really. Include the library (available here), set your appId and secret and request the $login_url.

    $facebook->getLoginUrl(array('redirect_uri' => "http://example.com/index.php"));
    

    That will give you a link which will take care of logging the user in and giving you basic access permissions and details about them.

    Nokia Maps JS API

    When I'm hacking together something quick and simple with the Nokia Maps API, I usually use the properly awsm jQuery plugin jOVI written by the equally awsm Max. This makes 90% of the things you would want to do with a map extremely easy and if you're doing stuff advanced enough to want the extra 10%, you're probably not the type who'd want to use a jQuery plugin, anyway. Either way, you need to register on the Nokia developer site to get your Nokia app_id and secret.

    To create a map using jOVI, simply include the plugin in your page then run .jOVI on the object you want to contain the map along with starting parameters:

    $(window).on('load', function() {
      $('#mapContainer').jOVI({
        center: [38.895111, -77.036667], // Washington D.C.
        zoom: 12,           // zoom level
        behavior: true,     // map interaction
        zoomBar: true,      // zoom bar
        scaleBar: false,    // scale bar at the bottom
        overview: false,    // minimap (bottom-right)
        typeSelector: false,// normal, satellite, terrain
        positioning: true   // geolocation
      }, "APP_ID", "APP_SECRET");
    });
    

    This gives us a complete embedded map.

    As I mentioned above, part of the idea for CoverMap.me was to allow the to choose from any of the available map styles. This was an interesting oddity because the public JS API gives you the choice of 'Normal', 'Satellite', 'Satellite Plain' (a.k.a. no text), 'Smart' (a.k.a. grey), 'Smart Public Transport', 'Terrain' and 'Traffic' while the RESTful Maps API (the API that provides static, non-interactive map images) supports all of these plus options to choose each of them with big or small text plus a 'Night Time' mode. Because of this, I decided to go for a two-step approach where users were shown the JS-powered map to let them choose their location then they went through to the RESTful static map to allow them to choose from the larger array of static tiles.

    RESTful Maps

    The RESTful Maps API is relatively new but does provide a nice, quick map solution when you don't need any interactivity. Just set an img src with the query parameters you need and get back an image.

    (this should be all on one line)
    http://m.nok.it/
        ?app_id=APP_ID
        &token=APP_TOKEN
        &nord       // Don't redirect to maps.nokia.com
        &w=640      // Width
        &h=480      // Height
        &nodot      // Don't put a green dot in the centre
        &c=38.895111, -77.036667 // Where to centre
        &z=12       // Zoom level
        &t=0        // Tile Style
    

    That URL produces this image:

    Map of Washington D.C.

    Upload to Facebook

    Given the above, we've now got an image showing a map positioned exactly where the user wants it in the tile style the user likes. We just need to make the Facebook API call to set it as Timeline Cover Image and we're done.

    You'd think.

    Facebook doesn't provide an API endpoint to update a user's profile image or timeline cover. It's probably a privacy thing or a security thing or something. Either way, it doesn't exist. Never fear! There's a solution!

    With the default permissions given by a Facebook login/OAUTH token exchange/etc... (that thing we did earlier), we are allowed to upload a photo to an album.

    The easiest way to do this is to download the map tile using cURL then repost it to Facebook. The clever way to do it would be to pipe the incoming input stream directly back out to Facebook without writing to the local file system but it would be slightly more hassle to set that up and wouldn't really make much of a difference to how it works.

    // Download from RESTful Maps
    $tileUrl = "http://m.nok.it/?app_id=APP_ID&token=APP_TOKEN&nord&w=640&h=480&nodot&c=38.895111,%20-77.036667&z=12&t=0";
    $ch = curl_init( $tileUrl );
    $fp = fopen( $filename, 'wb' );
    curl_setopt( $ch, CURLOPT_FILE, $fp );
    curl_setopt( $ch, CURLOPT_HEADER, 0 );
    curl_exec( $ch ); 
    curl_close( $ch );
    fclose( $fp );
    
    //Upload to Facebook
    $full_image_path = realpath($filename);
    $args = array('message' => 'Uploaded by CoverMap.me');
    $args['image'] = '@' . $full_image_path;
    $data = $facebook->api("/{$album_id}/photos", 'post', $args);
    

    The closest thing we can do then is to construct a Facebook link which suggests the user should set the uploaded image as their Timeline Cover:

    // $data['id'] is the image's Facebook ID 
    $fb_image_link = "http://www.facebook.com/" . $username . "?preview_cover=" . $data['id'];
    

    Done

    There we go. Minimal development required to create a web app with very little demand on the user that gives them a Nokia Map on their Facebook profile. Not too bad for a Sunday afternoon.

    Go try it out and let me know what you think.

    The code is now available on GitHub

    Geek, Guides, Toys, Development

  • 15 Jul 2012

    Using CSS :target to control state

    There can be a fair amount of discussion provoked by the phrase "CSS only" or "Built entirely in HTML and CSS" when it comes to tech demos. The discussion generally revolves around the fact that what the phrase actually means 99% of the time is "Using CSS for the graphical bits but tracking the mouse using JS" or "Using CSS transforms for most of it but using JS to calculate the values" or any number of variations on that theme.

    Now, I'm not saying that's a bad thing at all, I quite happily called my interpretation of Super Mario Kart CSS-only even though without JS, Yoshi wouldn't make it to the first bend. What these demos are doing, essentially, is using CSS as the rendering layer where previously, JS would have been used. By doing so, you even get some nice hardware acceleration thrown in. Not too bad.

    Why fall back?

    The reason we fall back to JS for a lot of things is because CSS is a declarative language (see my post on CSS testing to learn more). However you say things should be is how they are. In CSS, you can't set a variable to one value, do something with it then set it to a different value and do something else. For a start, you don't have variables. Even if you did, the style sheet is read top-to-bottom before anything is done with it. The variable would always have the final value assigned to it, even the first time you used it. I'm simplifying a bit but not much. If you want to do anything clever, you generally need to resort to JS, an interpreted language.

    Really CSS only

    If you want to make something properly interactive but entirely CSS, you have to find a way to modify the state of the DOM so that different sets of styles can be applied to the same sets of elements. We actually do this all the time when we change the colour of a link on :hover. The user interacts with the page, the state of the page is changed slightly, a different style applies. There's a lot you can do now that you have a way to modify the page based on user interaction. Hooray for pseudo-classes!

    An extremely important addition to the set of pseudo-classes available in CSS3 is the :target class. This becomes set on an element when the element is the target of a clicked link. Think of in-page jump links. When you click on one and the URL changes to 'blah.html#the-thing-you-clicked', the element with id="the-thing-you-clicked" gets the :target pseudo-class. Now you can affect it and its children with new styles. Now it becomes interesting, you can click on something on one bit of the page and it cause something to happen on another bit of the page.

    Multiple-nested states

    By nesting several elements around the thing you're intending to modify, you can now create a set of states entirely controlled by CSS. For example, with this HTML:

    <div id="red">
      <div id="blue">
        <div id="green">
          <div id="yellow">
              <p>Hello.</p>
          </div>
        </div>
      </div>
    </div>
    <ul>
      <li><a href="#red">Red</a></li>
      <li><a href="#blue">Blue</a></li>
      <li><a href="#green">Green</a></li>
      <li><a href="#yellow">Yellow</a></li>
      <li><a href="#default">Default</a></li>
    </ul>
    
    And this CSS:
    p {
        color:black;
    }
    #red:target p {
        color:red;
    }
    #blue:target p {
        color:blue;
    }
    #green:target p {
        color:green;
    }
    #yellow:target p {
        color:yellow;
    }

    You can change the colour of the text by clicking on the link. Without any JS.

    See this on JSFiddle.

    Shiny demos

    This still isn't perfect. There are still going to be many things that JS is best for, calculations being one, keyboard input being another. To try and find the best way to show this off, I tried to update CSS Mario Kart to be entirely CSS and I almost got there but wasn't 100% successful.

    • CSS-only Mario Kart

    I then started to build a zoetrope in CSS, found someone else had already done it and decided to modify it.

    • CSS-only Zoetrope

    Maybe soon, the phrase "CSS only" will really mean "CSS only. And a bit of HTML."

    Geek, CSS, Development

  • 19 Jun 2012

    Web Audio API Part 1

    I'm enjoying the chance to write for another site that I get with creativejs.com but it does leave me less time to create new posts for here.

    Having said that, there's nothing wrong with the occasional cross-post. Here's the first part of the introduction to Web Audio that I promised a couple of weeks ago:

    Web Audio API - Getting Started on CreativeJS

    Development, Development, Development, Development

  • newer posts
  • older posts

Categories

Toys, Guides, Opinion, Geek, Non-geek, Development, Design, CSS, JS, Open-source Ideas, Cartoons, Photos

Shop

Colourful clothes for colourful kids

I'm currently reading

Projects

  • Awsm Street – Kid's clothing
  • Stickture
  • Explanating
  • Open Source Snacks
  • My life in sans-serif
  • My life in monospace
Simon Madine (thingsinjars)

@thingsinjars.com

Hi, I’m Simon Madine and I make music, write books and code.

I’m the Engineering Lead for komment.

© 2025 Simon Madine