Modernizing Kitsap County’s Parcel Details

Parcel Details is a public service offered by Kitsap County that allows anyone to look up information about parcels of land using a tax account, street address, or parcel ID number. Originally this application built over a period of about a year by a single developer. As part of my role with the County I took over as the maintainer of this web app in February.

In the gallery above you can see the current release of Parcel Details that I created over the past couple of months. In the gallery below you can see what the public release of this web app looked like when I took it over.

There are some really clear differences between these two versions of the app, but for me, the biggest difference is adding responsive design in the current build. Before the current release, Parcel Details was a fixed width web app; now it scales from phones to 21:9 desktop monitors. This is all thanks to my effort to scaffold Bootstrap 3.3 over the top of the custom UI elements provided by a company called Telerik.

Integrating Responsive Design

The creator of Parcel Details built it using rapid application development or RAD tools from Telerik. These tools are drag and drop UI elements made available through a Visual Studio extension and a licensing fee. The database connections are made using Table Adapters and then the application sits on top of ASP.NET and .NET 4.0. In the current iteration you’ll see that it’s been upgraded to the latest 4.7.x release of .NET.

If you use Chrome’s inspect tool you’ll see that render pages are structured as a series of tables nested inside of a table at times this nesting is up to four layers deep. This complicated the process of applying bootstrap to this project and required me to spend some time removing unnecessary table nesting on the master page and in the controller pages which when present either broke Bootstrap’s container system or signaled for line break elements where they weren’t necessary.

Another wrinkle to this process was trying to understand how Telerik’s RAD UI elements were styled. Simply referencing an element by its class tag in CSS resulted in no changes. The styling profile that Telerik was providing as a linked script was overriding those changes. To disable the default UI style I had to go element by element and table by table to add a flag to disable the built-in styling and give the element the tags it need to get styled by Bootstrap. Needless to say, this was a time-intensive process.

Trial and Error

The menu structure for this application is also unusual in that the nav button elements are generated by a loop at runtime that iterates through an XML list of parent and child navigation nodes. For web apps I’m used to seeing navigation elements defined as part of a static list rather generated through a loop, so this was rather confusing for me. Once I realized what was going on it was only a matter of finding the navigation generation class and having it assign each node a CSS class that Bootstrap could style ex. btn btn-primary col-xs-4.

Finally, there was a lot of trial and error tuning of this UX. Because I was going through and modifying the element individually there were a number of times when I found a new page in Parcel Details that had unstyled or incorrectly styled elements. Additionally working through and controlling how the menu elements reflowed at different window widths is a process that requires a fair bit of experimentation.

With those major issues worked out I overrode the Bootstrap’s -primary color with the County’s shade of blue, implemented a header bar with the logo, and added the footer from the main website. The purpose of these changes was to give Parcel Detail’s a look and feel that was consistent with the rest of the County’s online presence.

Adding Telemetry and Logging

Parcel Details Azure

The last step was to take advantage of the free services that Microsoft offers through its Azure platform and add Application Insights to this project. This tool handles all the logging and profiling that this app previously used a custom service to handle and dumps it into a nicely styled dashboard on my Azure account that I can share with my coworkers.

I can also use the telemetry it provides to trigger custom events like email blasts tied to downtime events. The catch is that you can only log up to a 1 GB of data per month per app before Azure will bill your account. This is a cap that was fine for testing and development but was surpassed in production. Luckily my account is credited with $50 a month thanks to my MSDN subscription which is more than enough to cover the $0.30 Azure is charging me.

For my purposes, Application Insights was a perfect fit and has really streamlined my process for dealing with logs and troubleshooting exceptions. Often times I’m able to identify a service interruption or broken page using Application Insights before the help desk starts getting reports.

A Roadmap for the Future

With this mobile friendly conversion of the front-end of Parcel Details the next steps are to improve the page load performance of the application, improve the stability of this app’s server infrastructure, modernize the deployment model, and build out a suite of unit tests to prevent regressions. I call this a user-first application improvement roadmap. I’m starting with the changes that will have the biggest impact on the public’s perception of the application first, and then moving toward the items that will improve my perception of the application’s quality.

You can head over the see the public version of Parcel Details here: https://psearch.kitsapgov.com/pdetails/

Kick the tires and ping me if you find anything. 😀

Cloning Kitsap County’s Parcel Viewer

Parcel viewing applications are notorious for being a bit ugly and a major resource sink for municipalities on the development and maintenance side. Although Mapbox may not have intended for their tools to be used to create this kind of application, the strengths that make it a good choice for VR and AR app development also make it a very interesting play when we apply it to more traditional GIS applications like a parcel viewer.

Anyone that’s tried working with a large, high precision, vector dataset like a parcels layer know that it can be pretty difficult to work with due to amount of data they contain. For example rendering just the parcel shapefile provided by Kitsap County inside of QGIS takes a little bit over 2 seconds.

KitsapParcelsQGISLoading

 

Exporting that same parcel layer out to a GeoJSON file for use inside of a Leaflet-based webmap results in map that’s better described as a slideshow and that can take upwards of 30 seconds to move between zoom levels and positions.

