Let's Geocode with Here.com

 Welcome to the World of Geocodes



Have you ever wanted to see if an address is real and if it is get the geocode for it? Geocode, what is that? Ok, let's start with defining what a geocode is and what it can be used for. The location of everything on Earth can be defined as a set of latitude and longitude (a sort of set of coordinates). So, a geocode is simply this set of latitude and longitude that represents a geographic entity. Now that we know this, what is it used for. Simple, if you want to store a location on a Google map, it is easiest to store the geocode for it. If you have the geocode you can use it to add a marker to the map or even center the map. Another use is when you have several geocodes, you can build a fence on a map and then check the fence to see if a point is within the boundary of the fence, but that is for another post on another day, today we simply want to get the geocode for an address. 

In this post I am going to take you through an example of how I validate and address and get its geocode. I will be using the Here.com platform to geocode an address. I will be using C# and .Net Core 6 to talk to the geocode api that Here.com provides. 

Here.com - Map Data and Tools for Enterprises

Here/com is an alternative to Google Maps. It allows you to do a whole bunch of things relating to maps from visual maps, to geocoding, to reverse geocoding. In fact far more than I am going to cover in this blog. To get started we need to get an account with Here.com. Got to Here.com and click on Sign up to start building.

You will then see the sign up page
Fill out everything and select the Free tier and don't enter your payment details no matter how many times they ask you to. On the Free tier we get 1000 transactions a day and no support. If you want more, or need support you can upgrade later. Now that you have signup up and logged in, lets take a look at the platform.

Access is Something we can't live without

This is the page you will see when you log in. The first thing we need to do to use any the rest apis is to get an API Key.
Click on Go to Access Manager. From there click on Register New App. Give it a name and click Register. You want an API Key. Click Create API key. 
Congratulations, you now have the api key you need to make calls. We will use this key when we make our calls. Now we want to find out about the Api that we want to use. Go to here.com/docs and click on HERE Geocoding& Search. Take a look around and get familiar with the documentation then go to here.com/docs/bundle/geocoding-and-search-api-developer-guide/page/topics/quick-start.html. The part of the page we are interested in is the geocode request...
https://geocode.search.hereapi.com/v1/
geocode
?q=Invalidenstr+117+Berlin
&apiKey={YOUR_API_KEY}
Using the API Key from earlier try it in a browser. You should see a JSON response...
{"items":[{"title":"Invalidenstraße 117, 10115 Berlin, Deutschland","id":"here:af:streetsection:tVuvjJYhO86yd5jk1cmzNB:CgcIBCCf2912EAEaAzExNw","resultType":"houseNumber","houseNumberType":"PA","address":{"label":"Invalidenstraße 117, 10115 Berlin, Deutschland","countryCode":"DEU","countryName":"Deutschland","stateCode":"BE","state":"Berlin","countyCode":"B","county":"Berlin","city":"Berlin","district":"Mitte","street":"Invalidenstraße","postalCode":"10115","houseNumber":"117"},"position":{"lat":52.53041,"lng":13.38527},"access":[{"lat":52.53105,"lng":13.3848}],"mapView":{"west":13.38379,"south":52.52951,"east":13.38675,"north":52.53131},"scoring":{"queryScore":1.0,"fieldScore":{"city":1.0,"streets":[1.0],"houseNumber":1.0}}}]}
There are a few things in the JSON that we are interested in. The first in the resultType. The next is the position and finally the fieldScore. I'll let you play around with various addresses to see the various responses.
Now that we have our API and API Key, we want to be able to use it inside our C# project.

Now for the magic

For this I will use Newtonsoft.Json and Restsharp. You can get them from Nuget. Before we dive into the code, there is one thing I want to make my life easier. I want a set of classes that will represent the Json reponse. Yes, could use a dynamic, but why not just use a set of classes. Well, good news, if you have some Json and you want a set of classes to represent it, simply go to json2csharp.com. Drop in the Json you got when you ran the Api in a browser into the left box and press the Green Convert button and as if by magic a set of classes appears.


Now to code. I have a .Net 6 Console Application already set up. I've added a class called HereGeoCode to it where I have pasted the classes from json2sharp. I changed the namespace to HereGeoCode.

So, now we have the classes, let's dive into the code.

First we need to tell it we want to use NewtonSoft.Json and RestSharp.

using Newtonsoft.Json;
using RestSharp;
Next we want to get the geocode for an address...
var client = new RestClient("https://geocode.search.hereapi.com");
var request = new RestRequest("v1/geocode?q=84404+Njjdd+Dunes+Trl+McKinney+TX+75070&apiKey=jnddtDKi68lNy75MGM9bjx4LGnKpR74x_cVYd8o8Wi8", Method.Get);
request.AddHeader("User-Agent", "Nothing");
var geoResult = client.Execute(request).Content;
See how useful RestSharp is. The Execute method calls the API and gets more than just the Json back. If it had simply returned Json we code have told it to cast it to the classes by adding after the Execute. Instead we use the Content from it. Nextwe want to deserialize the Json into our set of classes.
var root = JsonConvert.DeserializeObject<HereGeoCode.Root>(geoResult);
Now we have the result in our classes we can start to look at how to use the data... I've added a new class to my project to hold the final result.
namespace GeoCode
{
    public class AddressValidation
    {
        public double geoLat { get; set; }
        public double geoLon { get; set; }
        public bool isSuspect { get; set; }

    }
}

So, let's use it with the response we get that we deserialized into the root class.
var result = new GeoCode.AddressValidation();

if (root == null || root.items.Count == 0)
{
    result.isSuspect = true;
    result.geoLat = 0.00;
    result.geoLon = 0.00;
}
else
{
    var item = root.items[0];
    result.geoLat = item.position.lat;
    result.geoLon = item.position.lng;
    if (item.resultType == "houseNumber")
    {       
        result.isSuspect = false;
    }
    else if (item.resultType == "street")
    {
        if (item.scoring.fieldScore.streets[0] < 0.5)
        {
            result.isSuspect = true;
        }
        else
        {
            result.isSuspect = false;
        }
    }
    else {
        result.isSuspect = true;
    }
}
So, to break it down. First we check that we got a result by checking for null or no items. It is possible that more than one item is returned if an exact match cannot be made. For this example, if items have been returned we use the first one. Next we set the geoLat and geoLon from the item.position. Now we check the resultType. Ideally we want it to be houseNumber. This would mean that the address has been mapped to the house you requested. If not, street is acceptable but only is it has a fieldScore of at least 0.5 for it streets score. Note, there could be more than one streets fieldScore, but for this example we always take the first.Any other resultType is suspect for our example.

So, let's warp it up

So, in this blog you learned how to get a geocde from Here.com, turned the result into classes at json2csharp.com, then used RestSharp and NewtonSoft.Json to get the geocode and deserialize it before we checked the deserialized result to determine if we had a good address. Of course, you would need to add error handling and may want to allow more than the street or houseNumber, but by using this code you can easily get the geocode for an address.

You can get the code from this blog @ Geocode-an-Address-in-.Net-Core-6.

Comments

Popular posts from this blog

When Greed and Deception Destroy a Company

I am Me, no excuses, just Me