我想将Result
对象序列化为JSON,但是要花很多时间,例如整个过程只花1.5秒而没有序列化部分就需要1分钟以上。
我已经尝试过使用Json.NET和fastJSON,但是两者的速度相同。
IEnumerable<IEnumerable<int>> geometry
中的 ResultFeature
可能真的很大,因为它可以包含成千上万的整数。
为什么要花这么长时间?
using System;
using System.Collections.Generic;
using fastJSON;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
namespace DesktopConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
Result result = new Result
{
fields = new List<string>
{
"CD_MUNCP",
"NOM_MUNCP"
},
features = CreateResultFeatures().ToList()
};
string json = JSON.ToJSON(result);
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
Console.ReadLine();
}
public class Result
{
public List<string> fields { get; set; }
public string geometryType { get; set; }
public IEnumerable<ResultFeature> features { get; set; }
}
public class ResultFeature
{
public Dictionary<string, dynamic> attributes { get; set; }
public IEnumerable<IEnumerable<int>> geometry { get; set; }
}
public static IEnumerable<ResultFeature> CreateResultFeatures()
{
IWorkspace gdbWorkspace = FileGdbWorkspaceFromPath(@"\\vnageop1\geod\Maxime\test.gdb");
IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)gdbWorkspace;
IFeatureClass featureClass = featureWorkspace.OpenFeatureClass(@"GEO09E04_MUNCP_GEN");
IQueryFilter queryFilter = new QueryFilterClass();
queryFilter.SubFields = "CD_MUNCP, NOM_MUNCP, SHAPE";
int cd_muncp_idx = featureClass.FindField("CD_MUNCP");
int nom_muncp_idx = featureClass.FindField("NOM_MUNCP");
using (ComReleaser comReleaser = new ComReleaser())
{
IFeatureCursor cursor = featureClass.Search(queryFilter, false);
comReleaser.ManageLifetime(cursor);
IFeature feature = null;
while ((feature = cursor.NextFeature()) != null)
{
ResultFeature resultFeature = new ResultFeature
{
attributes = new Dictionary<string,dynamic>
{
{ "CD_MUNCP", Convert.ToString(feature.Value[cd_muncp_idx]) },
{ "NOM_MUNCP", Convert.ToString(feature.Value[nom_muncp_idx]) }
},
geometry = PolygonToDeltas(feature.Shape as IPolygon4).ToLiist()
};
yield return resultFeature;
}
}
}
public static IEnumerable<IEnumerable<int>> PolygonToDeltas(IPolygon4 polygon)
{
IGeometryBag exteriorRingGeometryBag = polygon.ExteriorRingBag;
IGeometryCollection exteriorRingGeometryCollection = exteriorRingGeometryBag as IGeometryCollection;
for (int i = 0; i < exteriorRingGeometryCollection.GeometryCount; i++)
{
IGeometry exteriorRingGeometry = exteriorRingGeometryCollection.get_Geometry(i);
IPointCollection exteriorRingPointCollection = exteriorRingGeometry as IPointCollection;
yield return CreateDeltas(exteriorRingPointCollection);
IGeometryBag interiorRingGeometryBag = polygon.get_InteriorRingBag(exteriorRingGeometry as IRing);
IGeometryCollection interiorRingGeometryCollection = interiorRingGeometryBag as IGeometryCollection;
for (int k = 0; k < interiorRingGeometryCollection.GeometryCount; k++)
{
IGeometry interiorRingGeometry = interiorRingGeometryCollection.get_Geometry(k);
IPointCollection interiorRingPointCollection = interiorRingGeometry as IPointCollection;
yield return CreateDeltas(interiorRingPointCollection);
}
}
}
private static IEnumerable<int> CreateDeltas(IPointCollection pointCollection)
{
int previous_x = (int)pointCollection.get_Point(0).X;
int previous_y = (int)pointCollection.get_Point(0).Y;
yield return previous_x;
yield return previous_y;
for (int i = 1; i < pointCollection.PointCount; i++)
{
int current_x = (int)pointCollection.get_Point(i).X;
int current_y = (int)pointCollection.get_Point(i).Y;
yield return previous_x - current_x;
yield return previous_y - current_y;
previous_x = current_x;
previous_y = current_y;
}
}
}
}