utils.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import { Geometry, GeometryCollection, LineString, Point } from 'ol/geom';
  2. import { fromLonLat } from 'ol/proj';
  3. import { ArrayVector, Field, FieldConfig, FieldType } from '@grafana/data';
  4. import { getCenterPoint } from 'app/features/transformers/spatial/utils';
  5. import { Gazetteer } from '../gazetteer/gazetteer';
  6. import { decodeGeohash } from './geohash';
  7. export function pointFieldFromGeohash(geohash: Field<string>): Field<Point> {
  8. return {
  9. name: geohash.name ?? 'Point',
  10. type: FieldType.geo,
  11. values: new ArrayVector<any>(
  12. geohash.values.toArray().map((v) => {
  13. const coords = decodeGeohash(v);
  14. if (coords) {
  15. return new Point(fromLonLat(coords));
  16. }
  17. return undefined;
  18. })
  19. ),
  20. config: hiddenTooltipField,
  21. };
  22. }
  23. export function pointFieldFromLonLat(lon: Field, lat: Field): Field<Point> {
  24. const buffer = new Array<Point>(lon.values.length);
  25. for (let i = 0; i < lon.values.length; i++) {
  26. buffer[i] = new Point(fromLonLat([lon.values.get(i), lat.values.get(i)]));
  27. }
  28. return {
  29. name: 'Point',
  30. type: FieldType.geo,
  31. values: new ArrayVector(buffer),
  32. config: hiddenTooltipField,
  33. };
  34. }
  35. export function getGeoFieldFromGazetteer(gaz: Gazetteer, field: Field<string>): Field<Geometry | undefined> {
  36. const count = field.values.length;
  37. const geo = new Array<Geometry | undefined>(count);
  38. for (let i = 0; i < count; i++) {
  39. geo[i] = gaz.find(field.values.get(i))?.geometry();
  40. }
  41. return {
  42. name: 'Geometry',
  43. type: FieldType.geo,
  44. values: new ArrayVector(geo),
  45. config: hiddenTooltipField,
  46. };
  47. }
  48. export function createGeometryCollection(
  49. src: Field<Geometry | undefined>,
  50. dest: Field<Geometry | undefined>
  51. ): Field<Geometry | undefined> {
  52. const v0 = src.values.toArray();
  53. const v1 = dest.values.toArray();
  54. if (!v0 || !v1) {
  55. throw 'missing src/dest';
  56. }
  57. if (v0.length !== v1.length) {
  58. throw 'Source and destination field lengths do not match';
  59. }
  60. const count = src.values.length!;
  61. const geo = new Array<Geometry | undefined>(count);
  62. for (let i = 0; i < count; i++) {
  63. const a = v0[i];
  64. const b = v1[i];
  65. if (a && b) {
  66. geo[i] = new GeometryCollection([a, b]);
  67. } else if (a) {
  68. geo[i] = a;
  69. } else if (b) {
  70. geo[i] = b;
  71. }
  72. }
  73. return {
  74. name: 'Geometry',
  75. type: FieldType.geo,
  76. values: new ArrayVector(geo),
  77. config: hiddenTooltipField,
  78. };
  79. }
  80. export function createLineBetween(
  81. src: Field<Geometry | undefined>,
  82. dest: Field<Geometry | undefined>
  83. ): Field<Geometry | undefined> {
  84. const v0 = src.values.toArray();
  85. const v1 = dest.values.toArray();
  86. if (!v0 || !v1) {
  87. throw 'missing src/dest';
  88. }
  89. if (v0.length !== v1.length) {
  90. throw 'Source and destination field lengths do not match';
  91. }
  92. const count = src.values.length!;
  93. const geo = new Array<Geometry | undefined>(count);
  94. for (let i = 0; i < count; i++) {
  95. const a = v0[i];
  96. const b = v1[i];
  97. if (a && b) {
  98. geo[i] = new LineString([getCenterPoint(a), getCenterPoint(b)]);
  99. }
  100. }
  101. return {
  102. name: 'Geometry',
  103. type: FieldType.geo,
  104. values: new ArrayVector(geo),
  105. config: hiddenTooltipField,
  106. };
  107. }
  108. const hiddenTooltipField: FieldConfig = Object.freeze({
  109. custom: {
  110. hideFrom: { tooltip: true },
  111. },
  112. });