Rebuilding FourSquare for ActivityPub using OpenStreetMap

I used to like the original FourSquare. The "mayor" stuff was a bit silly, and my friends never left that many reviews, but I loved being able to signal to my friends "I am at this cool museum" or "We're at this pub if you want to meet" or "Spending the day at the park".

So, is there a way to recreate that early Web 2.0 experience with open data and ActivityPub? Let's find out!

This quest is divided into two parts.

  1. Get nearby "Points of Interest" (POI) from OpenStreetMap.
  2. Share a location on the Fediverse.

OpenStreetMap API

OpenStreetMap is the Wikipedia of maps. It is a freely available resource which anyone can edit (if they're skilled enough).

It also comes with a pretty decent API for querying things. For example, nw["amenity"]({{bbox}}); finds all "amenities" near a specific location.

Map of a part of London. Some parts are highlighted.

As you can see, it has highlighted some useful areas - a pharmacy and a pub. But it has ignored other useful locations - the train station and the park. It has also included some things that we may not want - bike parking and a taxi rank.

What API call is needed to get useful locations of of OverPass?

It's possible to specify the type of thing to find using nw["amenity"="restaurant"]; - but adding every single type of thing would quickly end up with a very large query containing hundreds of types.

It is also possible to exclude specific types of places. This retrieves all amenities except for fast food joints:


Again, that would be complex.

Perhaps one solution is just to return everything and let the user decide if they want to check in to a telephone kiosk or a fire hydrant? That's a bit user-hostile.

Instead, this query returns everything which has a name nw["name"]({{bbox}});

Map of London with several bits highlighted.

That cuts out any unnamed things - like park benches and car-sharing spots. But it does add named roads and train lines.

It is possible to use filters to exclude results from OverPass. The best that I can come up with is: nw["name"][!"highway"][!"railway"][!"waterway"][!"power"]({{bbox}});

That gets everything which has a name, but isn't a highway or railway or waterway or powerline. It isn't perfect - but it will do!

This is the query which will retrieve the 25 nearest things within 100 metres of a specific latitude and longitude. It includes the name and any other tags, the location, and the OSM ID.[out:json];nw["name"][!"highway"][!"railway"][!"waterway"][!"power"](around:100,51.5202,-0.1040);out center qt 25;


There's good news and bad news here. Firstly, ActivityStreams (which are subscribed to in ActivityPub) supports the concept of "Place" and "Location".

Once the user has a latitude and longitude, the can share it - along with a message, photo, or anything else.

Something like:

    "@context": "",
    "type": "Note",
    "content": "Here in NYC! <a href=\"\">John Lennon's Imagine Mosaic</a>.",
    "attachment": [
            "type": "Image",
            "mediaType": "image\/jpeg",
            "url": "https:\/\/\/img\/general\/590x786\/56367_9pxuZJD7d1hgPdaMFcFq1pipvTTMynBJsYcpHH-b8mU.jpg",
            "name": "A photo of a mosaic which says 'Imagine'."
    "location": {
        "name": "John Lennon's Imagine",
        "type": "Place",
        "longitude": 40.77563,
        "latitude": -73.97474

For example, here's a PixelFed post with an attached location - and this is the JSON representation. That status can be reposted into other social networks.

It is worth noting that Mastodon doesn't (natively) support location - if you view my repost of that PixelFed post you'll see there's no location metadata attached. That's OK! It just means that the status needs to include human-readable data.

Similarly, Mastodon doesn't support the arrive vocabulary. So this will be limited to a message with a location attached.

Other ActivityPub services do support location.

Putting it all together

Well… that's a job for next week. Probably!

  • Building a web site which gets the user's location is easy.
  • Getting the data from OverPass should be straightforward.
  • Creating an ActivityPub server which can post geotagged notes into the Fediverse might be a little beyond my skillset! Some testing with Darius Kazemi's AP Glitch suggests this should work.

If you'd like to help, please leave a comment.

Share this post on…

27 thoughts on “Rebuilding FourSquare for ActivityPub using OpenStreetMap”

  1. Tony says:

    I loved foursquare and it was a shame when they changed the app beyond recognition to chase VC money.

    I would definitely use something like this.. Pity the mastodon server won't accept it directly.. that limits its spread IMO (if all I needed was a frontend app connecting to a mastodon account, that's a much lower barrier to entry).

  2. says:

    @Edent great stuff! i’d been wondering if such a service was possible with ActivityPub! very keen to see how it progresses. if i can assist with testing or anything, let me know.

  3. @Edent yes!!! I can’t find the thread now but I was discussing this exact idea with… I think it was @tijs and @zverik a few months ago. I have no dev time to devote for it now but happy to chat if you’d like to swap ideas.

    In particular, I think one raison d’être for such an app (aside the obvious utility which obviously many of us got from 4sq) is to gamify submitting and verifying POIs in OSM. With a good UX and some careful thought, I’m optimistic it could really improve OSM for POIs.

  4. DaveF says:

    I maybe able to help with the Overpass query, except you don't actually say what the "useful locations" actually are. listing "every single type of thing" that you want, is probably the only way to do it.

    if that is actually what you need though. Wouldn't a flag/marker be just as good? For instance, parks can be pretty large & a supplying a specific point would be more convenient.

    1. @edent says:

      This is very much dependent on user needs. For some people, it's enough to say "I'm at the train station", but others might want to say "I'm on Platform 7".

      For me, it is important to have a human-readable location. So that might be a statue in a park, but it is unlikely to be a specific tree.

      Suggestions welcome for how to structure that query!

      1. DaveF says:

        [bbox:{{bbox}}];//global boundary only needs to be called once
        wr[leisure=park]->.Park; //All parks in the area store in .Parks variable
        // Searches for the various types of statues within each Park.
        out meta center; //output as a POI

        Find out how real world objects are tagged in OSM I find it best to use this tool:

        1. @edent says:

          As I pointed out in the blog post, it is difficult to build up a list of every tag that a user might possibly want to check in to. New tags are added all the time, so it becomes impossible to keep up.

          So that's why I'm just going for things which have names, but aren't streets.

          1. @blog This is a fun thing to be working on!

            You could also produce a few filters, so you could replicate the beer drinking one - can't remember it's name, but you log the beer you have in a pub or restaurant. Seems relatively simple with OSM.

  5. @Edent I'm hooked, waiting for the next post! (no pressure on the timing though). I'm new to the OSM space, so Overpass didn't make sense for quite some time, till I searched for it online.

  6. says:

    @Edent microformats know this as well. I toyed with this for my blog but finding a reliable map provider (without cookies) turned out to be quite difficult.

    I even tried setting up my own tile server for osm one day. The result was: Don't.

  7. @Edent so, I strongly recommend looking at the full Activity Vocabulary. There are several activities specifically for check-ins. I'm excited about this project.

  8. @Terence Eden Just FYI: At least Hubzilla has the built-in functionality to add a geographic location to each post, and you can optionally even enter a default location into your channel settings. There's an optional app named OpenStreetMap that can show the post location or any other place in OSM. There's also an optional app named Rendez-vous that can be used to plan meetings using OSM as the map provider.

    Both Friendica and (streams) have similar OpenStreetMap add-ons, but they don't have anything like Rendez-vous.

    Granted, it all dates back to before Mastodon, so it isn't geared towards working with Mastodon. Also, it isn't built against ActivityPub primarily but against DFRN (Friendica), Zot6 (Mastodon) and Nomad ((streams)). But maybe it's worth checking out.

    #Long #LongPost #CWLong #CWLongPost #FediMeta #FediverseMeta #CWFediMeta #CWFediverseMeta #Friendica #Hubzilla #Streams #(streams) #OpenStreetMap

  9. says:

    @Edent I've noodled around with trying to write some code to turn all of OSM into a Foursquare-style venues database but haven't had the time.

    My rough plan—a script that parses the entire OSM dataset and:

    • filters out the features one wants based on a predicate (pubs, restaurants, public buildings, etc.)
      - flattens ways/relations into points (calculate centroids)
      - emits lat, long, label, OSM type+ID

    Stick result in DB (SQLite+SpatiaLite appeals to me), index on coords, query N closest.

  10. @blog I loved the old FourSquare too. On multiple occasions it led to an impromptu beer with a mate or a discovery of a nifty cafe.

    A particular habit used to be avoiding rush hour traffic with a couple of drinks, for which I’d always check FourSquare to see who else was hiding from the rush and go join them.

    If I can help out, happy to pitch in.

Trackbacks and Pingbacks

What links here from around this blog?

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">

Discover more from Terence Eden’s Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading