Sunday, February 24, 2019

UK postcode data for February 2019

I have uploaded the latest UK postcode data from the ONS to my website. I’ve run my usual sanity checks and everything looks OK but let me know if anything appears amiss. Enjoy all the 2,611,698 postcodes (alive and dead)

Thursday, January 31, 2019

Land Registry data for Dec 2018

I’ve uploaded the latest house price data from the Land Registry to my website. Currently every month feels like Groundhog Day, prices continue to rise at about 2%, the number of transactions is stable.

Thursday, January 03, 2019

Land Registry house price data November 2018

The good people at the Land Registry were probably taking a well earned vacation, so the data arrived a little later than normal but house price data for England and Wales for November 2018 is now on my site. Not much to report, annual inflation is still sitting at about 2%, the number of transactions are holding steady. Maybe things will get interesting in March, I hear something might be happening around then.

Tuesday, December 11, 2018

Free for all

As mentioned in a previous post, Google have started charging me for some more Google Maps related things but have also given me some free credit to tide me over. In fact, they think my future usage of Google Maps is going to be so high, they have given me an absolutely huge amount of credits. Since I can’t actually do anything with those credits other than spend them on the Google Maps API, I have removed the requirement for a Google Maps API key on the pages that previously required one. This will remain in place until either my credits run out or we’re close to the end of January. So please go crazy. Happy Christmas.

Important note – if the API key field contains your API key, your API key will still be used!

Saturday, November 03, 2018

More Google Maps annoyances

The other day I got another email from Google

Hi,

In June 2016, we announced a change to Maps JavaScript API requests. At that time, we gave you temporary free usage based on your consumption to ensure that your applications would continue to function. The services included in this transition period were: Elevation, Directions, Distance Matrix, Geocoding and Places.

We appreciate you as a loyal and long-standing customer. Our goal is to make sure everyone is on a simple, consistent, and scalable plan with Google Maps Platform.Starting on November 29, 2018, we will bill all your usage for Elevation, Directions, Distance Matrix, Geocoding and Places, according to our new pricing plan.

To help you with this transition, we will provide you with two months of credits, which we will automatically apply to your billing account. Please read our FAQs to understand what these credits cover and how to estimate your monthly bill.

Thank you for using Google Maps Platform.

The Google of 2016 was clearly a different company to the Google of 2018, since grandfathering of old customers when a radical change to pricing is introduced is exactly the right thing to do unlike the recent shenanigans. And generally grandfathering is a permanent thing…

So once again I’m going to have to spend some time switching things off, moving other stuff over to one of Google’s many competitors who have more sane pricing and making other things require a Google Maps API key (the route elevation page now does, sorry)

Saturday, October 27, 2018

House price data for England and Wales September 2018

I’ve uploaded the latest Land Registry data to my website. Prices continue to creep up at around 2% a year, although several regions have seen falling prices

Implementing my own version of the Google Maps Timezone API

I noticed the other day that my usage of the Google Maps Timezone API was failing. I realised this was down to me not passing in an API key with the call. In their attempts to monetise their Maps API, Google now requires the API key and each call is chargeable. So I added the key and it still didn’t work, although with a different error message. Apparently using a key with a HTTP referrer restriction wasn’t allowed.

So I decided to add a server-side handler on my server that called out to the Timezone API using a server key instead. This was fairly straightforward since it just bounced the AJAX request from the browser to the Timezone API URL.

I checked back the next day to see what my API usage looked like. I’d spent $5 in 24 hours. Continuing with that meant with my other Maps API usage I’d hit the $200 per month free limit and would have to start paying Google money again, something I’ve been loath to do since their ridiculous price increases*

I realised at that point that the Timezone API wasn’t actually doing a huge amount behind the scenes. I guessed there would be libraries out there that could do the same thing but without paying for the privilege. Turns out there is. GeoTimeZone will give the time zone ID for a location and TimeZoneConverter will convert that to a Windows TimeZoneInfo that gives me everything else I needed to build my own version of the Timezone API. The code to do that is something like this

     var lat = double.Parse(HttpContext.Current.Request.QueryString["lat"]);
     var lng = double.Parse(HttpContext.Current.Request.QueryString["lng"]);
     var tz = TimeZoneLookup.GetTimeZone(lat, lng).Result;

// get other info
var tzi = TZConvert.GetTimeZoneInfo(tz);