Simply put parcel layers are too often much data for traditional desktop and web maps to render in real time.

Vector Tiles and OpenGL to the Rescue

The solution of course is to break the data down into bite sized chunks that can be dribbled out quickly, rather than trying to serve up a monolithic vector layer. I’m going to assume that most people are familiar with how most basemaps are rendered on the web. As a refresher, they are rendered as raster tiles; or put more simply a series of square images that are loaded in parallel to improve rendering speed.

A couple of years ago the big players got together and came up with a similar concept aimed at vector data dubbed vector tiles. The process of converting a monolithic vector layer into vector tiles breaks the dataset up into bite sized pieces that browsers can handle. When you upload a shapefile to Mapbox’s servers your vector data is immediately converted into vector tiles.

The other half of what makes Mapbox’s tool chain a workable choice for a parcel viewer is the Mapbox GL javascript library that they use for rendering web maps. This library allows you to take advantage of the increasingly impressive abilities of modern web-browsers to do real-time 3D rendering.

The combination of vector tiles and the Mapbox GL rendering library allows for us to render every parcel in Kitsap County in a 3D webmap at a buttery smooth 60 frames per second. This is not something that is possible or would require aggressive customization to recreate inside desktop GIS software like QGIS or inside of a 2D web map like leaflet provides using Shapefile or GeoJSON formatted data.

Understanding A Parcel Viewer

Before you can build a decent clone of an existing parcel viewer you need to understand the services that it’s providing.

2017-10-21

For this project I’m going to clone Kitsap County’s parcel viewer seen in the screenshot above. Let’s start by identifying the layers that they’re serving up with this map.

  • Section Townership Range (Red Grid Squares)
  • City Boundaries (Red Outlines)
  • First Peoples Reservations  (Grey Polygons with a Purple Outline)
  • Military Installations (Grey Polygons with a Grey Outline)
  • Labels for Cities and Military Installations
  • Labels for Section Township Ranges
  • Parcel Outlines (Transparent with Grey Outline)
  • Tax Parcel Labels (Light and Dark Themes)
  • Building Footprints (Grey Polygons)
  • A Custom basemap

This is already quite a bit of data. But there are two more pieces to this story.

2017-10-21 (1)

First up when you click on a parcels Kitsap’s parcel viewer opens a pretty complicated popup window that displays all the open tax accounts that are related to the selected parcel. It also has a button that bumps you into a different popup window that displays the same data but with spreadsheet styling. In addition there are also action buttons that can take bump you into a new window with the specific records.

I’m trying to focus on the mapping aspects of this parcel viewer. So going forward I’m going to ignore these, interesting, but more database and records related features of the Kitsap Parcel viewer.

2017-10-21 (3)

Moving back to the map the second feature worth talking about are the ‘map themes’ that can be selected in the floating legend of the Kitsap parcel viewer. I actually think these themes are super neat in that they change the data displayed based on the subject you’re inserted in. It’s a cool concept, especially given that a map displaying tax parcels is probably not the right map for looking at areas effected by the shoreline management act. These themes allow you to serve up many different kinds of maps in the same portal.

But I’m not going to replicate this many-maps-in-one theming feature either. Rather my goal is to clone the ‘General Features’ theme which seems to mostly focus on the parcels.

So what layer am I going to include?

  • Parcel Outlines
  • Parcel ID (PID) Labels
  • Section Township Range (Better Known as PLSS Grids)
  • Labels for Section Township Grids
  • First Peoples Reservations
  • Address Points
  • Labels for Address Points
  • Building Footprints
  • OpenStreetMaps basemap

And how is my map going to be an improvement over the existing parcel viewer?

  • Extruded building footprints
  • 3D Viewing and Panning
  • Fluid scrolling and pinch to zoom
  • Scales from Desktop to Mobile
  • Mapbox ‘Light’ themed basemap
  • Modern Grey-scale visual theme

And here is the product of my efforts:

2018-05-07

You can check out the Github repo and the live version here.

To build this project out into a real Parcel Viewer there are two things you’d have to do: improve the geocoder/search service and enable the popups to show more than just the attribute information from their layer. As it stand now the search service is just the Vanilla Mapbox geocoder which includes addresses from all over the world rather than limiting them to just Kitsap County. Additionally this geocoder lacks the ability to search by Parcel Number or Tax Account ID, hence a custom geocoder would make this Parcel Viewer much more useful.

Of course those two features would require a significantly more detailed data export from Kitsap County or access to their database. 😀 For another day then.

Plats Search: A .NET Core 2 Web App


Plats Search is the first project I’ve completed in my role as a GIS Programmer for Kitsap County. It’s a relatively simple application that allows you to query for a Plat number and then returns a list of Parcels that are related to that Plat. From there it offers links out to the County’s other GIS and Tax information services like Parcel Search and Parcel Details. Plat Search was the first project I’ve built using Microsoft’s .NET Core 2 ecosystem. The code behind and data models are written in C#, the database interactions are handed by EFCore, and the Frontend is defined using Razor Pages. The project is deployed to an IIS web server running on top of Windows Server 2012 R2.

Dealing with Existing DBs

The most difficult part of this project was handling the database interactions. This app replaces a legacy application created over a decade ago using rapid development tools provided by Oracle. When I began developing this replacement I designed the data model around interacting with an Oracle Database provider. Part way through the project it became clear that we needed to migrate away from depending on this Oracle DB because it was being set to legacy status at an organizational level. Given that the rest of the deployment stack for this web app is Microsoft based the obvious choice for a replacement DB was MS SQL Server.

Conveniently this DB was already a requirement of some of our other production web apps. Which means that making this transition was a matter of writing a script to sync the required tables from the Oracle DB to the Microsoft SQL DB on a nightly basis. Then modifying this web apps existing data model to use the new DB provider and compatible data types. Of course what I’m passing over here was the difficulty involved in learning a new way to build web apps, while switching between DBs that I hadn’t spent much time working with prior to this project.

Advocating for DevOps

On a personal level perhaps the most difficult aspect of this project was introducing source control to an organization that didn’t make much use of the technology and had struggled with it during previous projects. Initially there were concerns about the amount of additional time required to maintain a project repo and the documentation required to support it. The most effective way I found to address these concerns was by implementing source control, writing the documentation, and then walking through the process on a one on one basis with my direct colleagues to demonstrate the advantages of source control like making and committing changes to my work and giving them ability to independently clone, build, and deploy my project.

Implementing modern DevOps practices is an important goal for any organization. But it doesn’t have to be an all or nothing proposition. This is especially true when you’re coming from the outside and bringing in a complete DevOps stack is impractical. In my case and with this Plat Search app leading by example with the fundamentals was the right path. The next steps are to bring continuous integration and deployment to my projects, but for an organization that is just getting the hang of source control those two items are a bit much. Responsible change takes time and careful planning both of which are thankfully in abundance inside of a public organization.

Adding a Vector Tileset of Polygons hosted by Mapbox as a Custom Layer

2017-10-31 (1).png

The process for adding a Vector Tileset composed of polygons that you’ve uploaded to your Mapbox account as a layer to an HTML page is surprisingly complicated.

Here’s the example that Mapbox offers for this scenario:

https://www.mapbox.com/mapbox-gl-js/example/vector-source/

Unfortunately what they’re using in this example is a contours layer composed of lines rather than a polygon layer. If you simply change the example “source” URL to that of your own layer it will fail to load. Two things are missing: the “type” and the “source-layer”.

Example Vector Tileset.png

The correct way to accomplish this task is to grab the Map ID for the Mapbox Tileset that you want to add as a layer to your map by going to the ‘Tilesets’ page in your Mapbox account and hitting the ‘Menu’ button next to the Tileset you want to use. Then hit the clip board button to copy the Map ID of the Tileset.

2017-10-31 (2).png

Once you’ve got the URL for your Tileset paste it as a string into the “url” field of the “source” property. You’ll need to make sure that this URL beings with “mapbox://” in my case the complete URL reads “mapbox://uncheckederror.drjw848r”.

Next you need to make sure the map.addLayer call is filled out correctly. Because we are adding a polygon layer we need to make sure the “type” is set to “fill”. Then we need specifically call out the name of Tileset we want to use in the “source-layer” field. In this case the name of the “source-layer” is the title that Mapbox auto-generates for the shapefile you uploaded. Often this will be the name of the file you uploaded, a dash, and then six random characters. You’ll be able to see the “source-layer” name you need as the title of the tileset on the ‘Tilesets’ page of your Mapbox account.

Finally double check your “paint” settings to make sure that you’ve provide styling values for the “fill-color” and “fill-outline” fields. Without some kind of styling guidance for this layer you won’t be able to see anything anyway. Review my code here for more examples.

With all that done your polygon Tileset served up by Mapbox should now render on your custom webpage as vector tiles. Enjoy!

A Leaflet Map of King County Elections Ballot Drop-off Boxes

2017-10-18 (2)

As a project to get more comfortable with the leaflet Javascript library, I made a map of Ballot Drop-off box locations in King County.

2017-10-18 (1)

The county doesn’t have any publicly available GIS data on these drop-off locations. Rather they have a page with an embedded Google Maps window containing pins for each of the locations. Luckily for us scraping these locations is pretty straight forward using Chrome’s HTML inspection window.

2017-10-18 (3)

Here we can see that all of the drop-off locations are held in an array inside of bit of inline Javascript. From here I copy pasted the array into Excel, removed all the lines starting with ‘//’ to clear out the comments, removed all instances of the [ and ‘ characters as well as leading and trailing white spaces. Then I set the columns to break on : and , and dumped the whole thing out as a CSV.

The next steps were to open up QGIS and use the Add layer from CSV function. The tricky bit here was remember that the projection that Google Maps uses (EPSG:3857) Pseudeo-Mercator and then telling QGIS to read in the spatial coordinates as y, x not x, y. From their I styled the layer with a simple 3 pixel light-green point and exported it to a GeoJSON file so I could load it into of leaflet.

