Tuesday, April 14, 2020

How to insert GeoSpatial Data into Azure Cosmos DB by using .NET SDK


     GeoSpatial Data can help you to answer many questions in your business If you know how to use Spatial data. Searching data by radius can bring you all kind of interesting data. For example, If you know the path of hurricane, you can make searches by using the path and find all your customers under that path. Then you can be proactive and do something about this upcoming problem for your business.

     Many databases support Spatial Data Types, I will cover how to store Spatial Data in Azure Cosmos DB in this post. I have an earlier post about how to import Spatial Data into Azure Cosmos DB by using Data Migration Tool. I will focus on how to store spatial data by using .NET SDK in this post. I used .NET SDK 3.8.0, you can get the latest SDK from here..

     First, we need some spatial data. I will use Hurricana Katrina's data, I have downloaded this data from NOAA Here is my object I want to store in Cosmos DB.

using Microsoft.Azure.Cosmos.Spatial;

class Hurricane
    {
        public string id { get; set; }
        public int SignalOrder { get; set; }
        public int Year { get; set; }
        public string Name { get; set; } 
        public int Wind_kt { get; set; }
        public int Pressure_mb { get; set; }
        public Point Location { get; set; }

        public Hurricane() { }

        public Hurricane(int signalorder,int year, string name, int wind, int pressure,
 Point location)
        {
            id = signalorder.ToString();
            SignalOrder = signalorder;
            Year = year;
            Name = name;
            Wind_kt = wind;
            Pressure_mb = pressure;
            Location = location;
        }

    }

     Spatial Data will be stored in Point. You must use the Point object in Microsoft.Azure.Cosmos namespace. Don't use the Point object that comes with .NET. There are other types of spatial data types like LineString, Polygon, etc.. I want to store latitude and longtitude of Katrina hurricane's eye location so all I need to Point object.

      I created a database named Spatial, and created a container named Hurricanes in my Cosmos DB Emulator. I picked Name as my partition.



    I have the following function which loads the data to push into Azure Cosmos DB.

static List<Hurricane> GetData()
        {
            var katrina = new List<Hurricane>
            {
                new Hurricane(1, 2005, "Katrina", 30, 1008, new Point(-75.1, 23.1)),
                new Hurricane(2, 2005, "Katrina", 30, 1007, new Point(-75.7, 23.4)),
                new Hurricane(3, 2005, "Katrina", 30, 1007, new Point(-76.2, 23.8)),
                new Hurricane(4, 2005, "Katrina", 35, 1006, new Point(-76.5, 24.5)),
                new Hurricane(5, 2005, "Katrina", 40, 1003, new Point(-76.9, 25.4)),
                new Hurricane(6, 2005, "Katrina", 45, 1000, new Point(-77.7, 23.4)),
                new Hurricane(7, 2005, "Katrina", 50, 997, new Point(-78.4, 26.1)),
                new Hurricane(8, 2005, "Katrina", 55, 994, new Point(-79, 26.2)),
                new Hurricane(9, 2005, "Katrina", 60, 998, new Point(-79.6, 26.2)),
                new Hurricane(10, 2005, "Katrina", 70, 984, new Point(-80.1, 26)),
                new Hurricane(11, 2005, "Katrina", 70, 983, new Point(-80.3, 25.9)),
                new Hurricane(12, 2005, "Katrina", 65, 987, new Point(-81.3, 25.4)),
                new Hurricane(13, 2005, "Katrina", 75, 979, new Point(-82, 25.1)),
                new Hurricane(14, 2005, "Katrina", 85, 968, new Point(-82.6, 24.9)),
                new Hurricane(15, 2005, "Katrina", 90, 959, new Point(-83.3, 24.6)),
                new Hurricane(16, 2005, "Katrina", 95, 950, new Point(-84, 24.4)),
                new Hurricane(17, 2005, "Katrina", 100, 942, new Point(-84.7, 24.4)),
                new Hurricane(18, 2005, "Katrina", 100, 948, new Point(-85.3, 24.5)),
                new Hurricane(19, 2005, "Katrina", 100, 941, new Point(-85.9, 24.8)),
                new Hurricane(20, 2005, "Katrina", 125, 930, new Point(-86.7, 25.2)),
                new Hurricane(21, 2005, "Katrina", 145, 909, new Point(-87.7, 25.7)),
                new Hurricane(22, 2005, "Katrina", 150, 902, new Point(-88.6, 26.3)),
                new Hurricane(23, 2005, "Katrina", 140, 905, new Point(-89.2, 27.2)),
                new Hurricane(24, 2005, "Katrina", 125, 913, new Point(-83.6, 28.2)),
                new Hurricane(25, 2005, "Katrina", 110, 920, new Point(-89.6, 29.3)),
                new Hurricane(26, 2005, "Katrina", 110, 923, new Point(-89.6, 29.5)),
                new Hurricane(27, 2005, "Katrina", 105, 928, new Point(-89.6, 30.2)),
                new Hurricane(28, 2005, "Katrina", 80, 948, new Point(-89.6, 31.1)),
                new Hurricane(29, 2005, "Katrina", 50, 961, new Point(-89.1, 32.6)),
                new Hurricane(30, 2005, "Katrina", 40, 978, new Point(-88.6, 34.1)),
                new Hurricane(31, 2005, "Katrina", 30, 985, new Point(-88, 35.6)),
                new Hurricane(32, 2005, "Katrina", 30, 990, new Point(-87, 37)),
                new Hurricane(33, 2005, "Katrina", 30, 994, new Point(-85.3, 38.6)),
                new Hurricane(34, 2005, "Katrina", 25, 996, new Point(-82.9, 40.1))
            };
            return katrina;
        }

      As you can see, we have some interesting data here. I have the speed of wind and pressure information, We can use this two values to create circle around the hurricane's eye. We can use metadata of the hurricane to generate other geospatial data types. I am ready to push this data into Azure Cosmos DB now. Following function pushes this data into my Emulator.

static async Task<bool> PushToCosmos(List<Hurricane> hurricane)
{
   try
   {
     foreach (var h in hurricane)
     {
        var temp = await client.GetDatabase("Spatial").GetContainer("Hurricanes").UpsertItemAsync(h);                    
     }
     return true;
    }
    catch(Exception ex)
    {
      return false;
    }
}

     Believe it or not, That's it! We have Spatial Data in Azure Cosmos DB. We are ready to query this data. Querying spatial data by using SDK will be my next post.


1 comment: