I am working on a C# tool that is looping over polygons geometries vertices in order to create a list of deltas (distance) between vertices coordinates. The output is a json that will be consumed by a custom application.
The output is a JSON containing a list of features objects which contains attributes and geometry deltas arrays like this one:
<SPAN class="punctuation token">{</SPAN>
<SPAN class="string token">"features"</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">[</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="string token">"attributes"</SPAN> <SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">{</SPAN><SPAN class="string token">"CD_MUNCP"</SPAN> <SPAN class="punctuation token">:</SPAN> <SPAN class="number token">00000</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"NOM_MUNCP"</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">"Name1"</SPAN><SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">"geometry"</SPAN> <SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="number token">5767767</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">834778</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">10</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">199</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">99</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">332</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">9</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">9</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="number token">5787767</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">837709</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">123</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">33</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">31</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">121</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">12330</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="string token">"attributes"</SPAN> <SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">{</SPAN><SPAN class="string token">"CD_MUNCP"</SPAN> <SPAN class="punctuation token">:</SPAN> <SPAN class="number token">00001</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"NOM_MUNCP"</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="string token">"Name2"</SPAN><SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">"geometry"</SPAN> <SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="number token">5784576</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">831278</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">190</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">54</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">5464</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">789</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="number token">57354576</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">837008</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">66</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">872</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">3445</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">879</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="operator token">-</SPAN><SPAN class="number token">2</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="number token">22</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="punctuation token">]</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>The geometry deltas output is expected to be on this format: [[x0, y0, (x0-x1), (y0-y1), (x1-x2), (y1-y2)]<BR />
</CODE></P><P><CODE><SPAN style="font-family: arial, helvetica, sans-serif;">Exterior rings and interior rings deltas are on the same level in the array: <SPAN style="font-family: andale mono, monospace;">[[ExteriorRing1 deltas], [InteriorRing1 deltas], [ExteriorRing2 deltas], ...]<BR /></SPAN></SPAN><BR />
I am using deltas instead of absolute coordinates to compact the size of the json output. This method has proven to be able to reduce size by more than 50% for huge geometry.
I am using IEnumerable<> to create the geometry deltas because I thought it would be faster, but it appears this is not really compatible with JSON serialization (it takes very long to serialize) so I transform them using .ToList();
The most important thing with the code is the performance because it aims to be used in a custom GeoProcessing Service on ArcGIS Server.
My tests prove that the bottleneck is the JSON serialization that takes more than 50% of the processing time. For instance for a big FeatureClass it could takes 1.5 seconds to create the deltas but 25 seconds to serialize it to JSON.
Is there some optimizations or workarounds I can do to improve the performance? Any suggestions would be appreciated.
<SPAN class="keyword token">using</SPAN> System<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">using</SPAN> System<SPAN class="punctuation token">.</SPAN>Collections<SPAN class="punctuation token">.</SPAN>Generic<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">using</SPAN> fastJSON<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">using</SPAN> ESRI<SPAN class="punctuation token">.</SPAN>ArcGIS<SPAN class="punctuation token">.</SPAN>ADF<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">using</SPAN> ESRI<SPAN class="punctuation token">.</SPAN>ArcGIS<SPAN class="punctuation token">.</SPAN>Geodatabase<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">using</SPAN> ESRI<SPAN class="punctuation token">.</SPAN>ArcGIS<SPAN class="punctuation token">.</SPAN>Geometry<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">using</SPAN> ESRI<SPAN class="punctuation token">.</SPAN>ArcGIS<SPAN class="punctuation token">.</SPAN>esriSystem<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">namespace</SPAN> DesktopConsoleApplication1
<SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">class</SPAN> <SPAN class="token class-name">Program</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">static</SPAN> <SPAN class="keyword token">void</SPAN> <SPAN class="token function">Main</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">string</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN> args<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">var</SPAN> watch <SPAN class="operator token">=</SPAN> System<SPAN class="punctuation token">.</SPAN>Diagnostics<SPAN class="punctuation token">.</SPAN>Stopwatch<SPAN class="punctuation token">.</SPAN><SPAN class="token function">StartNew</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
Result result <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Result</SPAN>
<SPAN class="punctuation token">{</SPAN>
features <SPAN class="operator token">=</SPAN> <SPAN class="token function">CreateResultFeatures</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="token function">ToList</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">string</SPAN> output <SPAN class="operator token">=</SPAN> JSON<SPAN class="punctuation token">.</SPAN><SPAN class="token function">ToJSON</SPAN><SPAN class="punctuation token">(</SPAN>result<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
watch<SPAN class="punctuation token">.</SPAN><SPAN class="token function">Stop</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
Console<SPAN class="punctuation token">.</SPAN><SPAN class="token function">WriteLine</SPAN><SPAN class="punctuation token">(</SPAN>watch<SPAN class="punctuation token">.</SPAN>ElapsedMilliseconds<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
Console<SPAN class="punctuation token">.</SPAN><SPAN class="token function">ReadLine</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">public</SPAN> <SPAN class="keyword token">class</SPAN> <SPAN class="token class-name">Result</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">public</SPAN> IEnumerable<SPAN class="operator token"><</SPAN>ResultFeature<SPAN class="operator token">></SPAN> features <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">get</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">set</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">public</SPAN> <SPAN class="keyword token">class</SPAN> <SPAN class="token class-name">ResultFeature</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">public</SPAN> Dictionary<SPAN class="operator token"><</SPAN><SPAN class="keyword token">string</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="keyword token">dynamic</SPAN><SPAN class="operator token">></SPAN> attributes <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">get</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">set</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">public</SPAN> IEnumerable<SPAN class="operator token"><</SPAN>IEnumerable<SPAN class="operator token"><</SPAN><SPAN class="keyword token">int</SPAN><SPAN class="operator token">></SPAN><SPAN class="operator token">></SPAN> geometry <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">get</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">set</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">public</SPAN> <SPAN class="keyword token">static</SPAN> IEnumerable<SPAN class="operator token"><</SPAN>ResultFeature<SPAN class="operator token">></SPAN> <SPAN class="token function">CreateResultFeatures</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
IWorkspace gdbWorkspace <SPAN class="operator token">=</SPAN> <SPAN class="token function">FileGdbWorkspaceFromPath</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">@"\\vnageop1\geod\Maxime\test.gdb"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
IFeatureWorkspace featureWorkspace <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN>IFeatureWorkspace<SPAN class="punctuation token">)</SPAN>gdbWorkspace<SPAN class="punctuation token">;</SPAN>
IFeatureClass featureClass <SPAN class="operator token">=</SPAN> featureWorkspace<SPAN class="punctuation token">.</SPAN><SPAN class="token function">OpenFeatureClass</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">@"GEO09E04_MUNCP_GEN"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
IQueryFilter queryFilter <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">QueryFilterClass</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
queryFilter<SPAN class="punctuation token">.</SPAN>SubFields <SPAN class="operator token">=</SPAN> <SPAN class="string token">"CD_MUNCP, NOM_MUNCP, SHAPE"</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">int</SPAN> cd_muncp_idx <SPAN class="operator token">=</SPAN> featureClass<SPAN class="punctuation token">.</SPAN><SPAN class="token function">FindField</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"CD_MUNCP"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">int</SPAN> nom_muncp_idx <SPAN class="operator token">=</SPAN> featureClass<SPAN class="punctuation token">.</SPAN><SPAN class="token function">FindField</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"NOM_MUNCP"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">using</SPAN> <SPAN class="punctuation token">(</SPAN>ComReleaser comReleaser <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">ComReleaser</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
IFeatureCursor cursor <SPAN class="operator token">=</SPAN> featureClass<SPAN class="punctuation token">.</SPAN><SPAN class="token function">Search</SPAN><SPAN class="punctuation token">(</SPAN>queryFilter<SPAN class="punctuation token">,</SPAN> <SPAN class="keyword token">false</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
comReleaser<SPAN class="punctuation token">.</SPAN><SPAN class="token function">ManageLifetime</SPAN><SPAN class="punctuation token">(</SPAN>cursor<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
IFeature feature <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">null</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">while</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">(</SPAN>feature <SPAN class="operator token">=</SPAN> cursor<SPAN class="punctuation token">.</SPAN><SPAN class="token function">NextFeature</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">!=</SPAN> <SPAN class="keyword token">null</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
ResultFeature resultFeature <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">ResultFeature</SPAN>
<SPAN class="punctuation token">{</SPAN>
attributes <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Dictionary</SPAN><SPAN class="operator token"><</SPAN><SPAN class="keyword token">string</SPAN><SPAN class="punctuation token">,</SPAN><SPAN class="keyword token">dynamic</SPAN><SPAN class="operator token">></SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="punctuation token">{</SPAN> <SPAN class="string token">"CD_MUNCP"</SPAN><SPAN class="punctuation token">,</SPAN> Convert<SPAN class="punctuation token">.</SPAN><SPAN class="token function">ToString</SPAN><SPAN class="punctuation token">(</SPAN>feature<SPAN class="punctuation token">.</SPAN>Value<SPAN class="punctuation token">[</SPAN>cd_muncp_idx<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="punctuation token">{</SPAN> <SPAN class="string token">"NOM_MUNCP"</SPAN><SPAN class="punctuation token">,</SPAN> Convert<SPAN class="punctuation token">.</SPAN><SPAN class="token function">ToString</SPAN><SPAN class="punctuation token">(</SPAN>feature<SPAN class="punctuation token">.</SPAN>Value<SPAN class="punctuation token">[</SPAN>nom_muncp_idx<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">,</SPAN>
geometry <SPAN class="operator token">=</SPAN> <SPAN class="token function">PolygonToDeltas</SPAN><SPAN class="punctuation token">(</SPAN>feature<SPAN class="punctuation token">.</SPAN>Shape <SPAN class="keyword token">as</SPAN> IPolygon4<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="token function">ToList</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">yield</SPAN> <SPAN class="keyword token">return</SPAN> resultFeature<SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">public</SPAN> <SPAN class="keyword token">static</SPAN> IEnumerable<SPAN class="operator token"><</SPAN>IEnumerable<SPAN class="operator token"><</SPAN><SPAN class="keyword token">int</SPAN><SPAN class="operator token">></SPAN><SPAN class="operator token">></SPAN> <SPAN class="token function">PolygonToDeltas</SPAN><SPAN class="punctuation token">(</SPAN>IPolygon4 polygon<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
IGeometryBag exteriorRingGeometryBag <SPAN class="operator token">=</SPAN> polygon<SPAN class="punctuation token">.</SPAN>ExteriorRingBag<SPAN class="punctuation token">;</SPAN>
IGeometryCollection exteriorRingGeometryCollection <SPAN class="operator token">=</SPAN> exteriorRingGeometryBag <SPAN class="keyword token">as</SPAN> IGeometryCollection<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">for</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">int</SPAN> i <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">;</SPAN> i <SPAN class="operator token"><</SPAN> exteriorRingGeometryCollection<SPAN class="punctuation token">.</SPAN>GeometryCount<SPAN class="punctuation token">;</SPAN> i<SPAN class="operator token">++</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
IGeometry exteriorRingGeometry <SPAN class="operator token">=</SPAN> exteriorRingGeometryCollection<SPAN class="punctuation token">.</SPAN><SPAN class="token function">get_Geometry</SPAN><SPAN class="punctuation token">(</SPAN>i<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
IPointCollection exteriorRingPointCollection <SPAN class="operator token">=</SPAN> exteriorRingGeometry <SPAN class="keyword token">as</SPAN> IPointCollection<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">yield</SPAN> <SPAN class="keyword token">return</SPAN> <SPAN class="token function">CreateDeltas</SPAN><SPAN class="punctuation token">(</SPAN>exteriorRingPointCollection<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
IGeometryBag interiorRingGeometryBag <SPAN class="operator token">=</SPAN> polygon<SPAN class="punctuation token">.</SPAN><SPAN class="token function">get_InteriorRingBag</SPAN><SPAN class="punctuation token">(</SPAN>exteriorRingGeometry <SPAN class="keyword token">as</SPAN> IRing<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
IGeometryCollection interiorRingGeometryCollection <SPAN class="operator token">=</SPAN> interiorRingGeometryBag <SPAN class="keyword token">as</SPAN> IGeometryCollection<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">for</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">int</SPAN> k <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">;</SPAN> k <SPAN class="operator token"><</SPAN> interiorRingGeometryCollection<SPAN class="punctuation token">.</SPAN>GeometryCount<SPAN class="punctuation token">;</SPAN> k<SPAN class="operator token">++</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
IGeometry interiorRingGeometry <SPAN class="operator token">=</SPAN> interiorRingGeometryCollection<SPAN class="punctuation token">.</SPAN><SPAN class="token function">get_Geometry</SPAN><SPAN class="punctuation token">(</SPAN>k<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
IPointCollection interiorRingPointCollection <SPAN class="operator token">=</SPAN> interiorRingGeometry <SPAN class="keyword token">as</SPAN> IPointCollection<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">yield</SPAN> <SPAN class="keyword token">return</SPAN> <SPAN class="token function">CreateDeltas</SPAN><SPAN class="punctuation token">(</SPAN>interiorRingPointCollection <SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">static</SPAN> IEnumerable<SPAN class="operator token"><</SPAN><SPAN class="keyword token">int</SPAN><SPAN class="operator token">></SPAN> <SPAN class="token function">CreateDeltas</SPAN><SPAN class="punctuation token">(</SPAN>IPointCollection pointCollection<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">int</SPAN> previous_x <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">int</SPAN><SPAN class="punctuation token">)</SPAN>pointCollection<SPAN class="punctuation token">.</SPAN><SPAN class="token function">get_Point</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>X<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">int</SPAN> previous_y <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">int</SPAN><SPAN class="punctuation token">)</SPAN>pointCollection<SPAN class="punctuation token">.</SPAN><SPAN class="token function">get_Point</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>Y<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">yield</SPAN> <SPAN class="keyword token">return</SPAN> previous_x<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">yield</SPAN> <SPAN class="keyword token">return</SPAN> previous_y<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">for</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">int</SPAN> i <SPAN class="operator token">=</SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">;</SPAN> i <SPAN class="operator token"><</SPAN> pointCollection<SPAN class="punctuation token">.</SPAN>PointCount<SPAN class="punctuation token">;</SPAN> i<SPAN class="operator token">++</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">int</SPAN> current_x <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">int</SPAN><SPAN class="punctuation token">)</SPAN>pointCollection<SPAN class="punctuation token">.</SPAN><SPAN class="token function">get_Point</SPAN><SPAN class="punctuation token">(</SPAN>i<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>X<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">int</SPAN> current_y <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">int</SPAN><SPAN class="punctuation token">)</SPAN>pointCollection<SPAN class="punctuation token">.</SPAN><SPAN class="token function">get_Point</SPAN><SPAN class="punctuation token">(</SPAN>i<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>Y<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">yield</SPAN> <SPAN class="keyword token">return</SPAN> previous_x <SPAN class="operator token">-</SPAN> current_x<SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">yield</SPAN> <SPAN class="keyword token">return</SPAN> previous_y <SPAN class="operator token">-</SPAN> current_y<SPAN class="punctuation token">;</SPAN>
previous_x <SPAN class="operator token">=</SPAN> current_x<SPAN class="punctuation token">;</SPAN>
previous_y <SPAN class="operator token">=</SPAN> current_y<SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>