A Leaflet Map

After playing with the styling and popup functions the outcome was this:

https://thomasryan.xyz/Maps/KC/Drop.html

One advantage the King County map has over my own is the ability to bounce the user out from selecting a point to getting Driving Directions in Google Maps.

On the other hand my map has a sharper visual-style with multiple background layers, the ability to grab your current location if your device is GPS-enabled, the ability to search through all the ballot boxes by name, and it avoids the visual clutter of having 50 pins on a map with the heatmap-style point grouping at low-zoom levels.

I guess the next step is working in the ability to route from the user’s current location to the ballot drop box. Leaflet Routing Machine plugin looks like it will do the trick, but that’s a project for next week.

Later that Night

Aha, well it’s not next week but I’m back to add routing to this map. We’re going to use two leaflet plugins to accomplish this task. The first is the Leaflet Routing Machine and the second is the Leaflet Control Geocoder. The first plugin does the routing and the second plugin geocodes the location pins (ideally ballot drop-off boxes) that we’d like to route between.

2017-10-18 (7)

This is the default display for the map. To demo to the user that the map is routing capable, while still showing the whole map, I’ve set it to route between two rather distant Ballot Drop-off boxes. Clicking and dragging either routing pin will force the routing plugin to regenerate the directions its showing.

2017-10-18 (4)

Here’s an example route I created between a hypothetical election day party happening over on Alki beach and the Ballot Drop-off Box at the High Point Library.

It’s worth noting that this map not only supports turn-by-turn directions now, but it will also tell you the total distance between your two routing points and give you an estimate of the time required to make the trip.

Considering that this whole thing only took the better part of the day; I’m starting to really like Leaflet (and it’s plugins).

Interactive 3D Webmap of Pre War Korea

2017-10-12.png

I made a webmap based on a scanned copy of a map of pre war Korea made by the CIA.

https://www.thomasryan.xyz/Maps/PreWarKorea.html

You can find my notes on how I created this map on Github: https://github.com/uncheckederror/PreWarMapofKorea

Comparing Nikon’s Cheap 50mm Lenses

Nikon50mmComparison (1 of 21)

This is a comparison between three of Nikon’s entry-level 50mm Prime lenses: the AF-S NIKKOR 50mm f/1.8G, the AF NIKKOR 50mm f/1.4D, and the AF NIKKOR 50mm f/1.8D.

I own both the 1.8G and the 1.8D and the 1.4D is on loan from a friend. Both the 1.8G and the 1.4D sell for just a shade over $200. The 1.8D, on the other hand, goes for about $130.

Nikon50mmComparison (2 of 21)

The aim of this article is to help you decide what cheap 50mm Nikon Prime to buy. For years now we’ve been hearing about how wonderful lenses like Sigma’s 50mm F/1.4 Art and Tamron’s new SP 45mm f/1.8 VC are. But those lenses at $850 and $500 cost more than your average hobbyist can reasonably afford.

For most people when you buy your first 50mm prime lens you’ll be picking from one of these three choices.

Let me start by saying that each of these lenses are very capable tools and good in their own right. With that said there are many notable differences between them are going to appeal to different kinds of photographers.

In the simplest sense, this comparison boils down to picking which strength you prefer most. The tiny size and low cost of the 1.8D. The extra shallow depth of field that of the 1.4D produces. Or the wide open sharpness that the 1.8G can offer.

Perhaps the biggest X-factor to consider here is how you feel about the specific look that Nikon’s D series glass can offer.

We’ll delve back into those issues a little later. For now, let’s get the basics down.

The AF-S NIKKOR 50mm f/1.8G

Nikon50mmComparison (3 of 21)
Nikon AF-S NIKKOR 50mm f/1.8G

First up we have the AF-S NIKKOR 50mm f/1.8G which we’ll refer to throughout this article as the 1.8G for the sake of brevity. This lens is physically the largest of our competitors although it weighs less than the 1.4D and about the same as the tiny 1.8D. Compared to both of those lenses it offers a number of advantages.

Because the 1.8G is an AF-S lens it has an internal focusing motor. This is important because it means that unlike the 1.8D and the 1.4D it will autofocus on Nikon’s entry-level DX camera bodies like those in the D3000 series and the D5000 series.

This also means that when you auto-focus with the 1.8G you will hear a soft high-pitched humming followed by a few muffled clicks as it finds your focus point.

When changing focus from an object at the 1.8G’s minimum focusing distance to its maximum focusing distance or from its maximum focusing distance to its minimum focusing distance it will take about one second to require focus.

When changing focus between objects in the middle of the 1.8G’s focus range reacquiring focus takes about a half second.

Nikon50mmComparison (4 of 21)
Nikon AF-S NIKKOR 50mm f/1.8G

The 1.8G has the largest manual focus ring in this comparison. Unlike D series lenses the manual focus ring on the 1.8G can be twisted at any time to adjust focus without switching into manual focus mode using the lens’s or the camera body’s toggle switch.

