1

I have imported several shapefiles into a Microsoft SQL Server 2017 database When I use the STAsText() function on geography objects I get the following WKT:

SELECT [Adm0GeoBoundaryID]
      ,[Adm0Code]
      ,[Adm0Name]
      ,[Coords].STAsText() as WKT
      ,[CodeISO3166_1A3]
FROM [dbo].[Adm0GeoBoundaries]

This is the output:

MULTIPOLYGON (((-62.979628399999974 17.509175600000155, 
-62.979600899999951 17.509182200000058, 
-62.979600899999888 17.509228199999981, 
-62.979575599999933 17.5093026000002, 
-62.979671999999788 17.509398900000182, 
-62.979789100000083 17.509464600000079, 
....... [cut]......
-62.967030600000029 17.464950999999978, 
-62.966103599999975 17.464639899999998)))

This output is then converted to a GeoJSON to show it on the web.

As you can see the precision of the coordinates is exaggerated as we have 15 decimal places that correspond to precision to the millimeter and we are talking about showing boundaries over a map!

So it's enough to cut to 4 decimal places corresponding to ~1m of precision.

Reference: http://blog.brainsen.com/post/geographical-coordinate-precision

With the Reduce(tolerance) method I can simplify the geometry with the Douglas-Peucker algorithm and that's fine, but it's completely useless to millimetre precision, that in the end results to double my GeoJSON file.

So I'm wondering if there is an easy way to decrease the precision of the decimal places for each coordinate of a certain amount.

I was thinking also to a dirty solution like a RegEx on the WKT...

2 Answers 2

1

Use the ogr2ogr utility to convert from WKT (or shapefile) to GeoJSON, using the Layer Creation Option COORDINATE_PRECISION.

For shapefile to GeoJSON you'd use something like:

ogr2ogr -f GeoJSON -t_srs crs:84  output.geojson input.shp -lco:RFC7946=YES -lco:COORDINATE_PRECISION=4

For WKT, I think it should be:

ogr2ogr -f GeoJSON -t_srs crs:84  output.geojson input.csv -lco:RFC7946=YES -lco:COORDINATE_PRECISION=4
0

Here is a C# function that uses RegEx to do that. Note that it doesn't round, it just truncates extra digits:

using System.Text.RegularExpressions;

private string ReduceWKTPrecision(string wkt, int digits)
{
  string PrecisionReducer(Match match)
  {
    if (match.Length > digits + 2)
      return match.Value.Substring(0, digits + 1) + match.Value[match.Value.Length - 1];
    else
      return match.Value;
  }

  var regex = new Regex(@"\.([0-9]+)(\,|\])");
  var evaluator = new MatchEvaluator(PrecisionReducer);
  wkt = regex.Replace(wkt, evaluator);

  return wkt;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.