[mapguide-commits] r6453 - in trunk/Tools/Maestro: MaestroAPITests
OSGeo.MapGuide.MaestroAPI OSGeo.MapGuide.MaestroAPI/Internal
OSGeo.MapGuide.MaestroAPI.Http OSGeo.MapGuide.MaestroAPI.Native
OSGeo.MapGuide.MaestroAPI.Native/Commands
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Tue Jan 24 11:38:25 EST 2012
Author: jng
Date: 2012-01-24 08:38:24 -0800 (Tue, 24 Jan 2012)
New Revision: 6453
Added:
trunk/Tools/Maestro/MaestroAPITests/MiscTests.cs
trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Internal/
trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Internal/FixedWKTReader.cs
Modified:
trunk/Tools/Maestro/MaestroAPITests/MaestroAPITests.csproj
trunk/Tools/Maestro/MaestroAPITests/TestControl.cs
trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/XmlReaderBase.cs
trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/XmlRecord.cs
trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/Commands/FeatureCommandsImpl.cs
trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeDataReader.cs
trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeFeature.cs
trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeFeatureReader.cs
trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeRecord.cs
trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeSqlReader.cs
trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
Log:
#1928: Introduce a new FixedWKTReader.cs which is a copypasta of the original NTS WKTReader, with a small fix to gracefully handle 3D geometry WKT strings. Update all code that uses the NTS WKTReader to use our FixedWKTReader. Added a unit test to test against some sample 3D WKT strings.
Modified: trunk/Tools/Maestro/MaestroAPITests/MaestroAPITests.csproj
===================================================================
--- trunk/Tools/Maestro/MaestroAPITests/MaestroAPITests.csproj 2012-01-24 13:34:05 UTC (rev 6452)
+++ trunk/Tools/Maestro/MaestroAPITests/MaestroAPITests.csproj 2012-01-24 16:38:24 UTC (rev 6453)
@@ -78,6 +78,7 @@
<Compile Include="HttpSiteTests.cs" />
<Compile Include="LocalNativeFeatureTests.cs" />
<Compile Include="LocalNativePerformanceTests.cs" />
+ <Compile Include="MiscTests.cs" />
<Compile Include="ObjectTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
Added: trunk/Tools/Maestro/MaestroAPITests/MiscTests.cs
===================================================================
--- trunk/Tools/Maestro/MaestroAPITests/MiscTests.cs (rev 0)
+++ trunk/Tools/Maestro/MaestroAPITests/MiscTests.cs 2012-01-24 16:38:24 UTC (rev 6453)
@@ -0,0 +1,42 @@
+#region Disclaimer / License
+// Copyright (C) 2012, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at gmail.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using OSGeo.MapGuide.MaestroAPI.Internal;
+
+namespace MaestroAPITests
+{
+ [TestFixture(Ignore = TestControl.IgnoreMiscTests)]
+ public class MiscTests
+ {
+ [Test]
+ public void TestParse3dWkt()
+ {
+ var wkt1 = "LINESTRING XYZ (218941.59990888927 173858.42946731683 0, 218931.73921854934 173868.56834443274 0)";
+ var wkt2 = "POINT XYZ (1 2 3)";
+
+ var reader = new FixedWKTReader();
+ reader.Read(wkt1);
+ reader.Read(wkt2);
+ }
+ }
+}
Modified: trunk/Tools/Maestro/MaestroAPITests/TestControl.cs
===================================================================
--- trunk/Tools/Maestro/MaestroAPITests/TestControl.cs 2012-01-24 13:34:05 UTC (rev 6452)
+++ trunk/Tools/Maestro/MaestroAPITests/TestControl.cs 2012-01-24 16:38:24 UTC (rev 6453)
@@ -44,6 +44,7 @@
public const bool IgnoreSchemaTests = false;
public const bool IgnoreSerializationTests = false;
public const bool IgnoreValidationTests = false;
+ public const bool IgnoreMiscTests = false;
}
public class LocalNativeConnectionUtil
Added: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Internal/FixedWKTReader.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Internal/FixedWKTReader.cs (rev 0)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/Internal/FixedWKTReader.cs 2012-01-24 16:38:24 UTC (rev 6453)
@@ -0,0 +1,586 @@
+#region Disclaimer / License
+// Copyright (C) 2012, Jackie Ng
+// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie at gmail.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+#endregion
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using GeoAPI.Geometries;
+using GisSharpBlog.NetTopologySuite.Geometries;
+using GisSharpBlog.NetTopologySuite.Utilities;
+using RTools_NTS.Util;
+using GisSharpBlog.NetTopologySuite.IO;
+
+namespace OSGeo.MapGuide.MaestroAPI.Internal
+{
+ /// <summary>
+ /// A fixed version of WKTReader that can parse 3D geometry WKT
+ /// </summary>
+ public class FixedWKTReader
+ {
+ private IGeometryFactory geometryFactory;
+ private IPrecisionModel precisionModel;
+ int index;
+
+ bool hasXY = true;
+ bool hasZ = false;
+ bool hasM = false;
+
+ /// <summary>
+ /// Creates a <c>WKTReader</c> that creates objects using a basic GeometryFactory.
+ /// </summary>
+ public FixedWKTReader() : this(GeometryFactory.Default) { }
+
+ /// <summary>
+ /// Creates a <c>WKTReader</c> that creates objects using the given
+ /// <c>GeometryFactory</c>.
+ /// </summary>
+ /// <param name="geometryFactory">The factory used to create <c>Geometry</c>s.</param>
+ public FixedWKTReader(IGeometryFactory geometryFactory)
+ {
+ this.geometryFactory = geometryFactory;
+ precisionModel = geometryFactory.PrecisionModel;
+ }
+
+ /// <summary>
+ /// Converts a Well-known Text representation to a <c>Geometry</c>.
+ /// </summary>
+ /// <param name="wellKnownText">
+ /// one or more Geometry Tagged Text strings (see the OpenGIS
+ /// Simple Features Specification) separated by whitespace.
+ /// </param>
+ /// <returns>
+ /// A <c>Geometry</c> specified by <c>wellKnownText</c>
+ /// </returns>
+ public IGeometry Read(string wellKnownText)
+ {
+ using (StringReader reader = new StringReader(wellKnownText))
+ {
+ return Read(reader);
+ }
+ }
+
+ /// <summary>
+ /// Converts a Well-known Text representation to a <c>Geometry</c>.
+ /// </summary>
+ /// <param name="reader">
+ /// A Reader which will return a "Geometry Tagged Text"
+ /// string (see the OpenGIS Simple Features Specification).
+ /// </param>
+ /// <returns>A <c>Geometry</c> read from <c>reader</c>.
+ /// </returns>
+ public IGeometry Read(TextReader reader)
+ {
+ StreamTokenizer tokenizer = new StreamTokenizer(reader);
+ List<Token> tokens = new List<Token>();
+ tokenizer.Tokenize(tokens); // Read directly all tokens
+ index = 0; // Reset pointer to start of tokens
+
+ hasXY = true;
+ hasZ = false;
+ hasM = false;
+ try
+ {
+ return ReadGeometryTaggedText(tokens);
+ }
+ catch (IOException e)
+ {
+ throw new ParseException(e.ToString());
+ }
+ }
+
+ /// <summary>
+ /// Returns the next array of <c>Coordinate</c>s in the stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next element returned by the stream should be "(" (the
+ /// beginning of "(x1 y1, x2 y2, ..., xn yn)") or "EMPTY".
+ /// </param>
+ /// <param name="skipExtraParenthesis">
+ /// if set to <c>true</c> skip extra parenthesis around coordinates.
+ /// </param>
+ /// <returns>
+ /// The next array of <c>Coordinate</c>s in the
+ /// stream, or an empty array if "EMPTY" is the next element returned by
+ /// the stream.
+ /// </returns>
+ private ICoordinate[] GetCoordinates(IList tokens, Boolean skipExtraParenthesis)
+ {
+ string nextToken = GetNextEmptyOrOpener(tokens);
+ if (nextToken.Equals("EMPTY"))
+ return new ICoordinate[] { };
+ List<ICoordinate> coordinates = new List<ICoordinate>();
+ coordinates.Add(GetPreciseCoordinate(tokens, skipExtraParenthesis));
+ nextToken = GetNextCloserOrComma(tokens);
+ while (nextToken.Equals(","))
+ {
+ coordinates.Add(GetPreciseCoordinate(tokens, skipExtraParenthesis));
+ nextToken = GetNextCloserOrComma(tokens);
+ }
+ return coordinates.ToArray();
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="tokens"></param>
+ /// <param name="skipExtraParenthesis"></param>
+ /// <returns></returns>
+ private ICoordinate GetPreciseCoordinate(IList tokens, Boolean skipExtraParenthesis)
+ {
+ ICoordinate coord = new Coordinate();
+ Boolean extraParenthesisFound = false;
+ if (skipExtraParenthesis)
+ {
+ extraParenthesisFound = IsStringValueNext(tokens, "(");
+ if (extraParenthesisFound)
+ {
+ index++;
+ }
+ }
+ coord.X = GetNextNumber(tokens);
+ coord.Y = GetNextNumber(tokens);
+ if (IsNumberNext(tokens))
+ coord.Z = GetNextNumber(tokens);
+
+ if (skipExtraParenthesis &&
+ extraParenthesisFound &&
+ IsStringValueNext(tokens, ")"))
+ {
+ index++;
+ }
+
+ precisionModel.MakePrecise(coord);
+ return coord;
+ }
+
+ private Boolean IsStringValueNext(IList tokens, String stringValue)
+ {
+ Token token = tokens[index] as Token;
+ return token.StringValue == stringValue;
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="tokens"></param>
+ /// <returns></returns>
+ private bool IsNumberNext(IList tokens)
+ {
+ Token token = tokens[index] as Token;
+ return token is FloatToken || token is IntToken;
+ }
+
+ /// <summary>
+ /// Returns the next number in the stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next token must be a number.
+ /// </param>
+ /// <returns>The next number in the stream.</returns>
+ private double GetNextNumber(IList tokens)
+ {
+ Token token = tokens[index++] as Token;
+
+ if (token == null)
+ throw new ArgumentNullException("tokens", "Token list contains a null value");
+ else if (token is EofToken)
+ throw new ParseException("Expected number but encountered end of stream");
+ else if (token is EolToken)
+ throw new ParseException("Expected number but encountered end of line");
+ else if (token is FloatToken || token is IntToken)
+ return (double)token.ConvertToType(typeof(double));
+ else if (token is WordToken)
+ throw new ParseException("Expected number but encountered word: " + token.StringValue);
+ else if (token.StringValue == "(")
+ throw new ParseException("Expected number but encountered '('");
+ else if (token.StringValue == ")")
+ throw new ParseException("Expected number but encountered ')'");
+ else if (token.StringValue == ",")
+ throw new ParseException("Expected number but encountered ','");
+ else
+ {
+ Assert.ShouldNeverReachHere();
+ return double.NaN;
+ }
+ }
+
+ /// <summary>
+ /// Returns the next "EMPTY" or "(" in the stream as uppercase text.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next token must be "EMPTY" or "(".
+ /// </param>
+ /// <returns>
+ /// The next "EMPTY" or "(" in the stream as uppercase text.</returns>
+ private string GetNextEmptyOrOpener(IList tokens)
+ {
+ //The next word may be the dimension specifier. In such a case, read the
+ //next word after that.
+ string nextWord = GetNextWord(tokens);
+ if (nextWord.Equals("XYZ"))
+ {
+ hasZ = true;
+ nextWord = GetNextWord(tokens);
+ }
+ else if (nextWord.Equals("XYM"))
+ {
+ hasM = true;
+ nextWord = GetNextWord(tokens);
+ }
+ else if (nextWord.Equals("ZM"))
+ {
+ hasXY = false;
+ hasZ = true;
+ hasM = true;
+ nextWord = GetNextWord(tokens);
+ }
+ if (nextWord.Equals("EMPTY") || nextWord.Equals("("))
+ return nextWord;
+ throw new ParseException("Expected 'EMPTY' or '(' but encountered '" + nextWord + "'");
+ }
+
+ /// <summary>
+ /// Returns the next ")" or "," in the stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next token must be ")" or ",".
+ /// </param>
+ /// <returns>
+ /// The next ")" or "," in the stream.</returns>
+ private string GetNextCloserOrComma(IList tokens)
+ {
+ string nextWord = GetNextWord(tokens);
+ if (nextWord.Equals(",") || nextWord.Equals(")"))
+ return nextWord;
+
+ throw new ParseException("Expected ')' or ',' but encountered '" + nextWord
+ + "'");
+ }
+
+ /// <summary>
+ /// Returns the next ")" in the stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next token must be ")".
+ /// </param>
+ /// <returns>
+ /// The next ")" in the stream.</returns>
+ private string GetNextCloser(IList tokens)
+ {
+ string nextWord = GetNextWord(tokens);
+ if (nextWord.Equals(")"))
+ return nextWord;
+ throw new ParseException("Expected ')' but encountered '" + nextWord + "'");
+ }
+
+ /// <summary>
+ /// Returns the next word in the stream as uppercase text.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next token must be a word.
+ /// </param>
+ /// <returns>The next word in the stream as uppercase text.</returns>
+ private string GetNextWord(IList tokens)
+ {
+ Token token = tokens[index++] as Token;
+
+ if (token is EofToken)
+ throw new ParseException("Expected number but encountered end of stream");
+ else if (token is EolToken)
+ throw new ParseException("Expected number but encountered end of line");
+ else if (token is FloatToken || token is IntToken)
+ throw new ParseException("Expected word but encountered number: " + token.StringValue);
+ else if (token is WordToken)
+ return token.StringValue.ToUpper();
+ else if (token.StringValue == "(")
+ return "(";
+ else if (token.StringValue == ")")
+ return ")";
+ else if (token.StringValue == ",")
+ return ",";
+ else
+ {
+ Assert.ShouldNeverReachHere();
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Creates a <c>Geometry</c> using the next token in the stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next tokens must form a <Geometry Tagged Text.
+ /// </param>
+ /// <returns>A <c>Geometry</c> specified by the next token
+ /// in the stream.</returns>
+ private IGeometry ReadGeometryTaggedText(IList tokens)
+ {
+ /*
+ * A new different implementation by Marc Jacquin:
+ * this code manages also SRID values.
+ */
+ IGeometry returned = null;
+ string sridValue = null;
+ string type = tokens[0].ToString();
+
+ if (type == "SRID")
+ {
+ sridValue = tokens[2].ToString();
+ // tokens.RemoveRange(0, 4);
+ tokens.RemoveAt(0);
+ tokens.RemoveAt(0);
+ tokens.RemoveAt(0);
+ tokens.RemoveAt(0);
+ }
+ else type = GetNextWord(tokens);
+ if (type.Equals("POINT"))
+ returned = ReadPointText(tokens);
+ else if (type.Equals("LINESTRING"))
+ returned = ReadLineStringText(tokens);
+ else if (type.Equals("LINEARRING"))
+ returned = ReadLinearRingText(tokens);
+ else if (type.Equals("POLYGON"))
+ returned = ReadPolygonText(tokens);
+ else if (type.Equals("MULTIPOINT"))
+ returned = ReadMultiPointText(tokens);
+ else if (type.Equals("MULTILINESTRING"))
+ returned = ReadMultiLineStringText(tokens);
+ else if (type.Equals("MULTIPOLYGON"))
+ returned = ReadMultiPolygonText(tokens);
+ else if (type.Equals("GEOMETRYCOLLECTION"))
+ returned = ReadGeometryCollectionText(tokens);
+ else throw new ParseException("Unknown type: " + type);
+
+ if (returned == null)
+ throw new NullReferenceException("Error reading geometry");
+
+ if (sridValue != null)
+ returned.SRID = Convert.ToInt32(sridValue);
+
+ return returned;
+ }
+
+ /// <summary>
+ /// Creates a <c>Point</c> using the next token in the stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next tokens must form a <Point Text.
+ /// </param>
+ /// <returns>A <c>Point</c> specified by the next token in
+ /// the stream.</returns>
+ private IPoint ReadPointText(IList tokens)
+ {
+ string nextToken = GetNextEmptyOrOpener(tokens);
+ if (nextToken.Equals("EMPTY"))
+ return geometryFactory.CreatePoint((ICoordinate)null);
+ IPoint point = geometryFactory.CreatePoint(GetPreciseCoordinate(tokens, false));
+ GetNextCloser(tokens);
+ return point;
+ }
+
+ /// <summary>
+ /// Creates a <c>LineString</c> using the next token in the stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next tokens must form a <LineString Text.
+ /// </param>
+ /// <returns>
+ /// A <c>LineString</c> specified by the next
+ /// token in the stream.</returns>
+ private ILineString ReadLineStringText(IList tokens)
+ {
+ return geometryFactory.CreateLineString(GetCoordinates(tokens, false));
+ }
+
+ /// <summary>
+ /// Creates a <c>LinearRing</c> using the next token in the stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next tokens must form a <LineString Text.
+ /// </param>
+ /// <returns>A <c>LinearRing</c> specified by the next
+ /// token in the stream.</returns>
+ private ILinearRing ReadLinearRingText(IList tokens)
+ {
+ return geometryFactory.CreateLinearRing(GetCoordinates(tokens, false));
+ }
+
+ /// <summary>
+ /// Creates a <c>MultiPoint</c> using the next token in the stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next tokens must form a <MultiPoint Text.
+ /// </param>
+ /// <returns>
+ /// A <c>MultiPoint</c> specified by the next
+ /// token in the stream.</returns>
+ private IMultiPoint ReadMultiPointText(IList tokens)
+ {
+ return geometryFactory.CreateMultiPoint(ToPoints(GetCoordinates(tokens, true)));
+ }
+
+ /// <summary>
+ /// Creates an array of <c>Point</c>s having the given <c>Coordinate</c>s.
+ /// </summary>
+ /// <param name="coordinates">
+ /// The <c>Coordinate</c>s with which to create the <c>Point</c>s
+ /// </param>
+ /// <returns>
+ /// <c>Point</c>s created using this <c>WKTReader</c>
+ /// s <c>GeometryFactory</c>.
+ /// </returns>
+ private IPoint[] ToPoints(ICoordinate[] coordinates)
+ {
+ List<IPoint> points = new List<IPoint>();
+ for (int i = 0; i < coordinates.Length; i++)
+ points.Add(geometryFactory.CreatePoint(coordinates[i]));
+ return points.ToArray();
+ }
+
+ /// <summary>
+ /// Creates a <c>Polygon</c> using the next token in the stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next tokens must form a Polygon Text.
+ /// </param>
+ /// <returns>
+ /// A <c>Polygon</c> specified by the next token
+ /// in the stream.
+ /// </returns>
+ private IPolygon ReadPolygonText(IList tokens)
+ {
+ string nextToken = GetNextEmptyOrOpener(tokens);
+ if (nextToken.Equals("EMPTY"))
+ return geometryFactory.CreatePolygon(
+ geometryFactory.CreateLinearRing(new ICoordinate[] { }), new ILinearRing[] { });
+
+ List<ILinearRing> holes = new List<ILinearRing>();
+ ILinearRing shell = ReadLinearRingText(tokens);
+ nextToken = GetNextCloserOrComma(tokens);
+ while (nextToken.Equals(","))
+ {
+ ILinearRing hole = ReadLinearRingText(tokens);
+ holes.Add(hole);
+ nextToken = GetNextCloserOrComma(tokens);
+ }
+ return geometryFactory.CreatePolygon(shell, holes.ToArray());
+ }
+
+ /// <summary>
+ /// Creates a <c>MultiLineString</c> using the next token in the stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next tokens must form a MultiLineString Text.
+ /// </param>
+ /// <returns>
+ /// A <c>MultiLineString</c> specified by the
+ /// next token in the stream.</returns>
+ private IMultiLineString ReadMultiLineStringText(IList tokens)
+ {
+ string nextToken = GetNextEmptyOrOpener(tokens);
+ if (nextToken.Equals("EMPTY"))
+ return geometryFactory.CreateMultiLineString(new ILineString[] { });
+
+ List<ILineString> lineStrings = new List<ILineString>();
+ ILineString lineString = ReadLineStringText(tokens);
+ lineStrings.Add(lineString);
+ nextToken = GetNextCloserOrComma(tokens);
+ while (nextToken.Equals(","))
+ {
+ lineString = ReadLineStringText(tokens);
+ lineStrings.Add(lineString);
+ nextToken = GetNextCloserOrComma(tokens);
+ }
+ return geometryFactory.CreateMultiLineString(lineStrings.ToArray());
+ }
+
+ /// <summary>
+ /// Creates a <c>MultiPolygon</c> using the next token in the stream.
+ /// </summary>
+ /// <param name="tokens">Tokenizer over a stream of text in Well-known Text
+ /// format. The next tokens must form a MultiPolygon Text.
+ /// </param>
+ /// <returns>
+ /// A <c>MultiPolygon</c> specified by the next
+ /// token in the stream, or if if the coordinates used to create the
+ /// <c>Polygon</c> shells and holes do not form closed linestrings.</returns>
+ private IMultiPolygon ReadMultiPolygonText(IList tokens)
+ {
+ string nextToken = GetNextEmptyOrOpener(tokens);
+ if (nextToken.Equals("EMPTY"))
+ return geometryFactory.CreateMultiPolygon(new IPolygon[] { });
+
+ List<IPolygon> polygons = new List<IPolygon>();
+ IPolygon polygon = ReadPolygonText(tokens);
+ polygons.Add(polygon);
+ nextToken = GetNextCloserOrComma(tokens);
+ while (nextToken.Equals(","))
+ {
+ polygon = ReadPolygonText(tokens);
+ polygons.Add(polygon);
+ nextToken = GetNextCloserOrComma(tokens);
+ }
+ return geometryFactory.CreateMultiPolygon(polygons.ToArray());
+ }
+
+ /// <summary>
+ /// Creates a <c>GeometryCollection</c> using the next token in the
+ /// stream.
+ /// </summary>
+ /// <param name="tokens">
+ /// Tokenizer over a stream of text in Well-known Text
+ /// format. The next tokens must form a <GeometryCollection Text.
+ /// </param>
+ /// <returns>
+ /// A <c>GeometryCollection</c> specified by the
+ /// next token in the stream.</returns>
+ private IGeometryCollection ReadGeometryCollectionText(IList tokens)
+ {
+ string nextToken = GetNextEmptyOrOpener(tokens);
+ if (nextToken.Equals("EMPTY"))
+ return geometryFactory.CreateGeometryCollection(new IGeometry[] { });
+
+ List<IGeometry> geometries = new List<IGeometry>();
+ IGeometry geometry = ReadGeometryTaggedText(tokens);
+ geometries.Add(geometry);
+ nextToken = GetNextCloserOrComma(tokens);
+ while (nextToken.Equals(","))
+ {
+ geometry = ReadGeometryTaggedText(tokens);
+ geometries.Add(geometry);
+ nextToken = GetNextCloserOrComma(tokens);
+ }
+ return geometryFactory.CreateGeometryCollection(geometries.ToArray());
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj 2012-01-24 13:34:05 UTC (rev 6452)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI/OSGeo.MapGuide.MaestroAPI.csproj 2012-01-24 16:38:24 UTC (rev 6453)
@@ -221,6 +221,7 @@
<Compile Include="Feature\PropertyValue.cs" />
<Compile Include="Feature\ReaderBase.cs" />
<Compile Include="Feature\RecordBase.cs" />
+ <Compile Include="Internal\FixedWKTReader.cs" />
<Compile Include="IO\NsDoc.cs" />
<Compile Include="Mapping\Collections.cs" />
<Compile Include="Mapping\NsDoc.cs" />
Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/XmlReaderBase.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/XmlReaderBase.cs 2012-01-24 13:34:05 UTC (rev 6452)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/XmlReaderBase.cs 2012-01-24 16:38:24 UTC (rev 6453)
@@ -25,6 +25,7 @@
using System.Xml;
using OSGeo.MapGuide.MaestroAPI.Schema;
using GisSharpBlog.NetTopologySuite.IO;
+using OSGeo.MapGuide.MaestroAPI.Internal;
namespace OSGeo.MapGuide.MaestroAPI.Http
{
@@ -32,7 +33,7 @@
public abstract class XmlReaderBase : ReaderBase
{
- protected WKTReader _wktReader;
+ protected FixedWKTReader _wktReader;
protected XmlTextReader _reader;
protected XmlProperty[] _properties;
@@ -63,7 +64,7 @@
public XmlReaderBase(Stream source)
{
_reader = new XmlTextReader(source);
- _wktReader = new WKTReader();
+ _wktReader = new FixedWKTReader();
_reader.WhitespaceHandling = WhitespaceHandling.Significant;
_propertyMap = new Dictionary<string, XmlProperty>();
Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/XmlRecord.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/XmlRecord.cs 2012-01-24 13:34:05 UTC (rev 6452)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Http/XmlRecord.cs 2012-01-24 16:38:24 UTC (rev 6453)
@@ -24,6 +24,7 @@
using OSGeo.MapGuide.MaestroAPI.Schema;
using System.Xml;
using GisSharpBlog.NetTopologySuite.IO;
+using OSGeo.MapGuide.MaestroAPI.Internal;
namespace OSGeo.MapGuide.MaestroAPI.Http
{
@@ -42,7 +43,7 @@
public class XmlRecord : RecordBase
{
- public XmlRecord(XmlProperty[] properties, WKTReader wktReader, XmlNodeList propertyNodes, string nameElement, string valueElement)
+ public XmlRecord(XmlProperty[] properties, FixedWKTReader wktReader, XmlNodeList propertyNodes, string nameElement, string valueElement)
{
for (int i = 0; i < properties.Length; i++)
{
Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/Commands/FeatureCommandsImpl.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/Commands/FeatureCommandsImpl.cs 2012-01-24 13:34:05 UTC (rev 6452)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/Commands/FeatureCommandsImpl.cs 2012-01-24 16:38:24 UTC (rev 6453)
@@ -23,6 +23,7 @@
using OSGeo.MapGuide.MaestroAPI.Commands;
using OSGeo.MapGuide.MaestroAPI.Schema;
using OSGeo.MapGuide.MaestroAPI.Feature;
+using OSGeo.MapGuide.MaestroAPI.Internal;
#if LOCAL_API
namespace OSGeo.MapGuide.MaestroAPI.Local.Commands
@@ -57,13 +58,13 @@
{
static MgAgfReaderWriter _agfRw;
static MgWktReaderWriter _wktRw;
- static GisSharpBlog.NetTopologySuite.IO.WKTReader _reader;
+ static FixedWKTReader _reader;
static GeomConverter()
{
_agfRw = new MgAgfReaderWriter();
_wktRw = new MgWktReaderWriter();
- _reader = new GisSharpBlog.NetTopologySuite.IO.WKTReader();
+ _reader = new FixedWKTReader();
}
public static MgByteReader GetAgf(GeoAPI.Geometries.IGeometry geom)
Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeDataReader.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeDataReader.cs 2012-01-24 13:34:05 UTC (rev 6452)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeDataReader.cs 2012-01-24 16:38:24 UTC (rev 6453)
@@ -23,20 +23,21 @@
using OSGeo.MapGuide.MaestroAPI.Feature;
using OSGeo.MapGuide.MaestroAPI.Schema;
using GisSharpBlog.NetTopologySuite.IO;
+using OSGeo.MapGuide.MaestroAPI.Internal;
namespace OSGeo.MapGuide.MaestroAPI.Native
{
public class LocalNativeDataReader : ReaderBase
{
private MgDataReader _reader;
- private WKTReader _mgReader;
+ private FixedWKTReader _mgReader;
private MgAgfReaderWriter _agfRw;
private MgWktReaderWriter _wktRw;
public LocalNativeDataReader(MgDataReader reader)
{
_reader = reader;
- _mgReader = new WKTReader();
+ _mgReader = new FixedWKTReader();
_agfRw = new MgAgfReaderWriter();
_wktRw = new MgWktReaderWriter();
}
Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeFeature.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeFeature.cs 2012-01-24 13:34:05 UTC (rev 6452)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeFeature.cs 2012-01-24 16:38:24 UTC (rev 6453)
@@ -23,12 +23,13 @@
using OSGeo.MapGuide.MaestroAPI.Feature;
using OSGeo.MapGuide.MaestroAPI.Schema;
using GisSharpBlog.NetTopologySuite.IO;
+using OSGeo.MapGuide.MaestroAPI.Internal;
namespace OSGeo.MapGuide.MaestroAPI.Native
{
public class LocalNativeFeature : FeatureBase
{
- public LocalNativeFeature(MgFeatureReader reader, WKTReader mgReader, MgAgfReaderWriter agfRw, MgWktReaderWriter wktRw)
+ public LocalNativeFeature(MgFeatureReader reader, FixedWKTReader mgReader, MgAgfReaderWriter agfRw, MgWktReaderWriter wktRw)
: base(Utility.ConvertClassDefinition(reader.GetClassDefinition()))
{
for (int i = 0; i < reader.GetPropertyCount(); i++)
Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeFeatureReader.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeFeatureReader.cs 2012-01-24 13:34:05 UTC (rev 6452)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeFeatureReader.cs 2012-01-24 16:38:24 UTC (rev 6453)
@@ -23,20 +23,21 @@
using OSGeo.MapGuide.MaestroAPI.Exceptions;
using OSGeo.MapGuide.MaestroAPI.Feature;
using GisSharpBlog.NetTopologySuite.IO;
+using OSGeo.MapGuide.MaestroAPI.Internal;
namespace OSGeo.MapGuide.MaestroAPI.Native
{
public class LocalNativeFeatureReader : FeatureReaderBase
{
private MgFeatureReader _reader;
- private WKTReader _mgReader;
+ private FixedWKTReader _mgReader;
private MgAgfReaderWriter _agfRw;
private MgWktReaderWriter _wktRw;
public LocalNativeFeatureReader(MgFeatureReader reader)
{
_reader = reader;
- _mgReader = new WKTReader();
+ _mgReader = new FixedWKTReader();
_agfRw = new MgAgfReaderWriter();
_wktRw = new MgWktReaderWriter();
base.ClassDefinition = Utility.ConvertClassDefinition(reader.GetClassDefinition());
Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeRecord.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeRecord.cs 2012-01-24 13:34:05 UTC (rev 6452)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeRecord.cs 2012-01-24 16:38:24 UTC (rev 6453)
@@ -23,12 +23,13 @@
using OSGeo.MapGuide.MaestroAPI.Feature;
using OSGeo.MapGuide.MaestroAPI.Schema;
using GisSharpBlog.NetTopologySuite.IO;
+using OSGeo.MapGuide.MaestroAPI.Internal;
namespace OSGeo.MapGuide.MaestroAPI.Native
{
public class LocalNativeRecord : RecordBase
{
- public LocalNativeRecord(MgReader reader, WKTReader mgReader, MgAgfReaderWriter agfRw, MgWktReaderWriter wktRw)
+ public LocalNativeRecord(MgReader reader, FixedWKTReader mgReader, MgAgfReaderWriter agfRw, MgWktReaderWriter wktRw)
{
for (int i = 0; i < reader.GetPropertyCount(); i++)
{
Modified: trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeSqlReader.cs
===================================================================
--- trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeSqlReader.cs 2012-01-24 13:34:05 UTC (rev 6452)
+++ trunk/Tools/Maestro/OSGeo.MapGuide.MaestroAPI.Native/LocalNativeSqlReader.cs 2012-01-24 16:38:24 UTC (rev 6453)
@@ -23,20 +23,21 @@
using OSGeo.MapGuide.MaestroAPI.Feature;
using OSGeo.MapGuide.MaestroAPI.Schema;
using GisSharpBlog.NetTopologySuite.IO;
+using OSGeo.MapGuide.MaestroAPI.Internal;
namespace OSGeo.MapGuide.MaestroAPI.Native
{
public class LocalNativeSqlReader : ReaderBase
{
private MgSqlDataReader _reader;
- private WKTReader _mgReader;
+ private FixedWKTReader _mgReader;
private MgAgfReaderWriter _agfRw;
private MgWktReaderWriter _wktRw;
public LocalNativeSqlReader(MgSqlDataReader reader)
{
_reader = reader;
- _mgReader = new WKTReader();
+ _mgReader = new FixedWKTReader();
_agfRw = new MgAgfReaderWriter();
_wktRw = new MgWktReaderWriter();
}
More information about the mapguide-commits
mailing list