RSSAmplifier

Blog

James L Milner's Blog

James Milner's code and geo blog

jameslmilner.comRSS feed ↗51 posts

Latest posts

2025 Update

With two days to go before the end of the year and I realised that I have not written anything of substance this year on my blog (again, sigh ). A few days ago I updated the blog achieve a few things, firstly to remove links to Twitter and add them to Bluesky, also to improve the responsive design of the site as there were a few issues at various screen sizes. I wanted to bring the core…

I Have Not Released Any Books on Amazon

For avoidance of any doubt, I have not released any software development or related books on any Amazon stores, nor do I currently intend to. Please be careful out there to ensure you are ordering what you think you are ordering.

2024 Update

I had a realisation that it's been over a year since I posted anything on this blog and I've been wanting to rectify that for a while. I don't know if it's just getting older, or that I have genuinely been busy with 'other' things that I have struggled to string anything meaningful together. Ultimately I feel like having a technical blog is tough, because you need a perfect storm of a good topic,…

Stricter than Strict: 3 Compiler Flags to Consider in your TypeScript Codebase

As some of you will know, I am a fan of TypeScript and have written a few blog posts previously that touch on the language. For those of you who aren't familar TypeScript provides optional static typing and a range of advanced type-checking features, which allow users to catch type-related errors at compile time, paving the way for safer, more maintainable codebases. One of the primary attractions…

Generating GeoJSON with ChatGPT

I wrote a offhand tweet that picked up a (surprisingly) fair few likes about generating GeoJSON with OpenAI's (very in vogue) ChatGPT. I thought I would use this post to give an outline of my experiments with doing this and what the results were like. I started with something, simple but concrete for my first prompt: Can you generate a square polygon in valid GeoJSON format? The model came back…

Keeping an Automated Changelog in JavaScript

Having had it been a success for generating the CHANGELOG file in my project Terra Draw , I decide it would be good to share how that was achieved with the world. In this blog post we're going to look at how to implement an automated changelog using conventional commits, husky , commitlint and the standard-version package. You may have seen these types of automated changelogs previously in…

A Simple Introduction to Property Based Testing in JavaScript

Recently I have been exploring some other folks blog posts around a topic that really piqued my interest; property based testing. I wanted to take the time to explore it more as a concept, having experimented with it a little in the JavaScript ecosystem. Property Based Testing Overview # Firstly, I want to give an outline of property-based testing. Property based testing is slightly different from…

Speeding up TypeScript Jest Tests: ts-jest VS vitest VS @swc/jest

Recently on my project Terra Draw I took a look at different ways to try and speed up the unit test suite. The test suite wasn't slow, per se, but there are some obvious benefits to making the test suites faster. In general, faster running unit tests can provide several benefits for developers working on open source projects (and beyond!). Firstly, it allows for faster feedback on code changes,…

Why and How to Add Pull Request Templates to Your GitHub Project

Why # Pull request templates are a great way to give more structure to your open source project. Templates can be used to standardize the information that is included in pull requests, such a checklist of criteria that need to be fulfilled before it can be merged. This makes it easier for new contributors who get an understanding of the expectations of new code being merged into the project. They…

Downloading Text, JSON and Images with clientside JavaScript

Recently on the Terra Draw website I wanted to add the ability to download a GeoJSON file - it struck me that I wasn't immediately aware how to do this with it exclusively being a client side app. After a bit of research I was able to construct a simple solution for this. I have generalised this to three examples, namely text, JSON and images that you can reuse in your apps. The core of this is…

Publishing a Preact.js Site on GitHub Pages

I am currently working on a new map drawing library called Terra Draw. The public site makes up an important part of the project and it was getting to a point where maintaining a vanilla JavaScript app was becoming too unwieldy. Instead of reaching for my go to framework, React, I decided to be more conscious of the end users, shipping significantly less JavaScript to them. This was all good in…

Preventing Layout Reflow for Fluid Sized Images

One problem I had with redoing my blog was noticing that the sidebar photo was causing a layout reflow. This is because the image has a fluid size and until the image loads, the browser does not give the image a width or height and just renders the border radius as a small black circle: This is how the CSS for this looks: .container { width : 45% ; } .img { border-radius : 50% ; } However,…

Converting RGB, Hex and HSL Colors with JavaScript & TypeScript

post for myself for the future - a list of methods for converting between different color models. I was struggling to find working, modern JavaScript (TypeScript) implemenations for converting between Hex, RGB and HSL colors so I decided to put this together. Below is a combination of openly available implementations (StackOverflow, GitHub), modernised and converted to TypeScript: HSL to Hex #…

