public ProjCheck( Projection webMercator , string epsg , string projDefDest , Extent extent , double tolerance ) { _ProjWM = webMercator; _Extent = extent; _Tolerance = tolerance; _ProjInfo.EPSG = epsg; _ProjInfo.ProjDef = projDefDest; try { _ProjDest = new Projection( projDefDest ); _ProjInfo.initOk = true; } catch { _InitFailed = true; } }
/// <summary> /// Transform coordinates from one projection system to another /// </summary> /// <param name="src">The source projection</param> /// <param name="dst">The destination projection</param> /// <param name="x">The "X" coordinate values.</param> /// <param name="y">The "Y" coordinate values.</param> /// <exception cref="System.ApplicationException">Thrown when the projection is /// not initialized or the transformation failed. The message will indicate the error. /// </exception> /// <exception cref="System.ArgumentException"> /// May be thrown for any of the following reasons: /// <list type="bullet"> /// <item>The "x" array is null</item> /// <item>The "y" array is null</item> /// <item>The length of the x and y arrays don't match</item> /// </list> /// </exception> public static void Transform(Projection src, Projection dst, double[] x, double[] y) { Projection.Transform(src, dst, x, y, null); }
/// <summary> /// Transform coordinates from one projection system to another /// </summary> /// <param name="dst">The destination projection</param> /// <param name="x">The "X" coordinate values.</param> /// <param name="y">The "Y" coordinate values.</param> /// <param name="z">The "Z" coordinate values.</param> /// <exception cref="System.ApplicationException">Thrown when the projection is /// not initialized or the transformation failed. The message will indicate the error. /// </exception> /// <exception cref="System.ArgumentException"> /// May be thrown for any of the following reasons: /// <list type="bullet"> /// <item>The "x" array is null</item> /// <item>The "y" array is null</item> /// <item>The length of the x, y and z (if not null) arrays don't match</item> /// </list> /// </exception> public void Transform(Projection dst, double[] x, double[] y, double[] z) { Projection.Transform(this, dst, x, y, z); }
/// <summary> /// Transform coordinates from one projection system to another /// </summary> /// <param name="dst">The destination projection</param> /// <param name="x">The "X" coordinate values.</param> /// <param name="y">The "Y" coordinate values.</param> /// <exception cref="System.ApplicationException">Thrown when the projection is /// not initialized or the transformation failed. The message will indicate the error. /// </exception> /// <exception cref="System.ArgumentException"> /// May be thrown for any of the following reasons: /// <list type="bullet"> /// <item>The "x" array is null</item> /// <item>The "y" array is null</item> /// <item>The length of the x and y arrays don't match</item> /// </list> /// </exception> public void Transform(Projection dst, double[] x, double[] y) { this.Transform(dst, x, y, null); }
/// <summary> /// Instance version checks initialization status. /// </summary> private void CheckInitialized() { Projection.CheckInitialized(this); }
protected virtual void Dispose( bool dispose ) { if (!_Disposed) { if (dispose) { if (null != _ProjDest) { _ProjDest.Dispose(); _ProjDest = null; } } _Disposed = true; } }
static void Main( string[] args ) { string inputDir = string.Empty; string csvOut = string.Empty; string targetEpsg = "31287"; bool _ShowUsage = false; //bool _Verbose = false; int decimalPlaces = 6; string decimalsMsg = @"decimal places, optional (default: 6) depending on the chosen output crs it makes sense to limit the number of decimal places. e.g. 6 decimal places don't make sense for crs with [m] units and just necessarly bloat the resulting csv. But it makes sense to have 6 decimal places with EPSG:4326."; var p = new OptionSet() { {"i|input=", "diretory containing extracted CSVs", v=>inputDir=v }, {"o|output=", "output file, optional (default: out.csv)", v=>csvOut=v }, {"e|epsg=", "target epsg code, optional (default: 31287)", v=>targetEpsg=v }, {"d|decimals=", decimalsMsg, v=> {int dp; if(int.TryParse(v,out dp)) {decimalPlaces=dp; } } }, //{"v|verbose", "verbose output, optional", v=>_Verbose=v!=null }, {"u|usage","show this message and exit", v => _ShowUsage = v != null } }; List<string> extra; try { extra = p.Parse( args ); } catch (OptionException e) { Console.WriteLine( e.Message ); Console.WriteLine( "try 'convert-bev-address-data --usage'" ); return; } if (args.Length < 1 || string.IsNullOrWhiteSpace( inputDir ) || _ShowUsage) { ShowUsage( p ); return; } string csvAddress = Path.Combine( inputDir, "ADRESSE.CSV" ); string csvStreet = Path.Combine( inputDir, "STRASSE.CSV" ); string csvGemeinde = Path.Combine( inputDir, "GEMEINDE.CSV" ); string csvOrt = Path.Combine( inputDir, "ORTSCHAFT.CSV" ); if (!filesExist( csvAddress, csvStreet, csvGemeinde )) { return; } if (string.IsNullOrWhiteSpace( csvOut )) { csvOut = Path.Combine( inputDir, "out.csv" ); } else { string outPath = Path.GetFullPath( csvOut ); if (!string.IsNullOrWhiteSpace( outPath ) && !Directory.Exists( outPath )) { Console.Write( "output directory does not exists: {0}", outPath ); } } Projection prjTarget = null; try { prjTarget = new Projection( "+init=epsg:" + targetEpsg ); } catch (Exception ex) { Console.WriteLine( "could not initialize EPSG:" + targetEpsg ); Console.WriteLine( ex.Message ); return; } if (null == targetEpsg) { Console.WriteLine( "could not initialize EPSG:" + targetEpsg ); return; } Console.WriteLine( "output crs, EPSG:" + targetEpsg ); char[] delimiter = ";".ToCharArray(); CultureInfo enUS = new CultureInfo( "en-US" ); enUS.NumberFormat.NumberGroupSeparator = string.Empty; string decimalPlacesTxt = string.Format( "N{0}", decimalPlaces ); Console.WriteLine( "reading street names" ); Dictionary<string, string> streets = new Dictionary<string, string>(); using (TextReader tr = new StreamReader( csvStreet )) { tr.ReadLine(); string line; while (!string.IsNullOrWhiteSpace( line = tr.ReadLine() )) { string[] tokens = line.Split( delimiter ); string skz = tokens[0].Replace( "\"", string.Empty ); string name = tokens[1].Replace( "\"", string.Empty ); streets.Add( skz, name ); } } Console.WriteLine( "reading orte" ); Dictionary<string, string> orte = new Dictionary<string, string>(); using (TextReader tr = new StreamReader( csvOrt )) { tr.ReadLine(); string line; while (!string.IsNullOrWhiteSpace( line = tr.ReadLine() )) { string[] tokens = line.Split( delimiter ); string okz = tokens[1].Replace( "\"", string.Empty ); string name = tokens[2].Replace( "\"", string.Empty ); orte.Add( okz, name ); } } Console.WriteLine( "reading gemeinden" ); Dictionary<string, string> gemeinden = new Dictionary<string, string>(); using (TextReader tr = new StreamReader( csvGemeinde )) { tr.ReadLine(); string line; while (!string.IsNullOrWhiteSpace( line = tr.ReadLine() )) { string[] tokens = line.Split( delimiter ); string gkz = tokens[0].Replace( "\"", string.Empty ); string name = tokens[1].Replace( "\"", string.Empty ); gemeinden.Add( gkz, name ); } } Dictionary<string, Projection> srcProjs = new Dictionary<string, Projection>(); //wrong towgs84 paramters //srcProjs.Add( "31254", new Projection( "+init=epsg:31254" ) ); //srcProjs.Add( "31254", new Projection( "+init=epsg:31254" ) ); //srcProjs.Add( "31254", new Projection( "+init=epsg:31254" ) ); srcProjs.Add( "31254", new Projection( "+proj=tmerc +lat_0=0 +lon_0=10.33333333333333 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m +no_defs" ) ); srcProjs.Add( "31255", new Projection( "+proj=tmerc +lat_0=0 +lon_0=13.33333333333333 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m +no_defs" ) ); srcProjs.Add( "31256", new Projection( "+proj=tmerc +lat_0=0 +lon_0=16.33333333333333 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m +no_defs " ) ); Console.WriteLine( "reading addresses" ); var fileHelper = new FileHelperAsyncEngine<BevAddress>(); long skipCnt = 0; using (fileHelper.BeginReadFile( csvAddress )) { using (TextWriter tw = new StreamWriter( csvOut, false, Encoding.UTF8 )) { tw.WriteLine( "gemeinde;plz;ort;strasse;hnr;x-{0};y-{0}", targetEpsg ); long lineCnter = 1; //start with 1 (skipped header) foreach (var record in fileHelper) { lineCnter++; if (!record.RW.HasValue || !record.HW.HasValue) { skipCnt++; Console.WriteLine( "no coordinates: {0}", recordToString( record, streets ) ); continue; } double[] x = new double[] { record.RW.Value }; double[] y = new double[] { record.HW.Value }; try { srcProjs[record.EPSG].Transform( prjTarget, x, y ); } catch (Exception ex2) { Console.WriteLine( "{1}======ERROR: prj transform failed! line {0}:", lineCnter, Environment.NewLine ); Console.WriteLine( recordToString( record, streets ) ); Console.WriteLine( ex2 ); Console.WriteLine( Environment.NewLine ); continue; } string outline = string.Format( enUS , "{0};{1};{2};{3};{4};{5};{6}" , gemeinden.ContainsKey( record.GKZ ) ? gemeinden[record.GKZ] : string.Empty , record.PLZ , orte.ContainsKey( record.OKZ ) ? orte[record.OKZ] : string.Empty , streets.ContainsKey( record.SKZ ) ? streets[record.SKZ] : string.Empty , constructHouseNumber( record ) , x[0].ToString( decimalPlacesTxt, enUS ) , y[0].ToString( decimalPlacesTxt, enUS ) ); tw.WriteLine( outline ); } } } //clean up Console.WriteLine( "skipped: {0}{1}{0}", Environment.NewLine, skipCnt ); prjTarget.Dispose(); prjTarget = null; srcProjs["31254"].Dispose(); srcProjs["31254"] = null; srcProjs["31255"].Dispose(); srcProjs["31255"] = null; srcProjs["31256"].Dispose(); srcProjs["31256"] = null; }
/// <summary> /// Static version that checks initialization status. /// </summary> /// <param name="p">The projection object</param> private static void CheckInitialized(Projection p) { if (p.prj == IntPtr.Zero) { throw new ApplicationException("Projection not initialized"); } }
static void Main( string[] args ) { Dictionary<string, string> projDefs = new Dictionary<string, string>(); using (TextReader tw = new StreamReader( "epsg" )) { string line; while (!string.IsNullOrEmpty( line = tw.ReadLine() )) { line = line.Trim(); if (line.StartsWith( "#" )) { continue; } int idx1 = line.IndexOf( "<" ); int idx2 = line.IndexOf( ">" ); string epsg = line.Substring( idx1 + 1, idx2 - (idx1 + 1) ); string projDef = line.Substring( idx2 + 1, line.LastIndexOf( "<" ) - (idx2 + 1) ).Trim(); projDefs.Add( epsg, projDef ); } } string projDefWebMerc = projDefs["3857"]; double webMercMax = 20037508; double tolerance = 10; Extent extent = new Extent( -webMercMax , -webMercMax , -webMercMax , webMercMax , webMercMax , webMercMax , webMercMax , -webMercMax ); List<ProjInfo> projInfos = new List<ProjInfo>(); using (Projection prjMercSrc = new Projection( projDefWebMerc )) { foreach (string epsg in projDefs.Keys) { using (ProjCheck check = new ProjCheck( prjMercSrc, epsg, projDefs[epsg], extent, tolerance )) { projInfos.Add( check.DoTest() ); } } } long projs = projInfos.Count(); long allGreen = projInfos.Where( i => i.AllGreen ).Count(); long iniOk = projInfos.Where( i => i.initOk ).Count(); long iniFail = projInfos.Where( i => !i.initOk ).Count(); string[] initFailEpsg = projInfos.Where( i => !i.initOk ).Select( i => i.EPSG ).ToArray(); var transFailLL = projInfos.Where( i => !i.transLLOk ); var transFailUL = projInfos.Where( i => !i.transULOk ); var transFailUR = projInfos.Where( i => !i.transUROk ); var transFailLR = projInfos.Where( i => !i.transLROk ); long transOkLL = projInfos.Count( i => i.transLLOk == true ); long transOkUL = projInfos.Count( i => i.transULOk == true ); long transOkUR = projInfos.Count( i => i.transUROk == true ); long transOkLR = projInfos.Count( i => i.transLROk == true ); long backFailLLx = projInfos.Count( i => !i.backLLxOk ); long backFailLLy = projInfos.Count( i => !i.backLLyOk ); long backFailULx = projInfos.Count( i => !i.backULxOk ); long backFailULy = projInfos.Count( i => !i.backULyOk ); long backFailURx = projInfos.Count( i => !i.backULxOk ); long backFailURy = projInfos.Count( i => !i.backULyOk ); long backFailLRx = projInfos.Count( i => !i.backLRxOk ); long backFailLRy = projInfos.Count( i => !i.backLRyOk ); long backOkLLx = projInfos.Count( i => i.backLLxOk ); long backOkLLy = projInfos.Count( i => i.backLLyOk ); long backOkULx = projInfos.Count( i => i.backULxOk ); long backOkULy = projInfos.Count( i => i.backULyOk ); long backOkURx = projInfos.Count( i => i.backULxOk ); long backOkURy = projInfos.Count( i => i.backULyOk ); long backOkLRx = projInfos.Count( i => i.backLRxOk ); long backOkLRy = projInfos.Count( i => i.backLRyOk ); writeToFile( "trans-failed-LL.txt", transFailLL.Select( i => i.EPSG ).ToArray() ); writeToFile( "trans-failed-UL.txt", transFailUL.Select( i => i.EPSG ).ToArray() ); writeToFile( "trans-failed-UR.txt", transFailUR.Select( i => i.EPSG ).ToArray() ); writeToFile( "trans-failed-LR.txt", transFailLR.Select( i => i.EPSG ).ToArray() ); Console.WriteLine( "backward transformation tolerance: {0}m", tolerance ); Console.WriteLine( "bbox:{0}{1}", Environment.NewLine, extent ); Console.WriteLine( "# of projections tested: {0}", projs ); Console.WriteLine( "[AOK] everything successful: {0}", allGreen ); Console.WriteLine( "[IOK] pj_init successful: {0}", iniOk ); Console.WriteLine( "# of pj_init failed: {0} (EPSG: {1})", iniFail, string.Join( ",", initFailEpsg ) ); Console.WriteLine( "# of failed forward transformations:" ); Console.WriteLine( "LL: {0}", transFailLL.Count() ); Console.WriteLine( "UL: {0}", transFailUL.Count() ); Console.WriteLine( "UR: {0}", transFailUR.Count() ); Console.WriteLine( "LR: {0}", transFailLR.Count() ); Console.WriteLine( "# of successful forward transformations:" ); Console.WriteLine( "[LLF] LL: {0}", transOkLL ); Console.WriteLine( "[ULF] UL: {0}", transOkUL ); Console.WriteLine( "[URF] UR: {0}", transOkUR ); Console.WriteLine( "[LRF] LR: {0}", transOkLR ); Console.WriteLine( "# of failed back transformations within tolerance: {0}", tolerance ); Console.WriteLine( "LLx: {0}", backFailLLx ); Console.WriteLine( "LLy: {0}", backFailLLy ); Console.WriteLine( "ULx: {0}", backFailULx ); Console.WriteLine( "ULy: {0}", backFailULy ); Console.WriteLine( "URx: {0}", backFailURx ); Console.WriteLine( "URy: {0}", backFailURy ); Console.WriteLine( "LRx: {0}", backFailLRx ); Console.WriteLine( "LRy: {0}", backFailLRy ); Console.WriteLine( "# of successful back transformations within tolerace {0}:", tolerance ); Console.WriteLine( "[LLx]: {0}", backOkLLx ); Console.WriteLine( "[LLy]: {0}", backOkLLy ); Console.WriteLine( "[ULx]: {0}", backOkULx ); Console.WriteLine( "[ULy]: {0}", backOkULy ); Console.WriteLine( "[URx]: {0}", backOkURx ); Console.WriteLine( "[URy]: {0}", backOkURy ); Console.WriteLine( "[LRx]: {0}", backOkLRx ); Console.WriteLine( "[LRy]: {0}", backOkLRy ); Console.WriteLine( "=============================================================" ); Console.WriteLine( projInfos[0].Headers() ); foreach (var pi in projInfos) { Console.WriteLine( pi ); } }
// METHODS /// <summary> /// Get a projection object with the underlying /// Lat/Long definition /// </summary> /// <returns>Projection</returns> /// <exception cref="System.ApplicationException">Thrown when the projection is /// not initialized.</exception> /// <exception cref="System.ArgumentException">Thrown when the underlying library /// does not return a valid Lat/Long projection object. This might happen if the /// original projection does not have an underlying Lat/Long coordinate system. /// </exception> public Projection GetLatLong() { this.CheckInitialized(); Projection new_prj = new Projection(); new_prj.prj = Proj.pj_latlong_from_proj(this.prj); if (new_prj.prj == IntPtr.Zero) { string message = GetErrorMessage(GetErrNo()); throw new System.ArgumentException(message); } return new_prj; }
/// <summary> /// Transform coordinates from one projection system to another /// </summary> /// <param name="src">The source projection</param> /// <param name="dst">The destination projection</param> /// <param name="x">The "X" coordinate values.</param> /// <param name="y">The "Y" coordinate values.</param> /// <param name="z">The "Z" coordinate values.</param> /// <exception cref="System.ApplicationException">Thrown when the projection is /// not initialized or the transformation failed. The message will indicate the error. /// </exception> /// <exception cref="System.ArgumentException"> /// May be thrown for any of the following reasons: /// <list type="bullet"> /// <item>The "x" array is null</item> /// <item>The "y" array is null</item> /// <item>The length of the x, y and z (if not null) arrays don't match</item> /// </list> /// </exception> public static void Transform(Projection src, Projection dst, double[] x, double[] y, double[] z) { Projection.CheckInitialized(src); Projection.CheckInitialized(dst); if (x == null) { throw new ArgumentException("Argument is required", "x"); } if (y == null) { throw new ArgumentException("Argument is required", "y"); } if (x.Length != y.Length || (z != null && z.Length != x.Length)) { throw new ArgumentException("Coordinate arrays must have the same length"); } if (src.IsLatLong) { for (int i = 0; i < x.Length; i++) { x[i] *= Proj.DEG_TO_RAD; y[i] *= Proj.DEG_TO_RAD; } } int result = Proj.pj_transform(src.prj, dst.prj, x.Length, 1, x, y, z); if (result != 0) { string message = "Tranformation Error"; int errno = GetErrNo(); if (errno != 0) message = Projection.GetErrorMessage(errno); throw new ApplicationException(message); } if (dst.IsLatLong) { for (int i = 0; i < x.Length; i++) { x[i] *= Proj.RAD_TO_DEG; y[i] *= Proj.RAD_TO_DEG; } } }