2
0

GLS.FileGRD.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. //
  2. // The graphics engine GLScene
  3. //
  4. unit GLS.FileGRD;
  5. (* GRD (Grid Format) text and binary vector file format implementation *)
  6. interface
  7. {$I Stage.Defines.inc}
  8. uses
  9. System.Classes,
  10. System.SysUtils,
  11. Stage.VectorGeometry,
  12. Stage.VectorTypes,
  13. GLS.VectorFileObjects,
  14. GLS.ApplicationFileIO,
  15. GLS.Graph,
  16. Stage.Utils;
  17. type
  18. (* The GRD file represents ascii grid formats in 2D/3D.
  19. This is a format for storing regular grid values as a
  20. matrices of cell centers. The format supports variations and
  21. subformats. This importer works for Sutfer, ArcInfo and GMS formats *)
  22. TGLGRDVectorFile = class(TGLVectorFile)
  23. public
  24. GLHeightField: TGLHeightField;
  25. Nodes: array of TSingleArray;
  26. class function Capabilities: TGLDataFileCapabilities; override;
  27. procedure LoadFromStream(aStream: TStream); override;
  28. private
  29. StrVal: String;
  30. StrLine: String;
  31. MaxZ: Single;
  32. function ExtractWord(N: Integer; const S: string;
  33. const WordDelims: TSysCharSet): string;
  34. function WordPosition(const N: Integer; const S: string;
  35. const WordDelims: TSysCharSet): Integer;
  36. end;
  37. // ------------------------------------------------------------------
  38. implementation
  39. // ------------------------------------------------------------------
  40. // ------------------
  41. // ------------------ TGLGRDVectorFile ------------------
  42. // ------------------
  43. const
  44. dSURFBLANKVAL = 1.70141E38; // default value in Surfer for blanking
  45. NODATA_value = -9999; // default value in GIS ArcInfo for blanking
  46. class function TGLGRDVectorFile.Capabilities: TGLDataFileCapabilities;
  47. begin
  48. Result := [dfcRead];
  49. end;
  50. function TGLGRDVectorFile.WordPosition(const N: Integer; const S: string;
  51. const WordDelims: TSysCharSet): Integer;
  52. var
  53. Count, I: Integer;
  54. begin
  55. Count := 0;
  56. I := 1;
  57. Result := 0;
  58. while ((I <= Length(S)) and (Count <> N)) do
  59. begin
  60. // skip over delimiters
  61. while (I <= Length(S)) and CharInSet(S[I], WordDelims) do
  62. Inc(I);
  63. // if we're not beyond end of S, we're at the start of a word
  64. if I <= Length(S) then
  65. Inc(Count);
  66. // if not finished, find the end of the current word
  67. if Count <> N then
  68. while (I <= Length(S)) and not CharInSet(S[I], WordDelims) do
  69. Inc(I)
  70. else
  71. Result := I;
  72. end;
  73. end;
  74. function TGLGRDVectorFile.ExtractWord(N: Integer; const S: string;
  75. const WordDelims: TSysCharSet): string;
  76. var
  77. I, Len: Integer;
  78. begin
  79. Len := 0;
  80. I := WordPosition(N, S, WordDelims);
  81. if (I <> 0) then
  82. // find the end of the current word
  83. while (I <= Length(S)) and not CharInSet(S[I], WordDelims) do
  84. begin
  85. // add the I'th character to result
  86. Inc(Len);
  87. SetLength(Result, Len);
  88. Result[Len] := S[I];
  89. Inc(I);
  90. end;
  91. SetLength(Result, Len);
  92. end;
  93. procedure TGLGRDVectorFile.LoadFromStream(aStream: TStream);
  94. var
  95. I, J, K: Integer;
  96. N: Integer; // N => counter to increment through file
  97. SL, TL: TStringList;
  98. Nx, Ny: Integer;
  99. Dx, Dy: Single;
  100. Xo, Xe, Yo, Ye, Zo, Ze: Single;
  101. NBlanks: Integer; // Number of blank nodes
  102. BlankVal, NoData: Double;
  103. function ReadLine: string;
  104. begin
  105. Result := SL[N];
  106. Inc(N);
  107. end;
  108. begin
  109. SL := TStringList.Create;
  110. TL := TStringList.Create;
  111. try
  112. SL.LoadFromStream(aStream);
  113. if (Copy(SL[0], 1, 4) <> 'DSAA') and (Copy(SL[0], 1, 5) <> 'ncols') then
  114. begin
  115. raise Exception.Create('Not a valid grd file !');
  116. Exit;
  117. end;
  118. GLHeightField := TGLHeightField.Create(Owner);
  119. Zo := 3 * 10E38; // Low
  120. Ze := -3 * 10E38; // High
  121. TL.DelimitedText := Copy(ReadLine, 1, 4);
  122. if (TL[0] = 'DSAA') then // Surfer ASCII grid
  123. begin
  124. TL.DelimitedText := ReadLine;
  125. Nx := StrToInt(Tl[0]);
  126. Ny := StrToInt(Tl[1]);
  127. TL.DelimitedText := ReadLine;
  128. Xo := GLStrToFloatDef(Tl[0]);
  129. Xe := GLStrToFloatDef(Tl[1]);
  130. TL.DelimitedText := ReadLine;
  131. Yo := GLStrToFloatDef(Tl[0]);
  132. Ye := GLStrToFloatDef(Tl[1]);
  133. TL.DelimitedText := ReadLine;
  134. Zo := GLStrToFloatDef(Tl[0]);
  135. Ze := GLStrToFloatDef(Tl[1]);
  136. Dx := (Xe - Xo) / Nx;
  137. Dy := (Ye - Yo) / Ny;
  138. SetLength(Nodes, Ny, Nx);
  139. NBlanks := 0;
  140. BlankVal := dSURFBLANKVAL;
  141. NoData := BlankVal; // NoData value
  142. // loop over the Ny-1 Rows
  143. for I := 0 to Ny - 1 do
  144. begin
  145. J := 0;
  146. // reading lines until Nx-1 Cols entries have been obtained
  147. while J <= Nx - 1 do
  148. begin
  149. StrLine := ReadLine;
  150. K := 1;
  151. StrVal := ExtractWord(K, StrLine, [' ']);
  152. while (StrVal <> '') do
  153. begin
  154. if (J <= Nx - 1) then
  155. Nodes[I, J] := GLStrToFloatDef(StrVal);
  156. if Nodes[I, J] > MaxZ then
  157. MaxZ := Nodes[I, J];
  158. if (Nodes[I, J] >= BlankVal) then
  159. NBlanks := NBlanks + 1;
  160. Inc(J);
  161. Inc(K);
  162. StrVal := ExtractWord(K, StrLine, [' ']);
  163. end;
  164. if (J > Nx - 1) then
  165. Break;
  166. end;
  167. end
  168. end
  169. else // ArcInfo ASCII grid
  170. begin
  171. TL.DelimitedText := Sl[0];
  172. Ny := StrToInt(TL[1]); // ncols
  173. TL.DelimitedText := SL[1];
  174. Nx := StrToInt(TL[1]); // nrows
  175. TL.DelimitedText := SL[2];
  176. Xo := GLStrToFloatDef(Tl[1]); // xllcorner
  177. TL.DelimitedText := SL[3];
  178. Yo := GLStrToFloatDef(TL[1]); // yllcorner
  179. TL.DelimitedText := Sl[4];
  180. Dx := GLStrToFloatDef(TL[1]);
  181. Dy := Dx; // cellsize
  182. TL.DelimitedText := SL[5];
  183. NoData := GLStrToFloatDef(TL[1]); // NoData value
  184. MaxZ := -3 * 10E38;
  185. SetLength(Nodes, Nx, Ny);
  186. for I := 0 to Nx - 1 do
  187. begin
  188. TL.DelimitedText := SL[I + 6];
  189. for J := 0 to Ny - 1 do
  190. begin
  191. StrVal := TL[J];
  192. Nodes[I, J] := GLStrToFloatDef(StrVal);
  193. if Nodes[I, J] > MaxZ then
  194. MaxZ := Nodes[I, J];
  195. end;
  196. end;
  197. end;
  198. GLHeightField.XSamplingScale.Min := -(Nx div 2);
  199. GLHeightField.XSamplingScale.Max := (Nx div 2);
  200. GLHeightField.YSamplingScale.Min := -(Ny div 2);
  201. GLHeightField.YSamplingScale.Max := (Ny div 2);
  202. finally
  203. TL.Free;
  204. SL.Free;
  205. end;
  206. end;
  207. // ------------------------------------------------------------------
  208. initialization
  209. // ------------------------------------------------------------------
  210. RegisterVectorFileFormat('grd', 'ArcInfo/Surfer grids', TGLGRDVectorFile);
  211. end.