// write out as JSON
     var jsonObj = new JObject();
     var rawOffset = tzi.BaseUtcOffset.TotalSeconds;
     jsonObj["dstOffset"] = tzi.GetUtcOffset(DateTime.UtcNow).TotalSeconds - rawOffset;
     jsonObj["rawOffset"] = rawOffset;
     jsonObj["timeZoneId"] = tz;
     jsonObj["timeZoneName"] = tzi.StandardName;
     jsonObj["status"] = "OK";

    var json = JsonConvert.SerializeObject(jsonObj);
     HttpContext.Current.Response.Write(json);

The only thing to consider is that time zones change so it’s worth keeping the two packages up to date.

* For the record, I used to pay about $200 a month to Google. Now I pay about the same to here maps and nothing to Google. I’m intrigued to know how their new pricing has worked out for them, I’m assuming most websites would have made the same decision I did and moved somewhere else.

Friday, October 19, 2018

Downloads on Chrome

If you’re having problems downloading files from my website, it may be down to the latest release of Chrome. It seems it’s got a bug that stops downloads working in some cases. I’ve found a workaround for some downloads but there are a few places where I haven’t figured out what to do you yet. Right clicking and selecting ‘Save link as..’ may fix the issue but if that’s not offered as an option, all I can suggest is switching to a different browser

Sunday, October 07, 2018

New features on doogal.co.uk

I’ve been making a few enhancements to the website recently so thought I’d point out a few things that might be of interest.

Editable labels on geocoded locationsThe labels displayed on the map after geocoding can now be edited. Editing the label will update the text output and the KML output.

Coloured elevation charts – I’ve updated my elevation charts to include colours based on the gradient at that point of the route/segment. Here’s Box Hill in all its technicolour glory. Due to the variable quality of elevation data, it can sometimes be difficult to calculate sensible gradients, so let me know if you see anything that doesn’t look sensible.

View your starred segmentsThe segment viewer page had fairly limited functionality before so I’ve now added the ability to view all your starred segments. If you’ve connected my website to Strava on the segment explorer page, you should see a ‘View starred segments’ button which will display them all on a map. This will be quite slow to load initially if the segments are not already available on the site, but should be quicker on subsequent loads. It’s also currently limited to 100 segments.

Friday, September 28, 2018

House price data for August 2018

Another month has flown by and it’s time to upload some more Land Registry data to my website. Annual house price inflation sits at 2%, another drop that may be becoming a trend. Number of sales also appears to be on a downward trend

Thursday, August 30, 2018

House price data for July 2018

I’ve uploaded the latest house price data from the Land Registry to my website. Not much excitement in the overall figures but there’s more interesting data at the regional level. A year after being the City of Culture, Hull is suffering the hangover and the wild swings continue in central London (although this is mostly down to the small number of sales that occur in the WC postcode area).

Thursday, August 23, 2018

Decoding paths in here maps

In my panic to move my website off Google Maps, I took some shortcuts. One of those was to continue to use the helper function google.maps.geometry.encoding.decodePath. I primarily use this for decoding the paths of Strava segments, since these are encoded using the same algorithm as Google. But loading up the Google Maps API script for a single function is rather ridiculous, so I’ve converted the path decoder from the rather marvellous (and seemingly abandoned) Strava.NET library.

For your pleasure, here is some TypeScript that will create a here maps LineString from an encoded path. Other map providers are available and adjusting it for them should be fairly straightforward.

function decodePath(polylinechars: string): H.geo.LineString {
  var poly = new H.geo.LineString();

  if (polylinechars == null || polylinechars === "") {
    return poly;
  }

  var index = 0;

  var currentLat = 0;
  var currentLng = 0;

  while (index < polylinechars.length) {
    // calculate next latitude
    var sum = 0;
    var shifter = 0;
    var next5bits;
    do {
      next5bits = polylinechars.charCodeAt(index++) - 63;
      sum |= (next5bits & 31) << shifter;
      shifter += 5;
    } while (next5bits >= 32 && index < polylinechars.length);

    if (index >= polylinechars.length)
      break;

    currentLat += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);

    // calculate next longitude
    sum = 0;
    shifter = 0;
    do {
      next5bits = polylinechars.charCodeAt(index++) - 63;
      sum |= (next5bits & 31) << shifter;
      shifter += 5;
    } while (next5bits >= 32 && index < polylinechars.length);

    if (index >= polylinechars.length && next5bits >= 32)
      break;

    currentLng += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);

    poly.pushPoint(new H.geo.Point(currentLat / 100000.0, currentLng / 100000.0));
  }

  return poly;
}