Making a Data Structure Iterable in JavaScript & TypeScript

In my last post I explained how to make a Map and Set that allowed you to use coordinates ([number, number] arrays) more like values than references. This means that adding a coordinate array with the same values twice will only result in one entry in the respective data structures. For example, in the CoordinateSet data structure you can see this behaviour where we add the same coordinate twice…

Coordinate Maps and Sets

One problem I was pondering recently is in the geospatial arena - somewhere I spend a lot of my time working. I've noticed that it's relatively easy to do key-value lookups on a single piece of data, i.e. a string or a number. For example, if you want to associate a letter in the alphabet to a score you could use a Map to do something like this: const map = new Map ( [ "a" , 1 ] , [ "b" , 2 ] , […

Debugging TypeScript Node Apps

This blog post will be a short overview of how you can use the Chrome Node inspector with TypeScript programs. We'll assume here we have a basic program called index.ts . We'll need to kick off with setting up the Node debugger in Chrome. You can go to chrome://inspect/#devices , you'll see a link called Open dedicated DevTools for Node . This will open up a separate window with the Chrome Node…

Exploring TypeScript Template Literal Types

Another one in the short sharp blog posts that I am trying to do more of - this time on TypeScripts new Template Literal Types . Up until version 4.1, TypeScript had three literal types, namely strings, numbers and booleans. If you're familiar with TypeScript there's no doubt you use these every day, maybe something like this: let maxPostLength : number ; // Later on you might do: maxPostLength =…

Measuring the World with JavaScript

If I asked you to measure two points on a table, you might get out a ruler or a tape measure to tell me the distance between the two. However, what if I asked you to measure the points between two capital cities? Suddenly it becomes more complicated, not only just logistically but also in terms of assumptions we have to make about that measurement. One big change, apart from just scale, is that we…

Experimenting Producing AVIF Images with Node.js

I've wanted to experiment with writing shorter and easier to digest blog posts on interesting web topics. So, this is my first exploring the AVIF Image format! AV1 Image File Format or AVIF is an exciting new image format that can work with the web. It has been developed by the Alliance for Open Media aiming to be an open-source and royalty-free image format. It already has adopters some big-name…

Getting Started With Handling TypeScript ASTs

TypeScript provides a language which builds on top of JavaScript adding static types to help determine type mismatches at compile time (and even whilst you write!). This is useful from a developmental perspective as (without wanting to dive into the dynamic vs static typing) it makes it easier to reason about the data flowing through your programs, documenting the shape of data at each stage.…

AssemblyScript - Passing Data to and From Your WebAssembly Program

AssemblyScript takes a strict subset of TypeScript and allows it to be compiled to WebAssembly. This is a very persuasive selling point for developers familiar with JavaScript and TypeScript as it immediately allows them to transfer their skills to be able to write WebAssembly programs. This is exciting as WebAssembly has proved useful from things like game engines such as Unity to design tools…

Writing Web Workers in TypeScript

TypeScript has taken the web development world by storm, and I too am a fan. Unfortuantely what I'm not a fan of is contention on the main thread, which has increased over time as we ship more and more JavaScript to our pages. I've written in previous posts about Web Workers , but for those of you not familiar they allow the developer to move work off of the main thread and into a separate thread…

Thinking Critically About Code Quality

I have been thinking recently about an aspect of software development which I feel can often be overlooked. The catalyst that triggered the thoughts in question was a post to Erlang mailing list from Joe Armstrong (the author of the Elang programming language). The email is titled with the subject ‘ Why do we need modules at all? ’. Joe’s post starts with a bold opening statement: I'm proposing a…

External Blog Post Roundup

You may notice that I have not blogged in a while, at least not on this site. Recently I have been blogging on my current employers ( SitePen ) blog on a whole host of different topics. I thought it may be useful to round these up and link to them here for reference. This is the list: Using WebAssembly with Web Workers - 22/07/2019 Augmented Reality on the Web in 2019 - 21/05/2019 Getting Started…

A Quick Look at WorkerDOM

In the browser, many operations occur on a single main thread. Due to the number of things we need to handle as web developers such as styling, DOM updates, fetches, data transforms, timers and so forth we can end up with a lot going on that thread. Unfortunately, this thread is also responsible for handling user inputs and rendering to the screen, which are user critical requirements and have…

Creating Your Own OS Zoomstack Tiles

In a past life I worked for the Ordnance Survey, specifically at the Geovation Hub in London working with startups doing interesting things with geospatial tools and data. One thing we experimented with there was Ordnance Survey based Vector Tiles. Since I left the OS has now invested a full open data Vector Tile product called Zoomstack. I thought it was a good chance to give it a whirl! You can…

Service Worker State Management

With this post I want to build upon a previous technique I wrote about ; message passing with Service Workers . Here I will be looking at how you might integrate this concept to manage application state across tabs for a site. For those of you unfamiliar, Service Workers are a separate thread that sit at in the background at browser level (rather than the page level like Web Workers) allowing…

Examining Web Worker Performance

Recently I've been writing about Web Workers and various options developers have for leveraging them in their applications. For those unfamiliar, Web Workers allow you to create a separate thread for execution in a web browser. This is powerful as it allows work to be done off the main thread which is responsible for rendering and responding to user events. Over recent times we've seen a growth in…

The Rise of JavaScript Scheduling

What is scheduling? # At a high level, scheduling can be thought of as a way of splitting up work and allocating it to be completed by a compute resource. The work can be processed at some point in the future, in an order, and by a given resource that the scheduler specifies. For example, if we had a set of tasks of equal importance, lets say calculating billing and distributing invoices for users…

Cancelling Requests with Abortable Fetch

There are often times in a web application where you need to send a request for the latest user input or interaction. Some examples might be a autocomplete or zooming in and out a map. Let's think about each of these examples for a moment. Firstly autocomplete; every time we type (or maybe less if we were to debounce ) we might send out a request. If the user input changes the old requests might…

Easier Web Workers

Ever been on a web page and everything feels a bit slow? Delays typing, scrolling, and general interactions with the page? One of the main causes of this is 'blocking the main thread'. Browsers do their best to keep the rendered contents of a page in sync with the refresh rate of a monitor (generally this is about 60 frames per second). However doing expensive operations in your main thread (i.e.…

Implementing the Web Share API in Your App

I was looking into how I might be able to improve the sharing experience on https://scratchthe.world , a digital scratch map PWA that I have been working. One thing I came across recently is the Web Share API , which I thought might be a strong contender for integration. The Web Share API allows for a smoother integration of sharing with popular applications on your mobile device (WhatsApp,…

Messaging Between Tabs Using Service Worker

As of late I've been thinking a lot about Service Workers (sorry if this is getting boring!), predominantly in relation to the Cache API. For those of you who aren't familiar, Service Workers are a type of Web Worker that are shared between a domain scope, and can do cool things like intercept network requests and cache them. This is powerful because it means you can improve the performance of…

Getting going with ES6 Maps

As we move into a world where modern browsers are supporting the nearly the entire ES6 specification , we have a variety of data structures to use for storing and accessing our data as native built-in primitives. In ES6 we specifically gain access to 'keyed collections'. Keyed collections encompasses four built-ins, these are namely Set , Map , WeakSet and WeakMap . Here we'll be talking about the…

Creating Gradient Borders with CSS

Products have seen a resurgence of gradients in the past year or so. I too wanted to cash in on the PowerPoint circa 2003 aesthetic and as such I took to work on finding how I could add some gradients to the button outlines on my blog. Unfortunately I really struggled to find any decent guides on the matter, but after a little bit of digging and understanding the solution was fairly…

Replicating JavaScripts setTimeout and setInterval in Go

In JavaScript we have two inbuilt functions for doing some work at some given point in the future. Firstly setTimeout ; this allows us to run a function after a given period of time in milliseconds. We also have setInterval which allows us to run a function every x milliseconds until the interval is cancelled with clearInterval . You can find a solid overview of timers in JavaScript on MDN here .…

Low Hanging PWA Fruit: Manifest Files and Service Worker Precache

It would be a fair assessment to state that Progressive Web Apps (often abbreviated to PWA) are a popular buzzword in the web development and JavaScript communities at the moment. We have also seen further excitement recently, generated by Apple's move to start supporting development for PWA features within Safari . Many great posts and documentation exist around explaining the full case for PWAs…

Using Go to Plot Global Data

Wanting to explore more around geospatial tools with Go, this week I've been exploring Globe . Globe creates wireframe global visualisations of data sets, provided they contain latitude and longitude points. Here's an example of the API from the README: shops , err := LoadCoffeeShops ( "./starbucks.json" ) if err != nil { log . Fatal ( err ) } green := color . NRGBA { 0x00 , 0x64 , 0x3c , 192 } g…

Icon Font to SVG Icons: A worked example

There has been an on going discussion about wether Icon Fonts or SVG Icons are 'better' for usage on the web. This css-tricks article outlines the introductory differences between the two nicely. The author concludes that "If you can go IE 9+ / Android 3+, inline SVG is better at pretty much everything than icon fonts" . This view has been debated somewhat, with Tyler Sticka laying down a solid…

Deploying a Static Blog with Continuous Integration

In recent years, static sites have seen a resurgence . In this post we'll explore how to use Hugo, a static site generator, in conjunction with a remote web server and a continuous integration provider. Although the site generation software here is Hugo it could easily be another provider such as Jekyll. The web server will be hosted on a Digital Ocean droplet running Nginx , and CircleCI will be…

Effective Cartograms

Earlier today I tweeted something that I had been contemplating for a little while about cartograms. For those of you unfamiliar, a cartogram is a type of map that uses a attribute (population, income etc) of a geographic feature to influence it's area in some capacity. The cartogram that is most familar to most people is the 'continuous irregular cartogram', which can be seen as figure C in this…

Dense Spatial Data and User Experience

Across many disciplines we are increasingly seeing the inflation in size of datasets. From megabytes to gigabytes and beyond, with certainly no exception in the geospatial industry. This is in turn posing an ongoing challenges for geospatial developers, web mappers, cartographers and various other spatial data wrangling professionals. As with web pages, increased density of data on our focus point…

Visualising Facebook's Population Data on the Web

Over the past month or so (on and off!) I've had the opportunity to explore two really interesting ideas. The first was relating to a talk I saw at FOSS4G in Bonn this year by Fabian Schindler. Fabian's talk was on how to use GeoTIFF data in the web using a set of libraries called geotiff.js and plotty.js. You can see a post about his talk here . The talk got me thinking and interesting in what…

10kB Web Pages

Over recent times there has been a lot of stir around the growth of website assets and total transfer over the wire. It has been pointed out that the average size of a website is now larger than Doom! (Credit: mobiForge ) In response to these acusations of page bloat, we have seen an emerging trend which is that top websites are now decreasing there page weights . For example Financial Times has…

The Geospatial Continuum: Is Geo Breaking Out Of Its Niche?

A curious thing struck me during the recent hype surrounding Pokemon Go. I was discussing with a friend at my current place of work, the Geovation Hub about the intersection of GIS and society, and how Pokemon Go might help bring geo and GIS more into the public eye. My gut reaction was "I doubt that" . Why you may ponder? My reasoning goes that the majority of geospatial innovations don’t really…

Why I Moved To Hugo For My Blog

You might have noticed my blog's had a bit of spring clean. The new site is powered by a static site generator called Hugo, which is written in the loveable Go language. I also finally moved off of shared hosting (don't ask...) to a Digital Ocean server which also provides me a host of other freedoms. My previous site was a custom site I wrote using PHP + MySQL over the years. It worked well as a…

Big Geo Data, Spatial Indexes and Parallelization

As geospatial datasets continue to increase in size, the necessity to be able to query and gain meaning from them efficiently has never been more important. I have talked a little bit previously about why geospatial problems are inherently complex to solve (predominantly down to the multidimensional nature of the data). To demonstrate swiftly however, we can imagine that some years ago it would…

The Hard Thing About Hard Geo Things

As spatial data sets have become larger, aggregated faster and from a wider variety of sources, handling large spatial datasets has become a challenge. As I'm sure many of you have experienced, many GIS operations can take a fairly long time to complete, especially with traditional desktop GIS techniques. Last week at the pub after geomob , I was discussing with a friend who works for Google in…

On Well Known Text and the Web

Over the past week I have made a start on looking back at the problem of transferring spatial data out of databases into front end applications. This issue stemed from a project I worked on UCL called Lacuna . Lacuna was a 3D, WebGL based Geographic Information System that I worked on for my masters dissertation. I have since deprecated Lacuna because, in all honesty I dived straight in the deep…

Devangelism: Finding My Feet - Part 2

At the beginning of June I wrote part one of 'Devangelism: Finding My Feet'. This post is the follow up of my experiences as a Developer Evangelist at Esri UK over the past ten months or so. The article is a continuation of the previous post, touching on a few things I have learned and feel may be pertinent for other people undertaking a roll in developer relations. Hopefully if you're new or…