1

I've been having trouble converting a datatable into a GeoJSON object.

The datatable looks like this:

Name       Status       imageUrl          lat       lon
Joe        Dev          markers/Dev.svg   34.21092  -77.59384
Mary       Dev          markers/Dev.svg   32.49323  -78.43144

The GeoJSON should look like this:

{
    "type" : "FeatureCollection",
    "features" : [
        {
            "type" : "Feature",
            "properties" : {
                "Name " : "Joe",
                "Status" : "Dev",
                "imageUrl" : "markers/Dev.svg",
                "lat" : 34.21092,
                "lon" : -77.59384
            },
            "geometry" : {
                "type" : "Point",
                "coordinates" : [ -77.59384, 34.21092 ]
            }
        },
        {
            "type" : "Feature",
            "properties" : {
                "Name " : "Mary",
                "Status" : "Dev",
                "imageUrl" : "markers/Dev.svg",
                "lat" : 32.49323,
                "lon" : -78.43144
            },
            "geometry" : {
                "type" : "Point",
                "coordinates" : [ -78.43144, 32.49323 ]
            }
        }
    ]
}

I've been searching everywhere, but have yet find a solution. I've been using NewtonSoft for serializing a DataTable to a JSON object, but GeoJSON is a much more complex format.

The most difficult part is having to include categories within other categories. In any case, this is what I've tried:

Using Newtonsoft, I'm able to convert the datatable to a JSON. Obviously, it's not the solution:

string callback = JsonConvert.SerializeObject(dataTable);
[] resultBytes = Encoding.UTF8.GetBytes(callback);
return new System.IO.MemoryStream(resultBytes);

One step forward, this is what I tried to add some geojson properties:

var envelope = new
{
    type = "FeatureCollection",
    features = result.Tables[0]
};

string callback = JsonConvert.SerializeObject(envelope);
byte[] resultBytes = Encoding.UTF8.GetBytes(callback);

This returns something closer, but it's still missing the {"type": "Feature", "properties" within each array.

And finally, I posted a similar question here, and it was very helpful, but it takes as parameter the actual json instead of the datatable, which brings a host of other issues, mainly this one here.

So I decided to just start from scratch and post a question asking how I can take my source (a regular datatable) and convert it into a GeoJson object like the one above.

Any help is appreciated.

canon
  • 40,609
  • 10
  • 73
  • 97
fdkgfosfskjdlsjdlkfsf
  • 3,165
  • 2
  • 43
  • 110

1 Answers1

1

You need to map the dataTable records into a multi dimensional object structure. I suggest doing so with LinQ.

To iterate on a dataTable, use the .AsEnumerable() on the dataTable object.

Solution : Create a function that convert the DataTable into a GeoJSON string.

Make sure to imports the System.Linq namespace in your .cs file

public static string DataTableToGeoJSONString(DataTable dataTable)
{

    var envelope = new
    {
        type = "FeatureCollection",
        features = dataTable.AsEnumerable().Select(record => new {
            type = "Feature",
            properties = new
            {
                Name = Convert.ToString(record["Name"]),
                Status = Convert.ToString(record["Status"]),
                imageUrl = Convert.ToString(record["imageUrl"]),
                lat = Convert.ToDecimal(record["lat"]),
                lon = Convert.ToDecimal(record["lon"])

            },
            geometry = new
            {
                type = "Point",
                coordinates = new[] {
                    Convert.ToDecimal(record["lon"]),
                    Convert.ToDecimal(record["lat"])
                }
            }
        }).ToArray()
    };
    return JsonConvert.SerializeObject(envelope);
}

And the just get the JSON string out of it

string geoJson = DataTableToGeoJSONString(dataTable);

Note that this code sample uses anonymous classes new {}. It works but I would recommend to use strongly typed class that you'll have to create.

That should serialize in the expected GeoJSON format.