Tuesday, August 21, 2018

Thursday, August 02, 2018

Here Maps full screen control

One thing missing from Here Maps is a full screen control, but fortunately it’s possible to add your own custom controls to the map. This isn’t brilliantly documented but a support person from Here Maps was able to help me out with an example. That combined with the fact I’d built something similar in Google Maps before it had its own full screen control. So here’s a TypeScript function that will add a full screen button to a Here Map.

function hereMapsFullScreenControl(ui: H.ui.UI) {
  // add custom UI control
  const myCustomControl = new H.ui.Control();
  myCustomControl.addClass("customControl");
  ui.addControl("myCustomControl", myCustomControl);
  // Set the position of the control in the UI's layout
  myCustomControl.setAlignment(H.ui.LayoutAlignment.TOP_RIGHT);

  const myCustomPanel = new H.ui.base.OverlayPanel();
  myCustomPanel.addClass("customPanel");
  myCustomControl.addChild(myCustomPanel);

  // store original styles
  const mapDiv = ui.getMap().getElement() as HTMLElement;
  let divStyle: CSSStyleDeclaration = mapDiv.style;
  if (mapDiv.runtimeStyle) {
    divStyle = mapDiv.runtimeStyle;
  }
  const originalPos: string = divStyle.position;
  let originalWidth: string = divStyle.width;
  let originalHeight: string = divStyle.height;
  // ie8 hack
  if (originalWidth === "") {
    originalWidth = mapDiv.style.width;
  }
  if (originalHeight === "") {
    originalHeight = mapDiv.style.height;
  }
  const originalTop: string = divStyle.top;
  const originalLeft: string = divStyle.left;
  const originalZIndex: string = divStyle.zIndex;
  let bodyStyle: CSSStyleDeclaration = document.body.style;
  if (document.body.runtimeStyle) {
    bodyStyle = document.body.runtimeStyle;
  }
  const originalOverflow: string = bodyStyle.overflow;

  const myCustomButton = new H.ui.base.PushButton({
    label: "Full screen",
    onStateChange: (evt) => {
      // OK, button state changed... if it's currently down
      if (myCustomButton.getState() === H.ui.base.Button.State.DOWN) {
        // go full screen
        mapDiv.style.position = "fixed";
        mapDiv.style.width = "100%";
        mapDiv.style.height = "100%";
        mapDiv.style.top = "0";
        mapDiv.style.left = "0";
        mapDiv.style.zIndex = "100";
        document.body.style.overflow = "hidden";
      } else {
        // exit full screen
        if (originalPos === "") {
          mapDiv.style.position = "relative";
        } else {
          mapDiv.style.position = originalPos;
        }
        mapDiv.style.width = originalWidth;
        mapDiv.style.height = originalHeight;
        mapDiv.style.top = originalTop;
        mapDiv.style.left = originalLeft;
        mapDiv.style.zIndex = originalZIndex;
        document.body.style.overflow = originalOverflow;
      }
      ui.getMap().getViewPort().resize();
    },
  });

  myCustomPanel.addChild(myCustomButton as any);
  myCustomPanel.setState(H.ui.base.OverlayPanel.State.OPEN);
}

Wednesday, August 01, 2018

Land Registry data for June 2018

The server is still churning through the data for the England and Wales house price data for June 2018 but the top-level data is there. Annual inflation has dropped a little, but not enough to warrant any excitement.

Saturday, July 21, 2018

The economics of the new Google Maps API pricing

The insane new pricing for the Google Maps API with a $200 per month credit leads to an odd situation. For anyone using less than $200 a month, Google Maps is probably the best option (although other map providers also generally have some kind of free tier). For anyone going over that limit, you’d have to be insane to use Google Maps since it now costs so much more than other map providers.

So if you’re in a similar situation to me and you have a bunch of pages using Google Maps, the sensible option is to convert them until you get to a stage where your Google costs are approximately $6.67 per day. The Billings Report in the Google APIs console gives a fairly up to date picture of what’s going on (turn off the ‘Include credit in costs’ option). My current costs are about $20 per day so some work still to be done.

I’d much prefer to be improving the site, but since Google have decided to be dicks, I have to rewrite stuff until I’m no longer paying them a penny…