wkt.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. var D2R = 0.01745329251994329577;
  2. var extend = require('./extend');
  3. function mapit(obj, key, v) {
  4. obj[key] = v.map(function(aa) {
  5. var o = {};
  6. sExpr(aa, o);
  7. return o;
  8. }).reduce(function(a, b) {
  9. return extend(a, b);
  10. }, {});
  11. }
  12. function sExpr(v, obj) {
  13. var key;
  14. if (!Array.isArray(v)) {
  15. obj[v] = true;
  16. return;
  17. }
  18. else {
  19. key = v.shift();
  20. if (key === 'PARAMETER') {
  21. key = v.shift();
  22. }
  23. if (v.length === 1) {
  24. if (Array.isArray(v[0])) {
  25. obj[key] = {};
  26. sExpr(v[0], obj[key]);
  27. }
  28. else {
  29. obj[key] = v[0];
  30. }
  31. }
  32. else if (!v.length) {
  33. obj[key] = true;
  34. }
  35. else if (key === 'TOWGS84') {
  36. obj[key] = v;
  37. }
  38. else {
  39. obj[key] = {};
  40. if (['UNIT', 'PRIMEM', 'VERT_DATUM'].indexOf(key) > -1) {
  41. obj[key] = {
  42. name: v[0].toLowerCase(),
  43. convert: v[1]
  44. };
  45. if (v.length === 3) {
  46. obj[key].auth = v[2];
  47. }
  48. }
  49. else if (key === 'SPHEROID') {
  50. obj[key] = {
  51. name: v[0],
  52. a: v[1],
  53. rf: v[2]
  54. };
  55. if (v.length === 4) {
  56. obj[key].auth = v[3];
  57. }
  58. }
  59. else if (['GEOGCS', 'GEOCCS', 'DATUM', 'VERT_CS', 'COMPD_CS', 'LOCAL_CS', 'FITTED_CS', 'LOCAL_DATUM'].indexOf(key) > -1) {
  60. v[0] = ['name', v[0]];
  61. mapit(obj, key, v);
  62. }
  63. else if (v.every(function(aa) {
  64. return Array.isArray(aa);
  65. })) {
  66. mapit(obj, key, v);
  67. }
  68. else {
  69. sExpr(v, obj[key]);
  70. }
  71. }
  72. }
  73. }
  74. function rename(obj, params) {
  75. var outName = params[0];
  76. var inName = params[1];
  77. if (!(outName in obj) && (inName in obj)) {
  78. obj[outName] = obj[inName];
  79. if (params.length === 3) {
  80. obj[outName] = params[2](obj[outName]);
  81. }
  82. }
  83. }
  84. function d2r(input) {
  85. return input * D2R;
  86. }
  87. function cleanWKT(wkt) {
  88. if (wkt.type === 'GEOGCS') {
  89. wkt.projName = 'longlat';
  90. }
  91. else if (wkt.type === 'LOCAL_CS') {
  92. wkt.projName = 'identity';
  93. wkt.local = true;
  94. }
  95. else {
  96. if (typeof wkt.PROJECTION === "object") {
  97. wkt.projName = Object.keys(wkt.PROJECTION)[0];
  98. }
  99. else {
  100. wkt.projName = wkt.PROJECTION;
  101. }
  102. }
  103. if (wkt.UNIT) {
  104. wkt.units = wkt.UNIT.name.toLowerCase();
  105. if (wkt.units === 'metre') {
  106. wkt.units = 'meter';
  107. }
  108. if (wkt.UNIT.convert) {
  109. wkt.to_meter = parseFloat(wkt.UNIT.convert, 10);
  110. }
  111. }
  112. if (wkt.GEOGCS) {
  113. //if(wkt.GEOGCS.PRIMEM&&wkt.GEOGCS.PRIMEM.convert){
  114. // wkt.from_greenwich=wkt.GEOGCS.PRIMEM.convert*D2R;
  115. //}
  116. if (wkt.GEOGCS.DATUM) {
  117. wkt.datumCode = wkt.GEOGCS.DATUM.name.toLowerCase();
  118. }
  119. else {
  120. wkt.datumCode = wkt.GEOGCS.name.toLowerCase();
  121. }
  122. if (wkt.datumCode.slice(0, 2) === 'd_') {
  123. wkt.datumCode = wkt.datumCode.slice(2);
  124. }
  125. if (wkt.datumCode === 'new_zealand_geodetic_datum_1949' || wkt.datumCode === 'new_zealand_1949') {
  126. wkt.datumCode = 'nzgd49';
  127. }
  128. if (wkt.datumCode === "wgs_1984") {
  129. if (wkt.PROJECTION === 'Mercator_Auxiliary_Sphere') {
  130. wkt.sphere = true;
  131. }
  132. wkt.datumCode = 'wgs84';
  133. }
  134. if (wkt.datumCode.slice(-6) === '_ferro') {
  135. wkt.datumCode = wkt.datumCode.slice(0, - 6);
  136. }
  137. if (wkt.datumCode.slice(-8) === '_jakarta') {
  138. wkt.datumCode = wkt.datumCode.slice(0, - 8);
  139. }
  140. if (~wkt.datumCode.indexOf('belge')) {
  141. wkt.datumCode = "rnb72";
  142. }
  143. if (wkt.GEOGCS.DATUM && wkt.GEOGCS.DATUM.SPHEROID) {
  144. wkt.ellps = wkt.GEOGCS.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\_18/, 'clrk');
  145. if (wkt.ellps.toLowerCase().slice(0, 13) === "international") {
  146. wkt.ellps = 'intl';
  147. }
  148. wkt.a = wkt.GEOGCS.DATUM.SPHEROID.a;
  149. wkt.rf = parseFloat(wkt.GEOGCS.DATUM.SPHEROID.rf, 10);
  150. }
  151. if (~wkt.datumCode.indexOf('osgb_1936')) {
  152. wkt.datumCode = "osgb36";
  153. }
  154. }
  155. if (wkt.b && !isFinite(wkt.b)) {
  156. wkt.b = wkt.a;
  157. }
  158. function toMeter(input) {
  159. var ratio = wkt.to_meter || 1;
  160. return parseFloat(input, 10) * ratio;
  161. }
  162. var renamer = function(a) {
  163. return rename(wkt, a);
  164. };
  165. var list = [
  166. ['standard_parallel_1', 'Standard_Parallel_1'],
  167. ['standard_parallel_2', 'Standard_Parallel_2'],
  168. ['false_easting', 'False_Easting'],
  169. ['false_northing', 'False_Northing'],
  170. ['central_meridian', 'Central_Meridian'],
  171. ['latitude_of_origin', 'Latitude_Of_Origin'],
  172. ['latitude_of_origin', 'Central_Parallel'],
  173. ['scale_factor', 'Scale_Factor'],
  174. ['k0', 'scale_factor'],
  175. ['latitude_of_center', 'Latitude_of_center'],
  176. ['lat0', 'latitude_of_center', d2r],
  177. ['longitude_of_center', 'Longitude_Of_Center'],
  178. ['longc', 'longitude_of_center', d2r],
  179. ['x0', 'false_easting', toMeter],
  180. ['y0', 'false_northing', toMeter],
  181. ['long0', 'central_meridian', d2r],
  182. ['lat0', 'latitude_of_origin', d2r],
  183. ['lat0', 'standard_parallel_1', d2r],
  184. ['lat1', 'standard_parallel_1', d2r],
  185. ['lat2', 'standard_parallel_2', d2r],
  186. ['alpha', 'azimuth', d2r],
  187. ['srsCode', 'name']
  188. ];
  189. list.forEach(renamer);
  190. if (!wkt.long0 && wkt.longc && (wkt.PROJECTION === 'Albers_Conic_Equal_Area' || wkt.PROJECTION === "Lambert_Azimuthal_Equal_Area")) {
  191. wkt.long0 = wkt.longc;
  192. }
  193. }
  194. module.exports = function(wkt, self) {
  195. var lisp = JSON.parse(("," + wkt).replace(/\s*\,\s*([A-Z_0-9]+?)(\[)/g, ',["$1",').slice(1).replace(/\s*\,\s*([A-Z_0-9]+?)\]/g, ',"$1"]').replace(/,\["VERTCS".+/,''));
  196. var type = lisp.shift();
  197. var name = lisp.shift();
  198. lisp.unshift(['name', name]);
  199. lisp.unshift(['type', type]);
  200. lisp.unshift('output');
  201. var obj = {};
  202. sExpr(lisp, obj);
  203. cleanWKT(obj.output);
  204. return extend(self, obj.output);
  205. };