[{"data":1,"prerenderedAt":59},["ShallowReactive",2],{"blog-post-working-with-file-geodatabase-in-csharp-2":3,"blog-sidebar-tags":41,"blog-sidebar-popular":46},{"overview":4,"post":30},{"slug":5,"title":6,"subtitle":7,"opener":8,"tags":9,"date":12,"headerImage":13,"author":18,"images":28,"__typename":29},"working-with-file-geodatabase-in-csharp-2","Working with File Geodatabase using GDAL\u002FOGR in C# - Part 2","","The second part of this blog series is looking into reading the actual data within a File Geodatabase. We will explore how to access both the attribute as well as the spatial data of a vector layer and build some indexes, that will be used later.",[10,11],"Geo","C#","2020-08-28T00:00:00Z",[14],{"fileName":15,"url":16,"__typename":17},"gdb-ua2012.png","https:\u002F\u002Fcms.spatial-focus.net\u002Fapi\u002Fassets\u002Fspatialfocus\u002Fd99f43f5-59a9-42e3-bafa-20901048c80c\u002F","Asset",[19],{"id":20,"flatData":21,"__typename":27},"247edfce-2ecf-40b8-87e1-58e549d0c243",{"name":22,"image":23,"__typename":26},"Christoph Perger",[24],{"url":25,"__typename":17},"https:\u002F\u002Fcms.spatial-focus.net\u002Fapi\u002Fassets\u002Fspatialfocus\u002F967c15d7-bd4a-4d6e-9e34-b891dccb9906\u002F","AuthorFlatDataDto","Author",null,"PostsFlatDataDto",{"slug":5,"title":6,"subtitle":7,"headerImage":31,"opener":8,"text":33,"tags":34,"date":12,"repo":35,"author":36,"images":28,"__typename":29},[32],{"fileName":15,"url":16,"__typename":17},"# Walkthrough\n\nThis tutorial series is split into 3 separate posts and gives you some insights into how to handle File Geodatabase in your C# solutions. \n\n- Part 1: [Getting started, opening and examining the File Geodatabase](\u002Fblog\u002Fworking-with-file-geodatabase-in-csharp-1)\n- Part 2: Analyzing the data and building indexes for later use\n- Part 3: [Sampling data from the File Geodatabase](\u002Fblog\u002Fworking-with-file-geodatabase-in-csharp-3)\n\n__Note:__ As test data for the following examples, we are using the [Urban Atlas 2012](https:\u002F\u002Fland.copernicus.eu\u002Flocal\u002Furban-atlas\u002Furban-atlas-2012) for Austria, which you also find in the sample code of this blog post. Any sceenshots or output we are showing here will visualize the output of this particular file geodatabase, but the results should look very similar for any other dataset as well.\n\n\n# Data analysis and indexing\n\nIn the following chapters we are going to examine the layer's content and do more in-depth analysis regarding attribute and geometric properties. Addionally we are deriving aggregated numbers as indexes for a later use.\n\n## Attribute indexing\n\nLet's take a closer look at the attributes. We know that the Urban Atlas 2012 classification for each polygon can be found in the field *CODE2012*. So our next task is to find out what values we can find in that field. We write a small loop that iterates over the features in the dataset and extracts the values from the *CODE2012* field and counts their occurance:\n\n```csharp\nprivate static void AttributeIndex(string dataSetPath)\n{\n    var values = new Dictionary\u003Cstring, int>();\n\n    var fileGdbDriver = Ogr.GetDriverByName(\"OpenFileGDB\");\n    var dataSource = fileGdbDriver.Open(dataSetPath, 0);\n    var layer = dataSource.GetLayerByIndex(0);\n\n    var feature = layer.GetNextFeature();\n    while (feature != null)\n    {\n        var classification = feature.GetFieldAsString(\"CODE2012\");\n        if (!values.ContainsKey(classification))\n        {\n            values.Add(classification, 1);\n        }\n        else\n        {\n            values[classification]++;\n        }\n\n        feature = layer.GetNextFeature();\n    }\n\n    var result = values.OrderBy(x => x.Key);\n    foreach (var keyValuePair in result)\n    {\n        Console.WriteLine($\"Value: {keyValuePair.Key} occurs {keyValuePair.Value} times.\");\n    }\n}\n\n```\n\nResult:\n```\nClassification 11100 occurs  6416 times.\nClassification 11210 occurs 24024 times.\nClassification 11220 occurs 29536 times.\nClassification 11230 occurs 23425 times.\nClassification 11240 occurs 10800 times.\nClassification 11300 occurs 27735 times.\nClassification 12100 occurs 21215 times.\nClassification 12210 occurs  1569 times.\nClassification 12220 occurs 44160 times.\nClassification 12230 occurs  3563 times.\nClassification 12300 occurs   176 times.\nClassification 12400 occurs    32 times.\nClassification 13100 occurs  1355 times.\nClassification 13300 occurs   659 times.\nClassification 13400 occurs  3568 times.\nClassification 14100 occurs  4297 times.\nClassification 14200 occurs  3099 times.\nClassification 21000 occurs 33946 times.\nClassification 22000 occurs  2695 times.\nClassification 23000 occurs 39897 times.\nClassification 31000 occurs 19154 times.\nClassification 32000 occurs   547 times.\nClassification 33000 occurs   126 times.\nClassification 40000 occurs    53 times.\nClassification 50000 occurs  1994 times.\nClassification 91000 occurs    81 times.\n```\n\n## Spatial indexing\n\nNow that we know the numeric distribution of classes in the dataset we are interested in their spatial coverage\u002Fdistribution. A quite simple adjustment is needed to accomplish this task. Instead of counting the occurance of a value, we just calculate the area of the geometry of this feature and store that. Finally we devide it by the total size of all features, to get the percentage for each class.\n\n```csharp\nprivate static void SpatialIndex(string dataSetPath)\n{\n    var values = new Dictionary\u003Cstring, double>();\n\n    var fileGdbDriver = Ogr.GetDriverByName(\"OpenFileGDB\");\n    var dataSource = fileGdbDriver.Open(dataSetPath, 0);\n    var layer = dataSource.GetLayerByIndex(0);\n\n    var feature = layer.GetNextFeature();\n    while (feature != null)\n    {\n        var classification = feature.GetFieldAsString(\"CODE2012\");\n        var geometry = feature.GetGeometryRef();\n        var area = geometry.Area();\n\n        if (!values.ContainsKey(classification))\n        {\n            values.Add(classification, area);\n        }\n        else\n        {\n            values[classification] += area;\n        }\n\n        feature = layer.GetNextFeature();\n    }\n\n    var totalArea = values.Sum(x => x.Value);\n\n    var result = values\n        .OrderBy(x => x.Key)\n        .ToDictionary(o => o.Key, o => o.Value \u002F totalArea);\n    foreach (var keyValuePair in result)\n    {\n        Console.WriteLine($\"Value: {keyValuePair.Key} occupies {keyValuePair.Value,7:P} of the total area.\");\n    }\n}\n```\n\nResult:\n```\nClassification 11100 occupies  0,27 % of the total area.\nClassification 11210 occupies  1,48 % of the total area.\nClassification 11220 occupies  1,96 % of the total area.\nClassification 11230 occupies  1,38 % of the total area.\nClassification 11240 occupies  0,41 % of the total area.\nClassification 11300 occupies  0,67 % of the total area.\nClassification 12100 occupies  1,70 % of the total area.\nClassification 12210 occupies  0,20 % of the total area.\nClassification 12220 occupies  1,71 % of the total area.\nClassification 12230 occupies  0,25 % of the total area.\nClassification 12300 occupies  0,05 % of the total area.\nClassification 12400 occupies  0,12 % of the total area.\nClassification 13100 occupies  0,28 % of the total area.\nClassification 13300 occupies  0,04 % of the total area.\nClassification 13400 occupies  0,13 % of the total area.\nClassification 14100 occupies  0,45 % of the total area.\nClassification 14200 occupies  0,46 % of the total area.\nClassification 21000 occupies 30,65 % of the total area.\nClassification 22000 occupies  1,43 % of the total area.\nClassification 23000 occupies 15,09 % of the total area.\nClassification 31000 occupies 35,08 % of the total area.\nClassification 32000 occupies  3,93 % of the total area.\nClassification 33000 occupies  0,33 % of the total area.\nClassification 40000 occupies  0,25 % of the total area.\nClassification 50000 occupies  1,63 % of the total area.\nClassification 91000 occupies  0,08 % of the total area.\n```\n\n# Next steps\n\nLook at the actual data in the layer, we have been able to get some more insight into the features and derived some statistics about the number of occurance of each classification and their spatial distribution. In [part 3](\u002Fblog\u002Fworking-with-file-geodatabase-in-csharp-3) of our series we are going to create access methods to extract some specific features from the data.",[10,11],"https:\u002F\u002Fgithub.com\u002FSpatialFocus\u002Fsample-working-with-file-geodatabase-in-csharp",[37],{"id":20,"flatData":38,"__typename":27},{"name":22,"image":39,"__typename":26},[40],{"url":25,"__typename":17},[11,42,43,44,10,45],"DDD","EF","Clean code","web",[47,53],{"slug":48,"title":49,"headerImage":50,"__typename":29},"radial-progress-css-animation","Radial progress with CSS",[51],{"url":52,"__typename":17},"https:\u002F\u002Fcms.spatial-focus.net\u002Fapi\u002Fassets\u002Fspatialfocus\u002Fb7cdc0ef-364e-4444-8dd3-b85f19e87820\u002F",{"slug":54,"title":55,"headerImage":56,"__typename":29},"load-testing-put-endpoints-with-apache-jmeter","Load testing PUT endpoints",[57],{"url":58,"__typename":17},"https:\u002F\u002Fcms.spatial-focus.net\u002Fapi\u002Fassets\u002Fspatialfocus\u002Fad44fc84-935c-4ab4-ab0e-9fbcb84fb2c1\u002F",1783525747568]