The manual focus ring on the 1.8G feels very smooth and precise on your fingertips. It remains smooth both when you are adjusting it quickly when you are making slow, precise adjustments. When you turn the ring to the minimum or maximum focus point of the lens you will hear and feel a dull thud. But the manual focus ring will continue turning as long as you’re twisting it.

Both manual focus and autofocus performance are good on the 1.8G.

Here we have the oldest lens in this comparison Nikon’s AF Nikkor 50mm F/1.4D. The 1.4D is also the heaviest lens, weighing about a 1/3rd more than the 1.8G. On the other hand, the 1.4D has a metal body and the largest maximum aperture of any lens here.

Because the 1.4D has a maximum aperture of F/1.4 it can gather about 2/3rds of an exposure stop more light. Practically this means that where you could take a properly exposed image inside of a dark club at F/1.8, 1/80 of a second, and ISO 6400 using one of the other lenses in this comparison; with the 1.4D your settings could be F/1.4, 1/80 of a second, and ISO 4000. The result of this change is a less noisy image thanks to the use of a lower ISO.

The other advantage to a maximum aperture of F/1.4 is a shallower depth of field. There are many uses for a shallow depth of field. The most common applications are headshots and portraits where you want to separate or isolate the subject of the image from the background.

It’s important to note that while the 1.4D does give you a shallower depth of field than the 1.8G or 1.8D those two lenses already produced an extremely shallow depth of field a F/1.8.

But unlike the 1.8G and 1.8D which are both plastic on the outside and metal on the inside, the 1.4D is made of metal on the inside and out.

Nikon50mmComparison (6 of 21)
Nikon AF Nikkor 50mm F/1.4D

Because the 1.4D is an AF lens it requires a camera body with a built-in focusing motor to auto-focus. All of Nikon FX bodies have a built focusing motor and the D7000 series of DX camera bodies also have them.

Unlike AF-S lenses which emit a high-pitched humming and soft clicking noises when they focus; AF lenses make a very mechanical screwing noise that sounds most similar to a cordless drill. Our 1.4D is significantly louder than the 1.8G when focusing. Although the sound of either lens focusing is audible in a quiet room.

The speed of changing between focus points and refocusing with the 1.4D is very similar to that of the 1.8G.

Manual focusing with the 1.4D is enjoyable. The 1.4D has a rubberized focusing ring that spins very smoothly. The rubber ring gives a better and more comfortable sense of control than the hard plastic ring on the 1.8G. It also requires less force to adjust at low speeds and makes a soft gear turning sound.

The 1.4D has hard stops at its minimum and maximum focus settings. This means that when you reach either end of the focus range you hit stop that will prevent you from twisting the focusing ring any further and make a metallic sounding thud.

Just like the 1.8G both auto-focus and manual focus performance on the 1.4D are good.

The AF NIKKOR 50mm f/1.8D

Nikon50mmComparison (7 of 21)
Nikon AF NIKKOR 50mm f/1.8D

Finally, we have the AF NIKKOR 50mm f/1.8D the cheapest and smallest of the lenses in this comparison. This was the first lens I ever purchased. It’s about 2/3rds the size of the 1.8G and a bit smaller than the 1.4D.

The advantages of the 1.8D are pretty straightforward: cost and size. Like Nikon’s other D series primes the 1.8D exhibits its best performance from F/2.2 and up. It’s sharpest at F/5.6 but f/1.8 is perfectly usable. Given that this is a ~$130 lens its performance is really quite admirable.

Of course, compromises had to be made to hit that price point. Unlike the 1.4D the 1.8D has a plastic exterior and that feels a bit more slippery than the textured plastic on the 1.8G. It also has the thinnest manual focus ring and uses the same hard plastic as the 1.8G ring rather than the excellent rubberized ring of the 1.4D.

Nikon50mmComparison (8 of 21)
Nikon AF NIKKOR 50mm f/1.8D

The autofocus performance of the 1.8D is slightly slower than the other two lenses in this comparison. It’s not make or break slower, perhaps a quarter of a second at the worst, and more often than not its the same speed as the 1.4D and 1.8G.

Because this is an AF lens, like the 1.4D, it requires a camera body with a built-in focusing motor to auto-focus. It also emits the same power drill noises as the 1.4D when it’s focusing. The 1.8D also has hard stops as its maximum and minimum focusing distances.

That said, manual focusing performance is clearly not as good. With a small, hard plastic focusing ring, the 1.8D is at a disadvantage. The use of cheaper materials is exacerbated by the chunky feel of adjusting the focusing ring. Quick adjustments are smooth, but small low-speed adjustments require a lot of initial force which creates chunky movements and imprecise adjustments.

To be clear manual focusing is still easy to do with the 1.8D but using the manual focus ring can be frustrating at times and will certainly require a bit more effort and time than it would with the 1.8G or 1.4D.

Auto-focus performance on the 1.8D is good, although worse than the other lenses in this comparison. Manual focusing, while usable, leaves something more to be desired.

