Extracting Tiles from PMTiles

There are a couple ways to extract map tiles from the various archives - the most popular being MBTiles and PMTiles these days. The best way, though, is using tile-join from felt/tippecanoe:

tile-join -e dir/ input.pmtiles

This will output all tiles as a hierarchy in dir - dir/{z}/{x}/{y}.{ext}. When working with vector tiles, you might need to specify -pC (no tile compression). By default, tiles are compressed in the archive, but if you need the raw tiles in a directory, specifying this option will output the raw, uncompressed files.

Read more

Homebrew and PostgreSQL 9.5 (or 9.6)

Edit Sept. 30 2016: PostgreSQL 9.6 was released today, and these instructions should work – just replace 9.4 with 9.5 and 9.5 with 9.6. I also have a guide using pg_upgradecluster on Ubuntu.

PostgreSQL 9.5 was released on Jan. 7, with lots of exciting new features.

I wrote a post about upgrading from 9.3 to 9.4 in the past, and many people found it useful, so I decided to update it a bit for the 9.4 to 9.5 upgrade.

Read more

Elixir Pattern Matching in Anonymous Funs

filter_zed_by = "1"
list = [
  %{"a" => "1", "b" => "2"},
  %{"a" => "1", "b" => "5"},
  %{"a" => "2", "b" => "5"},
  %{"z" => "1", "x" => "2"}
]
Enum.filter list, fn
  %{"z" => ^filter_zed_by} -> true
  _ -> false
end

# => [%{"z" => "1", "x" => "2"}]
  • case in a fun is usually redundant
  • if is even worse
  • keep it simple

Hosting a Single-Page App on S3, with proper URLs

Note (2019/07/05): I’ve posted a follow-up to this post about limitations about the technique used here, especially when hosting an API on the same domain.

Amazon S3 is a great place to store static files. You might want to even serve a single-page application (SPA) written in JavaScript there.

When you’re writing a single-page app, there are a couple ways to handle URLs:

A) http://example.com/#!/path/of/resource
B) http://example.com/path/of/resource

A is easy to serve from S3. The server only sees the http://example.com/ part, and so it serves that file to everyone.

Read more

bundler gotcha

So, this is a thing:

bundle install --without development:test
...
...
Bundle complete! XX Gemfile dependencies, XX gems now installed.
Gems in the groups development and test were not installed.

Now,

bundle install
...
...
Bundle complete! XX Gemfile dependencies, XX gems now installed.
Gems in the groups development and test were not installed.

Basically – you run bundle install --without <group> once, and that’s saved in .bundle/config. So next time you run bundle install without any arguments, it won’t install gems in the groups you specify.

Read more

Heroku + SSL = Expensive?

Note: This blog post covers the legacy SSL Endpoint. Heroku now recommends the use of Heroku SSL, which can provide you with a free certificate and HTTPS (provided you are using the Hobby tier or higher).


If you use Heroku, you probably know a couple things:

  1. You can’t use an apex domain for your site (unless you use a DNS service that emulates ALIAS / ANAME records).
  2. Using your own SSL certificate costs $20/month.

I’m going to solve both of these problems with one stone: AWS CloudFront.

Read more

My Great Language Hunt -- Elixir

Edit 2016/4/29 I have written a follow-up piece to this blog post.

As many of you probably know, I am a professional programmer. I started my professional career with WordPress and PHP development, and now I find myself doing a lot of Ruby work. I am still in the very early stages of my professional career – I have only been doing this for about 5 years. There are people who are much more experienced than I am, and there is a whole world of things that I have yet to learn and experience.

Read more

Amazon IAM Policies: Granting one user access to a S3 bucket

It may be easy to use the same master Access Key and Secret Access Key for all your apps using Amazon AWS, but it’s definitely not secure and recommended against.

That said, I had a little trouble writing the IAM policy granting a single user access to a single S3 bucket. I finally had time to sit down and figure it out today, and turns out - it’s pretty easy. Up to this point, I’m assuming that you’ve already created your user, but if you haven’t - the IAM management console is located here: https://console.aws.amazon.com/iam/home?#users.

Read more

LocationMatch and ProxyPass

Want to mix LocationMatch and ProxyPass? Not so fast.

<LocationMatch ^/(regex/here/.*)$>
  ProxyPassMatch http://backend/$1
</LocationMatch>

Don’t forget to use ProxyPassReverse if you need it (it shouldn’t be inside the LocationMatch directive, though).

References:

Anchor Links inside Facebook Apps

If you haven’t noticed, you can’t use anchor links:

<a href="#hello">Go to id="hello"</a>

Inside Facebook Apps (Page tab, Canvas app, etc). So I wrote a little snippet that emulates this behaviour by using FB.Canvas.scrollTo(x, y);

/*
anchorlinks-fbcanvas.js

Enables anchor links (<a href="#hello">Go to id="hello"</a>) in
Facebook Canvas (page tabs, canvas app, etc)

Requires: jQuery, Facebook JS SDK
*/

jQuery(function($) {
  $('a').filter(function() {
    return $(this).attr('href').match(/^#/);
  }).each(function(i, el) {
    $(el).click(function(e) {
      e.preventDefault();
      var elementId = $(el).attr('href').replace(/^#(.*)/, '$1');
      var $goTo = $(document.getElementById(elementId));
      FB.Canvas.scrollTo(0, $goTo.offset().top);
    });
  });
});

Thoughts about App.net

I’m sure you have heard of App.net by now. The paid, non-advertisement-supported “live social stream” (read: Twitter). They set a $500,000 goal, and raised more than $800,000 - a clear indicator that some level of demand is there for such a service.

There are two levels of membership, the $50 “User” level and the $100 “Developer” level. A developer account will give you the necessary API keys to build apps that connect to App.net. I was very interested in how these prices were chosen, and thankfully App.net published their logic (“How did you come up with the pricing tiers?” in the FAQ).

Read more