How do I parse a DbGeometry object into a List <T>?
I am trying to parse a polygon that is represented as a DbGeometry
class (from System.Data.Entity.Spatial
) to some kind of List view, but it crashed.
I tried: - convert it using the .ToList <> () method - parse using the JSON library in .NET, but with deserialization example DbGeometry
So right now I'm returning geometry as a string in a web API application:
If I could not find any solution to represent it as a list of paired numbers, I would have to manually parse it in JavaScript, and I think that this is very incorrect and there must be some kind of solution.
I am using Entity Framework v.6.1.1 which prepared the following model:
public partial class Buildings
{
public int id { get; set; }
public Nullable<bool> has_holes { get; set; }
public System.Data.Entity.Spatial.DbGeometry polygon_data { get; set; }
public System.Data.Entity.Spatial.DbGeometry position_wgs { get; set; }
public System.Data.Entity.Spatial.DbGeometry position_mercator { get; set; }
public Nullable<int> height { get; set; }
public string street_name { get; set; }
public System.Data.Entity.Spatial.DbGeometry holes_data { get; set; }
public Nullable<double> angle { get; set; }
}
I showed this in case you want to see the table structure from MSSQL CE
(which is an inline db or whatever LocalDb
name).
So, I want:
- System.Data.Entity.Spatial.DbGeometry polygon_data li>
- System.Data.Entity.Spatial.DbGeometry holes_data li>
Be prepared as lists of pairs, so my question is How can I parse DbGeometry instance, which holds a collection of points into List<Point>?
.
I had a similar problem. What I did was create an extension method that parses the geometry data in points. However, @Erik Philips also has a good solution. This is what I came up with.
public static class ExtensionString
{
private static Dictionary<string, string> _replacements = new Dictionary<string, string>();
static ExtensionString()
{
_replacements["LINESTRING"] = "";
_replacements["CIRCLE"] = "";
_replacements["POLYGON"] = "";
_replacements["POINT"] = "";
_replacements["("] = "";
_replacements[")"] = "";
}
public static List<Point> ParseGeometryData(this string s)
{
var points = new List<Point>();
foreach (string to_replace in _replacements.Keys)
{
s = s.Replace(to_replace, _replacements[to_replace]);
}
string[] pointsArray = s.Split(',');
for (int i = 0; i < pointsArray.Length; i++)
{
double[] coordinates = new double[2];
//gets x and y coordinates split by space, trims whitespace at pos 0, converts to double array
coordinates = Array.ConvertAll(pointsArray[i].Remove(0, 1).Split(null), double.Parse);
points.Add(new Point() { X = coordinates[0], Y = coordinates[1] });
}
return points;
}
}
And just use it like this
List<System.Drawing.Point> points = geometryDataStr.ParseGeometryData();
source to share
If your geometry is valid then you can do the following:
class Program
{
static void Main(string[] args)
{
DbGeometry test = DbGeometry.FromText("POLYGON((1 1, 1 2, 3 3, 1 1))");
var foo = test.AsText();
var points = new List<Point>();
Console.WriteLine(foo);
if (foo.StartsWith("POLYGON ((")
&& foo.EndsWith("))"))
{
foo = foo.Substring(10, foo.Length - 12);
var rawPoints = foo.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
foreach (var rawPoint in rawPoints)
{
var splitPoint = rawPoint.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
points.Add(new Point() { X = decimal.Parse(splitPoint[1]), Y = decimal.Parse(splitPoint[0]) });
}
}
foreach (var point in points)
{
Console.WriteLine(point.ToString());
}
Console.ReadKey();
}
}
class Point
{
public decimal X { get; set; }
public decimal Y { get; set; }
public override string ToString()
{
return string.Format("[X={0}],[Y={1}]", X, Y);
}
}
result:
POLYGON ((1 1, 1 2, 3 3, 1 1))
[X=1],[Y=1]
[X=2],[Y=1]
[X=3],[Y=3]
[X=1],[Y=1]
source to share