Mounts, Materials, and Glass

Looking at the rear elements of these lenses we can that they all use metal F-mounts. The use of different optical coatings produces the different coloration in the glass of each of these lenses. More importantly, you can see that the size of the glass elements differs in each lens.

Nikon50mmComparison (9 of 21)
Right to Left: 1.8D — 1.8G — 1.4D

In the image below you see what each of these lenses look like when they are fully extended to their minimum focusing distance. The front elements on the two D series lenses extend out from the barrel of the lens and towards the subject while the front element of the 1.8G never extends out of the barrel of the lens.

Nikon50mmComparison (14 of 21)
Right to Left: 1.8D — 1.4D — 1.8G

One of the more important characteristics of these primes is the bokeh they produce. For those of you that are unfamiliar with the term bokeh it refers to the character of the out of focus area and highlights in an image. Using different apertures will change the bokeh in an image based on the number and type of aperture blades in the lens and the amount of depth of field in the image.

A prime lens at its maximum aperture will have circular out of focus highlights and a relatively shallow depth of field. While a lens at middle apertures like F/5.6 or F/8 will have out of focus highlight the mirror the shape of the aperture blades and more depth of field.

What kind of bokeh you like will depend on a lot your personal preference. But in general, softer out of focus areas and more circular highlights are preferable hard out of focus shapes and hexagonal highlights.

All three of the lenses we’re comparing here have seven bladed apertures. The 1.4D has an advantage thanks to its large maximum aperture which allows it to throw more of the image out of focus. But the 1.8G has rounded aperture blades so that even when you stop it down from its maximum aperture its out of focus highlights will still have a semi-circular appearance. This is opposed to the hexagonal highlight appearance you’ll see with the 1.8D and 1.4D when they’re stopped down.

Nikon50mmComparison (10 of 21)
Nikon AF NIKKOR 50mm f/1.8D
Nikon50mmComparison (11 of 21)
Nikon AF Nikkor 50mm F/1.4D
Nikon50mmComparison (12 of 21)
Nikon AF-S NIKKOR 50mm f/1.8G

In the photos above, you can clearly see the differences in the aperture blades between these three lenses.

For this comparison, I’m using a landscape of the inter-bay area of Seattle looking into downtown. These shots were all taken at ISO 100 using the lenses maximum aperture from a tripod using a wireless trigger to ensure consistency.

Specifically, we’ll be comparing the quality of the background bokeh in these images. In the first set, all of these lenses were at their minimum focus distance.

Nikon50mmComparison (16 of 21)
Nikon AF-S NIKKOR 50mm f/1.8G
Nikon50mmComparison (17 of 21)
Nikon AF Nikkor 50mm F/1.4D
Nikon50mmComparison (18 of 21)
Nikon AF NIKKOR 50mm f/1.8D

There are two things that immediately stand out: the 1.4D produces largest out of focus highlights and the 1.8D has the smallest highlights. 1.8G has the smoothest bokeh while the 1.8D has the most character. The 1.4D and the 1.8G actually have very similar bokeh, but the highlights on the 1.4D have a thin green outline around them that isn’t present in the photo from the 1.8G.

The bokeh of the 1.8D is arguably the least attractive looking of all three of these lenses. Its spheres have both hard outlines and morph into half spheres as they get closer to the edge of the frame. On the other hand, some people are into that. Maybe you’re one of them; I know, that at times, I am.

To consider the sharpness of these lenses I’m going to defer to DXOMark’s lab testing for basic insights and then I’ll be supplementing that with additional field testing. My field testing will be broken down into two categories: a maximum aperture portrait and a landscape shot at F/8.

Nikon50mmDXoCOmparison

Looking at a comparison of these three lenses tested on a Nikon D7000 (my personal camera) by DXOMark we can see that the 1.8G is notably sharper than the other two lenses at F/1.8 its maximum aperture. Stopped down below F/1.8 the performance of these three lenses is essentially the same with the D series lenses both offering slightly sharper corner performance than the 1.8G up until F/8.

Nikon50mmComparison (19 of 21)
Nikon AF NIKKOR 50mm f/1.8D
Nikon50mmComparison (20 of 21)
Nikon AF Nikkor 50mm F/1.4D
Nikon50mmComparison (21 of 21)
Nikon AF-S NIKKOR 50mm f/1.8G

In this portrait performance comparison, I shot the model at the maximum aperture of each lens and focusing on the left eye of the subject using live view to ensuring critical focus from a tripod with a Nikon D7000. Shutter speed will vary and ISO will be set to 100. The distance from the camera to the subject is about one meter.

Given that we’ve just talked about sharpness we’ll start our comparison there. The 1.4D and the 1.8D offer very similar levels of sharpness while the 1.8G is clearly a bit sharper here. The difference becomes more apparent when the images are viewed 1:1 which we’ll get to in a moment. The other big issue when considering perceived sharpness is contrast. Both of the D series lenses offer less contrast wide open than the 1.8G. But again that’s part of what people like about D series lenses.

There are also major differences in terms of the bokeh in these images. 1.8D creates a relatively chaotic background with lots of overlapping hard edges and non-spherical shapes. Conversely, both the 1.4D and the 1.8G offers very smooth and round out of focus highlights.

Given the similarity between the 1.4D and the 1.8G in terms of the character of their out of focus areas the 1.4D offers the slight advantage of larger out of focus highlights due to its larger f/1.4 maximum aperture.

Moving back to sharpness: here’s a 1:1 comparison with the 1.8G on the left and the 1.4D on the right. The 1.4D and the 1.8D offer almost the same levels of sharpness at their maximum apertures. Also take note of the higher contrast image that the 1.8G produces.

2017-02-05 (1)
1.8G on the left and the 1.4D on the right

The takeaway here is pretty straight forward: The 1.8G is the sharpest lens in this comparison at its maximum aperture. It’s notably sharper in the center of the frame than either the 1.4D or the 1.8D. On the other hand, I hope you noticed how difficult it was to tell the sharpness of these three lenses apart in the full images thanks to how much detail is lost when presenting photos on the web. For usage on social media or Facebook you’ll be hard pressed to see significant differences in sharpness between any of these lenses. The biggest consideration for those use cases is which lens offers the bokeh you prefer.

Moving to our landscape comparison I decided to spice things up a bit by shooting each of these lenses directly into the sun without any kind of lens hood. All of these images were taken at an aperture of f/8 and an ISO of 100; shutter speeds varied but all of these images have the same level of exposure.

While the sharpness of each of these lenses is almost the same both in the corners and at the center the way they handle direct sunlight and the flare they produce are markedly different.

Both D series lens produced large hexagonal flare near the center of the frame. While the 1.8G had cone shaped flare leading from the center of the frame to the edge.

There are also major differences in the tint of the flare. The 1.4D has the blue flare, the 1.8D has the purple flare, and the 1.8G has the green flare.

Another point to consider is the sharpness and contrast that each lens produces in and around the flared areas.

2017-02-05

Here we can see a 1:1 comparison of the 1.4D and the 1.8G where the 1.8G retains much more contrast in the rock wall and sharpness in the grass when both lenses are fighting with the same level of flare.

Again all three of these lenses produce similar levels of sharpness shooting landscapes at f/8. But in difficult conditions like shooting with the sun in the frame, the 1.8G produces the most technically correct image. That said the 1.8G and the 1.4D certainly produce some interesting looking flare patterns.

Nikon50mmComparison (13 of 21)
1.8D bottom left, 1.4D bottom right, 1.8G top

So there you have it. Now we know what these lenses are and how the compare to one another. As I said at the start all three of these lenses are great. Deciding which lens is the right lens for you will depend on three major factors: price, what camera body you have, and what kind of bokeh you prefer.

If you can’t spend a lot of money and you own a camera with a built-in auto-focus motor like one of Nikon’s D7000 series or FX format cameras then the 1.8D is a great choice. On the other hand, if you can spare some extra cash the larger aperture and smoother bokeh of the 1.4D are a worthwhile upgrade.

But if you own one of Nikon’s lower end camera bodies like a D3000 or D5000 series camera then you only have one option: the 1.8G. Accurately manual focusing on Nikon’s lower-end camera is difficult and you’ll curse yourself for not picking up a lens that can auto-focus. The other big reason to pick up the 1.8G is sharpness at wide open apertures where it’s clearly ahead of the 1.8D and 1.4D.

Nikon50mmComparison (15 of 21)
1.8D right, 1.4D center. 1.8G left

My recommendation for those of you who are still confused about which lens is the right one for them or who didn’t completely understand the technical information in this comparison is to pick up the 1.8G. This lens is compatible with all of Nikon’s recent camera bodies and offers great performance for its price point.

Note: This is a revised version of a piece I published on Medium a year ago. It contains spelling and grammar enhancements, but most importantly the images are hosted on Flickr, rather than Medium, so their quality is much better preserved in this iteration. 

Bulk Merging GeoJSONs into a Single File

I’ve spent a lot of time with Mapbox’s geojson.io and the GeoJSON format lately. One of the things I realized that I wanted to do was to take a pile of small GeoJSON files and combine them into a single file outside of the context of a database.

Scouring the Web

Of course, someone else had already thought of doing this and so I stumbled onto a series of Gists from 2012. There was a problem of course: these Gists used command line arguments for specifying the input and output files. I’m not a fan of this method because of the strain it puts on people who are uncomfortable with the command line. Rather I prefer to use text prompts to capture this same information.

Thus I ended up rewriting most of what was in th9ese Gists with the exception of the JSON (and GeoJSON) formatting logic which was perfectly fine.  I broke it down into discrete functions as opposed to a monolithic main function and spun it out into a repo with the test GeoJSON files that I was using to ensure its functionality.

The other twist here is that instead of requiring the user to supply the path names for the specific GeoJSONs that they want to combine I opt to have the script take the path to a folder and then have the OS return a list of file paths that were of the type GeoJSON. This change saves a lot of time when you’re setting up a batch processing operation and it eliminates the frustration of incorrectly entering a path name.

