// Copyright 2005, 2006 - Morten Nielsen (www.iter.dk)
//
// This file is part of SharpMap.
// SharpMap 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 of the License, or
// (at your option) any later version.
//
// SharpMap 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 SharpMap; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// SOURCECODE IS MODIFIED FROM ANOTHER WORK AND IS ORIGINALLY BASED ON GeoTools.NET:
/*
* Copyright (C) 2002 Urban Science Applications, Inc.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
using GeoAPI.Geometries;
using GisSharpBlog.NetTopologySuite.IO;
namespace SharpMap.Converters.WellKnownText
{
///
/// Converts a Well-known Text representation to a instance.
///
///
/// The Well-Known Text (WKT) representation of Geometry is designed to exchange geometry data in ASCII form.
/// Examples of WKT representations of geometry objects are:
///
/// Geometry WKT Representation
/// - A Point
/// POINT(15 20)
Note that point coordinates are specified with no separating comma.
/// - A LineString with four points:
/// LINESTRING(0 0, 10 10, 20 25, 50 60)
/// - A Polygon with one exterior ring and one interior ring:
/// POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))
/// - A MultiPoint with three Point values:
/// MULTIPOINT(0 0, 20 20, 60 60)
/// - A MultiLineString with two LineString values:
/// MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
/// - A MultiPolygon with two Polygon values:
/// MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
/// - A GeometryCollection consisting of two Point values and one LineString:
/// GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
///
///
public class GeometryFromWKT
{
///
/// Converts a Well-known text representation to a .
///
/// A tagged text string ( see the OpenGIS Simple Features Specification.
/// Returns a specified by wellKnownText. Throws an exception if there is a parsing problem.
public static IGeometry Parse(string wellKnownText)
{
return new WKTReader().Read(wellKnownText);
// // throws a parsing exception is there is a problem.
// System.IO.StringReader reader = new System.IO.StringReader(wellKnownText);
// return Parse(reader);
}
// ///
// /// Converts a Well-known Text representation to a .
// ///
// /// A Reader which will return a Geometry Tagged Text
// /// string (see the OpenGIS Simple Features Specification)
// /// Returns a read from StreamReader.
// /// An exception will be thrown if there is a parsing problem.
// public static Geometry Parse(System.IO.TextReader reader)
// {
// WktStreamTokenizer tokenizer = new WktStreamTokenizer(reader);
//
// return ReadGeometryTaggedText(tokenizer);
// }
//
// ///
// /// Returns the next array of Coordinates in the stream.
// ///
// /// 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".
// /// The next array of Coordinates in the stream, or an empty array of "EMPTY" is the
// /// next element returned by the stream.
// private static Collection GetCoordinates(WktStreamTokenizer tokenizer)
// {
// Collection coordinates = new Collection();
// string nextToken = GetNextEmptyOrOpener(tokenizer);
// if (nextToken=="EMPTY")
// return coordinates;
//
// SharpMap.Geometries.Point externalCoordinate = new SharpMap.Geometries.Point();
// SharpMap.Geometries.Point internalCoordinate = new SharpMap.Geometries.Point();
// externalCoordinate.X = GetNextNumber(tokenizer);
// externalCoordinate.Y = GetNextNumber(tokenizer);
// coordinates.Add(externalCoordinate);
// nextToken = GetNextCloserOrComma(tokenizer);
// while (nextToken==",")
// {
// internalCoordinate = new SharpMap.Geometries.Point();
// internalCoordinate.X = GetNextNumber(tokenizer);
// internalCoordinate.Y = GetNextNumber(tokenizer);
// coordinates.Add(internalCoordinate);
// nextToken = GetNextCloserOrComma(tokenizer);
// }
// return coordinates;
// }
//
//
// ///
// /// Returns the next number in the stream.
// ///
// /// Tokenizer over a stream of text in Well-known text format. The next token
// /// must be a number.
// /// Returns the next number in the stream.
// ///
// /// ParseException is thrown if the next token is not a number.
// ///
// private static double GetNextNumber(WktStreamTokenizer tokenizer)
// {
// tokenizer.NextToken();
// return tokenizer.GetNumericValue();
// }
//
// ///
// /// Returns the next "EMPTY" or "(" in the stream as uppercase text.
// ///
// /// Tokenizer over a stream of text in Well-known Text
// /// format. The next token must be "EMPTY" or "(".
// /// the next "EMPTY" or "(" in the stream as uppercase
// /// text.
// ///
// /// ParseException is thrown if the next token is not "EMPTY" or "(".
// ///
// private static string GetNextEmptyOrOpener(WktStreamTokenizer tokenizer)
// {
// tokenizer.NextToken();
// string nextWord = tokenizer.GetStringValue();
// if (nextWord == "EMPTY" || nextWord == "(")
// return nextWord;
//
// throw new Exception("Expected 'EMPTY' or '(' but encountered '" + nextWord + "'");
//
// }
//
// ///
// /// Returns the next ")" or "," in the stream.
// ///
// /// tokenizer over a stream of text in Well-known Text
// /// format. The next token must be ")" or ",".
// /// Returns the next ")" or "," in the stream.
// ///
// /// ParseException is thrown if the next token is not ")" or ",".
// ///
// private static string GetNextCloserOrComma(WktStreamTokenizer tokenizer)
// {
// tokenizer.NextToken();
// string nextWord = tokenizer.GetStringValue();
// if (nextWord == "," || nextWord == ")")
// {
// return nextWord;
// }
// throw new Exception("Expected ')' or ',' but encountered '" + nextWord + "'");
// }
//
// ///
// /// Returns the next ")" in the stream.
// ///
// /// Tokenizer over a stream of text in Well-known Text
// /// format. The next token must be ")".
// /// Returns the next ")" in the stream.
// ///
// /// ParseException is thrown if the next token is not ")".
// ///
// private static string GetNextCloser(WktStreamTokenizer tokenizer)
// {
//
// string nextWord = GetNextWord(tokenizer);
// if (nextWord == ")")
// return nextWord;
//
// throw new Exception("Expected ')' but encountered '" + nextWord + "'");
// }
//
// ///
// /// Returns the next word in the stream as uppercase text.
// ///
// /// Tokenizer over a stream of text in Well-known Text
// /// format. The next token must be a word.
// /// Returns the next word in the stream as uppercase text.
// ///
// /// Exception is thrown if the next token is not a word.
// ///
// private static string GetNextWord(WktStreamTokenizer tokenizer)
// {
// TokenType type = tokenizer.NextToken();
// string token = tokenizer.GetStringValue();
// if (type == TokenType.Number)
// throw new Exception("Expected a number but got " + token);
// else if (type == TokenType.Word)
// return token.ToUpper();
// else if (token == "(")
// return "(";
// else if (token == ")")
// return ")";
// else if (token == ",")
// return ",";
//
// throw new Exception("Not a valid symbol in WKT format.");
// }
//
// ///
// /// Creates a Geometry using the next token in the stream.
// ///
// /// Tokenizer over a stream of text in Well-known Text
// /// format. The next tokens must form a <Geometry Tagged Text>.
// /// Returns a Geometry specified by the next token in the stream.
// ///
// /// Exception is thrown if the coordinates used to create a Polygon
// /// shell and holes do not form closed linestrings, or if an unexpected
// /// token is encountered.
// ///
// private static Geometry ReadGeometryTaggedText(WktStreamTokenizer tokenizer)
// {
// tokenizer.NextToken();
// string type = tokenizer.GetStringValue().ToUpper();
// Geometry geometry = null;
// switch (type)
// {
// case "POINT":
// geometry = ReadPointText(tokenizer);
// break;
// case "LINESTRING":
// geometry = ReadLineStringText(tokenizer);
// break;
// case "MULTIPOINT":
// geometry = ReadMultiPointText(tokenizer);
// break;
// case "MULTILINESTRING":
// geometry = ReadMultiLineStringText(tokenizer);
// break;
// case "POLYGON":
// geometry = ReadPolygonText(tokenizer);
// break;
// case "MULTIPOLYGON":
// geometry = ReadMultiPolygonText(tokenizer);
// break;
// case "GEOMETRYCOLLECTION":
// geometry = ReadGeometryCollectionText(tokenizer);
// break;
// default:
// throw new Exception(String.Format(SharpMap.Map.numberFormat_EnUS, "Geometrytype '{0}' is not supported.", type));
// }
// return geometry;
// }
//
// ///
// /// Creates a using the next token in the stream.
// ///
// /// tokenizer over a stream of text in Well-known Text
// /// format. The next tokens must form a MultiPolygon.
// /// a MultiPolygon specified by the next token in the
// /// stream, or if if the coordinates used to create the
// /// shells and holes do not form closed linestrings.
// private static MultiPolygon ReadMultiPolygonText(WktStreamTokenizer tokenizer)
// {
// MultiPolygon polygons = new MultiPolygon();
// string nextToken = GetNextEmptyOrOpener(tokenizer);
// if (nextToken == "EMPTY")
// return polygons;
//
// Polygon polygon = ReadPolygonText(tokenizer);
// polygons.Polygons.Add(polygon);
// nextToken = GetNextCloserOrComma(tokenizer);
// while (nextToken == ",")
// {
// polygon = ReadPolygonText(tokenizer);
// polygons.Polygons.Add(polygon);
// nextToken = GetNextCloserOrComma(tokenizer);
// }
// return polygons;
// }
//
// ///
// /// Creates a Polygon using the next token in the stream.
// ///
// /// Tokenizer over a stream of text in Well-known Text
// /// format. The next tokens must form a <Polygon Text>.
// /// Returns a Polygon specified by the next token
// /// in the stream
// ///
// /// ParseException is thown if the coordinates used to create the Polygon
// /// shell and holes do not form closed linestrings, or if an unexpected
// /// token is encountered.
// ///
// private static Polygon ReadPolygonText(WktStreamTokenizer tokenizer)
// {
// Polygon pol = new Polygon();
// string nextToken = GetNextEmptyOrOpener(tokenizer);
// if (nextToken == "EMPTY")
// return pol;
//
// pol.ExteriorRing = new LinearRing(GetCoordinates(tokenizer));
// nextToken = GetNextCloserOrComma(tokenizer);
// while (nextToken == ",")
// {
// //Add holes
// pol.InteriorRings.Add(new LinearRing(GetCoordinates(tokenizer)));
// nextToken = GetNextCloserOrComma(tokenizer);
// }
// return pol;
//
// }
//
//
// ///
// /// Creates a Point using the next token in the stream.
// ///
// /// Tokenizer over a stream of text in Well-known Text
// /// format. The next tokens must form a <Point Text>.
// /// Returns a Point specified by the next token in
// /// the stream.
// ///
// /// ParseException is thrown if an unexpected token is encountered.
// ///
// private static Point ReadPointText(WktStreamTokenizer tokenizer)
// {
// Point p = new Point();
// string nextToken = GetNextEmptyOrOpener(tokenizer);
// if (nextToken == "EMPTY")
// return p;
// p.X = GetNextNumber(tokenizer);
// p.Y = GetNextNumber(tokenizer);
// GetNextCloser(tokenizer);
// return p;
// }
//
// ///
// /// Creates a Point using the next token in the stream.
// ///
// /// Tokenizer over a stream of text in Well-known Text
// /// format. The next tokens must form a <Point Text>.
// /// Returns a Point specified by the next token in
// /// the stream.
// ///
// /// ParseException is thrown if an unexpected token is encountered.
// ///
// private static MultiPoint ReadMultiPointText(WktStreamTokenizer tokenizer)
// {
// SharpMap.Geometries.MultiPoint mp = new MultiPoint();
// string nextToken = GetNextEmptyOrOpener(tokenizer);
// if (nextToken == "EMPTY")
// return mp;
// mp.Points.Add(new SharpMap.Geometries.Point(GetNextNumber(tokenizer),GetNextNumber(tokenizer)));
// nextToken = GetNextCloserOrComma(tokenizer);
// while (nextToken == ",")
// {
// mp.Points.Add(new SharpMap.Geometries.Point(GetNextNumber(tokenizer), GetNextNumber(tokenizer)));
// nextToken = GetNextCloserOrComma(tokenizer);
// }
// return mp;
// }
//
// ///
// /// Creates a using the next token in the stream.
// ///
// /// tokenizer over a stream of text in Well-known Text format. The next tokens must form a MultiLineString Text
// /// a specified by the next token in the stream
// private static MultiLineString ReadMultiLineStringText(WktStreamTokenizer tokenizer)
// {
// MultiLineString lines = new MultiLineString();
// string nextToken = GetNextEmptyOrOpener(tokenizer);
// if (nextToken == "EMPTY")
// return lines;
//
// lines.LineStrings.Add(ReadLineStringText(tokenizer));
// nextToken = GetNextCloserOrComma(tokenizer);
// while (nextToken == ",")
// {
// lines.LineStrings.Add(ReadLineStringText(tokenizer));
// nextToken = GetNextCloserOrComma(tokenizer);
// }
// return lines;
// }
//
// ///
// /// Creates a LineString using the next token in the stream.
// ///
// /// Tokenizer over a stream of text in Well-known Text format. The next
// /// tokens must form a LineString Text.
// /// Returns a LineString specified by the next token in the stream.
// ///
// /// ParseException is thrown if an unexpected token is encountered.
// ///
// private static LineString ReadLineStringText(WktStreamTokenizer tokenizer)
// {
// return new SharpMap.Geometries.LineString(GetCoordinates(tokenizer));
// }
//
// ///
// /// Creates a using the next token in the stream.
// ///
// /// Tokenizer over a stream of text in Well-known Text
// /// format. The next tokens must form a GeometryCollection Text.
// ///
// /// A specified by the next token in the stream.
// private static GeometryCollection ReadGeometryCollectionText(WktStreamTokenizer tokenizer)
// {
// GeometryCollection geometries = new GeometryCollection();
// string nextToken = GetNextEmptyOrOpener(tokenizer);
// if (nextToken.Equals("EMPTY"))
// return geometries;
// geometries.Collection.Add(ReadGeometryTaggedText(tokenizer));
// nextToken = GetNextCloserOrComma(tokenizer);
// while (nextToken.Equals(","))
// {
// geometries.Collection.Add(ReadGeometryTaggedText(tokenizer));
// nextToken = GetNextCloserOrComma(tokenizer);
// }
// return geometries;
// }
//
}
}