/nettopologysuite/NetTopologySuite/IO/GML2/GMLWriter.cs
C# | 368 lines | 222 code | 25 blank | 121 comment | 47 complexity | b3f93455530007a66299b26c0d1cce33 MD5 | raw file
1using System;
2using System.Globalization;
3using System.IO;
4using System.Xml;
5using GeoAPI.Geometries;
6using GisSharpBlog.NetTopologySuite.Utilities;
7
8namespace GisSharpBlog.NetTopologySuite.IO.GML2
9{
10 /// <summary>
11 /// Writes the GML representation of the features of NetTopologySuite model.
12 /// Uses GML 2.1.1 <c>Geometry.xsd</c> schema for base for features.
13 /// <remarks>
14 /// Thanks to <see href="http//www.codeplex.com/Wiki/View.aspx?ProjectName=MsSqlSpatial">rstuven</see> for improvements :)
15 /// </remarks>
16 /// </summary>
17 public class GMLWriter
18 {
19 private const int InitValue = 150;
20 private const int CoordSize = 200;
21
22 /// <summary>
23 /// Formatter for double values of coordinates
24 /// </summary>
25 protected static NumberFormatInfo NumberFormatter
26 {
27 get { return Global.GetNfi(); }
28 }
29
30 /// <summary>
31 /// Returns an <c>XmlReader</c> with feature informations.
32 /// Use <c>XmlDocument.Load(XmlReader)</c> for obtain a <c>XmlDocument</c> to work.
33 /// </summary>
34 /// <param name="geometry"></param>
35 /// <returns></returns>
36 public XmlReader Write(IGeometry geometry)
37 {
38 byte[] data = GetBytes(geometry);
39 using (Stream stream = new MemoryStream(data))
40 Write(geometry, stream);
41 Stream outStream = new MemoryStream(data);
42 return new XmlTextReader(outStream);
43 }
44
45 /// <summary>
46 /// Writes a GML feature into a generic <c>Stream</c>, such a <c>FileStream</c> or other streams.
47 /// </summary>
48 /// <param name="geometry"></param>
49 /// <param name="stream"></param>
50 public void Write(IGeometry geometry, Stream stream)
51 {
52 XmlTextWriter writer = new XmlTextWriter(stream, null);
53 writer.Namespaces = true;
54 writer.WriteStartElement(GMLElements.gmlPrefix, "GML", GMLElements.gmlNS);
55 writer.Formatting = Formatting.Indented;
56 Write(geometry, writer);
57 writer.WriteEndElement();
58 writer.Close();
59 }
60
61 /// <summary>
62 ///
63 /// </summary>
64 /// <param name="coordinate"></param>
65 /// <param name="writer"></param>
66 protected void Write(ICoordinate coordinate, XmlTextWriter writer)
67 {
68 writer.WriteStartElement(GMLElements.gmlPrefix, "coord", GMLElements.gmlNS);
69 writer.WriteElementString(GMLElements.gmlPrefix, "X", GMLElements.gmlNS, coordinate.X.ToString("g", NumberFormatter));
70 writer.WriteElementString(GMLElements.gmlPrefix, "Y", GMLElements.gmlNS, coordinate.Y.ToString("g", NumberFormatter));
71 writer.WriteEndElement();
72 }
73
74 /// <summary>
75 ///
76 /// </summary>
77 /// <param name="coordinates"></param>
78 /// <param name="writer"></param>
79 protected void Write(ICoordinate[] coordinates, XmlTextWriter writer)
80 {
81 foreach (ICoordinate coord in coordinates)
82 Write(coord, writer);
83 }
84
85 /// <summary>
86 ///
87 /// </summary>
88 /// <param name="geometry"></param>
89 /// <param name="writer"></param>
90 protected void Write(IGeometry geometry, XmlTextWriter writer)
91 {
92 if (geometry is IPoint)
93 Write(geometry as IPoint, writer);
94 else if (geometry is ILineString)
95 Write(geometry as ILineString, writer);
96 else if (geometry is IPolygon)
97 Write(geometry as IPolygon, writer);
98 else if (geometry is IMultiPoint)
99 Write(geometry as IMultiPoint, writer);
100 else if (geometry is IMultiLineString)
101 Write(geometry as IMultiLineString, writer);
102 else if (geometry is IMultiPolygon)
103 Write(geometry as IMultiPolygon, writer);
104 else if (geometry is IGeometryCollection)
105 Write(geometry as IGeometryCollection, writer);
106 else throw new ArgumentException("Geometry not recognized: " + geometry.ToString());
107 }
108
109 /// <summary>
110 ///
111 /// </summary>
112 /// <param name="point"></param>
113 /// <param name="writer"></param>
114 protected void Write(IPoint point, XmlTextWriter writer)
115 {
116 writer.WriteStartElement("Point", GMLElements.gmlNS);
117 Write(point.Coordinate, writer);
118 writer.WriteEndElement();
119 }
120
121 /// <summary>
122 ///
123 /// </summary>
124 /// <param name="lineString"></param>
125 /// <param name="writer"></param>
126 protected void Write(ILineString lineString, XmlTextWriter writer)
127 {
128 writer.WriteStartElement("LineString", GMLElements.gmlNS);
129 Write(lineString.Coordinates, writer);
130 writer.WriteEndElement();
131 }
132
133 /// <summary>
134 ///
135 /// </summary>
136 /// <param name="linearRing"></param>
137 /// <param name="writer"></param>
138 protected void Write(ILinearRing linearRing, XmlTextWriter writer)
139 {
140 writer.WriteStartElement("LinearRing", GMLElements.gmlNS);
141 Write(linearRing.Coordinates, writer);
142 writer.WriteEndElement();
143 }
144
145 /// <summary>
146 ///
147 /// </summary>
148 /// <param name="polygon"></param>
149 /// <param name="writer"></param>
150 protected void Write(IPolygon polygon, XmlTextWriter writer)
151 {
152 writer.WriteStartElement("Polygon", GMLElements.gmlNS);
153 writer.WriteStartElement("outerBoundaryIs", GMLElements.gmlNS);
154 Write(polygon.ExteriorRing as ILinearRing, writer);
155 writer.WriteEndElement();
156 for (int i = 0; i < polygon.NumInteriorRings; i++)
157 {
158 writer.WriteStartElement("innerBoundaryIs", GMLElements.gmlNS);
159 Write(polygon.InteriorRings[i] as ILinearRing, writer);
160 writer.WriteEndElement();
161 }
162 writer.WriteEndElement();
163 }
164
165 /// <summary>
166 ///
167 /// </summary>
168 /// <param name="multiPoint"></param>
169 /// <param name="writer"></param>
170 protected void Write(IMultiPoint multiPoint, XmlTextWriter writer)
171 {
172 writer.WriteStartElement("MultiPoint", GMLElements.gmlNS);
173 for (int i = 0; i < multiPoint.NumGeometries; i++)
174 {
175 writer.WriteStartElement("pointMember", GMLElements.gmlNS);
176 Write(multiPoint.Geometries[i] as IPoint, writer);
177 writer.WriteEndElement();
178 }
179 writer.WriteEndElement();
180 }
181
182 /// <summary>
183 ///
184 /// </summary>
185 /// <param name="multiLineString"></param>
186 /// <param name="writer"></param>
187 protected void Write(IMultiLineString multiLineString, XmlTextWriter writer)
188 {
189 writer.WriteStartElement("MultiLineString", GMLElements.gmlNS);
190 for (int i = 0; i < multiLineString.NumGeometries; i++)
191 {
192 writer.WriteStartElement("lineStringMember", GMLElements.gmlNS);
193 Write(multiLineString.Geometries[i] as ILineString, writer);
194 writer.WriteEndElement();
195 }
196 writer.WriteEndElement();
197 }
198
199 /// <summary>
200 ///
201 /// </summary>
202 /// <param name="multiPolygon"></param>
203 /// <param name="writer"></param>
204 protected void Write(IMultiPolygon multiPolygon, XmlTextWriter writer)
205 {
206 writer.WriteStartElement("MultiPolygon", GMLElements.gmlNS);
207 for (int i = 0; i < multiPolygon.NumGeometries; i++)
208 {
209 writer.WriteStartElement("polygonMember", GMLElements.gmlNS);
210 Write(multiPolygon.Geometries[i] as IPolygon, writer);
211 writer.WriteEndElement();
212 }
213 writer.WriteEndElement();
214 }
215
216 /// <summary>
217 ///
218 /// </summary>
219 /// <param name="geometryCollection"></param>
220 /// <param name="writer"></param>
221 protected void Write(IGeometryCollection geometryCollection, XmlTextWriter writer)
222 {
223 writer.WriteStartElement("MultiGeometry", GMLElements.gmlNS);
224 for (int i = 0; i < geometryCollection.NumGeometries; i++)
225 {
226 writer.WriteStartElement("geometryMember", GMLElements.gmlNS);
227 Write(geometryCollection.Geometries[i] as IGeometry, writer);
228 writer.WriteEndElement();
229 }
230 writer.WriteEndElement();
231 }
232
233
234 /// <summary>
235 /// Sets corrent length for Byte Stream.
236 /// </summary>
237 /// <param name="geometry"></param>
238 /// <returns></returns>
239 protected byte[] GetBytes(IGeometry geometry)
240 {
241 if (geometry is IPoint)
242 return new byte[SetByteStreamLength(geometry as IPoint)];
243 else if (geometry is ILineString)
244 return new byte[SetByteStreamLength(geometry as ILineString)];
245 else if (geometry is IPolygon)
246 return new byte[SetByteStreamLength(geometry as IPolygon)];
247 else if (geometry is IMultiPoint)
248 return new byte[SetByteStreamLength(geometry as IMultiPoint)];
249 else if (geometry is IMultiLineString)
250 return new byte[SetByteStreamLength(geometry as IMultiLineString)];
251 else if (geometry is IMultiPolygon)
252 return new byte[SetByteStreamLength(geometry as IMultiPolygon)];
253 else if (geometry is IGeometryCollection)
254 return new byte[SetByteStreamLength(geometry as IGeometryCollection)];
255 else throw new ArgumentException("ShouldNeverReachHere");
256 }
257
258 /// <summary>
259 /// Sets corrent length for Byte Stream.
260 /// </summary>
261 /// <param name="geometry"></param>
262 /// <returns></returns>
263 protected int SetByteStreamLength(IGeometry geometry)
264 {
265 if (geometry is IPoint)
266 return SetByteStreamLength(geometry as IPoint);
267 else if (geometry is ILineString)
268 return SetByteStreamLength(geometry as ILineString);
269 else if (geometry is IPolygon)
270 return SetByteStreamLength(geometry as IPolygon);
271 else if (geometry is IMultiPoint)
272 return SetByteStreamLength(geometry as IMultiPoint);
273 else if (geometry is IMultiLineString)
274 return SetByteStreamLength(geometry as IMultiLineString);
275 else if (geometry is IMultiPolygon)
276 return SetByteStreamLength(geometry as IMultiPolygon);
277 else if (geometry is IGeometryCollection)
278 return SetByteStreamLength(geometry as IGeometryCollection);
279 else throw new ArgumentException("ShouldNeverReachHere");
280 }
281
282 /// <summary>
283 ///
284 /// </summary>
285 /// <param name="geometryCollection"></param>
286 /// <returns></returns>
287 protected int SetByteStreamLength(IGeometryCollection geometryCollection)
288 {
289 int count = InitValue;
290 foreach (IGeometry g in geometryCollection.Geometries)
291 count += SetByteStreamLength(g);
292 return count;
293 }
294
295 /// <summary>
296 ///
297 /// </summary>
298 /// <param name="multiPolygon"></param>
299 /// <returns></returns>
300 protected int SetByteStreamLength(IMultiPolygon multiPolygon)
301 {
302 int count = InitValue;
303 foreach (IPolygon p in multiPolygon.Geometries)
304 count += SetByteStreamLength(p);
305 return count;
306 }
307
308 /// <summary>
309 ///
310 /// </summary>
311 /// <param name="multiLineString"></param>
312 /// <returns></returns>
313 protected int SetByteStreamLength(IMultiLineString multiLineString)
314 {
315 int count = InitValue;
316 foreach (ILineString ls in multiLineString.Geometries)
317 count += SetByteStreamLength(ls);
318 return count;
319 }
320
321 /// <summary>
322 ///
323 /// </summary>
324 /// <param name="multiPoint"></param>
325 /// <returns></returns>
326 protected int SetByteStreamLength(IMultiPoint multiPoint)
327 {
328 int count = InitValue;
329 foreach (IPoint p in multiPoint.Geometries)
330 count += SetByteStreamLength(p);
331 return count;
332 }
333
334 /// <summary>
335 ///
336 /// </summary>
337 /// <param name="polygon"></param>
338 /// <returns></returns>
339 protected int SetByteStreamLength(IPolygon polygon)
340 {
341 int count = InitValue;
342 count += polygon.NumPoints * CoordSize;
343 return count;
344 }
345
346 /// <summary>
347 ///
348 /// </summary>
349 /// <param name="lineString"></param>
350 /// <returns></returns>
351 protected int SetByteStreamLength(ILineString lineString)
352 {
353 int count = InitValue;
354 count += lineString.NumPoints * CoordSize;
355 return count;
356 }
357
358 /// <summary>
359 ///
360 /// </summary>
361 /// <param name="point"></param>
362 /// <returns></returns>
363 protected int SetByteStreamLength(IPoint point)
364 {
365 return InitValue + CoordSize;
366 }
367 }
368}