You can find the repo for this project dubbed BatchMergeGeoJSONs on Github.

Using Bokeh in the Foreground and the Background

One of my favorite photographic tools is Bokeh. You can use it to clean up messy backgrounds, messy foregrounds, or to just straight up isolate the subject of the image. The thoughtful application of bokeh can be very helpful in directing the attention of the audience.  In this article I’ll be discussing how I’ve worked to integrate Bokeh into both the foreground and background of my images.

An Extreme Example

Water Front Lights

I made this image during the Christmas Season. The highlights in the bottom left corner are passing cars, the tree near the center of the frame was wrapped in white string lights, and the Bokeh balls in the foreground are string lights on a different tree. In order to get the circular pattern I wanted in the Bokeh I used an older manual lens: the 58mm Helios 44-7 which is known for producing this effect.

Thinking more specifically about the layering of Bokeh in this image there are three variables I had to consider: distance to the foreground, distance to the background, and the character of the lens. There are two ways to control the balance between the foreground and the background: the focus point and the physical position of the camera.

To throw both foreground and background out of focus in this image I had to get right up on the lights in the foreground. I was well within the minimum focusing distance of this lens. At the same time my focus point was just ahead of the minimum focusing distance of this lens to get the kind of character I wanted from the background Bokeh.

Practically this leaning on the tree and playing around with the focus point in Liveview mode for a minute until I was confident that I was pulling the best image I could out of this scene and this lens. It’s also worth noting that I shot this image with the aperture of this lens wide open at f/2 with the intent of getting the bokeh balls to be as circular as possible and not hexagonal.

This image uses foreground and background bokeh not to isolate a subject but rather to convey a complex and yet decidedly abstract scene. I consider this image an extreme example given that there isn’t a single object that’s in focus in this image.

For Enhancing Subject Isolation

Winter Berries

In this image the foreground is on the right-hand side of the frame and includes the white berries that oppose the subject of the image. Here I’m using Bokeh in the foreground to obscure the specifics of a compositional element because I wanted its color and shape but not its detail.

In the background I’ve aligned the subject so that the Bokeh’ed twigs act as leading lines. Obviously these berries are rather small and while I wasn’t using a macro lens to create this image I did pair a 10mm extension tube with a Nikkor 70-300mm VR lens and shot wide open at f/4.5.

Through the use of these three layers of focus I’ve worked to isolate the subject of the image while demonstrating the pleasing qualities of this lens’s Bokeh. It’s worth noting that often times the way a lens will render out of focus objects in the foreground is different from how it will render them in the background. Case and point the foreground Bokeh is smooth while the background Bokeh is busier in this image.

Natural Framing and Foreground Bokeh

Athlon X4 880K in Flowers

Placing foreground elements outside of the lens’ focusing range is a technique that I relied on in the first image and I’ve used it again in this product shot. Here its purpose is to frame in the left and top of the image. I’ve then opposed that by leaving the bottom and right side clean and empty. Isolating the subject was my end goal in this image.

Working with plants can be challenging at times. In this shot I placed the subject at the intersection of a set of branches in a horse-sized bush. This intersection was useful because it immediately gave me a set of leading lines to build the image around. It also allowed me to play with the dappled lighting that was coming through the outer edges of the bush.

I imagine that I looked pretty strange to people walking by as I shoved my camera into this blossoming bush but I’m still very pleased how things worked out.

Conventional Isolation

Resting Place

In this image we have a more conventional use of depth of field to support the isolation of the subject. But rather than obliterating the background I stopped the lens down so that while specific details of are long gone the color and shape of the environment remain. There’s no mystery in this image; you’re looking at a fallen tree in an evergreen forest and at least that much is clear.

The reason that I’ve brought this image up is to look at how foreground Bokeh can be used not only to isolate the subject but also as a compositional element. Thanks to the curvature of this tree trunk, field curvature of this lens, and the close proximity of the camera to the subject I was able to build this image around leading the viewer’s eye through the image and along the plane of focus which extends from corner to corner.

Thus I’ve not only isolated the subject but used the plane of focus as a leading element to draw the audience into the image.

Foreground Bokeh in Macro Photography

Hard Drive Platters

Macro photography is a pretty popular genre at the moment but one of the elements that I rarely see used is foreground Bokeh. Often when I do see it in popular images it’s not there intentionally rather it’s included as a by-product of the lens and camera combination that were used to create a given image. Because of how much I enjoy utilizing foreground Bokeh on a personal level when I see Macro shots where it could have easily been included I think of it as a missed opportunity.

In the image above I’ve used both foreground and background Bokeh to isolate and frame the subject of the image which are the edges of these three hard drive platters.

Actively and intentionally using foreground Bokeh as framing tool for the subject of the image is what I’m striving for these days. It’s a personal preference obviously and there’s nothing wrong with other ways. But hopefully in my discussion of these photos you’ve picked up on why they’re my focus at the moment.