I am trying to create JSON output similar to the GeoJSON format described here: http://geojson.org/geojson-spec.html
In particular, I have text that comes back from my data source in text format and would like to convert my DTO to JSON in the format shown below in my comments. The main problem I am facing is creating an array of coordinates [[...]] without property names.
code:
/* Geometry Text Format from database: POLYGON ((319686.3666000003 7363726.7955, 319747.05190000031 7363778.9233, 319700.78849999979 7363832.7814, 319640.10329999961 7363780.6536, 319686.3666000003 7363726.7955)) And we want format: "geometry": { "type": "Polygon", "coordinates": [[ [319686.3666000003, 7363726.795], [319747.0519000003, 7363778.9233], [319700.78849999979, 7363832.7814], [319640.10329999961, 7363780.6536], [319686.3666000003, 7363726.795] ]] } */ // Strip out everything except the coordinates var coordRawText = myWkt.Replace("POLYGON ((", ""); coordRawText = coordRawText.Replace("))", ""); coordRawText = coordRawText.Replace(", ", ","); // Seperate coordinates to iterate through var coordsArray = coordRawText.Split(','); var coordsEnumerable = coordsArray.Select(coord => coord.Replace(" ", ",")); // Build list of coordinates var coordsList = new List<CoordinateDto>(); foreach (var coord in coordsEnumerable) { var splt = coord.Split(','); var x = double.Parse(splt[0]); var y = double.Parse(splt[1]); coordsList.Add(new CoordinateDto {X = x, Y = y}); } myDto.Geometry = new GeometryDto { Type = "Polygon", Coordinates = coordsList };
The above results are βalmostβ what I want, but not really. The output is as shown below:
"geometry":{"type":"Polygon","coordinates":[{"x":319686.3666000003,"y":7363726.7955},{"x":319747.05190000031,"y":7363778.9233},{"x":319700.78849999979,"y":7363832.7814},{"x":319640.10329999961,"y":7363780.6536},{"x":319686.3666000003,"y":7363726.7955}]}
My DTOs are defined as follows:
[DataContract] public class GeometryDto { [DataMember] public string Type { get; set; } [DataMember] public List<CoordinateDto> Coordinates { get; set; } } [DataContract] public class CoordinateDto { [DataMember] public double X { get; set; } [DataMember] public double Y { get; set; } }
I tried using tuples instead of the coordinate class, but it just inserted the property names "item1" and "item2" instead of "x" and "y".
The only thing I have not tried to create my own JSON Converter yet?
Thanks in advance for your help,
Yours faithfully,
Stephen
UPDATE TO DECISION
I got the solution thanks to the answer selected here (from Dhanuka777) about multidimensional arrays, but for completeness in case this helps:
I had to create a new helper function (a modified version of the Jon Skeet Create Rectangular Array function from here: How to convert a list of arrays to a multidimensional array )
Code solution as below:
/* Geometry Text Format from database: POLYGON ((319686.3666000003 7363726.7955, 319747.05190000031 7363778.9233, 319700.78849999979 7363832.7814, 319640.10329999961 7363780.6536, 319686.3666000003 7363726.7955)) And we want format: "geometry": { "type": "Polygon", "coordinates": [[ [319686.3666000003, 7363726.795], [319747.0519000003, 7363778.9233], [319700.78849999979, 7363832.7814], [319640.10329999961, 7363780.6536], [319686.3666000003, 7363726.795] ]] } */ // Strip out everything except the coordinates var coordRawText = myWkt.Replace("POLYGON ((", ""); coordRawText = coordRawText.Replace("))", ""); coordRawText = coordRawText.Replace(", ", ","); // Seperate coordinates to iterate through var coordsArray = coordRawText.Split(','); var coordsEnumerable = coordsArray.Select(coord => coord.Replace(" ", ",")); // Build list of coordinates var coordsList = new List<double[,]>(); foreach (var coord in coordsEnumerable) { var splt = coord.Split(','); var x = double.Parse(splt[0]); var y = double.Parse(splt[1]); coordsList.Add(new[,] {{ x, y }}); } myDto.Geometry = new GeometryDto { Type = "Polygon", Coordinates = CreateRectangularArray(coordsList) };
And a slightly modified version of the definition of "Rectangle", as shown below:
static T[,] CreateRectangularArray<T>(IList<T[,]> arrays) { // TODO: Validation and special-casing for arrays.Count == 0 int minorLength = arrays[0].Length; T[,] ret = new T[arrays.Count, minorLength]; for (int i = 0; i < arrays.Count; i++) { var array = arrays[i]; if (array.Length != minorLength) { throw new ArgumentException ("All arrays must be the same length"); } for (int j = 0; j < minorLength; j++) { ret[i, j] = array[0, j]; } } return ret; }
And the updated GeometryDto looks like this:
[DataContract] public class GeometryDto { [DataMember] public string Type { get; set; } [DataMember] public double[,] Coordinates { get; set; } }
The Web API will use Newtonsoft Json to serialize objects in the required format.