-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2 dimensional coordinates (XY) are converted in 3 dimensions (XYZ) in postgis #23
Comments
The issue arises because var reader new WKTReader() { IsOldNtsCoordinateSyntaxAllowed = false }; |
see also NTS Issue #567 |
@FObermaier do you think Npgsql needs to be changed in any way here? |
@roji , a hint to the documentation on how to use the |
Given a |
The workaround is to prevent creating the var wktRdr = new NetTopologySuite.IO.WKTReader(/* possible NetTopologySuite.NtsGeometryServices instance */) {
IsOldNtsCoordinateSyntaxAllowed = false
}; |
@FObermaier that works on the reader. But subsequently manipulating the geometry, if using any of the NTS geometry calculations, |
@Swoorup can you add a testcase (I mean, a complete example) that reproduces the error? |
@DGuidi I use other operations as well but even a buffer(0.0) causes an issue. let rec hasZ (p: Geometry) =
match p with
| :? Point as pp -> pp.CoordinateSequence.HasZ
| :? Polygon as pp -> pp.ExteriorRing.CoordinateSequence.HasZ
| :? LineString as ls -> ls.CoordinateSequence.HasZ
| :? GeometryCollection as gc -> hasZ (gc.GetGeometryN(0))
| _ -> failwith "Unexpected"
let geom = WKTReader(IsOldNtsCoordinateSyntaxAllowed = false).Read("POINT (0 0)")
let fixed = geom.Buffer(0.0) // removing this line makes `hasZ` false
printfn $"%A{hasZ fixed}" |
HasZ is
|
@DGuidi It fails for this wkt: Details
Another operation that causes it to have Z dimension (just NaNs):
|
nope, it works. at least with latest main. var reader = new WKTReader()
{
IsOldNtsCoordinateSyntaxAllowed = false
};
const string wkt = "MULTIPOLYGON(((138.4012 -35.638,138.3996 -35.6404,138.3802 -35.6389,138.3732 -35.6397,138.3678 -35.6423,138.3547 -35.6398,138.2847 -35.6389,138.2651 -35.6413,138.258 -35.6482,138.254 -35.6503,138.2529 -35.6493,138.2474 -35.6539,138.2448 -35.6532,138.2434 -35.6554,138.2403 -35.6545,138.232 -35.6597,138.227 -35.6607,138.2264 -35.6594,138.2208 -35.6624,138.2159 -35.661,138.2066 -35.664,138.2004 -35.6631,138.1948 -35.6653,138.1928 -35.6642,138.185 -35.6649,138.1793 -35.6625,138.1767 -35.6638,138.1714 -35.6607,138.1626 -35.6608,138.1562 -35.6582,138.1549 -35.6544,138.149 -35.655,138.1439 -35.6526,138.1424 -35.6494,138.1356 -35.6472,138.1358 -35.6453,138.1309 -35.6463,138.1274 -35.6445,138.1251 -35.6409,138.1179 -35.6377,138.1147 -35.6328,138.1065 -35.633,138.1 -35.6296,138.0949 -35.6238,138.0957 -35.6162,138.0946 -35.6155,138.0958 -35.6138,138.0935 -35.6024,138.0952 -35.5997,138.1055 -35.5949,138.1115 -35.5872,138.1147 -35.5816,138.1141 -35.5783,138.1199 -35.5693,138.1196 -35.5667,138.1212 -35.5659,138.1226 -35.5611,138.1271 -35.5569,138.1263 -35.5558,138.1505 -35.5364,138.151 -35.5331,138.1578 -35.5302,138.1639 -35.5234,138.165 -35.5197,138.1686 -35.5183,138.1769 -35.5196,138.1884 -35.524,138.2121 -35.5134,138.2149 -35.5111,138.2143 -35.5099,138.218 -35.5113,138.2241 -35.5098,138.2378 -35.5021,138.2442 -35.5013,138.2484 -35.4963,138.2604 -35.4904,138.2766 -35.4782,138.2754 -35.4817,138.2806 -35.4739,138.2919 -35.47,138.29 -35.4695,138.2941 -35.4674,138.295 -35.4641,138.2975 -35.4625,138.3034 -35.4503,138.3185 -35.4287,138.3229 -35.4194,138.3257 -35.4173,138.3279 -35.4092,138.3414 -35.3928,138.3591 -35.3827,138.3624 -35.3781,138.3658 -35.378,138.3809 -35.371,138.3861 -35.3723,138.3932 -35.3677,138.4103 -35.3661,138.4305 -35.3533,138.4398 -35.3513,138.4424 -35.3452,138.4409 -35.3435,138.4458 -35.3368,138.447 -35.3193,138.4437 -35.2903,138.4416 -35.2849,138.4409 -35.2858,138.4391 -35.284,138.4401 -35.2827,138.4419 -35.2834,138.4423 -35.2812,138.4393 -35.2764,138.4401 -35.2691,138.4428 -35.2677,138.4521 -35.2678,138.4603 -35.2602,138.4609 -35.2478,138.4817 -35.2463,138.4609 -35.2471,138.4611 -35.245,138.4672 -35.2449,138.4695 -35.2406,138.4692 -35.2283,138.4672 -35.2215,138.4797 -35.2203,138.4677 -35.2211,138.4668 -35.2185,138.4705 -35.2118,138.4688 -35.194,138.4903 -35.1907,138.5158 -35.1894,138.5147 -35.1748,138.5204 -35.1732,138.52 -35.1688,138.5301 -35.1683,138.5296 -35.1654,138.5345 -35.1636,138.5356 -35.1612,138.5477 -35.1641,138.5522 -35.1588,138.5571 -35.1615,138.5651 -35.1615,138.5661 -35.1585,138.5727 -35.1574,138.5794 -35.1606,138.5797 -35.1559,138.5824 -35.1559,138.5834 -35.152,138.5868 -35.1524,138.5886 -35.1498,138.586 -35.1479,138.5866 -35.1466,138.5957 -35.1451,138.6026 -35.15,138.6056 -35.148,138.6115 -35.1501,138.6182 -35.1577,138.6234 -35.1585,138.6264 -35.1619,138.6319 -35.1638,138.6295 -35.1649,138.6264 -35.1703,138.6175 -35.1763,138.6177 -35.1794,138.6243 -35.1837,138.6342 -35.1832,138.6379 -35.1758,138.6379 -35.1664,138.7188 -35.1664,138.7188 -35.2414,138.7218 -35.2414,138.7206 -35.2427,138.7272 -35.2465,138.7249 -35.2529,138.7221 -35.2542,138.7486 -35.2564,138.7491 -35.253,138.7438 -35.2516,138.7451 -35.2511,138.7459 -35.2453,138.7462 -35.2298,138.7516 -35.2224,138.7567 -35.2203,138.7536 -35.2136,138.7581 -35.2107,138.7659 -35.2114,138.7662 -35.209,138.7754 -35.2099,138.774 -35.2197,138.7723 -35.2222,138.7738 -35.2214,138.7772 -35.2263,138.7851 -35.2286,138.7814 -35.2356,138.7733 -35.2442,138.7728 -35.2471,138.7817 -35.248,138.7836 -35.2504,138.7891 -35.2512,138.7917 -35.2494,138.7936 -35.2526,138.7989 -35.253,138.7972 -35.2505,138.8069 -35.246,138.7997 -35.2454,138.8008 -35.2366,138.8071 -35.239,138.8079 -35.2326,138.812 -35.2297,138.8213 -35.2278,138.8301 -35.2286,138.84 -35.2176,138.8426 -35.2178,138.8401 -35.2146,138.8411 -35.2068,138.8471 -35.2069,138.8481 -35.2042,138.8568 -35.2052,138.8607 -35.2023,138.8596 -35.2016,138.8652 -35.1953,138.8677 -35.1967,138.8692 -35.192,138.872 -35.1899,138.8757 -35.1918,138.8774 -35.1969,138.8842 -35.1938,138.8872 -35.1983,138.8917 -35.1963,138.892 -35.2023,138.8981 -35.1966,138.9035 -35.1942,138.9104 -35.1936,138.9127 -35.2049,138.9201 -35.2086,138.9374 -35.2354,138.9385 -35.2348,138.9433 -35.2411,138.9505 -35.2352,138.9552 -35.2403,138.9892 -35.2262,138.9891 -35.228,138.9919 -35.2304,138.9911 -35.2314,138.9972 -35.2292,139.0035 -35.2412,139.0153 -35.237,139.0232 -35.2523,139.0368 -35.2474,139.0422 -35.2576,139.0947 -35.2575,139.0962 -35.237,139.1115 -35.2341,139.1583 -35.2535,139.1552 -35.3029,139.1521 -35.3039,139.1551 -35.3045,139.1522 -35.353,139.161 -35.3559,139.1583 -35.3578,139.1564 -35.3561,139.1579 -35.3605,139.1551 -35.3635,139.1565 -35.3637,139.1521 -35.366,139.1508 -35.3736,139.1567 -35.3729,139.1436 -35.3763,139.1354 -35.3753,139.1315 -35.3766,139.1349 -35.3765,139.1323 -35.3774,139.1297 -35.3767,139.1098 -35.3821,139.1069 -35.3815,139.1081 -35.382,139.1007 -35.3831,139.1022 -35.3837,139.1012 -35.3849,139.0925 -35.3887,139.0954 -35.387,139.0913 -35.3859,139.089 -35.3884,139.0842 -35.3877,139.0839 -35.3891,139.0765 -35.391,139.0613 -35.3901,139.0356 -35.3917,139.0345 -35.3912,139.0396 -35.3897,139.0285 -35.3906,139.0197 -35.3924,139.0184 -35.3954,139.0132 -35.397,139.0091 -35.3974,139.0081 -35.3952,139.006 -35.3954,139.0007 -35.3987,138.9986 -35.3976,138.993 -35.3985,138.9929 -35.3996,138.9904 -35.3993,138.9914 -35.4004,138.9845 -35.4014,138.9768 -35.4054,138.9773 -35.4067,138.972 -35.4114,138.9732 -35.4143,138.9701 -35.4174,138.9707 -35.4201,138.9662 -35.426,138.9663 -35.4308,138.9655 -35.4285,138.9604 -35.4358,138.9596 -35.4413,138.9575 -35.4423,138.9587 -35.4432,138.9561 -35.444,138.9514 -35.4501,138.9518 -35.4529,138.9547 -35.4556,138.9647 -35.4541,138.9577 -35.4567,138.9549 -35.4606,138.9552 -35.4655,138.9584 -35.4677,138.9578 -35.4735,138.9734 -35.4813,138.9748 -35.4836,138.9809 -35.4819,138.9824 -35.4856,138.9881 -35.4901,138.9991 -35.4885,139.0058 -35.4852,139.0117 -35.4874,139.0121 -35.4898,139.015 -35.492,139.0208 -35.4928,139.0258 -35.4955,139.0275 -35.4944,139.0315 -35.4962,139.0389 -35.4961,139.0476 -35.5018,139.0319 -35.5138,139.0229 -35.5131,139.0163 -35.5155,139.0032 -35.5137,138.9913 -35.5166,138.9892 -35.52,138.981 -35.5182,138.966 -35.5288,138.9663 -35.5413,138.963 -35.5454,138.943 -35.5558,138.9351 -35.5558,138.9315 -35.5624,138.9261 -35.5589,138.9177 -35.5612,138.9077 -35.5564,138.9 -35.5552,138.8989 -35.5507,138.8941 -35.5494,138.8883 -35.5522,138.8881 -35.5554,138.8751 -35.5578,138.8246 -35.5395,138.7731 -35.5242,138.7461 -35.5182,138.7099 -35.5141,138.7005 -35.5182,138.6931 -35.5235,138.6926 -35.5265,138.6957 -35.5272,138.6954 -35.5289,138.6904 -35.5339,138.6883 -35.5327,138.6851 -35.5337,138.6843 -35.5383,138.6789 -35.5367,138.6635 -35.5366,138.6269 -35.5443,138.6323 -35.5443,138.6256 -35.5508,138.6263 -35.5583,138.6192 -35.5579,138.6132 -35.5621,138.6133 -35.5656,138.6097 -35.5702,138.5983 -35.581,138.5993 -35.5826,138.598 -35.5855,138.5992 -35.5845,138.6027 -35.5888,138.6056 -35.5889,138.6057 -35.5927,138.6026 -35.5948,138.5998 -35.5925,138.5844 -35.5993,138.582 -35.6015,138.5822 -35.6055,138.5747 -35.606,138.5651 -35.609,138.5593 -35.6137,138.5556 -35.6193,138.5222 -35.6431,138.5078 -35.637,138.5061 -35.6379,138.5046 -35.6361,138.4945 -35.634,138.4926 -35.6349,138.4924 -35.6334,138.4868 -35.6342,138.4874 -35.6328,138.4834 -35.6334,138.483 -35.6322,138.4792 -35.6348,138.4628 -35.6302,138.4566 -35.6326,138.4491 -35.63,138.4399 -35.631,138.4312 -35.6292,138.421 -35.6335,138.4125 -35.6399,138.4037 -35.6403,138.4012 -35.638)),((138.4903 -35.1907,138.4688 -35.194,138.4665 -35.188,138.4676 -35.1875,138.4649 -35.1846,138.4665 -35.1844,138.467 -35.1821,138.4659 -35.1777,138.4764 -35.1773,138.4766 -35.1809,138.4895 -35.1804,138.4903 -35.1907)))";
var geom = (Polygon)reader.Read(wkt).GetGeometryN(0);
Assert.IsFalse(geom.ExteriorRing.CoordinateSequence.HasZ);
var buff0 = (Polygon)geom.Buffer(0.0);
Assert.IsFalse(buff0.IsEmpty);
Assert.IsFalse(buff0.ExteriorRing.CoordinateSequence.HasZ);
var buff10 = (Polygon)geom.Buffer(10.0);
Assert.IsFalse(buff10.IsEmpty);
Assert.IsFalse(buff10.ExteriorRing.CoordinateSequence.HasZ); |
Ahh, I forgot about that.... As a workaround (namespace imports are missing):
public class ChangeDimensionUtility
{
private static CoordinateSequence ChangeToXY(CoordinateSequence sequence, Geometry geometry)
{
if ((sequence?.Dimension ?? 2) == 2)
return sequence;
var res = geometry.Factory.CoordinateSequenceFactory.Create(sequence.Count, 2, 0);
CoordinateSequences.Copy(sequence, 0, res, 0, sequence.Count);
return res;
}
private static CoordinateSequence ChangeToXYZ(CoordinateSequence sequence, Geometry geometry)
{
if ((sequence?.Dimension ?? 3) == 3 && (sequence?.Measures ?? 0) == 0)
return sequence;
var res = geometry.Factory.CoordinateSequenceFactory.Create(sequence.Count, 3, 0);
CoordinateSequences.Copy(sequence, 0, res, 0, sequence.Count);
return res;
}
private static CoordinateSequence ChangeToXYM(CoordinateSequence sequence, Geometry geometry)
{
if ((sequence?.Dimension ?? 3) == 3 && (sequence?.Measures ?? 1) == 1)
return sequence;
var res = geometry.Factory.CoordinateSequenceFactory.Create(sequence.Count, 3, 1);
CoordinateSequences.Copy(sequence, 0, res, 0, sequence.Count);
return res;
}
public static CoordinateSequence ChangeToXYZM(CoordinateSequence sequence, Geometry geometry)
{
if ((sequence?.Dimension ?? 4) == 4 && (sequence?.Measures ?? 1) == 1)
return sequence;
var res = geometry.Factory.CoordinateSequenceFactory.Create(sequence.Count, 4, 1);
CoordinateSequences.Copy(sequence, 0, res, 0, sequence.Count);
return res;
}
public static T ChangeDimension<T>(T geometry, Ordinates ordinates) where T: Geometry
{
if (geometry == null)
return null;
Func<CoordinateSequence, Geometry, CoordinateSequence> fn = null;
switch (ordinates)
{
case Ordinates.XY:
fn = ChangeToXY;
break;
case Ordinates.XYZ:
fn = ChangeToXYZ;
break;
case Ordinates.XYM:
fn = ChangeToXYM;
break;
case Ordinates.XYZM:
fn = ChangeToXYZM;
break;
default:
throw new ArgumentOutOfRangeException(nameof(ordinates));
}
var ge = new GeometryEditor(geometry.Factory) { CopyUserData = true };
var op = new GeometryEditor.CoordinateSequenceOperation(fn);
return (T)ge.Edit(geometry, op);
}
} |
Wonder if the easiest fix in the future would be to revert those lines, i.e also check for NaN in the PostGisWriter? |
I believe that I'm seeing the same behavior, Creating a polygon like this:
Outputs the following:
But subsequently INSERTING it into a database creates a column with the following:
I've worked around it by doing the following:
but that seems very awkward. This is with version 7.0.6. Any chance on this being addressed? |
As workaround I forced the usage of NetTopologySuite.IO.PostGis 2.0.0
|
@FObermaier I'm one of the Npgsql maintainers. We're using PostGisReader and PostGisWriter to implement our serialization. How would we prevent these NaNs from ending up in the database? |
@NinoFloris are you able to set I'm not able to reproduce any of the alledgedly not working examples in this thread. |
At most we know the datatypename that a user wants to send a db parameter as. We do expose some config options for the NTS plugin https://github.com/npgsql/npgsql/blob/e8f20a0f74c26dd59b2e02e2bf1889afc231246d/src/Npgsql.NetTopologySuite/NpgsqlNetTopologySuiteExtensions.cs#L23. It seems like that might be too coarse if users have multiple columns with different needs though. |
Hi,
the version 2.1.0 introduced this issue: all XY geometries are stored in postgis as XYZ geometries, with NaN value in Z.
Example: I store
POINT(0 0)
using Npgsql and NTS.Using NetTopologySuite.IO.PostGis v2.0.0, postgis'
st_ndims
returns:2
andst_astext
returns:POINT (0 0)
Using NetTopologySuite.IO.PostGis v2.1.0, postgis'
st_ndims
returns:3
andst_astext
returns:POINT Z (0 0 -1.#IND)
-1.#IND
is aNaN
representation in Windows https://stackoverflow.com/a/347940.I'm using:
Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite
5.0.7 (and later)PostgreSQL 11.11, compiled by Visual C++ build 1800, 64-bit
managed in Azure as Single ServerPOSTGIS="2.5.1 r17027" [EXTENSION] PGSQL="110" GEOS="3.7.0-CAPI-1.11.0 3.7.1" PROJ="Rel. 4.9.3, 15 August 2016" GDAL="GDAL 2.2.4, released 2018/03/19 GDAL_DATA not found" LIBXML="2.7.8" LIBJSON="0.12" LIBPROTOBUF="1.2.1" RASTER
How to reproduce the issue:
The above code works in net6.0 with
Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite
5.0.5 (usingNetTopologySuite.IO.PostGis
2.0.0). Using the next version 5.0.7 (usingNetTopologySuite.IO.PostGis
2.1.0) it throws Npgsql.PostgresException with the message23514: new row for relation "test" violates check constraint "enforce_dims"
.The PostGisReader is smart enougth to see the Z coordinate is NaN, returning a 2 dimensional coordinate.
I think the issue has been introduced with the following commit:
ddd394c#diff-b1018343089a37cb228d0c3357039b782d592ad2591204f0d4c6d41089d1ecf8L585
Version 2.1.0 is:
if (sequence.HasZ)
version 2.0.0 was:
if (sequence.HasZ && !double.IsNaN(sequence.GetZ(0)))
The text was updated successfully, but these errors were encountered: