[Maps] add WKT and geohash string support (#34472)
This commit is contained in:
parent
2791becd27
commit
3a3bcfb498
|
@ -334,6 +334,7 @@
|
|||
"vscode-jsonrpc": "^3.6.2",
|
||||
"vscode-languageserver": "^4.2.1",
|
||||
"vscode-languageserver-types": "^3.10.0",
|
||||
"wellknown": "^0.5.0",
|
||||
"xml2js": "^0.4.19",
|
||||
"xregexp": "3.2.0"
|
||||
},
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
import _ from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { parse } from 'wellknown';
|
||||
import { decodeGeoHash } from 'ui/utils/decode_geo_hash';
|
||||
import { DECIMAL_DEGREES_PRECISION, ES_GEO_FIELD_TYPE } from '../common/constants';
|
||||
|
||||
/**
|
||||
|
@ -69,23 +71,22 @@ export function geoPointToGeometry(value, accumulator) {
|
|||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
const commaSplit = value.split(',');
|
||||
if (commaSplit.length === 1) {
|
||||
const errorMessage = i18n.translate('xpack.maps.elasticsearch_geo_utils.geohashIsUnsupportedErrorMessage', {
|
||||
defaultMessage: `Unable to convert to geojson, geohash not supported`
|
||||
});
|
||||
|
||||
throw new Error(errorMessage);
|
||||
const commaSplit = value.split(',');
|
||||
let point;
|
||||
if (commaSplit.length === 1) {
|
||||
const geohash = decodeGeoHash(value);
|
||||
point = pointGeometryFactory(geohash.latitude[2], geohash.longitude[2]);
|
||||
} else {
|
||||
const lat = parseFloat(commaSplit[0]);
|
||||
const lon = parseFloat(commaSplit[1]);
|
||||
point = pointGeometryFactory(lat, lon);
|
||||
}
|
||||
// Geo-point expressed as a string with the format: "lat,lon".
|
||||
const lat = parseFloat(commaSplit[0]);
|
||||
const lon = parseFloat(commaSplit[1]);
|
||||
accumulator.push(pointGeometryFactory(lat, lon));
|
||||
accumulator.push(point);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof value === 'object' && _.has(value, 'lat') && _.has(value, 'lon')) {
|
||||
// Geo-point expressed as an object with the format: { lon, lat }
|
||||
accumulator.push(pointGeometryFactory(value.lat, value.lon));
|
||||
return;
|
||||
}
|
||||
|
@ -103,7 +104,6 @@ export function geoPointToGeometry(value, accumulator) {
|
|||
if (value.length === 2
|
||||
&& typeof value[0] === 'number'
|
||||
&& typeof value[1] === 'number') {
|
||||
// Geo-point expressed as an array with the format: [lon, lat]
|
||||
const lat = value[1];
|
||||
const lon = value[0];
|
||||
accumulator.push(pointGeometryFactory(lat, lon));
|
||||
|
@ -116,26 +116,7 @@ export function geoPointToGeometry(value, accumulator) {
|
|||
}
|
||||
}
|
||||
|
||||
export function geoShapeToGeometry(value, accumulator) {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
// value expressed as an array of values
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
geoShapeToGeometry(value[i], accumulator);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO handle case where value is WKT and convert to geojson
|
||||
if (typeof value === 'string') {
|
||||
const errorMessage = i18n.translate('xpack.maps.elasticsearch_geo_utils.wktIsUnsupportedErrorMessage', {
|
||||
defaultMessage: `Unable to convert WKT to geojson, not supported`,
|
||||
});
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
export function convertESShapeToGeojsonGeometry(value) {
|
||||
|
||||
const geoJson = {
|
||||
type: value.type,
|
||||
|
@ -172,8 +153,51 @@ export function geoShapeToGeometry(value, accumulator) {
|
|||
break;
|
||||
case 'envelope':
|
||||
case 'circle':
|
||||
// TODO handle envelope and circle geometry types which exist in elasticsearch but not in geojson
|
||||
throw new Error(`Unable to convert ${geoJson.type} geometry to geojson, not supported`);
|
||||
const errorMessage = i18n.translate('xpack.maps.elasticsearch_geo_utils.convert.unsupportedGeometryTypeErrorMessage', {
|
||||
defaultMessage: `Unable to convert {geometryType} geometry to geojson, not supported`,
|
||||
values: {
|
||||
geometryType: geoJson.type
|
||||
}
|
||||
});
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
return geoJson;
|
||||
}
|
||||
|
||||
function convertWKTStringToGeojson(value) {
|
||||
try {
|
||||
return parse(value);
|
||||
} catch (e) {
|
||||
const errorMessage = i18n.translate('xpack.maps.elasticsearch_geo_utils.wkt.invalidWKTErrorMessage', {
|
||||
defaultMessage: `Unable to convert {wkt} to geojson. Valid WKT expected.`,
|
||||
values: {
|
||||
wkt: value
|
||||
}
|
||||
});
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function geoShapeToGeometry(value, accumulator) {
|
||||
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
// value expressed as an array of values
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
geoShapeToGeometry(value[i], accumulator);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let geoJson;
|
||||
if (typeof value === 'string') {
|
||||
geoJson = convertWKTStringToGeojson(value);
|
||||
} else {
|
||||
geoJson = convertESShapeToGeojsonGeometry(value);
|
||||
}
|
||||
|
||||
accumulator.push(geoJson);
|
||||
|
|
|
@ -59,6 +59,7 @@ describe('hitsToGeoJson', () => {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
it('Should handle documents where geoField is not populated', () => {
|
||||
const hits = [
|
||||
{
|
||||
|
@ -244,6 +245,15 @@ describe('geoPointToGeometry', () => {
|
|||
expect(points[0].coordinates).toEqual([lon, lat]);
|
||||
expect(points[1].coordinates).toEqual([lon2, lat2]);
|
||||
});
|
||||
|
||||
it('Should handle point as geohash string', () => {
|
||||
const geohashValue = 'drm3btev3e86';
|
||||
const points = [];
|
||||
geoPointToGeometry(geohashValue, points);
|
||||
expect(points.length).toBe(1);
|
||||
expect(points[0].coordinates).toEqual([-71.34000012651086, 41.12000000663102]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('geoShapeToGeometry', () => {
|
||||
|
@ -281,6 +291,30 @@ describe('geoShapeToGeometry', () => {
|
|||
expect(shapes[1].type).toBe('Point');
|
||||
expect(shapes[1].coordinates).toEqual(pointCoordinates);
|
||||
});
|
||||
|
||||
|
||||
it('Should convert wkt shapes to geojson', () => {
|
||||
|
||||
const pointWkt = 'POINT (32 40)';
|
||||
const linestringWkt = 'LINESTRING (50 60, 70 80)';
|
||||
|
||||
|
||||
const shapes = [];
|
||||
geoShapeToGeometry(pointWkt, shapes);
|
||||
geoShapeToGeometry(linestringWkt, shapes);
|
||||
|
||||
expect(shapes.length).toBe(2);
|
||||
expect(shapes[0]).toEqual({
|
||||
coordinates: [32, 40],
|
||||
type: 'Point',
|
||||
});
|
||||
expect(shapes[1]).toEqual({
|
||||
coordinates: [[50, 60], [70, 80]],
|
||||
type: 'LineString',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe('createExtentFilter', () => {
|
||||
|
|
19
yarn.lock
19
yarn.lock
|
@ -8152,6 +8152,15 @@ concat-stream@^1.4.7, concat-stream@~1.6.0:
|
|||
readable-stream "^2.2.2"
|
||||
typedarray "^0.0.6"
|
||||
|
||||
concat-stream@~1.5.0:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266"
|
||||
integrity sha1-cIl4Yk2FavQaWnQd790mHadSwmY=
|
||||
dependencies:
|
||||
inherits "~2.0.1"
|
||||
readable-stream "~2.0.0"
|
||||
typedarray "~0.0.5"
|
||||
|
||||
conf@^1.1.2, conf@^1.3.1:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/conf/-/conf-1.4.0.tgz#1ea66c9d7a9b601674a5bb9d2b8dc3c726625e67"
|
||||
|
@ -18242,7 +18251,7 @@ minimist@1.1.x:
|
|||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8"
|
||||
integrity sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=
|
||||
|
||||
minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0:
|
||||
minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
|
||||
|
@ -27867,6 +27876,14 @@ websocket-extensions@>=0.1.1:
|
|||
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
|
||||
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
|
||||
|
||||
wellknown@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/wellknown/-/wellknown-0.5.0.tgz#09ae9871fa826cf0a6ec1537ef00c379d78d7101"
|
||||
integrity sha1-Ca6YcfqCbPCm7BU37wDDedeNcQE=
|
||||
dependencies:
|
||||
concat-stream "~1.5.0"
|
||||
minimist "~1.2.0"
|
||||
|
||||
wgs84@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wgs84/-/wgs84-0.0.0.tgz#34fdc555917b6e57cf2a282ed043710c049cdc76"
|
||||
|
|
Loading…
Reference in a new issue