Skip to content

Commit 2972eee

Browse files
committed
* Allow round brackets
refers to #94
1 parent ce85ea4 commit 2972eee

File tree

5 files changed

+134
-34
lines changed

5 files changed

+134
-34
lines changed

src/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
<PropertyGroup Label="Version numbers">
3939
<!-- MAJOR, MINOR, and PATCH are defined according to SemVer 2.0.0. -->
4040
<NtsMajorVersion>2</NtsMajorVersion>
41-
<NtsMinorVersion>0</NtsMinorVersion>
41+
<NtsMinorVersion>1</NtsMinorVersion>
4242
<NtsPatchVersion>0</NtsPatchVersion>
4343

4444
<NtsBuildTimestamp>$([System.DateTime]::UtcNow.Ticks)</NtsBuildTimestamp>

src/ProjNet/IO/CoordinateSystems/CoordinateSystemWktReader.cs

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public static IInfo Parse(string wkt)
9696
/// <returns>An object that implements the IUnit interface.</returns>
9797
private static IUnit ReadUnit(WktStreamTokenizer tokenizer)
9898
{
99-
tokenizer.ReadToken("[");
99+
var bracket = tokenizer.ReadOpener();
100100
string unitName = tokenizer.ReadDoubleQuotedWord();
101101
tokenizer.ReadToken(",");
102102
tokenizer.NextToken();
@@ -107,8 +107,11 @@ private static IUnit ReadUnit(WktStreamTokenizer tokenizer)
107107
if (tokenizer.GetStringValue() == ",")
108108
{
109109
tokenizer.ReadAuthority(out authority, out authorityCode);
110-
tokenizer.ReadToken("]");
110+
tokenizer.ReadCloser(bracket);
111111
}
112+
else
113+
tokenizer.CheckCloser(bracket);
114+
112115
return new Unit(unitsPerUnit, unitName, authority, authorityCode, string.Empty, string.Empty, string.Empty);
113116
}
114117
/// <summary>
@@ -118,7 +121,8 @@ private static IUnit ReadUnit(WktStreamTokenizer tokenizer)
118121
/// <returns>An object that implements the IUnit interface.</returns>
119122
private static LinearUnit ReadLinearUnit(WktStreamTokenizer tokenizer)
120123
{
121-
tokenizer.ReadToken("[");
124+
var bracket = tokenizer.ReadOpener();
125+
122126
string unitName = tokenizer.ReadDoubleQuotedWord();
123127
tokenizer.ReadToken(",");
124128
tokenizer.NextToken();
@@ -129,8 +133,11 @@ private static LinearUnit ReadLinearUnit(WktStreamTokenizer tokenizer)
129133
if (tokenizer.GetStringValue() == ",")
130134
{
131135
tokenizer.ReadAuthority(out authority, out authorityCode);
132-
tokenizer.ReadToken("]");
136+
tokenizer.ReadCloser(bracket);
133137
}
138+
else
139+
tokenizer.CheckCloser(bracket);
140+
134141
return new LinearUnit(unitsPerUnit, unitName, authority, authorityCode, string.Empty, string.Empty, string.Empty);
135142
}
136143
/// <summary>
@@ -140,7 +147,8 @@ private static LinearUnit ReadLinearUnit(WktStreamTokenizer tokenizer)
140147
/// <returns>An object that implements the IUnit interface.</returns>
141148
private static AngularUnit ReadAngularUnit(WktStreamTokenizer tokenizer)
142149
{
143-
tokenizer.ReadToken("[");
150+
var bracket = tokenizer.ReadOpener();
151+
144152
string unitName = tokenizer.ReadDoubleQuotedWord();
145153
tokenizer.ReadToken(",");
146154
tokenizer.NextToken();
@@ -151,7 +159,11 @@ private static AngularUnit ReadAngularUnit(WktStreamTokenizer tokenizer)
151159
if (tokenizer.GetStringValue() == ",")
152160
{
153161
tokenizer.ReadAuthority(out authority, out authorityCode);
154-
tokenizer.ReadToken("]");
162+
tokenizer.ReadCloser(bracket);
163+
}
164+
else
165+
{
166+
tokenizer.CheckCloser(bracket);
155167
}
156168
return new AngularUnit(unitsPerUnit, unitName, authority, authorityCode, string.Empty, string.Empty, string.Empty);
157169
}
@@ -165,12 +177,12 @@ private static AxisInfo ReadAxis(WktStreamTokenizer tokenizer)
165177
{
166178
if (tokenizer.GetStringValue() != "AXIS")
167179
tokenizer.ReadToken("AXIS");
168-
tokenizer.ReadToken("[");
180+
var bracket = tokenizer.ReadOpener();
169181
string axisName = tokenizer.ReadDoubleQuotedWord();
170182
tokenizer.ReadToken(",");
171183
tokenizer.NextToken();
172184
string unitname = tokenizer.GetStringValue();
173-
tokenizer.ReadToken("]");
185+
tokenizer.ReadCloser(bracket);
174186
switch (unitname.ToUpperInvariant())
175187
{
176188
case "DOWN": return new AxisInfo(axisName, AxisOrientationEnum.Down);
@@ -210,7 +222,7 @@ private static CoordinateSystem ReadCoordinateSystem(string coordinateSystem, Wk
210222
private static Wgs84ConversionInfo ReadWGS84ConversionInfo(WktStreamTokenizer tokenizer)
211223
{
212224
//TOWGS84[0,0,0,0,0,0,0]
213-
tokenizer.ReadToken("[");
225+
var bracket = tokenizer.ReadOpener();
214226
var info = new Wgs84ConversionInfo();
215227
tokenizer.NextToken();
216228
info.Dx = tokenizer.GetNumericValue();
@@ -244,14 +256,14 @@ private static Wgs84ConversionInfo ReadWGS84ConversionInfo(WktStreamTokenizer to
244256
}
245257
}
246258
if (tokenizer.GetStringValue() != "]")
247-
tokenizer.ReadToken("]");
259+
tokenizer.ReadCloser(bracket);
248260
return info;
249261
}
250262

251263
private static Ellipsoid ReadEllipsoid(WktStreamTokenizer tokenizer)
252264
{
253265
//SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]]
254-
tokenizer.ReadToken("[");
266+
var bracket = tokenizer.ReadOpener();
255267
string name = tokenizer.ReadDoubleQuotedWord();
256268
tokenizer.ReadToken(",");
257269
tokenizer.NextToken();
@@ -265,7 +277,7 @@ private static Ellipsoid ReadEllipsoid(WktStreamTokenizer tokenizer)
265277
if (tokenizer.GetStringValue() == ",") //Read authority
266278
{
267279
tokenizer.ReadAuthority(out authority, out authorityCode);
268-
tokenizer.ReadToken("]");
280+
tokenizer.ReadCloser(bracket);
269281
}
270282
var ellipsoid = new Ellipsoid(majorAxis, 0.0, e, true, LinearUnit.Metre, name, authority, authorityCode, string.Empty, string.Empty, string.Empty);
271283
return ellipsoid;
@@ -275,7 +287,7 @@ private static IProjection ReadProjection(WktStreamTokenizer tokenizer)
275287
{
276288
if (tokenizer.GetStringValue() != "PROJECTION")
277289
tokenizer.ReadToken("PROJECTION");
278-
tokenizer.ReadToken("[");//[
290+
var bracket = tokenizer.ReadOpener();
279291
string projectionName = tokenizer.ReadDoubleQuotedWord();
280292
string authority = string.Empty;
281293
long authorityCode = -1L;
@@ -284,20 +296,22 @@ private static IProjection ReadProjection(WktStreamTokenizer tokenizer)
284296
if (tokenizer.GetStringValue() == ",")
285297
{
286298
tokenizer.ReadAuthority(out authority, out authorityCode);
287-
tokenizer.ReadToken("]");
299+
tokenizer.ReadCloser(bracket);
288300
}
301+
else
302+
tokenizer.CheckCloser(bracket);
289303

290304
tokenizer.ReadToken(",");//,
291305
tokenizer.ReadToken("PARAMETER");
292306
var paramList = new List<ProjectionParameter>();
293307
while (tokenizer.GetStringValue() == "PARAMETER")
294308
{
295-
tokenizer.ReadToken("[");
309+
bracket = tokenizer.ReadOpener();
296310
string paramName = tokenizer.ReadDoubleQuotedWord();
297311
tokenizer.ReadToken(",");
298312
tokenizer.NextToken();
299313
double paramValue = tokenizer.GetNumericValue();
300-
tokenizer.ReadToken("]");
314+
tokenizer.ReadCloser(bracket);
301315
paramList.Add(new ProjectionParameter(paramName, paramValue));
302316
//tokenizer.ReadToken(",");
303317
//tokenizer.NextToken();
@@ -338,7 +352,7 @@ private static ProjectedCoordinateSystem ReadProjectedCoordinateSystem(WktStream
338352
AUTHORITY["EPSG","27700"]
339353
]
340354
*/
341-
tokenizer.ReadToken("[");
355+
var bracket = tokenizer.ReadOpener();
342356
string name = tokenizer.ReadDoubleQuotedWord();
343357
tokenizer.ReadToken(",");
344358
tokenizer.ReadToken("GEOGCS");
@@ -356,7 +370,10 @@ private static ProjectedCoordinateSystem ReadProjectedCoordinateSystem(WktStream
356370
switch (tokenizer.GetStringValue())
357371
{
358372
case ",":
373+
break;
359374
case "]":
375+
case ")":
376+
tokenizer.CheckCloser(bracket);
360377
break;
361378
case "PROJECTION":
362379
projection = ReadProjection(tokenizer);
@@ -372,7 +389,7 @@ private static ProjectedCoordinateSystem ReadProjectedCoordinateSystem(WktStream
372389
break;
373390
case "AUTHORITY":
374391
tokenizer.ReadAuthority(out authority, out authorityCode);
375-
//tokenizer.ReadToken("]");
392+
//tokenizer.ReadCloser(bracket);
376393
break;
377394
}
378395
ct = tokenizer.NextToken();
@@ -394,7 +411,7 @@ private static GeocentricCoordinateSystem ReadGeocentricCoordinateSystem(WktStre
394411
* GEOCCS["<name>", <datum>, <prime meridian>, <linear unit> {,<axis>, <axis>, <axis>} {,<authority>}]
395412
*/
396413

397-
tokenizer.ReadToken("[");
414+
var bracket = tokenizer.ReadOpener();
398415
string name = tokenizer.ReadDoubleQuotedWord();
399416
tokenizer.ReadToken(",");
400417
tokenizer.ReadToken("DATUM");
@@ -424,7 +441,7 @@ private static GeocentricCoordinateSystem ReadGeocentricCoordinateSystem(WktStre
424441
if (tokenizer.GetStringValue() == "AUTHORITY")
425442
{
426443
tokenizer.ReadAuthority(out authority, out authorityCode);
427-
tokenizer.ReadToken("]");
444+
tokenizer.ReadCloser(bracket);
428445
}
429446
}
430447

@@ -451,7 +468,7 @@ private static GeographicCoordinateSystem ReadGeographicCoordinateSystem(WktStre
451468
AUTHORITY["EPSG","4277"]
452469
]
453470
*/
454-
tokenizer.ReadToken("[");
471+
var bracket = tokenizer.ReadOpener();
455472
string name = tokenizer.ReadDoubleQuotedWord();
456473
tokenizer.ReadToken(",");
457474
tokenizer.ReadToken("DATUM");
@@ -480,7 +497,7 @@ private static GeographicCoordinateSystem ReadGeographicCoordinateSystem(WktStre
480497
if (tokenizer.GetStringValue() == "AUTHORITY")
481498
{
482499
tokenizer.ReadAuthority(out authority, out authorityCode);
483-
tokenizer.ReadToken("]");
500+
tokenizer.ReadCloser(bracket);
484501
}
485502
}
486503

@@ -502,7 +519,7 @@ private static HorizontalDatum ReadHorizontalDatum(WktStreamTokenizer tokenizer)
502519
string authority = string.Empty;
503520
long authorityCode = -1;
504521

505-
tokenizer.ReadToken("[");
522+
var bracket = tokenizer.ReadOpener();
506523
string name = tokenizer.ReadDoubleQuotedWord();
507524
tokenizer.ReadToken(",");
508525
tokenizer.ReadToken("SPHEROID");
@@ -519,7 +536,7 @@ private static HorizontalDatum ReadHorizontalDatum(WktStreamTokenizer tokenizer)
519536
else if (tokenizer.GetStringValue() == "AUTHORITY")
520537
{
521538
tokenizer.ReadAuthority(out authority, out authorityCode);
522-
tokenizer.ReadToken("]");
539+
tokenizer.ReadCloser(bracket);
523540
}
524541
}
525542
// make an assumption about the datum type.
@@ -531,7 +548,7 @@ private static HorizontalDatum ReadHorizontalDatum(WktStreamTokenizer tokenizer)
531548
private static PrimeMeridian ReadPrimeMeridian(WktStreamTokenizer tokenizer)
532549
{
533550
//PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]]
534-
tokenizer.ReadToken("[");
551+
var bracket = tokenizer.ReadOpener();
535552
string name = tokenizer.ReadDoubleQuotedWord();
536553
tokenizer.ReadToken(",");
537554
tokenizer.NextToken();
@@ -543,8 +560,11 @@ private static PrimeMeridian ReadPrimeMeridian(WktStreamTokenizer tokenizer)
543560
if (tokenizer.GetStringValue() == ",")
544561
{
545562
tokenizer.ReadAuthority(out authority, out authorityCode);
546-
tokenizer.ReadToken("]");
563+
tokenizer.ReadCloser(bracket);
547564
}
565+
else
566+
tokenizer.CheckCloser(bracket);
567+
548568
// make an assumption about the Angular units - degrees.
549569
var primeMeridian = new PrimeMeridian(longitude, AngularUnit.Degrees, name, authority, authorityCode, string.Empty, string.Empty, string.Empty);
550570

@@ -572,7 +592,7 @@ private static FittedCoordinateSystem ReadFittedCoordinateSystem (WktStreamToken
572592
AUTHORITY["CUSTOM","12345"]
573593
]
574594
*/
575-
tokenizer.ReadToken ("[");
595+
var bracket = tokenizer.ReadOpener();
576596
string name = tokenizer.ReadDoubleQuotedWord ();
577597
tokenizer.ReadToken (",");
578598
tokenizer.ReadToken ("PARAM_MT");
@@ -590,11 +610,15 @@ private static FittedCoordinateSystem ReadFittedCoordinateSystem (WktStreamToken
590610
switch (tokenizer.GetStringValue ())
591611
{
592612
case ",":
613+
break;
593614
case "]":
615+
case ")":
616+
tokenizer.CheckCloser(bracket);
617+
594618
break;
595619
case "AUTHORITY":
596620
tokenizer.ReadAuthority (out authority, out authorityCode);
597-
//tokenizer.ReadToken("]");
621+
//tokenizer.ReadCloser(bracket);
598622
break;
599623
}
600624
ct = tokenizer.NextToken ();

src/ProjNet/IO/CoordinateSystems/WKTStreamTokenizer.cs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,64 @@ public string ReadDoubleQuotedWord()
9191
return word;
9292
}
9393

94+
/// <summary>
95+
/// Reads an opener
96+
/// </summary>
97+
/// <param name="expectedBracket">The expected bracket type.</param>
98+
/// <returns>The bracket type encountered</returns>
99+
public WktBracket ReadOpener(WktBracket expectedBracket = WktBracket.DontCare)
100+
{
101+
NextToken();
102+
string stringValue = GetStringValue();
103+
if (stringValue == "[")
104+
{
105+
if (expectedBracket == WktBracket.Square || expectedBracket == WktBracket.DontCare)
106+
return WktBracket.Square;
107+
}
108+
else if (stringValue == "(")
109+
{
110+
if (expectedBracket == WktBracket.Round || expectedBracket == WktBracket.DontCare)
111+
return WktBracket.Round;
112+
}
113+
114+
string expectedToken = expectedBracket == WktBracket.Square ? "[" : "(";
115+
string s = string.Format(_nfi, "Expecting ('{3}') but got a '{0}' at line {1} column {2}.", stringValue, LineNumber, Column, expectedToken);
116+
throw new ArgumentException(s);
117+
}
118+
119+
/// <summary>
120+
/// Reads an closer
121+
/// </summary>
122+
/// <param name="expectedBracket">The expected bracket type.</param>
123+
public void ReadCloser(WktBracket expectedBracket)
124+
{
125+
NextToken();
126+
CheckCloser(expectedBracket);
127+
}
128+
129+
/// <summary>
130+
/// Checks if the current token is a closer of expected type.
131+
/// </summary>
132+
/// <param name="expectedBracket">The expected bracket type.</param>
133+
public void CheckCloser(WktBracket expectedBracket)
134+
{
135+
string stringValue = GetStringValue();
136+
if (stringValue == "]")
137+
{
138+
if (expectedBracket == WktBracket.Square || expectedBracket == WktBracket.DontCare)
139+
return;
140+
}
141+
else if (stringValue == ")")
142+
{
143+
if (expectedBracket == WktBracket.Round || expectedBracket == WktBracket.DontCare)
144+
return;
145+
}
146+
147+
string expectedToken = expectedBracket == WktBracket.Square ? "]" : ")";
148+
string s = string.Format(_nfi, "Expecting ('{3}') but got a '{0}' at line {1} column {2}.", stringValue, LineNumber, Column, expectedToken);
149+
throw new ArgumentException(s);
150+
}
151+
94152
/// <summary>
95153
/// Reads the authority and authority code.
96154
/// </summary>
@@ -101,15 +159,15 @@ public void ReadAuthority(out string authority, out long authorityCode)
101159
//AUTHORITY["EPGS","9102"]]
102160
if (GetStringValue() != "AUTHORITY")
103161
ReadToken("AUTHORITY");
104-
ReadToken("[");
162+
var bracket = ReadOpener();
105163
authority = ReadDoubleQuotedWord();
106164
ReadToken(",");
107165
NextToken();
108166
if (GetTokenType() == TokenType.Number)
109167
authorityCode = (long) GetNumericValue();
110168
else
111169
long.TryParse(ReadDoubleQuotedWord(), NumberStyles.Any, _nfi, out authorityCode);
112-
ReadToken("]");
170+
ReadCloser(bracket);
113171
}
114172
}
115173
}

src/ProjNet/ProjNET.csproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<RootNamespace>ProjNet</RootNamespace>
66
<TargetFramework>netstandard2.0</TargetFramework>
77
<SignAssembly>true</SignAssembly>
8+
<EnableApiCompat>true</EnableApiCompat>
89
</PropertyGroup>
910

1011
<PropertyGroup Label="Assembly Info">
@@ -28,4 +29,11 @@ Proj.NET performs point-to-point coordinate conversions between geodetic coordin
2829
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
2930
</ItemGroup>
3031

32+
<ItemGroup Condition=" '$(EnableApiCompat)' == 'true' ">
33+
<PackageReference Include="Microsoft.DotNet.ApiCompat" Version="6.0.0-beta.21159.11" PrivateAssets="All" />
34+
<PackageDownload Include="ProjNet" Version="[2.0.0]" PrivateAssets="All" />
35+
36+
<ResolvedMatchingContract Include="$(NugetPackageRoot)projnet\2.0.0\lib\netstandard2.0\ProjNet.dll" />
37+
</ItemGroup>
38+
3139
</Project>

0 commit comments

Comments
 (0)