1 module dsurf.io.zmapsaver;
2 
3 import std.stdio;
4 import std.math;
5 
6 import dsurf.cartesian;
7 import dsurf.io.saver;
8 import std.conv;
9 
10 /// Class provides saving cartesian surfaces to Zmap+ file
11 class ZmapSaver : CartesianSurfaceSaver
12 {
13     /// Saves a given surface in a file with a given fileName
14     override void save(CartesianSurface surface, string fileName) {
15         File file = File(fileName, "w");
16         immutable double blank = 1e30;
17         import std.path: baseName;
18         file.writeln("!     dsurf - library for surface handling");
19         file.writeln("!     for D programming language");
20         file.writeln("!     GRID FILE NAME   : ");
21         file.writeln("!     CREATION DATE    : ");
22         file.writeln("!     CREATION TIME    : ");
23         file.writeln("!");
24         file.writeln("@" ~ baseName(fileName) ~ " HEADER, GRID, 5");  
25         // according to https://github.com/OSGeo/gdal/blob/master/gdal/frmts/zmap/zmapdataset.cpp
26         // 5 is a number of values per line but both Petrel and RMS saves 5 but ignores it in actual data
27         // so do we
28 
29         file.write("     " ~ (surface.nx * surface.ny).to!string ~ ", " ~ blank.to!string ~ ", " ~ "," ~ "6, 1\n"); //6 decimals and default 1 (no idea whai it means)
30         file.write(surface.ny.to!string ~ ", " ~ surface.nx.to!string ~ ", ");
31         file.write("     " ~ surface.xOrigin.to!string ~ ", ");
32         file.write((surface.xOrigin + (surface.nx - 1) * surface.dx).to!string ~ ", ");
33         file.write(surface.yOrigin.to!string ~ ", ");
34         file.write((surface.yOrigin + (surface.ny - 1) * surface.dy).to!string ~ "\n");
35         file.writeln("     " ~ "0.00, 0.00, 0.00"); //transform apparently
36         file.writeln("@");    //start of an actual data
37         int n = 0;
38         for (int i = 0; i < surface.nx; i++) {
39             for (int j = surface.ny - 1; j >= 0; j--) {
40                 if (isNaN(surface.z[i][j]))
41                     file.write(blank);
42                 else
43                     file.write(surface.z[i][j]);
44                 n++;
45                 if (n > 5) {
46                     n = 0;
47                     file.write("\n");
48                 }
49                 else {
50                     file.write(" ");
51                 }
52             }
53         }
54     }
55 }