mirror of
				https://github.com/grafana/grafana.git
				synced 2025-02-25 18:55:37 -06:00 
			
		
		
		
	
		
			
	
	
		
			85 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			85 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
|   | import { DataFrame, DataFrameView } from '@grafana/data'; | ||
|  | import { Point } from 'ol/geom'; | ||
|  | import { fromLonLat } from 'ol/proj'; | ||
|  | import { FieldMappingOptions, QueryFormat } from '../../types' | ||
|  | 
 | ||
|  |  /** | ||
|  |    * Function that formats dataframe into a Point[] | ||
|  |    */ | ||
|  | export function dataFrameToPoints(frame: DataFrame, fieldMapping: FieldMappingOptions, queryFormat: QueryFormat): Point[] { | ||
|  | 
 | ||
|  |   let points: Point[] = []; | ||
|  | 
 | ||
|  |   if (frame && frame.length > 0) { | ||
|  | 
 | ||
|  |     // For each data point, create a Point
 | ||
|  |     const view = new DataFrameView(frame); | ||
|  |     view.forEach(row => { | ||
|  | 
 | ||
|  |       let lng; | ||
|  |       let lat; | ||
|  | 
 | ||
|  |       // Coordinate Data
 | ||
|  |       if (queryFormat.locationType === "coordinates") { | ||
|  |         lng = row[fieldMapping.longitudeField]; | ||
|  |         lat = row[fieldMapping.latitudeField]; | ||
|  |       } | ||
|  |       // Geohash Data
 | ||
|  |       else if (queryFormat.locationType === "geohash"){ | ||
|  |         const encodedGeohash = row[fieldMapping.geohashField]; | ||
|  |         const decodedGeohash = decodeGeohash(encodedGeohash); | ||
|  |         lng = decodedGeohash.longitude; | ||
|  |         lat = decodedGeohash.latitude; | ||
|  |       } | ||
|  |       points.push(new Point(fromLonLat([lng,lat]))); | ||
|  |     }); | ||
|  |   } | ||
|  |   return points; | ||
|  | } | ||
|  | 
 | ||
|  |  /** | ||
|  |    * Function that decodes input geohash into latitude and longitude | ||
|  |    */ | ||
|  | function decodeGeohash(geohash: string) { | ||
|  |   if (!geohash || geohash.length === 0) { | ||
|  |     throw new Error('Missing geohash value'); | ||
|  |   } | ||
|  |   const BITS = [16, 8, 4, 2, 1]; | ||
|  |   const BASE32 = '0123456789bcdefghjkmnpqrstuvwxyz'; | ||
|  |   let isEven = true; | ||
|  |   const lat: number[] = []; | ||
|  |   const lon: number[] = []; | ||
|  |   lat[0] = -90.0; | ||
|  |   lat[1] = 90.0; | ||
|  |   lon[0] = -180.0; | ||
|  |   lon[1] = 180.0; | ||
|  |   let base32Decoded: number; | ||
|  | 
 | ||
|  |   geohash.split('').forEach((item: string) => { | ||
|  |     base32Decoded = BASE32.indexOf(item); | ||
|  |     BITS.forEach(mask => { | ||
|  |       if (isEven) { | ||
|  |         refineInterval(lon, base32Decoded, mask); | ||
|  |       }  | ||
|  |       else { | ||
|  |         refineInterval(lat, base32Decoded, mask); | ||
|  |       } | ||
|  |       isEven = !isEven; | ||
|  |     }); | ||
|  |   }); | ||
|  |   const latCenter = (lat[0] + lat[1]) / 2; | ||
|  |   const lonCenter = (lon[0] + lon[1]) / 2; | ||
|  | 
 | ||
|  |   return { latitude: latCenter, longitude: lonCenter }; | ||
|  | } | ||
|  |    | ||
|  | function refineInterval(interval: any[], base32Decoded: number, mask: number) { | ||
|  |   /* tslint:disable no-bitwise*/ | ||
|  |   if (base32Decoded & mask) { | ||
|  |     interval[0] = (interval[0] + interval[1]) / 2; | ||
|  |   }  | ||
|  |   else { | ||
|  |     interval[1] = (interval[0] + interval[1]) / 2; | ||
|  |   } | ||
|  | } |