From 53b9a0481f8094dc8c1d5aa3058ff1960132b16a Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 5 Dec 2019 09:23:16 -0500 Subject: [PATCH 01/27] tmp --- .../legacy/plugins/maps/common/constants.js | 1 + .../maps/public/layers/sources/all_sources.js | 2 + .../layers/sources/tiled_vector_source.js | 52 +++ .../maps/public/layers/tiled_vector_layer.js | 300 ++++++++++++++++++ .../maps/public/selectors/map_selectors.js | 3 + 5 files changed, 358 insertions(+) create mode 100644 x-pack/legacy/plugins/maps/public/layers/sources/tiled_vector_source.js create mode 100644 x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js diff --git a/x-pack/legacy/plugins/maps/common/constants.js b/x-pack/legacy/plugins/maps/common/constants.js index 3b2f887e13c875..2befb15952be23 100644 --- a/x-pack/legacy/plugins/maps/common/constants.js +++ b/x-pack/legacy/plugins/maps/common/constants.js @@ -36,6 +36,7 @@ export function createMapPath(id) { export const LAYER_TYPE = { TILE: 'TILE', VECTOR: 'VECTOR', + TILED_VECTOR: 'TILED_VECTOR', VECTOR_TILE: 'VECTOR_TILE', HEATMAP: 'HEATMAP' }; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js b/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js index 6a518609dd77f9..abd7e90274c928 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js @@ -14,6 +14,7 @@ import { KibanaTilemapSource } from './kibana_tilemap_source'; import { ESGeoGridSource } from './es_geo_grid_source'; import { ESSearchSource } from './es_search_source'; import { ESPewPewSource } from './es_pew_pew_source/es_pew_pew_source'; +import {TiledVectorSource} from "./tiled_vector_source"; export const ALL_SOURCES = [ GeojsonFileSource, @@ -26,4 +27,5 @@ export const ALL_SOURCES = [ KibanaTilemapSource, XYZTMSSource, WMSSource, + TiledVectorSource ]; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/tiled_vector_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/tiled_vector_source.js new file mode 100644 index 00000000000000..c167593c514df0 --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/sources/tiled_vector_source.js @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + + +import { AbstractSource } from './source'; +import {ES_GEO_GRID} from "../../../common/constants"; +import {i18n} from "@kbn/i18n"; +import uuid from "uuid/v4"; +import {GRID_RESOLUTION} from "../grid_resolution"; +import {CreateSourceEditor} from "./es_geo_grid_source/create_source_editor"; +import {UpdateSourceEditor} from "./es_geo_grid_source/update_source_editor"; +import React from "react"; + +export class TiledVectorSource extends AbstractSource { + + static type = 'TiledVectorSource'; + static title = i18n.translate('xpack.maps.source.tiledVectorTitle', { + defaultMessage: 'Tiled vector' + }); + static description = i18n.translate('xpack.maps.source.tiledVectorDescription', { + defaultMessage: 'Tiled vector with url template' + }); + + static icon = 'logoElasticsearch'; + + + static createDescriptor({ urlTemplate }) { + return { + type: TiledVectorSource.type, + id: uuid(), + urlTemplate + }; + } + + static renderEditor({ onPreviewSource, inspectorAdapters }) { + return null; + } + + renderSourceSettingsEditor({ onChange }) { + return null; + } + + async getUrlTemplate() { + const indexName = 'parcels'; + const geometryName = 'geometry'; + return `http://localhost:8080/?x={x}&y={y}&z={z}&index=${indexName}&geometry=${geometryName}`; + + } +} diff --git a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js new file mode 100644 index 00000000000000..800bb857f30515 --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js @@ -0,0 +1,300 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { AbstractLayer } from './layer'; +import { VectorStyle } from './styles/vector/vector_style'; +import { + SOURCE_DATA_ID_ORIGIN, + LAYER_TYPE +} from '../../common/constants'; +import _ from 'lodash'; +import { JoinTooltipProperty } from './tooltips/join_tooltip_property'; +import { DataRequestAbortError } from './util/data_request'; +import { canSkipSourceUpdate } from './util/can_skip_fetch'; +import { assignFeatureIds } from './util/assign_feature_ids'; +import { + getFillFilterExpression, + getLineFilterExpression, + getPointFilterExpression, +} from './util/mb_filter_expressions'; +import { VectorLayer } from './vector_layer'; + +export class TiledVectorLayer extends AbstractLayer { + + static type = LAYER_TYPE.VECTOR_TILE; + + static createDescriptor(options, mapColors) { + const layerDescriptor = super.createDescriptor(options); + layerDescriptor.type = TiledVectorLayer.type; + return layerDescriptor; + } + + constructor(options) { + super(options); + // this._style = new VectorStyle(this._descriptor.style, this._source, this); + } + + destroy() { + if (this._source) { + this._source.destroy(); + } + this._joins.forEach(joinSource => { + joinSource.destroy(); + }); + } + + getLayerTypeIconName() { + return 'vector'; + } + + createDefaultLayer(options, mapColors) { + const layerDescriptor = this._createDefaultLayerDescriptor(options, mapColors); + const style = new VectorStyle(layerDescriptor.style, this); + return new VectorLayer({ + layerDescriptor: layerDescriptor, + source: this, + style + }); + } + + async getSourceName() { + return this._source.getDisplayName(); + } + + async getDateFields() { + return await this._source.getDateFields(); + } + + async _syncSource({ + startLoading, stopLoading, onLoadError, registerCancelCallback, dataFilters + }) { + + const requestToken = Symbol(`layer-source-refresh:${this.getId()} - source`); + // const searchFilters = this._getSearchFilters(dataFilters); + const prevDataRequest = this.getSourceDataRequest(); + + if (prevDataRequest) { + console.log('already has a data request'); + return; + } + + // const canSkipFetch = await canSkipSourceUpdate({ + // source: this._source, + // prevDataRequest, + // nextMeta: searchFilters, + // }); + // if (canSkipFetch) { + // return { + // refreshed: false, + // featureCollection: prevDataRequest.getData() + // }; + // } + + + + try { + // startLoading(SOURCE_DATA_ID_ORIGIN, requestToken, searchFilters); + // const layerName = await this.getDisplayName(); + // await this._source.getGeoJsonWithMeta(layerName, searchFilters, + // registerCancelCallback.bind(null, requestToken) + // ); + + + // stopLoading(SOURCE_DATA_ID_ORIGIN, requestToken, layerFeatureCollection, meta); + } catch (error) { + if (!(error instanceof DataRequestAbortError)) { + onLoadError(SOURCE_DATA_ID_ORIGIN, requestToken, error.message); + } + return { + refreshed: false + }; + } + } + + async syncData(syncContext) { + if (!this.isVisible() || !this.showAtZoomLevel(syncContext.dataFilters.zoom)) { + return; + } + + await this._syncSource(syncContext); + + } + + // _setMbPointsProperties(mbMap) { + // const pointLayerId = this._getMbPointLayerId(); + // const symbolLayerId = this._getMbSymbolLayerId(); + // const pointLayer = mbMap.getLayer(pointLayerId); + // const symbolLayer = mbMap.getLayer(symbolLayerId); + // + // let mbLayerId; + // if (this._style.arePointsSymbolizedAsCircles()) { + // mbLayerId = pointLayerId; + // if (symbolLayer) { + // mbMap.setLayoutProperty(symbolLayerId, 'visibility', 'none'); + // } + // this._setMbCircleProperties(mbMap); + // } else { + // mbLayerId = symbolLayerId; + // if (pointLayer) { + // mbMap.setLayoutProperty(pointLayerId, 'visibility', 'none'); + // } + // this._setMbSymbolProperties(mbMap); + // } + // + // this.syncVisibilityWithMb(mbMap, mbLayerId); + // mbMap.setLayerZoomRange(mbLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); + // } + + // _setMbCircleProperties(mbMap) { + // const sourceId = this.getId(); + // const pointLayerId = this._getMbPointLayerId(); + // const pointLayer = mbMap.getLayer(pointLayerId); + // + // if (!pointLayer) { + // mbMap.addLayer({ + // id: pointLayerId, + // type: 'circle', + // source: sourceId, + // paint: {} + // }); + // } + // + // const filterExpr = getPointFilterExpression(this._hasJoins()); + // if (filterExpr !== mbMap.getFilter(pointLayerId)) { + // mbMap.setFilter(pointLayerId, filterExpr); + // } + // + // this._style.setMBPaintPropertiesForPoints({ + // alpha: this.getAlpha(), + // mbMap, + // pointLayerId: pointLayerId, + // }); + // } + // + // _setMbSymbolProperties(mbMap) { + // const sourceId = this.getId(); + // const symbolLayerId = this._getMbSymbolLayerId(); + // const symbolLayer = mbMap.getLayer(symbolLayerId); + // + // if (!symbolLayer) { + // mbMap.addLayer({ + // id: symbolLayerId, + // type: 'symbol', + // source: sourceId, + // }); + // } + // + // const filterExpr = getPointFilterExpression(this._hasJoins()); + // if (filterExpr !== mbMap.getFilter(symbolLayerId)) { + // mbMap.setFilter(symbolLayerId, filterExpr); + // } + // + // this._style.setMBSymbolPropertiesForPoints({ + // alpha: this.getAlpha(), + // mbMap, + // symbolLayerId: symbolLayerId, + // }); + // } + // + // _setMbLinePolygonProperties(mbMap) { + // const sourceId = this.getId(); + // const fillLayerId = this._getMbPolygonLayerId(); + // const lineLayerId = this._getMbLineLayerId(); + // const hasJoins = this._hasJoins(); + // if (!mbMap.getLayer(fillLayerId)) { + // mbMap.addLayer({ + // id: fillLayerId, + // type: 'fill', + // source: sourceId, + // paint: {} + // }); + // } + // if (!mbMap.getLayer(lineLayerId)) { + // mbMap.addLayer({ + // id: lineLayerId, + // type: 'line', + // source: sourceId, + // paint: {} + // }); + // } + // this._style.setMBPaintProperties({ + // alpha: this.getAlpha(), + // mbMap, + // fillLayerId, + // lineLayerId, + // }); + // + // this.syncVisibilityWithMb(mbMap, fillLayerId); + // mbMap.setLayerZoomRange(fillLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); + // const fillFilterExpr = getFillFilterExpression(hasJoins); + // if (fillFilterExpr !== mbMap.getFilter(fillLayerId)) { + // mbMap.setFilter(fillLayerId, fillFilterExpr); + // } + // + // this.syncVisibilityWithMb(mbMap, lineLayerId); + // mbMap.setLayerZoomRange(lineLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); + // const lineFilterExpr = getLineFilterExpression(hasJoins); + // if (lineFilterExpr !== mbMap.getFilter(lineLayerId)) { + // mbMap.setFilter(lineLayerId, lineFilterExpr); + // } + // } + + _syncStylePropertiesWithMb(mbMap) { + console.log('need to sync style', mbMap); + // this._setMbPointsProperties(mbMap); + // this._setMbLinePolygonProperties(mbMap); + } + + _syncSourceBindingWithMb(mbMap) { + const mbSource = mbMap.getSource(this.getId()); + if (!mbSource) { + console.log('need to sync source'); + // mbMap.addSource(this.getId(), { + // type: 'geojson', + // data: EMPTY_FEATURE_COLLECTION + // }); + } + } + + syncLayerWithMB(mbMap) { + this._syncSourceBindingWithMb(mbMap); + this._syncStylePropertiesWithMb(mbMap); + } + + _getMbPointLayerId() { + return this.makeMbLayerId('circle'); + } + + _getMbSymbolLayerId() { + return this.makeMbLayerId('symbol'); + } + + _getMbLineLayerId() { + return this.makeMbLayerId('line'); + } + + _getMbPolygonLayerId() { + return this.makeMbLayerId('fill'); + } + + getMbLayerIds() { + // return [this._getMbPointLayerId(), this._getMbSymbolLayerId(), this._getMbLineLayerId(), this._getMbPolygonLayerId()]; + return [this._getMbLineLayerId()]; + } + + ownsMbLayerId(mbLayerId) { + return this._getMbPointLayerId() === mbLayerId || + this._getMbLineLayerId() === mbLayerId || + this._getMbPolygonLayerId() === mbLayerId || + this._getMbSymbolLayerId() === mbLayerId; + } + + ownsMbSourceId(mbSourceId) { + return this.getId() === mbSourceId; + } + +} diff --git a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js b/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js index 0b13db994193bf..14e4da000da2ec 100644 --- a/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js +++ b/x-pack/legacy/plugins/maps/public/selectors/map_selectors.js @@ -9,6 +9,7 @@ import _ from 'lodash'; import { TileLayer } from '../layers/tile_layer'; import { VectorTileLayer } from '../layers/vector_tile_layer'; import { VectorLayer } from '../layers/vector_layer'; +import { TiledVectorLayer } from '../layers/tiled_vector_layer'; import { HeatmapLayer } from '../layers/heatmap_layer'; import { ALL_SOURCES } from '../layers/sources/all_sources'; import { timefilter } from 'ui/timefilter'; @@ -27,6 +28,8 @@ function createLayerInstance(layerDescriptor, inspectorAdapters) { return new VectorTileLayer({ layerDescriptor, source }); case HeatmapLayer.type: return new HeatmapLayer({ layerDescriptor, source }); + case TiledVectorLayer.type: + return new TiledVectorLayer({layerDescriptor, source}); default: throw new Error(`Unrecognized layerType ${layerDescriptor.type}`); } From 709cb92857cb1b755b941e8370b7fb5654d1ac6d Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Mon, 27 Jan 2020 17:07:16 -0500 Subject: [PATCH 02/27] more boilerplate --- .../maps/public/layers/sources/all_sources.js | 4 +- .../mvt_vector_source/mvt_vector_source.js | 65 +++++++ .../mvt_vector_source_editor.js | 46 +++++ .../layers/sources/tiled_vector_source.js | 52 ------ .../maps/public/layers/tiled_vector_layer.js | 158 +++++++++--------- 5 files changed, 188 insertions(+), 137 deletions(-) create mode 100644 x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source.js create mode 100644 x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source_editor.js delete mode 100644 x-pack/legacy/plugins/maps/public/layers/sources/tiled_vector_source.js diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js b/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js index abd7e90274c928..86c3283fbd6204 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js @@ -14,9 +14,10 @@ import { KibanaTilemapSource } from './kibana_tilemap_source'; import { ESGeoGridSource } from './es_geo_grid_source'; import { ESSearchSource } from './es_search_source'; import { ESPewPewSource } from './es_pew_pew_source/es_pew_pew_source'; -import {TiledVectorSource} from "./tiled_vector_source"; +import { MVTVectorSource } from './mvt_vector_source/mvt_vector_source'; export const ALL_SOURCES = [ + MVTVectorSource, GeojsonFileSource, ESSearchSource, ESGeoGridSource, @@ -27,5 +28,4 @@ export const ALL_SOURCES = [ KibanaTilemapSource, XYZTMSSource, WMSSource, - TiledVectorSource ]; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source.js new file mode 100644 index 00000000000000..f896e2e2539a73 --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source.js @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { AbstractSource } from '../source'; +import { MVTVectorSourceEditor } from './mvt_vector_source_editor'; +import { i18n } from '@kbn/i18n'; +import uuid from 'uuid/v4'; +import React from 'react'; +import {TileLayer} from "../../tile_layer"; +import {TiledVectorLayer} from "../../tiled_vector_layer"; + +export class MVTVectorSource extends AbstractSource { + static type = 'TiledVectorSource'; + static title = i18n.translate('xpack.maps.source.tiledVectorTitle', { + defaultMessage: 'Tiled vector', + }); + static description = i18n.translate('xpack.maps.source.tiledVectorDescription', { + defaultMessage: 'Tiled vector with url template', + }); + + static icon = 'logoElasticsearch'; + + static createDescriptor({ urlTemplate }) { + return { + type: MVTVectorSource.type, + id: uuid(), + urlTemplate, + }; + } + + static renderEditor({ onPreviewSource, inspectorAdapters }) { + const onSourceConfigChange = sourceConfig => { + const sourceDescriptor = MVTVectorSource.createDescriptor(sourceConfig); + const source = new MVTVectorSource(sourceDescriptor, inspectorAdapters); + onPreviewSource(source); + }; + return ; + } + + renderSourceSettingsEditor({ onChange }) { + return (
No source settings to edit
); + } + + _createDefaultLayerDescriptor(options) { + return TiledVectorLayer.createDescriptor({ + sourceDescriptor: this._descriptor, + ...options, + }); + } + + createDefaultLayer(options) { + return new TiledVectorLayer({ + layerDescriptor: this._createDefaultLayerDescriptor(options), + source: this, + }); + } + + async getUrlTemplate() { + console.log('return templat', this._descriptor.urlTemplate); + return this._descriptor.urlTemplate; + } +} diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source_editor.js b/x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source_editor.js new file mode 100644 index 00000000000000..2daddaaed7b974 --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source_editor.js @@ -0,0 +1,46 @@ +import React, {Fragment} from "react"; +import _ from "lodash"; +import {EuiFieldText, EuiFormRow} from "@elastic/eui"; +import {i18n} from "@kbn/i18n"; + +export class MVTVectorSourceEditor extends React.Component { + state = { + mvtInput: '', + mvtCanPreview: false, + }; + + _sourceConfigChange = _.debounce(updatedSourceConfig => { + if (this.state.mvtCanPreview) { + this.props.onSourceConfigChange(updatedSourceConfig); + } + }, 2000); + + _handleMVTInputChange(e) { + const url = e.target.value; + + const canPreview = + url.indexOf('{x}') >= 0 && url.indexOf('{y}') >= 0 && url.indexOf('{z}') >= 0; + this.setState( + { + mvtInput: url, + mvtCanPreview: canPreview, + }, + () => this._sourceConfigChange({ urlTemplate: url }) + ); + } + + render() { + const example = `http://localhost:8080/?x={x}&y={y}&z={z}&index=ky_roads&geometry=geometry&size=10000&fields=fclass`; + return ( + +
{example}
+ + this._handleMVTInputChange(e)} + /> + +
+ ); + } +} diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/tiled_vector_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/tiled_vector_source.js deleted file mode 100644 index c167593c514df0..00000000000000 --- a/x-pack/legacy/plugins/maps/public/layers/sources/tiled_vector_source.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - - -import { AbstractSource } from './source'; -import {ES_GEO_GRID} from "../../../common/constants"; -import {i18n} from "@kbn/i18n"; -import uuid from "uuid/v4"; -import {GRID_RESOLUTION} from "../grid_resolution"; -import {CreateSourceEditor} from "./es_geo_grid_source/create_source_editor"; -import {UpdateSourceEditor} from "./es_geo_grid_source/update_source_editor"; -import React from "react"; - -export class TiledVectorSource extends AbstractSource { - - static type = 'TiledVectorSource'; - static title = i18n.translate('xpack.maps.source.tiledVectorTitle', { - defaultMessage: 'Tiled vector' - }); - static description = i18n.translate('xpack.maps.source.tiledVectorDescription', { - defaultMessage: 'Tiled vector with url template' - }); - - static icon = 'logoElasticsearch'; - - - static createDescriptor({ urlTemplate }) { - return { - type: TiledVectorSource.type, - id: uuid(), - urlTemplate - }; - } - - static renderEditor({ onPreviewSource, inspectorAdapters }) { - return null; - } - - renderSourceSettingsEditor({ onChange }) { - return null; - } - - async getUrlTemplate() { - const indexName = 'parcels'; - const geometryName = 'geometry'; - return `http://localhost:8080/?x={x}&y={y}&z={z}&index=${indexName}&geometry=${geometryName}`; - - } -} diff --git a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js index 800bb857f30515..8cdff1a86b168b 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js @@ -7,10 +7,7 @@ import React from 'react'; import { AbstractLayer } from './layer'; import { VectorStyle } from './styles/vector/vector_style'; -import { - SOURCE_DATA_ID_ORIGIN, - LAYER_TYPE -} from '../../common/constants'; +import { SOURCE_DATA_ID_ORIGIN, LAYER_TYPE } from '../../common/constants'; import _ from 'lodash'; import { JoinTooltipProperty } from './tooltips/join_tooltip_property'; import { DataRequestAbortError } from './util/data_request'; @@ -24,8 +21,7 @@ import { import { VectorLayer } from './vector_layer'; export class TiledVectorLayer extends AbstractLayer { - - static type = LAYER_TYPE.VECTOR_TILE; + static type = LAYER_TYPE.TILED_VECTOR; static createDescriptor(options, mapColors) { const layerDescriptor = super.createDescriptor(options); @@ -42,9 +38,6 @@ export class TiledVectorLayer extends AbstractLayer { if (this._source) { this._source.destroy(); } - this._joins.forEach(joinSource => { - joinSource.destroy(); - }); } getLayerTypeIconName() { @@ -57,73 +50,29 @@ export class TiledVectorLayer extends AbstractLayer { return new VectorLayer({ layerDescriptor: layerDescriptor, source: this, - style + style, }); } - async getSourceName() { - return this._source.getDisplayName(); - } - - async getDateFields() { - return await this._source.getDateFields(); - } - - async _syncSource({ - startLoading, stopLoading, onLoadError, registerCancelCallback, dataFilters - }) { - - const requestToken = Symbol(`layer-source-refresh:${this.getId()} - source`); - // const searchFilters = this._getSearchFilters(dataFilters); - const prevDataRequest = this.getSourceDataRequest(); - - if (prevDataRequest) { - console.log('already has a data request'); + async syncData({ startLoading, stopLoading, onLoadError, dataFilters }) { + if (!this.isVisible() || !this.showAtZoomLevel(dataFilters.zoom)) { return; } - - // const canSkipFetch = await canSkipSourceUpdate({ - // source: this._source, - // prevDataRequest, - // nextMeta: searchFilters, - // }); - // if (canSkipFetch) { - // return { - // refreshed: false, - // featureCollection: prevDataRequest.getData() - // }; - // } - - - + const sourceDataRequest = this.getSourceDataRequest(); + if (sourceDataRequest) { + //data is immmutable + return; + } + const requestToken = Symbol(`layer-source-refresh:${this.getId()} - source`); + startLoading(SOURCE_DATA_ID_ORIGIN, requestToken, dataFilters); try { - // startLoading(SOURCE_DATA_ID_ORIGIN, requestToken, searchFilters); - // const layerName = await this.getDisplayName(); - // await this._source.getGeoJsonWithMeta(layerName, searchFilters, - // registerCancelCallback.bind(null, requestToken) - // ); - - - // stopLoading(SOURCE_DATA_ID_ORIGIN, requestToken, layerFeatureCollection, meta); + const url = await this._source.getUrlTemplate(); + stopLoading(SOURCE_DATA_ID_ORIGIN, requestToken, url, {}); } catch (error) { - if (!(error instanceof DataRequestAbortError)) { - onLoadError(SOURCE_DATA_ID_ORIGIN, requestToken, error.message); - } - return { - refreshed: false - }; + onLoadError(SOURCE_DATA_ID_ORIGIN, requestToken, error.message); } } - async syncData(syncContext) { - if (!this.isVisible() || !this.showAtZoomLevel(syncContext.dataFilters.zoom)) { - return; - } - - await this._syncSource(syncContext); - - } - // _setMbPointsProperties(mbMap) { // const pointLayerId = this._getMbPointLayerId(); // const symbolLayerId = this._getMbSymbolLayerId(); @@ -261,40 +210,83 @@ export class TiledVectorLayer extends AbstractLayer { } syncLayerWithMB(mbMap) { - this._syncSourceBindingWithMb(mbMap); - this._syncStylePropertiesWithMb(mbMap); + const source = mbMap.getSource(this.getId()); + const mbLayerId = this._getMbLineLayerId(); + + if (!source) { + const sourceDataRequest = this.getSourceDataRequest(); + console.log('sdr', sourceDataRequest); + if (!sourceDataRequest) { + //this is possible if the layer was invisible at startup. + //the actions will not perform any data=syncing as an optimization when a layer is invisible + //when turning the layer back into visible, it's possible the url has not been resovled yet. + return; + } + const url = sourceDataRequest.getData(); + console.log('url', url); + if (!url) { + return; + } + + const sourceId = this.getId(); + mbMap.addSource(sourceId, { + type: 'vector', + tiles: [url], + }); + + console.log('source added'); + + console.log('going to add layer', mbLayerId, sourceId) + mbMap.addLayer({ + id: mbLayerId, + type: 'line', + source: sourceId, + 'source-layer': 'geojsonLayer', + "layout": { + "line-cap": "round", + "line-join": "round" + }, + "paint": { + "line-opacity": 0.6, + "line-color": "rgb(53, 175, 109)", + "line-width": 2 + } + }); + + console.log('layer added'); + } + + this._setTiledVectorLayerProperties(mbMap, mbLayerId); } - _getMbPointLayerId() { - return this.makeMbLayerId('circle'); + _setTiledVectorLayerProperties(mbMap, mbLayerId) { + this.syncVisibilityWithMb(mbMap, mbLayerId); + mbMap.setLayerZoomRange(mbLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); + mbMap.setPaintProperty(mbLayerId, 'line-opacity', this.getAlpha()); } - _getMbSymbolLayerId() { - return this.makeMbLayerId('symbol'); + ownsMbLayerId(mbLayerId) { + return this.getMbLayerIds().includes(mbLayerId); } + // _getMbSymbolLayerId() { + // return this.makeMbLayerId('symbol'); + // } + _getMbLineLayerId() { return this.makeMbLayerId('line'); } - _getMbPolygonLayerId() { - return this.makeMbLayerId('fill'); - } + // _getMbPolygonLayerId() { + // return this.makeMbLayerId('fill'); + // } getMbLayerIds() { // return [this._getMbPointLayerId(), this._getMbSymbolLayerId(), this._getMbLineLayerId(), this._getMbPolygonLayerId()]; return [this._getMbLineLayerId()]; } - ownsMbLayerId(mbLayerId) { - return this._getMbPointLayerId() === mbLayerId || - this._getMbLineLayerId() === mbLayerId || - this._getMbPolygonLayerId() === mbLayerId || - this._getMbSymbolLayerId() === mbLayerId; - } - ownsMbSourceId(mbSourceId) { return this.getId() === mbSourceId; } - } From c630e0d2be50ba44957b529738c026b35d7c45bb Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 28 Jan 2020 15:08:27 -0500 Subject: [PATCH 03/27] more boilerplate --- .../legacy/plugins/maps/common/constants.js | 2 + .../connected_components/map/mb/utils.js | 17 ++ .../connected_components/map/mb/view.js | 41 +++++ .../plugins/maps/server/mvt/get_tile.js | 162 ++++++++++++++++++ .../legacy/plugins/maps/server/mvt_routes.js | 105 ++++++++++++ x-pack/legacy/plugins/maps/server/routes.js | 5 + x-pack/package.json | 2 + 7 files changed, 334 insertions(+) create mode 100644 x-pack/legacy/plugins/maps/server/mvt/get_tile.js create mode 100644 x-pack/legacy/plugins/maps/server/mvt_routes.js diff --git a/x-pack/legacy/plugins/maps/common/constants.js b/x-pack/legacy/plugins/maps/common/constants.js index 080b98a687ae6a..0acc455d90e1e4 100644 --- a/x-pack/legacy/plugins/maps/common/constants.js +++ b/x-pack/legacy/plugins/maps/common/constants.js @@ -27,6 +27,8 @@ export const APP_ID = 'maps'; export const APP_ICON = 'gisApp'; export const TELEMETRY_TYPE = 'maps-telemetry'; +export const MVT_GETTILE_API_PATH = 'mvt/getTile'; + export const MAP_APP_PATH = `app/${APP_ID}`; export const GIS_API_PATH = `api/${APP_ID}`; export const INDEX_SETTINGS_API_PATH = `${GIS_API_PATH}/indexSettings`; diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js index 413d66fce7f70c..9693d0b9e6cb4d 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js @@ -8,6 +8,10 @@ import _ from 'lodash'; import { RGBAImage } from './image_utils'; export function removeOrphanedSourcesAndLayers(mbMap, layerList) { + + // console.log('dont remove orphaned'); + // return; + const mbStyle = mbMap.getStyle(); const mbLayerIdsToRemove = []; @@ -16,11 +20,17 @@ export function removeOrphanedSourcesAndLayers(mbMap, layerList) { return layer.ownsMbLayerId(mbLayer.id); }); if (!layer) { + if (mbLayer.id.startsWith('foobar')){ + console.log('dont remove', mbLayer.id); + return; + } mbLayerIdsToRemove.push(mbLayer.id); } }); mbLayerIdsToRemove.forEach(mbLayerId => mbMap.removeLayer(mbLayerId)); + return; + const mbSourcesToRemove = []; for (const mbSourceId in mbStyle.sources) { if (mbStyle.sources.hasOwnProperty(mbSourceId)) { @@ -28,6 +38,10 @@ export function removeOrphanedSourcesAndLayers(mbMap, layerList) { return layer.ownsMbSourceId(mbSourceId); }); if (!layer) { + if (mbSourceId.startsWith('foobar')){ + console.log('dont remove', mbSourceId); + return; + } mbSourcesToRemove.push(mbSourceId); } } @@ -42,6 +56,9 @@ export function removeOrphanedSourcesAndLayers(mbMap, layerList) { * @param layerList */ export function syncLayerOrderForSingleLayer(mbMap, layerList) { + + return; + if (!layerList || layerList.length === 0) { return; } diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js index cf6085e0c398cb..25716da23d6442 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js @@ -154,7 +154,48 @@ export class MBMapContainer extends React.Component { 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII='; emptyImage.crossOrigin = 'anonymous'; resolve(mbMap); + + + try { + mbMap.addLayer({ + "id": 'foobar_line', + "type": "line", + "source": { + "type": "vector", + // "tiles": ["https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt"], + "tiles": [`http://localhost:5601/jco/api/maps/mvt/getTile?x={x}&y={y}&z={z}&geometryFieldName=geometry&indexPattern=ky_roads&fields=fclass,_id`], + // "tiles": [`http://localhost:8080/?x={x}&y={y}&z={z}&index=ky_roads&geometry=geometry&size=10000&fields=fclass`], + + + // "minzoom": 6, + // "maxzoom": 14 + "tileSize": 512 + }, + "source-layer": "geojsonLayer", + "layout": { + "line-cap": "round", + "line-join": "round" + }, + "paint": { + "line-opacity": 0.6, + // "line-color": "rgb(53, 175, 109)", + "line-color": ["match", ['get', 'fclass'], "residential", "#00FF00", "#FF0000"], + "line-width": 2 + } + }); + }catch(e){ + console.error(e); + } + + + + }); + + + + + }); } diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js new file mode 100644 index 00000000000000..b0ea02d6d60009 --- /dev/null +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -0,0 +1,162 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import geojsonvt from 'geojson-vt'; +import vtpbf from 'vt-pbf'; + +export async function getTile({ + esClient, + server, + indexPattern, + size, + geometryFieldName, + x, + y, + z, + fields = [], +}) { + const polygon = toBoundingBox(x, y, z); + + try { + let result; + try { + const includes = fields.concat([geometryFieldName, '_id']); + const esQuery = { + index: indexPattern, + body: { + size: size, + _source: { + includes: includes, + }, + stored_fields: [geometryFieldName], + query: { + bool: { + must: [], + filter: [ + { + match_all: {}, + }, + { + geo_shape: { + [geometryFieldName]: { + shape: polygon, + relation: 'INTERSECTS', + }, + }, + }, + ], + should: [], + must_not: [], + }, + }, + }, + }; + result = await esClient.search(esQuery); + } catch (e) { + throw e; + } + + server.log('info', `result length ${result.body.hits.hits.length}`); + const feats = result.body.hits.hits.map(hit => { + let geomType; + const geometry = hit._source[geometryFieldName]; + if (geometry.type === 'polygon' || geometry.type === 'Polygon') { + geomType = 'Polygon'; + } else if (geometry.type === 'multipolygon' || geometry.type === 'MultiPolygon') { + geomType = 'MultiPolygon'; + } else if (geometry.type === 'linestring' || geometry.type === 'LineString') { + geomType = 'LineString'; + } else if (geometry.type === 'multilinestring' || geometry.type === 'MultiLineString') { + geomType = 'MultiLineString'; + } else { + return null; + } + const geometryGeoJson = { + type: geomType, + coordinates: geometry.coordinates, + }; + + const properties = { ...hit._source }; + delete properties[geometryFieldName]; + + return { + id: hit._id, + geometry: geometryGeoJson, + properties: properties, + }; + }); + + const ffeats = feats.filter(f => !!f); + + const featureCollection = { + features: ffeats, + type: 'FeatureCollection', + }; + + server.log('info', `feature length ${featureCollection.features.length}`); + + const tileIndex = geojsonvt(featureCollection, { + maxZoom: 14, // max zoom to preserve detail on; can't be higher than 24 + tolerance: 3, // simplification tolerance (higher means simpler) + extent: 4096, // tile extent (both width and height) + buffer: 64, // tile buffer on each side + debug: 0, // logging level (0 to disable, 1 or 2) + lineMetrics: false, // whether to enable line metrics tracking for LineString/MultiLineString features + promoteId: null, // name of a feature property to promote to feature.id. Cannot be used with `generateId` + generateId: false, // whether to generate feature ids. Cannot be used with `promoteId` + indexMaxZoom: 5, // max zoom in the initial tile index + indexMaxPoints: 100000, // max number of points per tile in the index + }); + const tile = tileIndex.getTile(z, x, y); + + if (tile) { + const pbf = vtpbf.fromGeojsonVt({ geojsonLayer: tile }, { version: 2 }); + const buffer = Buffer.from(pbf); + + server.log('info', `bytelength: ${buffer.byteLength}`); + + return buffer; + } else { + return null; + } + } catch (e) { + return null; + } +} + +function toBoundingBox(x, y, z) { + const w_lon = tile2long(x, z); + const s_lat = tile2lat(y + 1, z); + const e_lon = tile2long(x + 1, z); + const n_lat = tile2lat(y, z); + + const polygon = { + type: 'Polygon', + coordinates: [ + [ + [w_lon, s_lat], + [w_lon, n_lat], + [e_lon, n_lat], + [e_lon, s_lat], + [w_lon, s_lat], + ], + ], + }; + + return polygon; +} + +tile2long(0, 1); +tile2lat(1, 20); + +function tile2long(x, z) { + return (x / Math.pow(2, z)) * 360 - 180; +} + +function tile2lat(y, z) { + const n = Math.PI - (2 * Math.PI * y) / Math.pow(2, z); + return (180 / Math.PI) * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n))); +} diff --git a/x-pack/legacy/plugins/maps/server/mvt_routes.js b/x-pack/legacy/plugins/maps/server/mvt_routes.js new file mode 100644 index 00000000000000..459815d125afe9 --- /dev/null +++ b/x-pack/legacy/plugins/maps/server/mvt_routes.js @@ -0,0 +1,105 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EMS_FILES_API_PATH, + EMS_FILES_DEFAULT_JSON_PATH, + GIS_API_PATH, + MVT_GETTILE_API_PATH, +} from '../common/constants'; +import fetch from 'node-fetch'; +import Boom from 'boom'; +import { Client } from '@elastic/elasticsearch'; +import { getTile } from './mvt/get_tile'; + +const ROOT = `/${GIS_API_PATH}`; + +export function initMVTRoutes(server) { + const esClient = new Client({ node: 'http://elastic:changeme@localhost:9200' }); + + server.route({ + method: 'GET', + path: `${ROOT}/${MVT_GETTILE_API_PATH}`, + handler: async (request, h) => { + const { server, query } = request; + // const serverConfig = server.config(); + + server.log('warning', 'hallo'); + + // const esQuery = { + // index: 'kibana_sample_data_logs', + // body: {}, + // }; + // const results = await esClient.search(esQuery); + + const indexPattern = query.indexPattern; + + // http://localhost:8080/?x=133&y=198&z=9&index=ky_roads&geometry=geometry&size=10000&fields=fclass +// http://localhost:8080/?x=270&y=395&z=10&index=ky_roads&geometry=geometry&size=10000&fields=fclass + + + //http://localhost:8080/?x=16&y=25&z=6&index=ky_roads&geometry=geometry&size=10000&fields=fclass + // getTile ky_roads 10000 geometry 16 25 6 [ 'fclass' ] + // includes [ 'fclass', 'geometry', '_id' ] + // esquery { index: 'ky_roads', + // body: + // { size: 10000, + // _source: { includes: [Array] }, + // stored_fields: [ 'geometry' ], + // query: { bool: [Object] } } } + // esquery: 164.953ms + // { _index: 'ky_roads', + // _id: '2pVA1G8B3ZwlEckSf2yE', + // _score: 0, + // _source: + // { fclass: 'residential', + // geometry: { coordinates: [Array], type: 'MultiLineString' } } } + // feature length 2479 + // prep: 3.591ms + // cut: 39.516ms + // bufferize: 9.151ms + // bytelength 20250 + + const x = parseInt(query.x); + const y = parseInt(query.y); + const z = parseInt(query.z); + + // console.log('qd', queryData); + + const geometryFieldName = query.geometryFieldName; + const fields = query.fields ? query.fields.split(',') : []; + const size = parseInt(query.size) || 10000; + + const tile = await getTile({ + server, + esClient, + size, + geometryFieldName, + fields, + x, + y, + z, + indexPattern + }); + + server.log('info', tile); + + if (!tile) { + return null; + } + let response = h.response(tile); + response = response.bytes(tile.length); + response = response.header('Content-Disposition', 'inline'); + response.header('Content-Type', 'application/x-protobuf'); + response = response.encoding('binary'); + + return response; + // return { + // q: request.query, + // }; + }, + }); +} diff --git a/x-pack/legacy/plugins/maps/server/routes.js b/x-pack/legacy/plugins/maps/server/routes.js index 2e5ea299b6f679..626f7778da1542 100644 --- a/x-pack/legacy/plugins/maps/server/routes.js +++ b/x-pack/legacy/plugins/maps/server/routes.js @@ -27,6 +27,7 @@ import { i18n } from '@kbn/i18n'; import { getIndexPatternSettings } from './lib/get_index_pattern_settings'; import Boom from 'boom'; +import { initMVTRoutes } from './mvt_routes'; const ROOT = `/${GIS_API_PATH}`; @@ -65,6 +66,8 @@ export function initRoutes(server, licenseUid) { }; } + initMVTRoutes(server); + server.route({ method: 'GET', path: `${ROOT}/${EMS_FILES_API_PATH}/${EMS_FILES_DEFAULT_JSON_PATH}`, @@ -422,6 +425,8 @@ export function initRoutes(server, licenseUid) { handler: async (request, h) => { const { server, query } = request; + server.log('warning', 'getting index settings'); + if (!query.indexPatternTitle) { server.log('warning', `Required query parameter 'indexPatternTitle' not provided.`); return h.response().code(400); diff --git a/x-pack/package.json b/x-pack/package.json index ad0be351483f61..650eb57478b66d 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -233,6 +233,7 @@ "formsy-react": "^1.1.5", "fp-ts": "^2.3.1", "geojson-rewind": "^0.3.1", + "geojson-vt": "^3.2.1", "get-port": "4.2.0", "getos": "^3.1.0", "git-url-parse": "11.1.2", @@ -345,6 +346,7 @@ "uuid": "3.3.2", "venn.js": "0.2.20", "vscode-languageserver": "^5.2.1", + "vt-pbf": "^3.1.1", "webpack": "4.41.0", "wellknown": "^0.5.0", "xml2js": "^0.4.22", From ff049ff2769c1a09ce506ce7ac011476b3d94230 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 29 Jan 2020 09:43:43 -0500 Subject: [PATCH 04/27] more boilerplate --- .../legacy/plugins/maps/common/constants.js | 2 + .../connected_components/map/mb/utils.js | 16 +-- .../connected_components/map/mb/view.js | 60 ++++----- .../plugins/maps/public/layers/layer.js | 2 +- .../maps/public/layers/sources/all_sources.js | 2 + .../es_mvt_search_source.js | 125 ++++++++++++++++++ .../es_search_source/es_search_source.js | 5 +- .../maps/public/layers/sources/es_source.js | 4 + .../maps/public/layers/sources/source.js | 4 + .../plugins/maps/public/layers/tile_layer.js | 1 + .../maps/public/layers/tiled_vector_layer.js | 32 +++-- .../plugins/maps/server/mvt/get_tile.js | 5 +- 12 files changed, 207 insertions(+), 51 deletions(-) create mode 100644 x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js diff --git a/x-pack/legacy/plugins/maps/common/constants.js b/x-pack/legacy/plugins/maps/common/constants.js index 0acc455d90e1e4..31d61f494b6001 100644 --- a/x-pack/legacy/plugins/maps/common/constants.js +++ b/x-pack/legacy/plugins/maps/common/constants.js @@ -52,11 +52,13 @@ export const SORT_ORDER = { DESC: 'desc', }; +//sources export const EMS_TMS = 'EMS_TMS'; export const EMS_FILE = 'EMS_FILE'; export const ES_GEO_GRID = 'ES_GEO_GRID'; export const ES_SEARCH = 'ES_SEARCH'; export const ES_PEW_PEW = 'ES_PEW_PEW'; +export const ES_MVT_SEARCH = 'ES_MVT_SEARCH'; export const FIELD_ORIGIN = { SOURCE: 'source', diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js index 9693d0b9e6cb4d..5b3c090ab85ce9 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js @@ -20,10 +20,10 @@ export function removeOrphanedSourcesAndLayers(mbMap, layerList) { return layer.ownsMbLayerId(mbLayer.id); }); if (!layer) { - if (mbLayer.id.startsWith('foobar')){ - console.log('dont remove', mbLayer.id); - return; - } + // if (mbLayer.id.startsWith('foobar')){ + // console.log('dont remove', mbLayer.id); + // return; + // } mbLayerIdsToRemove.push(mbLayer.id); } }); @@ -38,10 +38,10 @@ export function removeOrphanedSourcesAndLayers(mbMap, layerList) { return layer.ownsMbSourceId(mbSourceId); }); if (!layer) { - if (mbSourceId.startsWith('foobar')){ - console.log('dont remove', mbSourceId); - return; - } + // if (mbSourceId.startsWith('foobar')){ + // console.log('dont remove', mbSourceId); + // return; + // } mbSourcesToRemove.push(mbSourceId); } } diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js index 25716da23d6442..03096df8ddb37d 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js @@ -156,36 +156,36 @@ export class MBMapContainer extends React.Component { resolve(mbMap); - try { - mbMap.addLayer({ - "id": 'foobar_line', - "type": "line", - "source": { - "type": "vector", - // "tiles": ["https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt"], - "tiles": [`http://localhost:5601/jco/api/maps/mvt/getTile?x={x}&y={y}&z={z}&geometryFieldName=geometry&indexPattern=ky_roads&fields=fclass,_id`], - // "tiles": [`http://localhost:8080/?x={x}&y={y}&z={z}&index=ky_roads&geometry=geometry&size=10000&fields=fclass`], - - - // "minzoom": 6, - // "maxzoom": 14 - "tileSize": 512 - }, - "source-layer": "geojsonLayer", - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "paint": { - "line-opacity": 0.6, - // "line-color": "rgb(53, 175, 109)", - "line-color": ["match", ['get', 'fclass'], "residential", "#00FF00", "#FF0000"], - "line-width": 2 - } - }); - }catch(e){ - console.error(e); - } + // try { + // mbMap.addLayer({ + // "id": 'foobar_line', + // "type": "line", + // "source": { + // "type": "vector", + // // "tiles": ["https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt"], + // "tiles": [`http://localhost:5601/jco/api/maps/mvt/getTile?x={x}&y={y}&z={z}&geometryFieldName=geometry&indexPattern=ky_roads&fields=fclass,_id`], + // // "tiles": [`http://localhost:8080/?x={x}&y={y}&z={z}&index=ky_roads&geometry=geometry&size=10000&fields=fclass`], + // + // + // // "minzoom": 6, + // // "maxzoom": 14 + // "tileSize": 512 + // }, + // "source-layer": "geojsonLayer", + // "layout": { + // "line-cap": "round", + // "line-join": "round" + // }, + // "paint": { + // "line-opacity": 0.6, + // // "line-color": "rgb(53, 175, 109)", + // "line-color": ["match", ['get', 'fclass'], "residential", "#00FF00", "#FF0000"], + // "line-width": 2 + // } + // }); + // }catch(e){ + // console.error(e); + // } diff --git a/x-pack/legacy/plugins/maps/public/layers/layer.js b/x-pack/legacy/plugins/maps/public/layers/layer.js index b76f1ebce15d21..13fa564f7f0344 100644 --- a/x-pack/legacy/plugins/maps/public/layers/layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/layer.js @@ -81,7 +81,7 @@ export class AbstractLayer { } supportsElasticsearchFilters() { - return this._source.isESSource(); + return this._source.supportsESFilters(); } async supportsFitToBounds() { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js b/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js index 86c3283fbd6204..c9a3542c9c170b 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js @@ -15,9 +15,11 @@ import { ESGeoGridSource } from './es_geo_grid_source'; import { ESSearchSource } from './es_search_source'; import { ESPewPewSource } from './es_pew_pew_source/es_pew_pew_source'; import { MVTVectorSource } from './mvt_vector_source/mvt_vector_source'; +import { ESMVTSearchSource } from './es_mvt_search_source/es_mvt_search_source'; export const ALL_SOURCES = [ MVTVectorSource, + ESMVTSearchSource, GeojsonFileSource, ESSearchSource, ESGeoGridSource, diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js new file mode 100644 index 00000000000000..69c6f93eebf997 --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -0,0 +1,125 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ESSearchSource } from '../es_search_source'; +import { + ES_MVT_SEARCH, + ES_SEARCH, + GIS_API_PATH, + MVT_GETTILE_API_PATH, + SORT_ORDER, +} from '../../../../common/constants'; +import { VectorStyle } from '../../styles/vector/vector_style'; +import { TiledVectorLayer } from '../../tiled_vector_layer'; +import uuid from 'uuid/v4'; +import { CreateSourceEditor } from '../es_search_source/create_source_editor'; +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { VectorLayer } from '../../vector_layer'; +import _ from 'lodash'; +import { DEFAULT_FILTER_BY_MAP_BOUNDS } from '../es_search_source/constants'; +import { getDataSourceLabel } from '../../../../common/i18n_getters'; + +export class ESMVTSearchSource extends ESSearchSource { + static type = ES_MVT_SEARCH; + static title = i18n.translate('xpack.maps.source.esMvtSearchTitle', { + defaultMessage: 'Documents as tiles', + }); + static description = i18n.translate('xpack.maps.source.esMvtSearchDescription', { + defaultMessage: 'Vector data from a Kibana index pattern (tiled)', + }); + + static renderEditor({ onPreviewSource, inspectorAdapters }) { + const onSourceConfigChange = sourceConfig => { + if (!sourceConfig) { + onPreviewSource(null); + return; + } + + const source = new ESMVTSearchSource( + { + id: uuid(), + ...sourceConfig, + type: ESMVTSearchSource.type, + }, + inspectorAdapters + ); + + console.log('create esmvt source', source); + onPreviewSource(source); + }; + return ; + } + + async getUrlTemplate() { + console.log('need to get vector template!', this); + + const indexPattern = await this.getIndexPattern(); + const ipTitle = indexPattern.title; + const geometryFieldBame = this._descriptor.geoField; + const fields = ['_id']; + const fieldsParam = fields.join(','); + + return `../${GIS_API_PATH}/${MVT_GETTILE_API_PATH}?x={x}&y={y}&z={z}&geometryFieldName=${geometryFieldBame}&indexPattern=${ipTitle}&fields=${fieldsParam}`; + } + + _createDefaultLayerDescriptor(options) { + const tvl = TiledVectorLayer.createDescriptor({ + sourceDescriptor: this._descriptor, + ...options, + }); + + console.log('create tiledvectorlayer descriptor'); + return tvl; + } + + renderSourceSettingsEditor({ onChange }) { + return
No source settings to edit
; + } + + isFilterByMapBounds() { + return false; + } + + isFilterByMapBoundsConfigurable() { + return false; + } + + isBoundsAware() { + return false; + } + + isFieldAware() { + return false; + } + + isRefreshTimerAware() { + return false; + } + + isQueryAware() { + return false; + } + + isJoinable() { + return false; + } + + supportsESFilters() { + return false; + } + + async getImmutableProperties() { + const ip = await super.getImmutableProperties(); + ip.push({ + label: i18n.translate('xpack.maps.source.esSearch.isMvt', { + defaultMessage: 'Is MBVT?', + }), + value: 'yes is mvt', + }); + return ip; + } +} diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index b8644adddcf7e2..7ad47c3bb1dfa1 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -49,6 +49,7 @@ export class ESSearchSource extends AbstractESSource { { id: uuid(), ...sourceConfig, + type: ESSearchSource.type }, inspectorAdapters ); @@ -58,11 +59,13 @@ export class ESSearchSource extends AbstractESSource { } constructor(descriptor, inspectorAdapters) { + console.log('de', descriptor); + console.log('type', descriptor.type); super( { ...descriptor, id: descriptor.id, - type: ESSearchSource.type, + // type: ESSearchSource.type, indexPatternId: descriptor.indexPatternId, geoField: descriptor.geoField, filterByMapBounds: _.get(descriptor, 'filterByMapBounds', DEFAULT_FILTER_BY_MAP_BOUNDS), diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js index 26cc7ece667539..3797c443d41447 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_source.js @@ -61,6 +61,10 @@ export class AbstractESSource extends AbstractVectorSource { return true; } + supportsESFilters() { + return this.isESSource(); + } + destroy() { this._inspectorAdapters.requests.resetRequest(this.getId()); } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/source.js b/x-pack/legacy/plugins/maps/public/layers/sources/source.js index cc5d62bbdfeefc..85aeba8859b81a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/source.js @@ -126,6 +126,10 @@ export class AbstractSource { return false; } + supportsESFilters() { + return false; + } + // Returns geo_shape indexed_shape context for spatial quering by pre-indexed shapes async getPreIndexedShape(/* properties */) { return null; diff --git a/x-pack/legacy/plugins/maps/public/layers/tile_layer.js b/x-pack/legacy/plugins/maps/public/layers/tile_layer.js index b35adcad976c32..5cb3da94d190e7 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tile_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/tile_layer.js @@ -30,6 +30,7 @@ export class TileLayer extends AbstractLayer { const requestToken = Symbol(`layer-source-refresh:${this.getId()} - source`); startLoading(SOURCE_DATA_ID_ORIGIN, requestToken, dataFilters); try { + console.log('calling', this._source); const url = await this._source.getUrlTemplate(); stopLoading(SOURCE_DATA_ID_ORIGIN, requestToken, url, {}); } catch (error) { diff --git a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js index 8cdff1a86b168b..56948ed52829c0 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js @@ -23,15 +23,28 @@ import { VectorLayer } from './vector_layer'; export class TiledVectorLayer extends AbstractLayer { static type = LAYER_TYPE.TILED_VECTOR; + // static createDescriptor(options, mapColors) { + // const layerDescriptor = super.createDescriptor(options); + // layerDescriptor.type = TiledVectorLayer.type; + // return layerDescriptor; + // } + static createDescriptor(options, mapColors) { const layerDescriptor = super.createDescriptor(options); layerDescriptor.type = TiledVectorLayer.type; + + if (!options.style) { + const styleProperties = VectorStyle.createDefaultStyleProperties(mapColors); + layerDescriptor.style = VectorStyle.createDescriptor(styleProperties); + } + return layerDescriptor; } constructor(options) { super(options); - // this._style = new VectorStyle(this._descriptor.style, this._source, this); + this._style = new VectorStyle(this._descriptor.style, this._source, this); + console.log('created oner with style!', this._style); } destroy() { @@ -44,15 +57,6 @@ export class TiledVectorLayer extends AbstractLayer { return 'vector'; } - createDefaultLayer(options, mapColors) { - const layerDescriptor = this._createDefaultLayerDescriptor(options, mapColors); - const style = new VectorStyle(layerDescriptor.style, this); - return new VectorLayer({ - layerDescriptor: layerDescriptor, - source: this, - style, - }); - } async syncData({ startLoading, stopLoading, onLoadError, dataFilters }) { if (!this.isVisible() || !this.showAtZoomLevel(dataFilters.zoom)) { @@ -63,9 +67,11 @@ export class TiledVectorLayer extends AbstractLayer { //data is immmutable return; } + console.log('need to syncdata'); const requestToken = Symbol(`layer-source-refresh:${this.getId()} - source`); startLoading(SOURCE_DATA_ID_ORIGIN, requestToken, dataFilters); try { + console.log('source!', this._source); const url = await this._source.getUrlTemplate(); stopLoading(SOURCE_DATA_ID_ORIGIN, requestToken, url, {}); } catch (error) { @@ -225,6 +231,7 @@ export class TiledVectorLayer extends AbstractLayer { const url = sourceDataRequest.getData(); console.log('url', url); if (!url) { + console.log('no url!'); return; } @@ -289,4 +296,9 @@ export class TiledVectorLayer extends AbstractLayer { ownsMbSourceId(mbSourceId) { return this.getId() === mbSourceId; } + + getJoins() { + console.log('wtf is this getting called?'); + return []; + } } diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index b0ea02d6d60009..a99bf9ac1f718a 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -18,12 +18,14 @@ export async function getTile({ z, fields = [], }) { + + server.log('info', {indexPattern, size,geometryFieldName,x,y,z,fields}); const polygon = toBoundingBox(x, y, z); try { let result; try { - const includes = fields.concat([geometryFieldName, '_id']); + const includes = fields.concat([geometryFieldName]); const esQuery = { index: indexPattern, body: { @@ -54,6 +56,7 @@ export async function getTile({ }, }, }; + server.log('info', esQuery); result = await esClient.search(esQuery); } catch (e) { throw e; From c6e5a268eb7a929518ecf58cf110abe84bc7a8ad Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 29 Jan 2020 10:47:54 -0500 Subject: [PATCH 05/27] ordering --- .../connected_components/map/mb/utils.js | 17 -- .../maps/public/layers/sources/all_sources.js | 2 +- .../es_mvt_search_source.js | 3 + .../maps/public/layers/tiled_vector_layer.js | 225 ++---------------- .../maps/public/layers/vector_layer.js | 22 +- .../plugins/maps/server/mvt/get_tile.js | 2 +- 6 files changed, 38 insertions(+), 233 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js index 5b3c090ab85ce9..413d66fce7f70c 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/utils.js @@ -8,10 +8,6 @@ import _ from 'lodash'; import { RGBAImage } from './image_utils'; export function removeOrphanedSourcesAndLayers(mbMap, layerList) { - - // console.log('dont remove orphaned'); - // return; - const mbStyle = mbMap.getStyle(); const mbLayerIdsToRemove = []; @@ -20,17 +16,11 @@ export function removeOrphanedSourcesAndLayers(mbMap, layerList) { return layer.ownsMbLayerId(mbLayer.id); }); if (!layer) { - // if (mbLayer.id.startsWith('foobar')){ - // console.log('dont remove', mbLayer.id); - // return; - // } mbLayerIdsToRemove.push(mbLayer.id); } }); mbLayerIdsToRemove.forEach(mbLayerId => mbMap.removeLayer(mbLayerId)); - return; - const mbSourcesToRemove = []; for (const mbSourceId in mbStyle.sources) { if (mbStyle.sources.hasOwnProperty(mbSourceId)) { @@ -38,10 +28,6 @@ export function removeOrphanedSourcesAndLayers(mbMap, layerList) { return layer.ownsMbSourceId(mbSourceId); }); if (!layer) { - // if (mbSourceId.startsWith('foobar')){ - // console.log('dont remove', mbSourceId); - // return; - // } mbSourcesToRemove.push(mbSourceId); } } @@ -56,9 +42,6 @@ export function removeOrphanedSourcesAndLayers(mbMap, layerList) { * @param layerList */ export function syncLayerOrderForSingleLayer(mbMap, layerList) { - - return; - if (!layerList || layerList.length === 0) { return; } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js b/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js index c9a3542c9c170b..5df2010157eb81 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js @@ -18,7 +18,7 @@ import { MVTVectorSource } from './mvt_vector_source/mvt_vector_source'; import { ESMVTSearchSource } from './es_mvt_search_source/es_mvt_search_source'; export const ALL_SOURCES = [ - MVTVectorSource, + // MVTVectorSource, ESMVTSearchSource, GeojsonFileSource, ESSearchSource, diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js index 69c6f93eebf997..33baf5a73c6a15 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -66,6 +66,9 @@ export class ESMVTSearchSource extends ESSearchSource { return `../${GIS_API_PATH}/${MVT_GETTILE_API_PATH}?x={x}&y={y}&z={z}&geometryFieldName=${geometryFieldBame}&indexPattern=${ipTitle}&fields=${fieldsParam}`; } + getMvtSourceLayer() { + return 'geojsonLayer'; + } _createDefaultLayerDescriptor(options) { const tvl = TiledVectorLayer.createDescriptor({ sourceDescriptor: this._descriptor, diff --git a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js index 56948ed52829c0..620c8d2345da3e 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js @@ -5,30 +5,14 @@ */ import React from 'react'; -import { AbstractLayer } from './layer'; import { VectorStyle } from './styles/vector/vector_style'; import { SOURCE_DATA_ID_ORIGIN, LAYER_TYPE } from '../../common/constants'; -import _ from 'lodash'; -import { JoinTooltipProperty } from './tooltips/join_tooltip_property'; -import { DataRequestAbortError } from './util/data_request'; -import { canSkipSourceUpdate } from './util/can_skip_fetch'; -import { assignFeatureIds } from './util/assign_feature_ids'; -import { - getFillFilterExpression, - getLineFilterExpression, - getPointFilterExpression, -} from './util/mb_filter_expressions'; import { VectorLayer } from './vector_layer'; +import {EuiIcon} from "@elastic/eui"; -export class TiledVectorLayer extends AbstractLayer { +export class TiledVectorLayer extends VectorLayer { static type = LAYER_TYPE.TILED_VECTOR; - // static createDescriptor(options, mapColors) { - // const layerDescriptor = super.createDescriptor(options); - // layerDescriptor.type = TiledVectorLayer.type; - // return layerDescriptor; - // } - static createDescriptor(options, mapColors) { const layerDescriptor = super.createDescriptor(options); layerDescriptor.type = TiledVectorLayer.type; @@ -57,8 +41,15 @@ export class TiledVectorLayer extends AbstractLayer { return 'vector'; } + getCustomIconAndTooltipContent() { + console.log('since no feature collection, not sure what to do..'); + return { + icon: , + }; + } async syncData({ startLoading, stopLoading, onLoadError, dataFilters }) { + console.log('tvl syncData'); if (!this.isVisible() || !this.showAtZoomLevel(dataFilters.zoom)) { return; } @@ -79,157 +70,20 @@ export class TiledVectorLayer extends AbstractLayer { } } - // _setMbPointsProperties(mbMap) { - // const pointLayerId = this._getMbPointLayerId(); - // const symbolLayerId = this._getMbSymbolLayerId(); - // const pointLayer = mbMap.getLayer(pointLayerId); - // const symbolLayer = mbMap.getLayer(symbolLayerId); - // - // let mbLayerId; - // if (this._style.arePointsSymbolizedAsCircles()) { - // mbLayerId = pointLayerId; - // if (symbolLayer) { - // mbMap.setLayoutProperty(symbolLayerId, 'visibility', 'none'); - // } - // this._setMbCircleProperties(mbMap); - // } else { - // mbLayerId = symbolLayerId; - // if (pointLayer) { - // mbMap.setLayoutProperty(pointLayerId, 'visibility', 'none'); - // } - // this._setMbSymbolProperties(mbMap); - // } - // - // this.syncVisibilityWithMb(mbMap, mbLayerId); - // mbMap.setLayerZoomRange(mbLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); - // } - - // _setMbCircleProperties(mbMap) { - // const sourceId = this.getId(); - // const pointLayerId = this._getMbPointLayerId(); - // const pointLayer = mbMap.getLayer(pointLayerId); - // - // if (!pointLayer) { - // mbMap.addLayer({ - // id: pointLayerId, - // type: 'circle', - // source: sourceId, - // paint: {} - // }); - // } - // - // const filterExpr = getPointFilterExpression(this._hasJoins()); - // if (filterExpr !== mbMap.getFilter(pointLayerId)) { - // mbMap.setFilter(pointLayerId, filterExpr); - // } - // - // this._style.setMBPaintPropertiesForPoints({ - // alpha: this.getAlpha(), - // mbMap, - // pointLayerId: pointLayerId, - // }); - // } - // - // _setMbSymbolProperties(mbMap) { - // const sourceId = this.getId(); - // const symbolLayerId = this._getMbSymbolLayerId(); - // const symbolLayer = mbMap.getLayer(symbolLayerId); - // - // if (!symbolLayer) { - // mbMap.addLayer({ - // id: symbolLayerId, - // type: 'symbol', - // source: sourceId, - // }); - // } - // - // const filterExpr = getPointFilterExpression(this._hasJoins()); - // if (filterExpr !== mbMap.getFilter(symbolLayerId)) { - // mbMap.setFilter(symbolLayerId, filterExpr); - // } - // - // this._style.setMBSymbolPropertiesForPoints({ - // alpha: this.getAlpha(), - // mbMap, - // symbolLayerId: symbolLayerId, - // }); - // } - // - // _setMbLinePolygonProperties(mbMap) { - // const sourceId = this.getId(); - // const fillLayerId = this._getMbPolygonLayerId(); - // const lineLayerId = this._getMbLineLayerId(); - // const hasJoins = this._hasJoins(); - // if (!mbMap.getLayer(fillLayerId)) { - // mbMap.addLayer({ - // id: fillLayerId, - // type: 'fill', - // source: sourceId, - // paint: {} - // }); - // } - // if (!mbMap.getLayer(lineLayerId)) { - // mbMap.addLayer({ - // id: lineLayerId, - // type: 'line', - // source: sourceId, - // paint: {} - // }); - // } - // this._style.setMBPaintProperties({ - // alpha: this.getAlpha(), - // mbMap, - // fillLayerId, - // lineLayerId, - // }); - // - // this.syncVisibilityWithMb(mbMap, fillLayerId); - // mbMap.setLayerZoomRange(fillLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); - // const fillFilterExpr = getFillFilterExpression(hasJoins); - // if (fillFilterExpr !== mbMap.getFilter(fillLayerId)) { - // mbMap.setFilter(fillLayerId, fillFilterExpr); - // } - // - // this.syncVisibilityWithMb(mbMap, lineLayerId); - // mbMap.setLayerZoomRange(lineLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); - // const lineFilterExpr = getLineFilterExpression(hasJoins); - // if (lineFilterExpr !== mbMap.getFilter(lineLayerId)) { - // mbMap.setFilter(lineLayerId, lineFilterExpr); - // } - // } - - _syncStylePropertiesWithMb(mbMap) { - console.log('need to sync style', mbMap); - // this._setMbPointsProperties(mbMap); - // this._setMbLinePolygonProperties(mbMap); - } - _syncSourceBindingWithMb(mbMap) { + console.log('tbl sync source bingins'); const mbSource = mbMap.getSource(this.getId()); if (!mbSource) { - console.log('need to sync source'); - // mbMap.addSource(this.getId(), { - // type: 'geojson', - // data: EMPTY_FEATURE_COLLECTION - // }); - } - } - - syncLayerWithMB(mbMap) { - const source = mbMap.getSource(this.getId()); - const mbLayerId = this._getMbLineLayerId(); - - if (!source) { const sourceDataRequest = this.getSourceDataRequest(); - console.log('sdr', sourceDataRequest); if (!sourceDataRequest) { //this is possible if the layer was invisible at startup. //the actions will not perform any data=syncing as an optimization when a layer is invisible //when turning the layer back into visible, it's possible the url has not been resovled yet. + console.log('no sdr'); return; } + const url = sourceDataRequest.getData(); - console.log('url', url); if (!url) { console.log('no url!'); return; @@ -240,61 +94,18 @@ export class TiledVectorLayer extends AbstractLayer { type: 'vector', tiles: [url], }); - - console.log('source added'); - - console.log('going to add layer', mbLayerId, sourceId) - mbMap.addLayer({ - id: mbLayerId, - type: 'line', - source: sourceId, - 'source-layer': 'geojsonLayer', - "layout": { - "line-cap": "round", - "line-join": "round" - }, - "paint": { - "line-opacity": 0.6, - "line-color": "rgb(53, 175, 109)", - "line-width": 2 - } - }); - - console.log('layer added'); } - - this._setTiledVectorLayerProperties(mbMap, mbLayerId); - } - - _setTiledVectorLayerProperties(mbMap, mbLayerId) { - this.syncVisibilityWithMb(mbMap, mbLayerId); - mbMap.setLayerZoomRange(mbLayerId, this._descriptor.minZoom, this._descriptor.maxZoom); - mbMap.setPaintProperty(mbLayerId, 'line-opacity', this.getAlpha()); - } - - ownsMbLayerId(mbLayerId) { - return this.getMbLayerIds().includes(mbLayerId); } - // _getMbSymbolLayerId() { - // return this.makeMbLayerId('symbol'); - // } - - _getMbLineLayerId() { - return this.makeMbLayerId('line'); + _syncStylePropertiesWithMb(mbMap) { + // this._setMbPointsProperties(mbMap); + this._setMbLinePolygonProperties(mbMap, {mvtSourceLayer: this._source.getMvtSourceLayer()}); } - // _getMbPolygonLayerId() { - // return this.makeMbLayerId('fill'); - // } - getMbLayerIds() { - // return [this._getMbPointLayerId(), this._getMbSymbolLayerId(), this._getMbLineLayerId(), this._getMbPolygonLayerId()]; - return [this._getMbLineLayerId()]; - } - - ownsMbSourceId(mbSourceId) { - return this.getId() === mbSourceId; + syncLayerWithMB(mbMap) { + this._syncSourceBindingWithMb(mbMap); + this._syncStylePropertiesWithMb(mbMap); } getJoins() { diff --git a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js index 31c3831fb612a6..2c0236e826f139 100644 --- a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js @@ -732,26 +732,34 @@ export class VectorLayer extends AbstractLayer { }); } - _setMbLinePolygonProperties(mbMap) { + _setMbLinePolygonProperties(mbMap, {mvtSourceLayer}) { const sourceId = this.getId(); const fillLayerId = this._getMbPolygonLayerId(); const lineLayerId = this._getMbLineLayerId(); const hasJoins = this._hasJoins(); if (!mbMap.getLayer(fillLayerId)) { - mbMap.addLayer({ + const mbLayer = { id: fillLayerId, type: 'fill', source: sourceId, paint: {}, - }); + }; + if (mvtSourceLayer) { + mbLayer['source-layer'] = mvtSourceLayer; + } + mbMap.addLayer(mbLayer); } if (!mbMap.getLayer(lineLayerId)) { - mbMap.addLayer({ + const mbLayer = { id: lineLayerId, type: 'line', source: sourceId, paint: {}, - }); + } + if (mvtSourceLayer) { + mbLayer['source-layer'] = mvtSourceLayer; + } + mbMap.addLayer(mbLayer); } this._style.setMBPaintProperties({ alpha: this.getAlpha(), @@ -776,8 +784,8 @@ export class VectorLayer extends AbstractLayer { } _syncStylePropertiesWithMb(mbMap) { - this._setMbPointsProperties(mbMap); - this._setMbLinePolygonProperties(mbMap); + this._setMbPointsProperties(mbMap, {}); + this._setMbLinePolygonProperties(mbMap, {}); } _syncSourceBindingWithMb(mbMap) { diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index a99bf9ac1f718a..55caae0e0688d2 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -102,7 +102,7 @@ export async function getTile({ server.log('info', `feature length ${featureCollection.features.length}`); const tileIndex = geojsonvt(featureCollection, { - maxZoom: 14, // max zoom to preserve detail on; can't be higher than 24 + maxZoom: 24, // max zoom to preserve detail on; can't be higher than 24 tolerance: 3, // simplification tolerance (higher means simpler) extent: 4096, // tile extent (both width and height) buffer: 64, // tile buffer on each side From 3e2fd61b161b29b5225f6eb0b2f7c87ec463920d Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 29 Jan 2020 11:53:42 -0500 Subject: [PATCH 06/27] cleanup --- .../es_mvt_search_source.js | 30 +++++++--- .../es_search_source/create_source_editor.js | 4 +- .../maps/public/layers/tiled_vector_layer.js | 28 ++++++---- .../maps/public/layers/vector_layer.js | 56 ++++++++++++------- 4 files changed, 77 insertions(+), 41 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js index 33baf5a73c6a15..87351d24f8afa6 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -7,21 +7,15 @@ import { ESSearchSource } from '../es_search_source'; import { ES_MVT_SEARCH, - ES_SEARCH, GIS_API_PATH, MVT_GETTILE_API_PATH, - SORT_ORDER, + ES_GEO_FIELD_TYPE, } from '../../../../common/constants'; -import { VectorStyle } from '../../styles/vector/vector_style'; import { TiledVectorLayer } from '../../tiled_vector_layer'; import uuid from 'uuid/v4'; import { CreateSourceEditor } from '../es_search_source/create_source_editor'; import React from 'react'; import { i18n } from '@kbn/i18n'; -import { VectorLayer } from '../../vector_layer'; -import _ from 'lodash'; -import { DEFAULT_FILTER_BY_MAP_BOUNDS } from '../es_search_source/constants'; -import { getDataSourceLabel } from '../../../../common/i18n_getters'; export class ESMVTSearchSource extends ESSearchSource { static type = ES_MVT_SEARCH; @@ -51,7 +45,9 @@ export class ESMVTSearchSource extends ESSearchSource { console.log('create esmvt source', source); onPreviewSource(source); }; - return ; + return ( + + ); } async getUrlTemplate() { @@ -80,7 +76,7 @@ export class ESMVTSearchSource extends ESSearchSource { } renderSourceSettingsEditor({ onChange }) { - return
No source settings to edit
; + return null; } isFilterByMapBounds() { @@ -115,6 +111,22 @@ export class ESMVTSearchSource extends ESSearchSource { return false; } + async getFields() { + return []; + } + + async getDateFields() { + return []; + } + + async getNumberFields() { + return []; + } + + async getCategoricalFields() { + return []; + } + async getImmutableProperties() { const ip = await super.getImmutableProperties(); ip.push({ diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/create_source_editor.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/create_source_editor.js index 28045eeb5e9b52..9d67a09b4547bc 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/create_source_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/create_source_editor.js @@ -185,7 +185,7 @@ export class CreateSourceEditor extends Component { } _renderFilterByMapBounds() { - if (!this.state.showFilterByBoundsSwitch) { + if (!this.state.showFilterByBoundsSwitch || this.props.showBoundsFilter === false) { return null; } @@ -261,7 +261,7 @@ export class CreateSourceEditor extends Component { defaultMessage: 'Select index pattern', } )} - fieldTypes={[ES_GEO_FIELD_TYPE.GEO_POINT, ES_GEO_FIELD_TYPE.GEO_SHAPE]} + fieldTypes={this.props.geoTypes ?this.props.geoTypes : [ES_GEO_FIELD_TYPE.GEO_POINT, ES_GEO_FIELD_TYPE.GEO_SHAPE]} onNoIndexPatterns={this._onNoIndexPatterns} /> diff --git a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js index 620c8d2345da3e..c006e20348cbcb 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js @@ -8,7 +8,7 @@ import React from 'react'; import { VectorStyle } from './styles/vector/vector_style'; import { SOURCE_DATA_ID_ORIGIN, LAYER_TYPE } from '../../common/constants'; import { VectorLayer } from './vector_layer'; -import {EuiIcon} from "@elastic/eui"; +import { EuiIcon } from '@elastic/eui'; export class TiledVectorLayer extends VectorLayer { static type = LAYER_TYPE.TILED_VECTOR; @@ -48,14 +48,11 @@ export class TiledVectorLayer extends VectorLayer { }; } - async syncData({ startLoading, stopLoading, onLoadError, dataFilters }) { - console.log('tvl syncData'); - if (!this.isVisible() || !this.showAtZoomLevel(dataFilters.zoom)) { - return; - } + async _syncMVTUrlTemplate({ startLoading, stopLoading, onLoadError, dataFilters }) { const sourceDataRequest = this.getSourceDataRequest(); if (sourceDataRequest) { //data is immmutable + console.log('already synced, no need to do again'); return; } console.log('need to syncdata'); @@ -63,13 +60,24 @@ export class TiledVectorLayer extends VectorLayer { startLoading(SOURCE_DATA_ID_ORIGIN, requestToken, dataFilters); try { console.log('source!', this._source); - const url = await this._source.getUrlTemplate(); + const url = await this._source.getUrlTemplate(dataFilters); stopLoading(SOURCE_DATA_ID_ORIGIN, requestToken, url, {}); } catch (error) { onLoadError(SOURCE_DATA_ID_ORIGIN, requestToken, error.message); } } + async syncData(syncContext) { + console.log('tvl syncData'); + if (!this.isVisible() || !this.showAtZoomLevel(syncContext.dataFilters.zoom)) { + return; + } + + await this._syncSourceStyleMeta(syncContext); + await this._syncSourceFormatters(syncContext); + await this._syncMVTUrlTemplate(syncContext); + } + _syncSourceBindingWithMb(mbMap) { console.log('tbl sync source bingins'); const mbSource = mbMap.getSource(this.getId()); @@ -98,11 +106,11 @@ export class TiledVectorLayer extends VectorLayer { } _syncStylePropertiesWithMb(mbMap) { - // this._setMbPointsProperties(mbMap); - this._setMbLinePolygonProperties(mbMap, {mvtSourceLayer: this._source.getMvtSourceLayer()}); + const options = { mvtSourceLayer: this._source.getMvtSourceLayer() }; + this._setMbPointsProperties(mbMap, options); + this._setMbLinePolygonProperties(mbMap, options); } - syncLayerWithMB(mbMap) { this._syncSourceBindingWithMb(mbMap); this._syncStylePropertiesWithMb(mbMap); diff --git a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js index 2c0236e826f139..a6426edd196af7 100644 --- a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js @@ -572,13 +572,7 @@ export class VectorLayer extends AbstractLayer { } } - async syncData(syncContext) { - if (!this.isVisible() || !this.showAtZoomLevel(syncContext.dataFilters.zoom)) { - return; - } - - await this._syncSourceStyleMeta(syncContext); - await this._syncSourceFormatters(syncContext); + async _syncGeoJsonSource(syncContext) { const sourceResult = await this._syncSource(syncContext); if ( !sourceResult.featureCollection || @@ -592,6 +586,16 @@ export class VectorLayer extends AbstractLayer { await this._performInnerJoins(sourceResult, joinStates, syncContext.updateSourceData); } + async syncData(syncContext) { + if (!this.isVisible() || !this.showAtZoomLevel(syncContext.dataFilters.zoom)) { + return; + } + + await this._syncSourceStyleMeta(syncContext); + await this._syncSourceFormatters(syncContext); + await this._syncGeoJsonSource(syncContext); + } + _getSourceFeatureCollection() { const sourceDataRequest = this.getSourceDataRequest(); return sourceDataRequest ? sourceDataRequest.getData() : null; @@ -623,7 +627,7 @@ export class VectorLayer extends AbstractLayer { } } - _setMbPointsProperties(mbMap) { + _setMbPointsProperties(mbMap, options) { const pointLayerId = this._getMbPointLayerId(); const symbolLayerId = this._getMbSymbolLayerId(); const pointLayer = mbMap.getLayer(pointLayerId); @@ -640,7 +644,7 @@ export class VectorLayer extends AbstractLayer { if (symbolLayer) { mbMap.setLayoutProperty(symbolLayerId, 'visibility', 'none'); } - this._setMbCircleProperties(mbMap); + this._setMbCircleProperties(mbMap, options); } else { markerLayerId = symbolLayerId; textLayerId = symbolLayerId; @@ -648,7 +652,7 @@ export class VectorLayer extends AbstractLayer { mbMap.setLayoutProperty(pointLayerId, 'visibility', 'none'); mbMap.setLayoutProperty(this._getMbTextLayerId(), 'visibility', 'none'); } - this._setMbSymbolProperties(mbMap); + this._setMbSymbolProperties(mbMap, options); } this.syncVisibilityWithMb(mbMap, markerLayerId); @@ -659,27 +663,35 @@ export class VectorLayer extends AbstractLayer { } } - _setMbCircleProperties(mbMap) { + _setMbCircleProperties(mbMap, { mvtSourceLayer }) { const sourceId = this.getId(); const pointLayerId = this._getMbPointLayerId(); const pointLayer = mbMap.getLayer(pointLayerId); if (!pointLayer) { - mbMap.addLayer({ + const mbLayer = { id: pointLayerId, type: 'circle', source: sourceId, paint: {}, - }); + }; + if (mvtSourceLayer) { + mbLayer['source-layer'] = mvtSourceLayer; + } + mbMap.addLayer(mbLayer); } const textLayerId = this._getMbTextLayerId(); const textLayer = mbMap.getLayer(textLayerId); if (!textLayer) { - mbMap.addLayer({ + const mbLayer = { id: textLayerId, type: 'symbol', source: sourceId, - }); + }; + if (mvtSourceLayer) { + mbLayer['source-layer'] = mvtSourceLayer; + } + mbMap.addLayer(mbLayer); } const filterExpr = getPointFilterExpression(this._hasJoins()); @@ -701,17 +713,21 @@ export class VectorLayer extends AbstractLayer { }); } - _setMbSymbolProperties(mbMap) { + _setMbSymbolProperties(mbMap, {mvtSourceLayer}) { const sourceId = this.getId(); const symbolLayerId = this._getMbSymbolLayerId(); const symbolLayer = mbMap.getLayer(symbolLayerId); if (!symbolLayer) { - mbMap.addLayer({ + const mbLayer = { id: symbolLayerId, type: 'symbol', source: sourceId, - }); + }; + if (mvtSourceLayer) { + mbLayer['source-layer'] = mvtSourceLayer; + } + mbMap.addLayer(mbLayer); } const filterExpr = getPointFilterExpression(this._hasJoins()); @@ -732,7 +748,7 @@ export class VectorLayer extends AbstractLayer { }); } - _setMbLinePolygonProperties(mbMap, {mvtSourceLayer}) { + _setMbLinePolygonProperties(mbMap, { mvtSourceLayer }) { const sourceId = this.getId(); const fillLayerId = this._getMbPolygonLayerId(); const lineLayerId = this._getMbLineLayerId(); @@ -755,7 +771,7 @@ export class VectorLayer extends AbstractLayer { type: 'line', source: sourceId, paint: {}, - } + }; if (mvtSourceLayer) { mbLayer['source-layer'] = mvtSourceLayer; } From 58b8fb3b7e90a10471c1e97769b9ac3d37d8512c Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 29 Jan 2020 14:38:28 -0500 Subject: [PATCH 07/27] show filter bar --- .../maps/public/components/global_filter_checkbox.js | 4 +++- .../layer_panel/filter_editor/filter_editor.js | 2 ++ .../sources/es_mvt_search_source/es_mvt_search_source.js | 6 +----- x-pack/legacy/plugins/maps/public/layers/sources/source.js | 4 ++++ 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js b/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js index a8c2908e75424b..9f3fa0caff7f43 100644 --- a/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js +++ b/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js @@ -7,14 +7,16 @@ import React from 'react'; import { EuiFormRow, EuiSwitch } from '@elastic/eui'; -export function GlobalFilterCheckbox({ applyGlobalQuery, label, setApplyGlobalQuery }) { +export function GlobalFilterCheckbox({ applyGlobalQuery, label, setApplyGlobalQuery, enableSwitch}) { const onApplyGlobalQueryChange = event => { setApplyGlobalQuery(event.target.checked); }; + console.log('enable switch', enableSwitch); return ( ); diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js index 87351d24f8afa6..22a9a7d0f4f3a8 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -91,10 +91,6 @@ export class ESMVTSearchSource extends ESSearchSource { return false; } - isFieldAware() { - return false; - } - isRefreshTimerAware() { return false; } @@ -108,7 +104,7 @@ export class ESMVTSearchSource extends ESSearchSource { } supportsESFilters() { - return false; + return true; } async getFields() { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/source.js b/x-pack/legacy/plugins/maps/public/layers/sources/source.js index 85aeba8859b81a..f5a19340675e11 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/source.js @@ -98,6 +98,10 @@ export class AbstractSource { return !!this._descriptor.applyGlobalQuery; } + supportsGlobalQuery() { + return false; + } + getIndexPatternIds() { return []; } From 5efc3f17cf381ba902796f17983eae6b77ec118f Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 29 Jan 2020 17:50:34 -0500 Subject: [PATCH 08/27] update on layer changes --- .../components/global_filter_checkbox.js | 1 - .../filter_editor/filter_editor.js | 2 +- .../es_mvt_search_source.js | 32 +++++-- .../es_search_source/es_search_source.js | 2 - .../mvt_vector_source/mvt_vector_source.js | 1 - .../maps/public/layers/sources/source.js | 8 +- .../plugins/maps/public/layers/tile_layer.js | 1 - .../maps/public/layers/tiled_vector_layer.js | 92 +++++++++++++++---- .../maps/public/layers/util/can_skip_fetch.js | 4 + .../plugins/maps/server/mvt/get_tile.js | 68 +++++++------- .../legacy/plugins/maps/server/mvt_routes.js | 41 ++------- 11 files changed, 151 insertions(+), 101 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js b/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js index 9f3fa0caff7f43..0a43e3d7f4efe8 100644 --- a/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js +++ b/x-pack/legacy/plugins/maps/public/components/global_filter_checkbox.js @@ -12,7 +12,6 @@ export function GlobalFilterCheckbox({ applyGlobalQuery, label, setApplyGlobalQu setApplyGlobalQuery(event.target.checked); }; - console.log('enable switch', enableSwitch); return ( ); diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js index 22a9a7d0f4f3a8..0510742543852d 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -16,6 +16,8 @@ import uuid from 'uuid/v4'; import { CreateSourceEditor } from '../es_search_source/create_source_editor'; import React from 'react'; import { i18n } from '@kbn/i18n'; +import {loadIndexSettings} from "../es_search_source/load_index_settings"; +import rison from 'rison-node'; export class ESMVTSearchSource extends ESSearchSource { static type = ES_MVT_SEARCH; @@ -38,11 +40,11 @@ export class ESMVTSearchSource extends ESSearchSource { id: uuid(), ...sourceConfig, type: ESMVTSearchSource.type, + applyGlobalQuery: false, }, inspectorAdapters ); - console.log('create esmvt source', source); onPreviewSource(source); }; return ( @@ -50,16 +52,33 @@ export class ESMVTSearchSource extends ESSearchSource { ); } - async getUrlTemplate() { - console.log('need to get vector template!', this); + async getUrlTemplate(searchFilters) { + const indexPattern = await this.getIndexPattern(); + const indexSettings = await loadIndexSettings(indexPattern.title); + + const searchSource = await this._makeSearchSource(searchFilters, indexSettings.maxResultWindow); + console.log('sf', searchFilters); + console.log('ss', searchSource); + + window._ss = searchSource; + + const ipTitle = indexPattern.title; const geometryFieldBame = this._descriptor.geoField; const fields = ['_id']; const fieldsParam = fields.join(','); - return `../${GIS_API_PATH}/${MVT_GETTILE_API_PATH}?x={x}&y={y}&z={z}&geometryFieldName=${geometryFieldBame}&indexPattern=${ipTitle}&fields=${fieldsParam}`; + const dsl = await searchSource.getSearchRequestBody(); + const dslString = JSON.stringify(dsl); + const urlEncode = encodeURI(dslString); + + const risonDsl = rison.encode(dsl); + console.log(risonDsl); + console.log(urlEncode); + + return `../${GIS_API_PATH}/${MVT_GETTILE_API_PATH}?x={x}&y={y}&z={z}&geometryFieldName=${geometryFieldBame}&indexPattern=${ipTitle}&fields=${fieldsParam}&requestBody=${risonDsl}`; } getMvtSourceLayer() { @@ -71,7 +90,6 @@ export class ESMVTSearchSource extends ESSearchSource { ...options, }); - console.log('create tiledvectorlayer descriptor'); return tvl; } @@ -95,11 +113,11 @@ export class ESMVTSearchSource extends ESSearchSource { return false; } - isQueryAware() { + isJoinable() { return false; } - isJoinable() { + isQueryAwareTogglable() { return false; } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index 7ad47c3bb1dfa1..2cdb3e98bc3803 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -59,8 +59,6 @@ export class ESSearchSource extends AbstractESSource { } constructor(descriptor, inspectorAdapters) { - console.log('de', descriptor); - console.log('type', descriptor.type); super( { ...descriptor, diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source.js index f896e2e2539a73..fd2887d9338cd7 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/mvt_vector_source/mvt_vector_source.js @@ -59,7 +59,6 @@ export class MVTVectorSource extends AbstractSource { } async getUrlTemplate() { - console.log('return templat', this._descriptor.urlTemplate); return this._descriptor.urlTemplate; } } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/source.js b/x-pack/legacy/plugins/maps/public/layers/sources/source.js index f5a19340675e11..75d1aca9dbe0ae 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/source.js @@ -82,6 +82,10 @@ export class AbstractSource { return false; } + isQueryAwareTogglable() { + return true; + } + getFieldNames() { return []; } @@ -98,10 +102,6 @@ export class AbstractSource { return !!this._descriptor.applyGlobalQuery; } - supportsGlobalQuery() { - return false; - } - getIndexPatternIds() { return []; } diff --git a/x-pack/legacy/plugins/maps/public/layers/tile_layer.js b/x-pack/legacy/plugins/maps/public/layers/tile_layer.js index 5cb3da94d190e7..b35adcad976c32 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tile_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/tile_layer.js @@ -30,7 +30,6 @@ export class TileLayer extends AbstractLayer { const requestToken = Symbol(`layer-source-refresh:${this.getId()} - source`); startLoading(SOURCE_DATA_ID_ORIGIN, requestToken, dataFilters); try { - console.log('calling', this._source); const url = await this._source.getUrlTemplate(); stopLoading(SOURCE_DATA_ID_ORIGIN, requestToken, url, {}); } catch (error) { diff --git a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js index c006e20348cbcb..3b2d228d5e7619 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js @@ -9,6 +9,8 @@ import { VectorStyle } from './styles/vector/vector_style'; import { SOURCE_DATA_ID_ORIGIN, LAYER_TYPE } from '../../common/constants'; import { VectorLayer } from './vector_layer'; import { EuiIcon } from '@elastic/eui'; +import { canSkipSourceUpdate } from './util/can_skip_fetch'; +import _ from 'lodash'; export class TiledVectorLayer extends VectorLayer { static type = LAYER_TYPE.TILED_VECTOR; @@ -28,7 +30,6 @@ export class TiledVectorLayer extends VectorLayer { constructor(options) { super(options); this._style = new VectorStyle(this._descriptor.style, this._source, this); - console.log('created oner with style!', this._style); } destroy() { @@ -42,25 +43,46 @@ export class TiledVectorLayer extends VectorLayer { } getCustomIconAndTooltipContent() { - console.log('since no feature collection, not sure what to do..'); return { icon: , }; } - async _syncMVTUrlTemplate({ startLoading, stopLoading, onLoadError, dataFilters }) { - const sourceDataRequest = this.getSourceDataRequest(); - if (sourceDataRequest) { - //data is immmutable - console.log('already synced, no need to do again'); - return; + _getSearchFilters(dataFilters) { + const fieldNames = [...this._source.getFieldNames(), ...this._style.getSourceFieldNames()]; + + return { + ...dataFilters, + fieldNames: _.uniq(fieldNames).sort(), + sourceQuery: this.getQuery(), + }; + } + + async _syncMVTUrlTemplate({ + startLoading, + stopLoading, + onLoadError, + registerCancelCallback, + dataFilters, + }) { + const requestToken = Symbol(`layer-${this.getId()}-${SOURCE_DATA_ID_ORIGIN}`); + const searchFilters = this._getSearchFilters(dataFilters); + const prevDataRequest = this.getSourceDataRequest(); + const canSkip = await canSkipSourceUpdate({ + source: this._source, + prevDataRequest, + nextMeta: searchFilters, + }); + if (canSkip) { + console.log('mvt Can skip update!'); + return null; + } else { + console.log('mvt cannot skip'); } - console.log('need to syncdata'); - const requestToken = Symbol(`layer-source-refresh:${this.getId()} - source`); - startLoading(SOURCE_DATA_ID_ORIGIN, requestToken, dataFilters); + + startLoading(SOURCE_DATA_ID_ORIGIN, requestToken, searchFilters); try { - console.log('source!', this._source); - const url = await this._source.getUrlTemplate(dataFilters); + const url = await this._source.getUrlTemplate(searchFilters); stopLoading(SOURCE_DATA_ID_ORIGIN, requestToken, url, {}); } catch (error) { onLoadError(SOURCE_DATA_ID_ORIGIN, requestToken, error.message); @@ -68,7 +90,6 @@ export class TiledVectorLayer extends VectorLayer { } async syncData(syncContext) { - console.log('tvl syncData'); if (!this.isVisible() || !this.showAtZoomLevel(syncContext.dataFilters.zoom)) { return; } @@ -79,7 +100,6 @@ export class TiledVectorLayer extends VectorLayer { } _syncSourceBindingWithMb(mbMap) { - console.log('tbl sync source bingins'); const mbSource = mbMap.getSource(this.getId()); if (!mbSource) { const sourceDataRequest = this.getSourceDataRequest(); @@ -87,13 +107,11 @@ export class TiledVectorLayer extends VectorLayer { //this is possible if the layer was invisible at startup. //the actions will not perform any data=syncing as an optimization when a layer is invisible //when turning the layer back into visible, it's possible the url has not been resovled yet. - console.log('no sdr'); return; } const url = sourceDataRequest.getData(); if (!url) { - console.log('no url!'); return; } @@ -106,18 +124,56 @@ export class TiledVectorLayer extends VectorLayer { } _syncStylePropertiesWithMb(mbMap) { + const mbSource = mbMap.getSource(this.getId()); + if (!mbSource) { + return; + } + const options = { mvtSourceLayer: this._source.getMvtSourceLayer() }; this._setMbPointsProperties(mbMap, options); this._setMbLinePolygonProperties(mbMap, options); } + _requiresPrevSourceCleanup(mbMap) { + const tileSource = mbMap.getSource(this.getId()); + if (!tileSource) { + return false; + } + const dataRequest = this.getSourceDataRequest(); + if (!dataRequest) { + return false; + } + const newUrl = dataRequest.getData(); + if (tileSource.tiles[0] === newUrl) { + //TileURL captures all the state. If this does not change, no updates are required. + return false; + } + + return true; + } + syncLayerWithMB(mbMap) { + const requiresCleanup = this._requiresPrevSourceCleanup(mbMap); + if (requiresCleanup) { + console.log('requires cleanup, source changed') + const mbStyle = mbMap.getStyle(); + mbStyle.layers.forEach(mbLayer => { + if (this.ownsMbLayerId(mbLayer.id)) { + mbMap.removeLayer(mbLayer.id); + } + }); + Object.keys(mbStyle.sources).some(mbSourceId => { + if (this.ownsMbSourceId(mbSourceId)) { + mbMap.removeSource(mbSourceId); + } + }); + } + this._syncSourceBindingWithMb(mbMap); this._syncStylePropertiesWithMb(mbMap); } getJoins() { - console.log('wtf is this getting called?'); return []; } } diff --git a/x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.js b/x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.js index 7abfee1b184f05..c0f678236b842c 100644 --- a/x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.js +++ b/x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.js @@ -59,6 +59,8 @@ export async function canSkipSourceUpdate({ source, prevDataRequest, nextMeta }) const isQueryAware = source.isQueryAware(); const isGeoGridPrecisionAware = source.isGeoGridPrecisionAware(); + console.log('can skip?', {timeAware, refreshTimerAware, extentAware, isFieldAware, isQueryAware, isGeoGridPrecisionAware}) + if ( !timeAware && !refreshTimerAware && @@ -122,6 +124,8 @@ export async function canSkipSourceUpdate({ source, prevDataRequest, nextMeta }) const updateDueToSourceMetaChange = !_.isEqual(prevMeta.sourceMeta, nextMeta.sourceMeta); + console.log('update due to source query?', updateDueToSourceQuery); + return ( !updateDueToTime && !updateDueToRefreshTimer && diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index 55caae0e0688d2..e18b611e934bb6 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -6,6 +6,7 @@ import geojsonvt from 'geojson-vt'; import vtpbf from 'vt-pbf'; +import _ from 'lodash'; export async function getTile({ esClient, @@ -17,48 +18,53 @@ export async function getTile({ y, z, fields = [], + requestBody = {}, }) { - - server.log('info', {indexPattern, size,geometryFieldName,x,y,z,fields}); + server.log('info', { indexPattern, size, geometryFieldName, x, y, z, fields }); const polygon = toBoundingBox(x, y, z); try { let result; try { - const includes = fields.concat([geometryFieldName]); - const esQuery = { - index: indexPattern, - body: { - size: size, - _source: { - includes: includes, - }, - stored_fields: [geometryFieldName], - query: { - bool: { - must: [], - filter: [ - { - match_all: {}, - }, - { - geo_shape: { - [geometryFieldName]: { - shape: polygon, - relation: 'INTERSECTS', - }, - }, - }, - ], - should: [], - must_not: [], - }, + + const geoShapeFilter = { + geo_shape: { + [geometryFieldName]: { + shape: polygon, + relation: 'INTERSECTS', }, }, }; - server.log('info', esQuery); + + requestBody.query.bool.filter.push(geoShapeFilter); + + // const esQuery = { + // index: indexPattern, + // body: { + // size: requestBody.size, + // _source: requestBody._source, + // stored_fields: requestBody.stored_fields, + // query: { + // bool: { + // must: [], + // filter: requestBody.query.bool.filter.concat(geoShapeFilter), + // should: [], + // must_not: [], + // }, + // }, + // }, + // }; + + + const esQuery = { + index: indexPattern, + body: requestBody, + } + server.log('info', JSON.stringify(esQuery)); result = await esClient.search(esQuery); + server.log('result', JSON.stringify(result)); } catch (e) { + server.log('error',e.message); throw e; } diff --git a/x-pack/legacy/plugins/maps/server/mvt_routes.js b/x-pack/legacy/plugins/maps/server/mvt_routes.js index 459815d125afe9..adab98d1b15ad1 100644 --- a/x-pack/legacy/plugins/maps/server/mvt_routes.js +++ b/x-pack/legacy/plugins/maps/server/mvt_routes.js @@ -14,6 +14,7 @@ import fetch from 'node-fetch'; import Boom from 'boom'; import { Client } from '@elastic/elasticsearch'; import { getTile } from './mvt/get_tile'; +import rison from 'rison-node'; const ROOT = `/${GIS_API_PATH}`; @@ -25,54 +26,23 @@ export function initMVTRoutes(server) { path: `${ROOT}/${MVT_GETTILE_API_PATH}`, handler: async (request, h) => { const { server, query } = request; - // const serverConfig = server.config(); - server.log('warning', 'hallo'); + server.log('warning', query); - // const esQuery = { - // index: 'kibana_sample_data_logs', - // body: {}, - // }; - // const results = await esClient.search(esQuery); const indexPattern = query.indexPattern; - // http://localhost:8080/?x=133&y=198&z=9&index=ky_roads&geometry=geometry&size=10000&fields=fclass -// http://localhost:8080/?x=270&y=395&z=10&index=ky_roads&geometry=geometry&size=10000&fields=fclass - - - //http://localhost:8080/?x=16&y=25&z=6&index=ky_roads&geometry=geometry&size=10000&fields=fclass - // getTile ky_roads 10000 geometry 16 25 6 [ 'fclass' ] - // includes [ 'fclass', 'geometry', '_id' ] - // esquery { index: 'ky_roads', - // body: - // { size: 10000, - // _source: { includes: [Array] }, - // stored_fields: [ 'geometry' ], - // query: { bool: [Object] } } } - // esquery: 164.953ms - // { _index: 'ky_roads', - // _id: '2pVA1G8B3ZwlEckSf2yE', - // _score: 0, - // _source: - // { fclass: 'residential', - // geometry: { coordinates: [Array], type: 'MultiLineString' } } } - // feature length 2479 - // prep: 3.591ms - // cut: 39.516ms - // bufferize: 9.151ms - // bytelength 20250 const x = parseInt(query.x); const y = parseInt(query.y); const z = parseInt(query.z); - // console.log('qd', queryData); - const geometryFieldName = query.geometryFieldName; const fields = query.fields ? query.fields.split(',') : []; const size = parseInt(query.size) || 10000; + const requestBodyDSL = rison.decode(query.requestBody); + server.log('info',requestBodyDSL); const tile = await getTile({ server, esClient, @@ -82,7 +52,8 @@ export function initMVTRoutes(server) { x, y, z, - indexPattern + indexPattern, + requestBody: requestBodyDSL }); server.log('info', tile); From 7d79a14eb44033b4c428331cb7885e1e8763de82 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 29 Jan 2020 18:20:21 -0500 Subject: [PATCH 09/27] update on quyery --- .../sources/es_mvt_search_source/es_mvt_search_source.js | 8 ++++---- .../plugins/maps/public/layers/tiled_vector_layer.js | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js index 0510742543852d..f72f0cf5570876 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -40,7 +40,7 @@ export class ESMVTSearchSource extends ESSearchSource { id: uuid(), ...sourceConfig, type: ESMVTSearchSource.type, - applyGlobalQuery: false, + applyGlobalQuery: true, }, inspectorAdapters ); @@ -117,9 +117,9 @@ export class ESMVTSearchSource extends ESSearchSource { return false; } - isQueryAwareTogglable() { - return false; - } + // isQueryAwareTogglable() { + // return false; + // } supportsESFilters() { return true; diff --git a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js index 3b2d228d5e7619..7dd0cb5ce7c39a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js @@ -55,6 +55,7 @@ export class TiledVectorLayer extends VectorLayer { ...dataFilters, fieldNames: _.uniq(fieldNames).sort(), sourceQuery: this.getQuery(), + applyGlobalQuery: this._source.getApplyGlobalQuery(), }; } From dd7a94ae3c303cde7ac26c6987a4d0c0b1e779da Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 30 Jan 2020 10:52:01 -0500 Subject: [PATCH 10/27] filtering tooltips --- .../features_tooltip/feature_properties.js | 4 ++- .../map/features_tooltip/features_tooltip.js | 3 ++ .../map/mb/tooltip_control/tooltip_control.js | 36 ++++++++----------- .../es_mvt_search_source.js | 21 +++++++++-- .../es_search_source/es_search_source.js | 1 + .../es_search_source/update_source_editor.js | 5 +++ .../maps/public/layers/tiled_vector_layer.js | 30 ++++++++++++---- .../maps/public/layers/vector_layer.js | 28 ++++++++++++++- .../plugins/maps/server/mvt/get_tile.js | 32 ++++++----------- 9 files changed, 106 insertions(+), 54 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js b/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js index 0b2b838f9feb75..8efd4537f22a21 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/feature_properties.js @@ -35,10 +35,11 @@ export class FeatureProperties extends React.Component { this._fetchProperties({ nextFeatureId: this.props.featureId, nextLayerId: this.props.layerId, + meta: this.props.meta }); }; - _fetchProperties = async ({ nextLayerId, nextFeatureId }) => { + _fetchProperties = async ({ nextLayerId, nextFeatureId, meta }) => { if (this.prevLayerId === nextLayerId && this.prevFeatureId === nextFeatureId) { // do not reload same feature properties return; @@ -64,6 +65,7 @@ export class FeatureProperties extends React.Component { properties = await this.props.loadFeatureProperties({ layerId: nextLayerId, featureId: nextFeatureId, + meta: meta, }); } catch (error) { if (this._isMounted) { diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js b/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js index 8a1b556d21c1f8..6e4c78eb42a104 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/features_tooltip/features_tooltip.js @@ -93,6 +93,7 @@ export class FeaturesTooltip extends React.Component { return this.props.loadPreIndexedShape({ layerId: this.state.currentFeature.layerId, featureId: this.state.currentFeature.id, + meta: this.state.currentFeature.meta }); }; @@ -104,6 +105,7 @@ export class FeaturesTooltip extends React.Component { const currentFeatureGeometry = this.props.loadFeatureGeometry({ layerId: this.state.currentFeature.layerId, featureId: this.state.currentFeature.id, + meta: this.state.currentFeature.meta, }); const geoFields = this._filterGeoFields(currentFeatureGeometry); @@ -132,6 +134,7 @@ export class FeaturesTooltip extends React.Component { { + _loadFeatureGeometry = ({ layerId, featureId, meta }) => { + const tooltipLayer = this._findLayerById(layerId); if (!tooltipLayer) { return null; } - const targetFeature = tooltipLayer.getFeatureById(featureId); - if (!targetFeature) { - return null; - } - - return targetFeature.geometry; + return tooltipLayer.getGeometryByFeatureId(featureId); }; - _loadFeatureProperties = async ({ layerId, featureId }) => { + _loadFeatureProperties = async ({ layerId, featureId, meta }) => { const tooltipLayer = this._findLayerById(layerId); if (!tooltipLayer) { return []; } - const targetFeature = tooltipLayer.getFeatureById(featureId); - if (!targetFeature) { - return []; - } - return await tooltipLayer.getPropertiesForTooltip(targetFeature.properties); + + return await tooltipLayer.getFeaturePropertiesByFeatureId(featureId, meta); }; - _loadPreIndexedShape = async ({ layerId, featureId }) => { + _loadPreIndexedShape = async ({ layerId, featureId, meta}) => { const tooltipLayer = this._findLayerById(layerId); if (!tooltipLayer) { return null; } - - const targetFeature = tooltipLayer.getFeatureById(featureId); - if (!targetFeature) { - return null; - } - - return await tooltipLayer.getSource().getPreIndexedShape(targetFeature.properties); + return await tooltipLayer.loadPreIndexedShapeByFeatureId(featureId, meta); }; _findLayerById = layerId => { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js index f72f0cf5570876..74d33358afbaa9 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -18,6 +18,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import {loadIndexSettings} from "../es_search_source/load_index_settings"; import rison from 'rison-node'; +import {UpdateSourceEditor} from "../es_search_source/update_source_editor"; export class ESMVTSearchSource extends ESSearchSource { static type = ES_MVT_SEARCH; @@ -58,10 +59,11 @@ export class ESMVTSearchSource extends ESSearchSource { const indexPattern = await this.getIndexPattern(); const indexSettings = await loadIndexSettings(indexPattern.title); - const searchSource = await this._makeSearchSource(searchFilters, indexSettings.maxResultWindow); console.log('sf', searchFilters); - console.log('ss', searchSource); + const searchSource = await this._makeSearchSource(searchFilters, indexSettings.maxResultWindow); + searchSource.setField('fields', searchFilters.fieldNames); + console.log('ss', searchSource); window._ss = searchSource; @@ -94,7 +96,20 @@ export class ESMVTSearchSource extends ESSearchSource { } renderSourceSettingsEditor({ onChange }) { - return null; + return ( + + ); } isFilterByMapBounds() { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index 2cdb3e98bc3803..910749352b059f 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -101,6 +101,7 @@ export class ESSearchSource extends AbstractESSource { useTopHits={this._descriptor.useTopHits} topHitsSplitField={this._descriptor.topHitsSplitField} topHitsSize={this._descriptor.topHitsSize} + showSorting={true} /> ); } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js index 4503856829ef25..9ed219756c790a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/update_source_editor.js @@ -230,6 +230,11 @@ export class UpdateSourceEditor extends Component { } _renderSortPanel() { + + if (!this.props.showSorting) { + return null; + } + return ( diff --git a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js index 7dd0cb5ce7c39a..e26f2bb358e1e4 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js @@ -6,7 +6,11 @@ import React from 'react'; import { VectorStyle } from './styles/vector/vector_style'; -import { SOURCE_DATA_ID_ORIGIN, LAYER_TYPE } from '../../common/constants'; +import { + SOURCE_DATA_ID_ORIGIN, + LAYER_TYPE, + FEATURE_ID_PROPERTY_NAME, +} from '../../common/constants'; import { VectorLayer } from './vector_layer'; import { EuiIcon } from '@elastic/eui'; import { canSkipSourceUpdate } from './util/can_skip_fetch'; @@ -38,10 +42,6 @@ export class TiledVectorLayer extends VectorLayer { } } - getLayerTypeIconName() { - return 'vector'; - } - getCustomIconAndTooltipContent() { return { icon: , @@ -51,6 +51,8 @@ export class TiledVectorLayer extends VectorLayer { _getSearchFilters(dataFilters) { const fieldNames = [...this._source.getFieldNames(), ...this._style.getSourceFieldNames()]; + console.log('fn', fieldNames); + return { ...dataFilters, fieldNames: _.uniq(fieldNames).sort(), @@ -156,7 +158,7 @@ export class TiledVectorLayer extends VectorLayer { syncLayerWithMB(mbMap) { const requiresCleanup = this._requiresPrevSourceCleanup(mbMap); if (requiresCleanup) { - console.log('requires cleanup, source changed') + console.log('requires cleanup, source changed'); const mbStyle = mbMap.getStyle(); mbStyle.layers.forEach(mbLayer => { if (this.ownsMbLayerId(mbLayer.id)) { @@ -177,4 +179,20 @@ export class TiledVectorLayer extends VectorLayer { getJoins() { return []; } + + getGeometryByFeatureId(featureId, meta) { + return null; + } + + async getFeaturePropertiesByFeatureId(featureId, meta) { + const test = await this._source.filterAndFormatPropertiesToHtml({ + _id: meta.docId, + _index: meta.indexName, + }); + return test; + } + + async loadPreIndexedShapeByFeatureId(featureId, meta) { + return null; + } } diff --git a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js index a6426edd196af7..a68990b596dc0a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js @@ -713,7 +713,7 @@ export class VectorLayer extends AbstractLayer { }); } - _setMbSymbolProperties(mbMap, {mvtSourceLayer}) { + _setMbSymbolProperties(mbMap, { mvtSourceLayer }) { const sourceId = this.getId(); const symbolLayerId = this._getMbSymbolLayerId(); const symbolLayer = mbMap.getLayer(symbolLayerId); @@ -898,4 +898,30 @@ export class VectorLayer extends AbstractLayer { return feature.properties[FEATURE_ID_PROPERTY_NAME] === id; }); } + + getGeometryByFeatureId(featureId) { + const targetFeature = this.getFeatureById(featureId); + if (!targetFeature) { + return null; + } + + return targetFeature.geometry; + } + + async getFeaturePropertiesByFeatureId(featureId) { + const targetFeature = this.getFeatureById(featureId); + if (!targetFeature) { + return []; + } + return await this.getPropertiesForTooltip(targetFeature.properties); + } + + async loadPreIndexedShapeByFeatureId(featureId) { + const targetFeature = this.getFeatureById(featureId); + if (!targetFeature) { + return null; + } + + return await this.getSource().getPreIndexedShape(targetFeature.properties); + } } diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index e18b611e934bb6..e191acbc958a48 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -7,6 +7,7 @@ import geojsonvt from 'geojson-vt'; import vtpbf from 'vt-pbf'; import _ from 'lodash'; +import { FEATURE_ID_PROPERTY_NAME } from '../../common/constants'; export async function getTile({ esClient, @@ -26,7 +27,6 @@ export async function getTile({ try { let result; try { - const geoShapeFilter = { geo_shape: { [geometryFieldName]: { @@ -38,33 +38,15 @@ export async function getTile({ requestBody.query.bool.filter.push(geoShapeFilter); - // const esQuery = { - // index: indexPattern, - // body: { - // size: requestBody.size, - // _source: requestBody._source, - // stored_fields: requestBody.stored_fields, - // query: { - // bool: { - // must: [], - // filter: requestBody.query.bool.filter.concat(geoShapeFilter), - // should: [], - // must_not: [], - // }, - // }, - // }, - // }; - - const esQuery = { index: indexPattern, body: requestBody, - } + }; server.log('info', JSON.stringify(esQuery)); result = await esClient.search(esQuery); server.log('result', JSON.stringify(result)); } catch (e) { - server.log('error',e.message); + server.log('error', e.message); throw e; } @@ -88,10 +70,16 @@ export async function getTile({ coordinates: geometry.coordinates, }; - const properties = { ...hit._source }; + const properties = { + ...hit._source, + _id: hit._id, + _index: hit._index, + [FEATURE_ID_PROPERTY_NAME]: hit._id, + }; delete properties[geometryFieldName]; return { + type: 'Feature', id: hit._id, geometry: geometryGeoJson, properties: properties, From e40cf86b654cf0708d900b24307806dc0d8a609b Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 30 Jan 2020 14:08:47 -0500 Subject: [PATCH 11/27] cat styling on vector data --- .../map/mb/tooltip_control/tooltip_control.js | 2 - .../es_mvt_search_source.js | 61 +++++++++++-------- .../es_search_source/es_search_source.js | 7 +++ .../vector/components/style_prop_editor.js | 1 + .../vector/components/vector_style_editor.js | 15 ++++- .../properties/dynamic_color_property.js | 2 + .../maps/public/layers/tiled_vector_layer.js | 2 - .../plugins/maps/server/mvt/get_tile.js | 12 ++++ 8 files changed, 70 insertions(+), 32 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js index c2659a621b7d46..1b4000a96260ae 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/tooltip_control/tooltip_control.js @@ -148,7 +148,6 @@ export class TooltipControl extends React.Component { } } - console.log('uf', uniqueFeatures); return uniqueFeatures; } @@ -203,7 +202,6 @@ export class TooltipControl extends React.Component { } const popupAnchorLocation = justifyAnchorLocation(e.lngLat, targetMbFeature); - console.log('features under point', mbFeatures); const features = this._getIdsForFeatures(mbFeatures); this.props.setTooltipState({ type: TOOLTIP_TYPE.HOVER, diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js index 74d33358afbaa9..08f1e47e826368 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -16,9 +16,9 @@ import uuid from 'uuid/v4'; import { CreateSourceEditor } from '../es_search_source/create_source_editor'; import React from 'react'; import { i18n } from '@kbn/i18n'; -import {loadIndexSettings} from "../es_search_source/load_index_settings"; -import rison from 'rison-node'; -import {UpdateSourceEditor} from "../es_search_source/update_source_editor"; +import { loadIndexSettings } from '../es_search_source/load_index_settings'; +import rison from 'rison-node'; +import { UpdateSourceEditor } from '../es_search_source/update_source_editor'; export class ESMVTSearchSource extends ESSearchSource { static type = ES_MVT_SEARCH; @@ -49,36 +49,45 @@ export class ESMVTSearchSource extends ESSearchSource { onPreviewSource(source); }; return ( - + ); } async getUrlTemplate(searchFilters) { - - const indexPattern = await this.getIndexPattern(); const indexSettings = await loadIndexSettings(indexPattern.title); - console.log('sf', searchFilters); + //assuming only geo_shape fields for now + const initialSearchContext = { + docvalue_fields: await this._getDateDocvalueFields(searchFilters.fieldNames), + }; + const geoField = await this._getGeoField(); + const docValueFields = await this._excludeDateFields(searchFilters.fieldNames); + const withoutGeoField = docValueFields.filter(field => field !== geoField.name); + + console.log('wg', withoutGeoField, geoField.name); + initialSearchContext.docvalue_fields.push(...withoutGeoField); - const searchSource = await this._makeSearchSource(searchFilters, indexSettings.maxResultWindow); + const searchSource = await this._makeSearchSource( + searchFilters, + indexSettings.maxResultWindow, + initialSearchContext + ); searchSource.setField('fields', searchFilters.fieldNames); - console.log('ss', searchSource); window._ss = searchSource; - const ipTitle = indexPattern.title; const geometryFieldBame = this._descriptor.geoField; const fields = ['_id']; const fieldsParam = fields.join(','); const dsl = await searchSource.getSearchRequestBody(); - const dslString = JSON.stringify(dsl); - const urlEncode = encodeURI(dslString); - const risonDsl = rison.encode(dsl); - console.log(risonDsl); - console.log(urlEncode); + console.log(dsl); return `../${GIS_API_PATH}/${MVT_GETTILE_API_PATH}?x={x}&y={y}&z={z}&geometryFieldName=${geometryFieldBame}&indexPattern=${ipTitle}&fields=${fieldsParam}&requestBody=${risonDsl}`; } @@ -144,17 +153,17 @@ export class ESMVTSearchSource extends ESSearchSource { return []; } - async getDateFields() { - return []; - } - - async getNumberFields() { - return []; - } - - async getCategoricalFields() { - return []; - } + // async getDateFields() { + // return []; + // } + // + // async getNumberFields() { + // return []; + // } + // + // async getCategoricalFields() { + // return []; + // } async getImmutableProperties() { const ip = await super.getImmutableProperties(); diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index 910749352b059f..81e15a3a59c2b2 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -363,6 +363,12 @@ export class ESSearchSource extends AbstractESSource { searchSource.setField('fields', searchFilters.fieldNames); // Setting "fields" filters out unused scripted fields } else { // geo_shape fields do not support docvalue_fields yet, so still have to be pulled from _source + const fields = await this._excludeDateFields(searchFilters.fieldNames); + const withoutGeoField = fields.filter(field => field !== geoField.name); + console.log('wg', withoutGeoField, geoField.name); + initialSearchContext.docvalue_fields.push( + ...(withoutGeoField) + ); searchSource = await this._makeSearchSource( searchFilters, maxResultWindow, @@ -424,6 +430,7 @@ export class ESSearchSource extends AbstractESSource { return !['_id', '_index'].includes(metaField); }); const flattenHit = hit => { + console.log(hit, hit.fields); const properties = indexPattern.flattenHit(hit); // remove metaFields unusedMetaFields.forEach(metaField => { diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js index e8b544d8ede161..a6b6d35e3ee8f2 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js @@ -60,6 +60,7 @@ export class StylePropEditor extends Component { }, ]; + console.log('f', this.props.fields); return ( { + console.log('selected fea', selectedFeature); this.setState({ selectedFeature }); }; @@ -364,6 +372,8 @@ export class VectorStyleEditor extends Component { _renderProperties() { const { supportedFeatures, selectedFeature } = this.state; + console.log('rp', supportedFeatures, selectedFeature); + if (!supportedFeatures) { return null; } @@ -407,6 +417,7 @@ export class VectorStyleEditor extends Component { styleProperties = this._renderPointProperties(); } + console.log('idsel', selectedFeature); return ( { + const value = fields[key]; + if (Array.isArray(value)) { + firstFields[key] = value[0]; + } else { + firstFields[key] = value; + } + }); + const properties = { ...hit._source, + ...firstFields, _id: hit._id, _index: hit._index, [FEATURE_ID_PROPERTY_NAME]: hit._id, From f0495c6651c3246b79245c8bf196cadfe4d3e89e Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 30 Jan 2020 14:23:56 -0500 Subject: [PATCH 12/27] parse fields --- .../plugins/maps/server/mvt/get_tile.js | 26 ++++++++++--------- .../legacy/plugins/maps/server/mvt_routes.js | 6 ++--- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index 051562527f702e..052895cce9d78d 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -21,7 +21,7 @@ export async function getTile({ fields = [], requestBody = {}, }) { - server.log('info', { indexPattern, size, geometryFieldName, x, y, z, fields }); + // server.log('info', { indexPattern, size, geometryFieldName, x, y, z, fields }); const polygon = toBoundingBox(x, y, z); try { @@ -71,15 +71,17 @@ export async function getTile({ }; const firstFields = {}; - const fields = hit.fields; - Object.keys(fields).forEach(key => { - const value = fields[key]; - if (Array.isArray(value)) { - firstFields[key] = value[0]; - } else { - firstFields[key] = value; - } - }); + if (hit.fields) { + const fields = hit.fields; + Object.keys(fields).forEach(key => { + const value = fields[key]; + if (Array.isArray(value)) { + firstFields[key] = value[0]; + } else { + firstFields[key] = value; + } + }); + } const properties = { ...hit._source, @@ -105,7 +107,7 @@ export async function getTile({ type: 'FeatureCollection', }; - server.log('info', `feature length ${featureCollection.features.length}`); + // server.log('info', `feature length ${featureCollection.features.length}`); const tileIndex = geojsonvt(featureCollection, { maxZoom: 24, // max zoom to preserve detail on; can't be higher than 24 @@ -125,7 +127,7 @@ export async function getTile({ const pbf = vtpbf.fromGeojsonVt({ geojsonLayer: tile }, { version: 2 }); const buffer = Buffer.from(pbf); - server.log('info', `bytelength: ${buffer.byteLength}`); + // server.log('info', `bytelength: ${buffer.byteLength}`); return buffer; } else { diff --git a/x-pack/legacy/plugins/maps/server/mvt_routes.js b/x-pack/legacy/plugins/maps/server/mvt_routes.js index adab98d1b15ad1..2a2d3221f59ad8 100644 --- a/x-pack/legacy/plugins/maps/server/mvt_routes.js +++ b/x-pack/legacy/plugins/maps/server/mvt_routes.js @@ -27,7 +27,7 @@ export function initMVTRoutes(server) { handler: async (request, h) => { const { server, query } = request; - server.log('warning', query); + // server.log('warning', query); const indexPattern = query.indexPattern; @@ -42,7 +42,7 @@ export function initMVTRoutes(server) { const size = parseInt(query.size) || 10000; const requestBodyDSL = rison.decode(query.requestBody); - server.log('info',requestBodyDSL); + // server.log('info',requestBodyDSL); const tile = await getTile({ server, esClient, @@ -56,7 +56,7 @@ export function initMVTRoutes(server) { requestBody: requestBodyDSL }); - server.log('info', tile); + // server.log('info', tile); if (!tile) { return null; From a382bb093150e09e0b831b1c0b1303d7d21a5f85 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 30 Jan 2020 14:27:40 -0500 Subject: [PATCH 13/27] cleanup logs --- .../sources/es_mvt_search_source/es_mvt_search_source.js | 2 -- .../layers/sources/es_search_source/es_search_source.js | 2 -- .../layers/styles/vector/components/style_prop_editor.js | 1 - .../layers/styles/vector/components/vector_style_editor.js | 5 ----- .../styles/vector/properties/dynamic_color_property.js | 2 -- .../legacy/plugins/maps/public/layers/tiled_vector_layer.js | 1 - .../legacy/plugins/maps/public/layers/util/can_skip_fetch.js | 4 ---- 7 files changed, 17 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js index 08f1e47e826368..6f742314a9a89b 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -69,7 +69,6 @@ export class ESMVTSearchSource extends ESSearchSource { const docValueFields = await this._excludeDateFields(searchFilters.fieldNames); const withoutGeoField = docValueFields.filter(field => field !== geoField.name); - console.log('wg', withoutGeoField, geoField.name); initialSearchContext.docvalue_fields.push(...withoutGeoField); const searchSource = await this._makeSearchSource( @@ -87,7 +86,6 @@ export class ESMVTSearchSource extends ESSearchSource { const dsl = await searchSource.getSearchRequestBody(); const risonDsl = rison.encode(dsl); - console.log(dsl); return `../${GIS_API_PATH}/${MVT_GETTILE_API_PATH}?x={x}&y={y}&z={z}&geometryFieldName=${geometryFieldBame}&indexPattern=${ipTitle}&fields=${fieldsParam}&requestBody=${risonDsl}`; } diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js index 81e15a3a59c2b2..e90d2ba064d14a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_search_source/es_search_source.js @@ -365,7 +365,6 @@ export class ESSearchSource extends AbstractESSource { // geo_shape fields do not support docvalue_fields yet, so still have to be pulled from _source const fields = await this._excludeDateFields(searchFilters.fieldNames); const withoutGeoField = fields.filter(field => field !== geoField.name); - console.log('wg', withoutGeoField, geoField.name); initialSearchContext.docvalue_fields.push( ...(withoutGeoField) ); @@ -430,7 +429,6 @@ export class ESSearchSource extends AbstractESSource { return !['_id', '_index'].includes(metaField); }); const flattenHit = hit => { - console.log(hit, hit.fields); const properties = indexPattern.flattenHit(hit); // remove metaFields unusedMetaFields.forEach(metaField => { diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js index a6b6d35e3ee8f2..e8b544d8ede161 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/style_prop_editor.js @@ -60,7 +60,6 @@ export class StylePropEditor extends Component { }, ]; - console.log('f', this.props.fields); return ( { - console.log('selected fea', selectedFeature); this.setState({ selectedFeature }); }; @@ -372,8 +370,6 @@ export class VectorStyleEditor extends Component { _renderProperties() { const { supportedFeatures, selectedFeature } = this.state; - console.log('rp', supportedFeatures, selectedFeature); - if (!supportedFeatures) { return null; } @@ -417,7 +413,6 @@ export class VectorStyleEditor extends Component { styleProperties = this._renderPointProperties(); } - console.log('idsel', selectedFeature); return ( { if (this.ownsMbLayerId(mbLayer.id)) { diff --git a/x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.js b/x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.js index c0f678236b842c..7abfee1b184f05 100644 --- a/x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.js +++ b/x-pack/legacy/plugins/maps/public/layers/util/can_skip_fetch.js @@ -59,8 +59,6 @@ export async function canSkipSourceUpdate({ source, prevDataRequest, nextMeta }) const isQueryAware = source.isQueryAware(); const isGeoGridPrecisionAware = source.isGeoGridPrecisionAware(); - console.log('can skip?', {timeAware, refreshTimerAware, extentAware, isFieldAware, isQueryAware, isGeoGridPrecisionAware}) - if ( !timeAware && !refreshTimerAware && @@ -124,8 +122,6 @@ export async function canSkipSourceUpdate({ source, prevDataRequest, nextMeta }) const updateDueToSourceMetaChange = !_.isEqual(prevMeta.sourceMeta, nextMeta.sourceMeta); - console.log('update due to source query?', updateDueToSourceQuery); - return ( !updateDueToTime && !updateDueToRefreshTimer && From ee45dc63669fbda10cf00047d4d0fbf165383b63 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 30 Jan 2020 15:39:08 -0500 Subject: [PATCH 14/27] more edits --- .../es_mvt_search_source.js | 5 +++ .../public/layers/sources/vector_source.js | 4 ++ .../maps/public/layers/styles/color_utils.js | 11 ++++- .../properties/dynamic_color_property.js | 45 ++++++++++++++++--- .../properties/dynamic_style_property.js | 6 ++- .../layers/styles/vector/vector_style.js | 9 +++- 6 files changed, 68 insertions(+), 12 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js index 6f742314a9a89b..687afc50f2c017 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -93,6 +93,11 @@ export class ESMVTSearchSource extends ESSearchSource { getMvtSourceLayer() { return 'geojsonLayer'; } + + isTileSource() { + return true; + } + _createDefaultLayerDescriptor(options) { const tvl = TiledVectorLayer.createDescriptor({ sourceDescriptor: this._descriptor, diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/vector_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/vector_source.js index 3952aacf03b334..b0e7b3ad519e20 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/vector_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/vector_source.js @@ -160,6 +160,10 @@ export class AbstractVectorSource extends AbstractSource { return true; } + isTileSource() { + return false; + } + async getSupportedShapeTypes() { return [VECTOR_SHAPE_TYPES.POINT, VECTOR_SHAPE_TYPES.LINE, VECTOR_SHAPE_TYPES.POLYGON]; } diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js b/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js index b04f8ff56e5ee4..f47f60db9b0389 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js @@ -62,13 +62,20 @@ export function getColorRampCenterColor(colorRampName) { // Returns an array of color stops // [ stop_input_1: number, stop_output_1: color, stop_input_n: number, stop_output_n: color ] -export function getOrdinalColorRampStops(colorRampName, numberColors = GRADIENT_INTERVALS) { +export function getOrdinalColorRampStops( + colorRampName, + scale = 1, + offset = 0 +) { + + const numberColors = GRADIENT_INTERVALS; if (!colorRampName) { return null; } + console.log('so', scale, offset); return getHexColorRangeStrings(colorRampName, numberColors).reduce( (accu, stopColor, idx, srcArr) => { - const stopNumber = idx / srcArr.length; // number between 0 and 1, increasing as index increases + const stopNumber = offset + ((idx * scale) / srcArr.length); // number between 0 and 1, increasing as index increases return [...accu, stopNumber, stopColor]; }, [] diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js index e80ccb9e144b9a..9b92ae9f0c672e 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js @@ -53,6 +53,7 @@ export class DynamicColorProperty extends DynamicStyleProperty { syncFillColorWithMb(mbLayerId, mbMap, alpha) { const color = this._getMbColor(); + console.log('color ul', color); mbMap.setPaintProperty(mbLayerId, 'fill-color', color); mbMap.setPaintProperty(mbLayerId, 'fill-opacity', alpha); } @@ -115,11 +116,11 @@ export class DynamicColorProperty extends DynamicStyleProperty { if (this.isCategorical()) { return this._getMbDataDrivenCategoricalColor({ targetName }); } else { - return this._getMbDataDrivenOrdinalColor({ targetName }); + return this._getMbDataDrivenOrdinalColor({ targetName, fieldName: this._options.field.name }); } } - _getMbDataDrivenOrdinalColor({ targetName }) { + _getMbDataDrivenOrdinalColor({ targetName, fieldName }) { if ( this._options.useCustomColorRamp && (!this._options.customColorRamp || !this._options.customColorRamp.length) @@ -127,7 +128,35 @@ export class DynamicColorProperty extends DynamicStyleProperty { return null; } - const colorStops = this._getMbOrdinalColorStops(); + let colorStops; + let getFunction; + let propFieldName; + if (this._style.isBackedByTileSource()) { + console.log( + 'This style is backed by a tilesource, need to do some fuzzy shiat for ', + targetName, + fieldName + ); + + const fieldMeta = this._getFieldMeta(fieldName); + if (!fieldMeta) { + console.log('no field meta'); + return null; + } + + + colorStops = this._getMbOrdinalColorStops(fieldMeta.max, fieldMeta.min); + console.log('cs', colorStops); + getFunction = 'get'; + propFieldName = fieldName; + } else { + colorStops = this._getMbOrdinalColorStops(); + getFunction = 'feature-state'; + propFieldName = targetName; + } + + console.log('cs', colorStops); + if (!colorStops) { return null; } @@ -137,7 +166,8 @@ export class DynamicColorProperty extends DynamicStyleProperty { const lessThenFirstStopValue = firstStopValue - 1; return [ 'step', - ['coalesce', ['feature-state', targetName], lessThenFirstStopValue], + // ['coalesce', ['feature-state', targetName], lessThenFirstStopValue], + ['coalesce', [getFunction, propFieldName], lessThenFirstStopValue], 'rgba(0,0,0,0)', // MB will assign the base value to any features that is below the first stop value ...colorStops, ]; @@ -145,7 +175,8 @@ export class DynamicColorProperty extends DynamicStyleProperty { return [ 'interpolate', ['linear'], - ['coalesce', ['feature-state', targetName], -1], + // ['coalesce', ['feature-state', targetName], -1], + ['coalesce', [getFunction, propFieldName], -1], -1, 'rgba(0,0,0,0)', ...colorStops, @@ -230,13 +261,13 @@ export class DynamicColorProperty extends DynamicStyleProperty { return ['match', ['to-string', ['get', this._options.field.name]], ...mbStops]; } - _getMbOrdinalColorStops() { + _getMbOrdinalColorStops(scale, offset) { if (this._options.useCustomColorRamp) { return this._options.customColorRamp.reduce((accumulatedStops, nextStop) => { return [...accumulatedStops, nextStop.stop, nextStop.color]; }, []); } else { - return getOrdinalColorRampStops(this._options.color); + return getOrdinalColorRampStops(this._options.color, scale, offset); } } diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js index 98e87b0305b447..57bf98b498d9db 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js @@ -17,11 +17,12 @@ import { OrdinalFieldMetaOptionsPopover } from '../components/ordinal_field_meta export class DynamicStyleProperty extends AbstractStyleProperty { static type = STYLE_TYPE.DYNAMIC; - constructor(options, styleName, field, getFieldMeta, getFieldFormatter) { + constructor(options, styleName, field, getFieldMeta, getFieldFormatter, style) { super(options, styleName); this._field = field; this._getFieldMeta = getFieldMeta; this._getFieldFormatter = getFieldFormatter; + this._style = style; } getFieldMeta() { @@ -74,7 +75,8 @@ export class DynamicStyleProperty extends AbstractStyleProperty { supportsFieldMeta() { if (this.isOrdinal()) { - return this.isComplete() && this.isOrdinalScaled() && this._field.supportsFieldMeta(); + // return this.isComplete() && this.isOrdinalScaled() && this._field.supportsFieldMeta(); + return this.isComplete() && this._field.supportsFieldMeta(); } else if (this.isCategorical()) { return this.isComplete() && this._field.supportsFieldMeta(); } else { diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js index 558df73f74595b..7a3afffae634b1 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js @@ -127,6 +127,10 @@ export class VectorStyle extends AbstractStyle { ]; } + isBackedByTileSource() { + return this._source.isTileSource(); + } + renderEditor({ layer, onStyleDescriptorChange }) { const rawProperties = this.getRawProperties(); const handlePropertyChange = (propertyName, settings) => { @@ -367,9 +371,11 @@ export class VectorStyle extends AbstractStyle { const data = styleMetaDataRequest.getData(); const fieldMeta = dynamicProp.pluckStyleMetaFromFieldMetaData(data); + console.log('fm', fieldMeta); return fieldMeta ? fieldMeta : fieldMetaFromLocalFeatures; }; + _getFieldFormatter = fieldName => { const dynamicProp = this._getDynamicPropertyByFieldName(fieldName); if (!dynamicProp) { @@ -622,7 +628,8 @@ export class VectorStyle extends AbstractStyle { styleName, field, this._getFieldMeta, - this._getFieldFormatter + this._getFieldFormatter, + this ); } else { throw new Error(`${descriptor} not implemented`); From f8290713c9b5de6a48e5bad72739903a07b9a4b7 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 30 Jan 2020 16:48:27 -0500 Subject: [PATCH 15/27] start refactoring --- .../legacy/plugins/maps/common/constants.js | 1 + .../maps/public/layers/sources/all_sources.js | 2 + .../es_geo_grid_source/es_geo_grid_source.js | 7 +- .../es_mvt_geo_grid_source.js | 92 +++++++++++++++++++ .../es_mvt_search_source.js | 24 ----- 5 files changed, 101 insertions(+), 25 deletions(-) create mode 100644 x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js diff --git a/x-pack/legacy/plugins/maps/common/constants.js b/x-pack/legacy/plugins/maps/common/constants.js index 863a702fe760c2..e46c799b028266 100644 --- a/x-pack/legacy/plugins/maps/common/constants.js +++ b/x-pack/legacy/plugins/maps/common/constants.js @@ -59,6 +59,7 @@ export const ES_GEO_GRID = 'ES_GEO_GRID'; export const ES_SEARCH = 'ES_SEARCH'; export const ES_PEW_PEW = 'ES_PEW_PEW'; export const ES_MVT_SEARCH = 'ES_MVT_SEARCH'; +export const ES_MVT_GEO_GRID = 'ES_MVT_GEO_GRID'; export const FIELD_ORIGIN = { SOURCE: 'source', diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js b/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js index 5df2010157eb81..3957e85c0e75db 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/all_sources.js @@ -16,10 +16,12 @@ import { ESSearchSource } from './es_search_source'; import { ESPewPewSource } from './es_pew_pew_source/es_pew_pew_source'; import { MVTVectorSource } from './mvt_vector_source/mvt_vector_source'; import { ESMVTSearchSource } from './es_mvt_search_source/es_mvt_search_source'; +import {ESMVTGeoGridSource} from "./es_mvt_geo_grid_source/es_mvt_geo_grid_source"; export const ALL_SOURCES = [ // MVTVectorSource, ESMVTSearchSource, + ESMVTGeoGridSource, GeojsonFileSource, ESSearchSource, ESGeoGridSource, diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js index cb8b43a6c312b2..63da20303cc094 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js @@ -175,7 +175,7 @@ export class ESGeoGridSource extends AbstractESAggSource { ); } - async getGeoJsonWithMeta(layerName, searchFilters, registerCancelCallback) { + async _makeSearchSourceWithAggConfigs(searchFilters) { const indexPattern = await this.getIndexPattern(); const searchSource = await this._makeSearchSource(searchFilters, 0); const aggConfigs = new AggConfigs( @@ -184,6 +184,11 @@ export class ESGeoGridSource extends AbstractESAggSource { aggSchemas.all ); searchSource.setField('aggs', aggConfigs.toDsl()); + return { searchSource, aggConfigs }; + } + + async getGeoJsonWithMeta(layerName, searchFilters, registerCancelCallback) { + const { searchSource, aggConfigs } = await this._makeSearchSourceWithAggConfigs(searchFilters); const esResponse = await this._runEsQuery({ requestId: this.getId(), requestName: layerName, diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js new file mode 100644 index 00000000000000..1c974c0ebff811 --- /dev/null +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ESSearchSource } from '../es_search_source'; +import { + ES_MVT_SEARCH, + GIS_API_PATH, + MVT_GETTILE_API_PATH, + ES_GEO_FIELD_TYPE, +} from '../../../../common/constants'; +import { TiledVectorLayer } from '../../tiled_vector_layer'; +import uuid from 'uuid/v4'; +import { CreateSourceEditor } from '../es_search_source/create_source_editor'; +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { loadIndexSettings } from '../es_search_source/load_index_settings'; +import rison from 'rison-node'; +import { UpdateSourceEditor } from '../es_search_source/update_source_editor'; +import {ESGeoGridSource} from "../es_geo_grid_source"; + +export class ESMVTGeoGridSource extends ESGeoGridSource { + static type = ES_MVT_SEARCH; + static title = i18n.translate('xpack.maps.source.esMvtSearchTitle', { + defaultMessage: 'Documents as tiles', + }); + static description = i18n.translate('xpack.maps.source.esMvtSearchDescription', { + defaultMessage: 'Vector data from a Kibana index pattern (tiled)', + }); + + static renderEditor({ onPreviewSource, inspectorAdapters }) { + return null; + } + + async getUrlTemplate(searchFilters) { + return null; + } + + getMvtSourceLayer() { + return 'geojsonLayer'; + } + + isTileSource() { + return true; + } + + _createDefaultLayerDescriptor(options) { + const tvl = TiledVectorLayer.createDescriptor({ + sourceDescriptor: this._descriptor, + ...options, + }); + + return tvl; + } + + renderSourceSettingsEditor({ onChange }) { + return null; + } + + isFilterByMapBounds() { + return false; + } + + isFilterByMapBoundsConfigurable() { + return false; + } + + isBoundsAware() { + return false; + } + + isRefreshTimerAware() { + return false; + } + + isJoinable() { + return false; + } + + async getImmutableProperties() { + const ip = await super.getImmutableProperties(); + ip.push({ + label: i18n.translate('xpack.maps.source.esSearch.isMvt', { + defaultMessage: 'Is MBVT?', + }), + value: 'yes is mvt', + }); + return ip; + } +} diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js index 687afc50f2c017..dc0a37d140418f 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -144,30 +144,6 @@ export class ESMVTSearchSource extends ESSearchSource { return false; } - // isQueryAwareTogglable() { - // return false; - // } - - supportsESFilters() { - return true; - } - - async getFields() { - return []; - } - - // async getDateFields() { - // return []; - // } - // - // async getNumberFields() { - // return []; - // } - // - // async getCategoricalFields() { - // return []; - // } - async getImmutableProperties() { const ip = await super.getImmutableProperties(); ip.push({ From e74b1acb0ed447d41182591150e761f76de720a8 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Thu, 30 Jan 2020 22:34:20 -0500 Subject: [PATCH 16/27] more settings --- .../legacy/plugins/maps/common/constants.js | 3 + .../connected_components/map/mb/view.js | 34 -------- .../create_source_editor.js | 16 ++-- .../update_source_editor.js | 17 +++- .../es_mvt_geo_grid_source.js | 80 ++++++++++++++---- .../es_mvt_search_source.js | 4 +- .../properties/dynamic_color_property.js | 2 +- .../plugins/maps/server/mvt/get_tile.js | 83 ++++++++++++++++++- .../legacy/plugins/maps/server/mvt_routes.js | 54 ++++++++++-- 9 files changed, 221 insertions(+), 72 deletions(-) diff --git a/x-pack/legacy/plugins/maps/common/constants.js b/x-pack/legacy/plugins/maps/common/constants.js index e46c799b028266..5f92a423e0d7b0 100644 --- a/x-pack/legacy/plugins/maps/common/constants.js +++ b/x-pack/legacy/plugins/maps/common/constants.js @@ -28,6 +28,7 @@ export const APP_ICON = 'gisApp'; export const TELEMETRY_TYPE = 'maps-telemetry'; export const MVT_GETTILE_API_PATH = 'mvt/getTile'; +export const MVT_GETGRIDTILE_API_PATH = 'mvt/getGridTile'; export const MAP_APP_PATH = `app/${APP_ID}`; export const GIS_API_PATH = `api/${APP_ID}`; @@ -39,6 +40,8 @@ export function createMapPath(id) { return `${MAP_BASE_URL}/${id}`; } +export const MVT_SOURCE_ID = 'geojsonLayer'; + export const LAYER_TYPE = { TILE: 'TILE', VECTOR: 'VECTOR', diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js index 91d6d48bb50229..f78019bb66e423 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js @@ -158,40 +158,6 @@ export class MBMapContainer extends React.Component { resolve(mbMap); - // try { - // mbMap.addLayer({ - // "id": 'foobar_line', - // "type": "line", - // "source": { - // "type": "vector", - // // "tiles": ["https://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt"], - // "tiles": [`http://localhost:5601/jco/api/maps/mvt/getTile?x={x}&y={y}&z={z}&geometryFieldName=geometry&indexPattern=ky_roads&fields=fclass,_id`], - // // "tiles": [`http://localhost:8080/?x={x}&y={y}&z={z}&index=ky_roads&geometry=geometry&size=10000&fields=fclass`], - // - // - // // "minzoom": 6, - // // "maxzoom": 14 - // "tileSize": 512 - // }, - // "source-layer": "geojsonLayer", - // "layout": { - // "line-cap": "round", - // "line-join": "round" - // }, - // "paint": { - // "line-opacity": 0.6, - // // "line-color": "rgb(53, 175, 109)", - // "line-color": ["match", ['get', 'fclass'], "residential", "#00FF00", "#FF0000"], - // "line-width": 2 - // } - // }); - // }catch(e){ - // console.error(e); - // } - - - - }); diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js index bd074386edb3f2..4dd526884b0d9f 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/create_source_editor.js @@ -24,6 +24,12 @@ import { npStart } from 'ui/new_platform'; const { IndexPatternSelect } = npStart.plugins.data.ui; const requestTypeOptions = [ + { + label: i18n.translate('xpack.maps.source.esGeoGrid.pointsDropdownOption', { + defaultMessage: 'clusters', + }), + value: RENDER_AS.POINT, + }, { label: i18n.translate('xpack.maps.source.esGeoGrid.gridRectangleDropdownOption', { defaultMessage: 'grid rectangles', @@ -36,12 +42,6 @@ const requestTypeOptions = [ }), value: RENDER_AS.HEATMAP, }, - { - label: i18n.translate('xpack.maps.source.esGeoGrid.pointsDropdownOption', { - defaultMessage: 'clusters', - }), - value: RENDER_AS.POINT, - }, ]; export class CreateSourceEditor extends Component { @@ -184,6 +184,8 @@ export class CreateSourceEditor extends Component { return null; } + const options = this.props.clustersOnly ? requestTypeOptions.slice(0, 1) : requestTypeOptions; + return ( - {this._renderMetricsPanel()} -
@@ -112,6 +114,15 @@ export class UpdateSourceEditor extends Component { onChange={this._onResolutionChange} /> + + ); + } + + render() { + return ( + + {this._renderMetricsPanel()} + {this._renderResolutionEditor()} ); diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js index 1c974c0ebff811..82e64a9ecc0758 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js @@ -9,54 +9,106 @@ import { ES_MVT_SEARCH, GIS_API_PATH, MVT_GETTILE_API_PATH, - ES_GEO_FIELD_TYPE, + ES_GEO_FIELD_TYPE, ES_MVT_GEO_GRID, COUNT_PROP_NAME, SOURCE_DATA_ID_ORIGIN, COLOR_MAP_TYPE, MVT_SOURCE_ID, } from '../../../../common/constants'; import { TiledVectorLayer } from '../../tiled_vector_layer'; import uuid from 'uuid/v4'; -import { CreateSourceEditor } from '../es_search_source/create_source_editor'; +import { CreateSourceEditor } from '../es_geo_grid_source/create_source_editor'; import React from 'react'; import { i18n } from '@kbn/i18n'; import { loadIndexSettings } from '../es_search_source/load_index_settings'; import rison from 'rison-node'; -import { UpdateSourceEditor } from '../es_search_source/update_source_editor'; +import { UpdateSourceEditor } from '../es_geo_grid_source/update_source_editor'; import {ESGeoGridSource} from "../es_geo_grid_source"; +import {GRID_RESOLUTION} from "../../grid_resolution"; +import {RENDER_AS} from "../es_geo_grid_source/render_as"; +import {HeatmapLayer} from "../../heatmap_layer"; +import {VectorStyle} from "../../styles/vector/vector_style"; +import {VectorLayer} from "../../vector_layer"; +import {getDefaultDynamicProperties, VECTOR_STYLES} from "../../styles/vector/vector_style_defaults"; +import {DynamicStyleProperty} from "../../styles/vector/properties/dynamic_style_property"; +import {COLOR_GRADIENTS} from "../../styles/color_utils"; +import {StaticStyleProperty} from "../../styles/vector/properties/static_style_property"; export class ESMVTGeoGridSource extends ESGeoGridSource { - static type = ES_MVT_SEARCH; + static type = ES_MVT_GEO_GRID; static title = i18n.translate('xpack.maps.source.esMvtSearchTitle', { - defaultMessage: 'Documents as tiles', + defaultMessage: 'Grids as tiles', }); static description = i18n.translate('xpack.maps.source.esMvtSearchDescription', { - defaultMessage: 'Vector data from a Kibana index pattern (tiled)', + defaultMessage: 'Grid agg with tiles', }); + static createDescriptor({ indexPatternId, geoField, requestType, resolution }) { + return { + type: ESMVTGeoGridSource.type, + id: uuid(), + indexPatternId: indexPatternId, + geoField: geoField, + requestType: requestType, + resolution: resolution ? resolution : GRID_RESOLUTION.COARSE, + }; + } + static renderEditor({ onPreviewSource, inspectorAdapters }) { - return null; + const onSourceConfigChange = sourceConfig => { + if (!sourceConfig) { + onPreviewSource(null); + return; + } + + const sourceDescriptor = ESMVTGeoGridSource.createDescriptor(sourceConfig); + const source = new ESMVTGeoGridSource(sourceDescriptor, inspectorAdapters); + console.log('shoudl preview', source); + onPreviewSource(source); + }; + + return ;; } async getUrlTemplate(searchFilters) { + console.log('should get url template for sf', searchFilters); return null; } getMvtSourceLayer() { - return 'geojsonLayer'; + return MVT_SOURCE_ID; } isTileSource() { return true; } - _createDefaultLayerDescriptor(options) { - const tvl = TiledVectorLayer.createDescriptor({ + _createTiledVectorLayerDescriptor(options) { + const descriptor = TiledVectorLayer.createDescriptor({ sourceDescriptor: this._descriptor, ...options, }); + descriptor.style = VectorStyle.createDescriptor({}); + return descriptor; + } - return tvl; + createDefaultLayer(options) { + const layerDescriptor = this._createTiledVectorLayerDescriptor(options); + const style = new VectorStyle(layerDescriptor.style, this); + return new TiledVectorLayer({ + layerDescriptor, + source: this, + style, + }); } renderSourceSettingsEditor({ onChange }) { - return null; + return ( + + ); } isFilterByMapBounds() { @@ -75,10 +127,6 @@ export class ESMVTGeoGridSource extends ESGeoGridSource { return false; } - isJoinable() { - return false; - } - async getImmutableProperties() { const ip = await super.getImmutableProperties(); ip.push({ diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js index dc0a37d140418f..fdcc1fcb59243d 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_search_source/es_mvt_search_source.js @@ -9,7 +9,7 @@ import { ES_MVT_SEARCH, GIS_API_PATH, MVT_GETTILE_API_PATH, - ES_GEO_FIELD_TYPE, + ES_GEO_FIELD_TYPE, MVT_SOURCE_ID, } from '../../../../common/constants'; import { TiledVectorLayer } from '../../tiled_vector_layer'; import uuid from 'uuid/v4'; @@ -91,7 +91,7 @@ export class ESMVTSearchSource extends ESSearchSource { } getMvtSourceLayer() { - return 'geojsonLayer'; + return MVT_SOURCE_ID; } isTileSource() { diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js index 86630db470c1fa..705c258993cd77 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js @@ -141,7 +141,7 @@ export class DynamicColorProperty extends DynamicStyleProperty { } - colorStops = this._getMbOrdinalColorStops(fieldMeta.max, fieldMeta.min); + colorStops = this._getMbOrdinalColorStops((fieldMeta.max - fieldMeta.min), fieldMeta.min); console.log('cs', colorStops); getFunction = 'get'; propFieldName = fieldName; diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index 052895cce9d78d..41550e33c2f193 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -7,7 +7,7 @@ import geojsonvt from 'geojson-vt'; import vtpbf from 'vt-pbf'; import _ from 'lodash'; -import { FEATURE_ID_PROPERTY_NAME } from '../../common/constants'; +import { FEATURE_ID_PROPERTY_NAME, MVT_SOURCE_ID } from '../../common/constants'; export async function getTile({ esClient, @@ -124,7 +124,7 @@ export async function getTile({ const tile = tileIndex.getTile(z, x, y); if (tile) { - const pbf = vtpbf.fromGeojsonVt({ geojsonLayer: tile }, { version: 2 }); + const pbf = vtpbf.fromGeojsonVt({ [MVT_SOURCE_ID]: tile }, { version: 2 }); const buffer = Buffer.from(pbf); // server.log('info', `bytelength: ${buffer.byteLength}`); @@ -138,6 +138,85 @@ export async function getTile({ } } +export async function getGridTile({ + esClient, + server, + indexPattern, + size, + geometryFieldName, + x, + y, + z, + fields = [], + requestBody = {}, +}) { + // server.log('info', { indexPattern, size, geometryFieldName, x, y, z, fields }); + const polygon = toBoundingBox(x, y, z); + + try { + let result; + try { + const geoShapeFilter = { + geo_shape: { + [geometryFieldName]: { + shape: polygon, + relation: 'INTERSECTS', + }, + }, + }; + + requestBody.query.bool.filter.push(geoShapeFilter); + + const esQuery = { + index: indexPattern, + body: requestBody, + }; + server.log('info', JSON.stringify(esQuery)); + result = await esClient.search(esQuery); + server.log('result', JSON.stringify(result)); + } catch (e) { + server.log('error', e.message); + throw e; + } + + server.log('info', `result length ${result.body.hits.hits.length}`); + + const ffeats = []; + + const featureCollection = { + features: ffeats, + type: 'FeatureCollection', + }; + + // server.log('info', `feature length ${featureCollection.features.length}`); + + const tileIndex = geojsonvt(featureCollection, { + maxZoom: 24, // max zoom to preserve detail on; can't be higher than 24 + tolerance: 3, // simplification tolerance (higher means simpler) + extent: 4096, // tile extent (both width and height) + buffer: 64, // tile buffer on each side + debug: 0, // logging level (0 to disable, 1 or 2) + lineMetrics: false, // whether to enable line metrics tracking for LineString/MultiLineString features + promoteId: null, // name of a feature property to promote to feature.id. Cannot be used with `generateId` + generateId: false, // whether to generate feature ids. Cannot be used with `promoteId` + indexMaxZoom: 5, // max zoom in the initial tile index + indexMaxPoints: 100000, // max number of points per tile in the index + }); + const tile = tileIndex.getTile(z, x, y); + + if (tile) { + const pbf = vtpbf.fromGeojsonVt({ [MVT_SOURCE_ID]: tile }, { version: 2 }); + const buffer = Buffer.from(pbf); + + return buffer; + } else { + return null; + } + } catch (e) { + return null; + } +} + function toBoundingBox(x, y, z) { const w_lon = tile2long(x, z); const s_lat = tile2lat(y + 1, z); diff --git a/x-pack/legacy/plugins/maps/server/mvt_routes.js b/x-pack/legacy/plugins/maps/server/mvt_routes.js index 2a2d3221f59ad8..c304cb406b5ad3 100644 --- a/x-pack/legacy/plugins/maps/server/mvt_routes.js +++ b/x-pack/legacy/plugins/maps/server/mvt_routes.js @@ -5,13 +5,10 @@ */ import { - EMS_FILES_API_PATH, - EMS_FILES_DEFAULT_JSON_PATH, GIS_API_PATH, MVT_GETTILE_API_PATH, + MVT_GETGRIDTILE_API_PATH, } from '../common/constants'; -import fetch from 'node-fetch'; -import Boom from 'boom'; import { Client } from '@elastic/elasticsearch'; import { getTile } from './mvt/get_tile'; import rison from 'rison-node'; @@ -27,9 +24,6 @@ export function initMVTRoutes(server) { handler: async (request, h) => { const { server, query } = request; - // server.log('warning', query); - - const indexPattern = query.indexPattern; @@ -73,4 +67,50 @@ export function initMVTRoutes(server) { // }; }, }); + + server.route({ + method: 'GET', + path: `${ROOT}/${MVT_GETGRIDTILE_API_PATH}`, + handler: async (request, h) => { + const { server, query } = request; + + const indexPattern = query.indexPattern; + + + const x = parseInt(query.x); + const y = parseInt(query.y); + const z = parseInt(query.z); + + const geometryFieldName = query.geometryFieldName; + const fields = query.fields ? query.fields.split(',') : []; + const size = parseInt(query.size) || 10000; + + const requestBodyDSL = rison.decode(query.requestBody); + // server.log('info',requestBodyDSL); + const tile = await getGridTile({ + server, + esClient, + size, + geometryFieldName, + fields, + x, + y, + z, + indexPattern, + requestBody: requestBodyDSL + }); + + + if (!tile) { + return null; + } + let response = h.response(tile); + response = response.bytes(tile.length); + response = response.header('Content-Disposition', 'inline'); + response.header('Content-Type', 'application/x-protobuf'); + response = response.encoding('binary'); + + return response; + }, + }); } From 6b0759cba37c81e5e235c00a69db6fbf66e17f59 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Fri, 31 Jan 2020 15:28:22 -0500 Subject: [PATCH 17/27] use callwithrequest --- .../public/layers/sources/es_agg_source.js | 4 +- .../es_geo_grid_source/es_geo_grid_source.js | 2 +- .../sources/es_geo_grid_source/index.js | 2 +- .../es_mvt_geo_grid_source.js | 83 ++++++++++++++++--- .../maps/public/layers/styles/color_utils.js | 1 - .../properties/dynamic_color_property.js | 4 - .../layers/styles/vector/vector_style.js | 1 - .../plugins/maps/server/mvt/get_tile.js | 27 +++--- .../legacy/plugins/maps/server/mvt_routes.js | 24 ++---- 9 files changed, 93 insertions(+), 55 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.js index 967a3c41aec269..203e74be78036c 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_agg_source.js @@ -99,7 +99,9 @@ export class AbstractESAggSource extends AbstractESSource { } createMetricAggConfigs() { - return this.getMetricFields().map(esAggMetric => esAggMetric.makeMetricAggConfig()); + const mf = this.getMetricFields().map(esAggMetric => esAggMetric.makeMetricAggConfig()); + + return mf; } async getNumberFields() { diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js index 63da20303cc094..13a7ad1ea05896 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/es_geo_grid_source.js @@ -37,7 +37,7 @@ import { StaticStyleProperty } from '../../styles/vector/properties/static_style const MAX_GEOTILE_LEVEL = 29; -const aggSchemas = new Schemas([ +export const aggSchemas = new Schemas([ AbstractESAggSource.METRIC_SCHEMA_CONFIG, { group: 'buckets', diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/index.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/index.js index 58d74c04c55529..582bed272a3e90 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/index.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_geo_grid_source/index.js @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { ESGeoGridSource } from './es_geo_grid_source'; +export { ESGeoGridSource, aggSchemas } from './es_geo_grid_source'; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js index 82e64a9ecc0758..abade816f07299 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js @@ -5,11 +5,17 @@ */ import { ESSearchSource } from '../es_search_source'; +import { AggConfigs, Schemas } from 'ui/agg_types'; import { ES_MVT_SEARCH, GIS_API_PATH, MVT_GETTILE_API_PATH, - ES_GEO_FIELD_TYPE, ES_MVT_GEO_GRID, COUNT_PROP_NAME, SOURCE_DATA_ID_ORIGIN, COLOR_MAP_TYPE, MVT_SOURCE_ID, + ES_GEO_FIELD_TYPE, + ES_MVT_GEO_GRID, + COUNT_PROP_NAME, + SOURCE_DATA_ID_ORIGIN, + COLOR_MAP_TYPE, + MVT_SOURCE_ID, MVT_GETGRIDTILE_API_PATH, } from '../../../../common/constants'; import { TiledVectorLayer } from '../../tiled_vector_layer'; import uuid from 'uuid/v4'; @@ -19,16 +25,19 @@ import { i18n } from '@kbn/i18n'; import { loadIndexSettings } from '../es_search_source/load_index_settings'; import rison from 'rison-node'; import { UpdateSourceEditor } from '../es_geo_grid_source/update_source_editor'; -import {ESGeoGridSource} from "../es_geo_grid_source"; -import {GRID_RESOLUTION} from "../../grid_resolution"; -import {RENDER_AS} from "../es_geo_grid_source/render_as"; -import {HeatmapLayer} from "../../heatmap_layer"; -import {VectorStyle} from "../../styles/vector/vector_style"; -import {VectorLayer} from "../../vector_layer"; -import {getDefaultDynamicProperties, VECTOR_STYLES} from "../../styles/vector/vector_style_defaults"; -import {DynamicStyleProperty} from "../../styles/vector/properties/dynamic_style_property"; -import {COLOR_GRADIENTS} from "../../styles/color_utils"; -import {StaticStyleProperty} from "../../styles/vector/properties/static_style_property"; +import { ESGeoGridSource, aggSchemas } from '../es_geo_grid_source'; +import { GRID_RESOLUTION } from '../../grid_resolution'; +import { RENDER_AS } from '../es_geo_grid_source/render_as'; +import { HeatmapLayer } from '../../heatmap_layer'; +import { VectorStyle } from '../../styles/vector/vector_style'; +import { VectorLayer } from '../../vector_layer'; +import { + getDefaultDynamicProperties, + VECTOR_STYLES, +} from '../../styles/vector/vector_style_defaults'; +import { DynamicStyleProperty } from '../../styles/vector/properties/dynamic_style_property'; +import { COLOR_GRADIENTS } from '../../styles/color_utils'; +import { StaticStyleProperty } from '../../styles/vector/properties/static_style_property'; export class ESMVTGeoGridSource extends ESGeoGridSource { static type = ES_MVT_GEO_GRID; @@ -63,12 +72,60 @@ export class ESMVTGeoGridSource extends ESGeoGridSource { onPreviewSource(source); }; - return ;; + return ; + } + + _makeAggConfigs(precision) { + const metricAggConfigs = this.createMetricAggConfigs(); + return [ + ...metricAggConfigs, + { + id: 'grid', + enabled: true, + type: 'geotile_grid', + schema: 'segment', + params: { + field: this._descriptor.geoField, + useGeocentroid: true, + precision: precision, + }, + }, + ]; + } + + async _makeSearchSourceWithAggConfigs(searchFilters) { + const indexPattern = await this.getIndexPattern(); + const searchSource = await this._makeSearchSource(searchFilters, 0); + const aggConfigs = new AggConfigs( + indexPattern, + this._makeAggConfigs(searchFilters.geogridPrecision), + aggSchemas.all + ); + searchSource.setField('aggs', aggConfigs.toDsl()); + return { searchSource, aggConfigs }; } async getUrlTemplate(searchFilters) { console.log('should get url template for sf', searchFilters); - return null; + + const indexPattern = await this.getIndexPattern(); + + const geoField = await this._getGeoField(); + + const { searchSource, aggConfigs } = await this._makeSearchSourceWithAggConfigs(searchFilters); + + console.log(searchSource); + + const dsl = await searchSource.getSearchRequestBody(); + console.log('dsl', dsl); + const risonDsl = rison.encode(dsl); + console.log('r', risonDsl); + + + const ipTitle = indexPattern.title; + + + return `../${GIS_API_PATH}/${MVT_GETGRIDTILE_API_PATH}?x={x}&y={y}&z={z}&indexPattern=${ipTitle}&requestBody=${risonDsl}`; } getMvtSourceLayer() { diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js b/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js index 3cac829a70c0d2..55278a918fb04e 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/color_utils.js @@ -74,7 +74,6 @@ export function getOrdinalColorRampStops( if (!colorRampName) { return null; } - console.log('so', scale, offset); return getHexColorRangeStrings(colorRampName, numberColors).reduce( (accu, stopColor, idx, srcArr) => { const stopNumber = offset + ((idx * scale) / srcArr.length); // number between 0 and 1, increasing as index increases diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js index 705c258993cd77..59a912061616f5 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js @@ -49,7 +49,6 @@ export class DynamicColorProperty extends DynamicStyleProperty { syncFillColorWithMb(mbLayerId, mbMap, alpha) { const color = this._getMbColor(); - console.log('color ul', color); mbMap.setPaintProperty(mbLayerId, 'fill-color', color); mbMap.setPaintProperty(mbLayerId, 'fill-opacity', alpha); } @@ -136,13 +135,11 @@ export class DynamicColorProperty extends DynamicStyleProperty { const fieldMeta = this._getFieldMeta(fieldName); if (!fieldMeta) { - console.log('no field meta'); return null; } colorStops = this._getMbOrdinalColorStops((fieldMeta.max - fieldMeta.min), fieldMeta.min); - console.log('cs', colorStops); getFunction = 'get'; propFieldName = fieldName; } else { @@ -151,7 +148,6 @@ export class DynamicColorProperty extends DynamicStyleProperty { propFieldName = targetName; } - console.log('cs', colorStops); if (!colorStops) { return null; diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js index add83561e342f9..85be14a324cc19 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/vector_style.js @@ -381,7 +381,6 @@ export class VectorStyle extends AbstractStyle { const data = styleMetaDataRequest.getData(); const fieldMeta = dynamicProp.pluckStyleMetaFromFieldMetaData(data); - console.log('fm', fieldMeta); return fieldMeta ? fieldMeta : fieldMetaFromLocalFeatures; }; diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index 41550e33c2f193..149214631d359f 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -10,18 +10,15 @@ import _ from 'lodash'; import { FEATURE_ID_PROPERTY_NAME, MVT_SOURCE_ID } from '../../common/constants'; export async function getTile({ - esClient, server, + request, indexPattern, - size, geometryFieldName, x, y, z, - fields = [], requestBody = {}, }) { - // server.log('info', { indexPattern, size, geometryFieldName, x, y, z, fields }); const polygon = toBoundingBox(x, y, z); try { @@ -42,16 +39,16 @@ export async function getTile({ index: indexPattern, body: requestBody, }; - server.log('info', JSON.stringify(esQuery)); - result = await esClient.search(esQuery); - server.log('result', JSON.stringify(result)); + + const { callWithRequest } = server.plugins.elasticsearch.getCluster('data'); + result = await callWithRequest(request, 'search', esQuery); } catch (e) { - server.log('error', e.message); + server.log('info', e.message); throw e; } - server.log('info', `result length ${result.body.hits.hits.length}`); - const feats = result.body.hits.hits.map(hit => { + server.log('info', `result length ${result.hits.hits.length}`); + const feats = result.hits.hits.map(hit => { let geomType; const geometry = hit._source[geometryFieldName]; if (geometry.type === 'polygon' || geometry.type === 'Polygon') { @@ -139,10 +136,9 @@ export async function getTile({ } export async function getGridTile({ - esClient, server, + request, indexPattern, - size, geometryFieldName, x, y, @@ -172,14 +168,15 @@ export async function getGridTile({ body: requestBody, }; server.log('info', JSON.stringify(esQuery)); - result = await esClient.search(esQuery); - server.log('result', JSON.stringify(result)); + + const { callWithRequest } = server.plugins.elasticsearch.getCluster('data'); + result = await callWithRequest(request, 'search', esQuery); + server.log('grid result', JSON.stringify(result)); } catch (e) { server.log('error', e.message); throw e; } - server.log('info', `result length ${result.body.hits.hits.length}`); const ffeats = []; diff --git a/x-pack/legacy/plugins/maps/server/mvt_routes.js b/x-pack/legacy/plugins/maps/server/mvt_routes.js index c304cb406b5ad3..655226e24625d5 100644 --- a/x-pack/legacy/plugins/maps/server/mvt_routes.js +++ b/x-pack/legacy/plugins/maps/server/mvt_routes.js @@ -4,19 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - GIS_API_PATH, - MVT_GETTILE_API_PATH, - MVT_GETGRIDTILE_API_PATH, -} from '../common/constants'; -import { Client } from '@elastic/elasticsearch'; -import { getTile } from './mvt/get_tile'; +import { GIS_API_PATH, MVT_GETTILE_API_PATH, MVT_GETGRIDTILE_API_PATH } from '../common/constants'; +import { getTile, getGridTile } from './mvt/get_tile'; import rison from 'rison-node'; const ROOT = `/${GIS_API_PATH}`; export function initMVTRoutes(server) { - const esClient = new Client({ node: 'http://elastic:changeme@localhost:9200' }); server.route({ method: 'GET', @@ -26,7 +20,6 @@ export function initMVTRoutes(server) { const indexPattern = query.indexPattern; - const x = parseInt(query.x); const y = parseInt(query.y); const z = parseInt(query.z); @@ -39,7 +32,7 @@ export function initMVTRoutes(server) { // server.log('info',requestBodyDSL); const tile = await getTile({ server, - esClient, + request, size, geometryFieldName, fields, @@ -47,7 +40,7 @@ export function initMVTRoutes(server) { y, z, indexPattern, - requestBody: requestBodyDSL + requestBody: requestBodyDSL, }); // server.log('info', tile); @@ -62,9 +55,6 @@ export function initMVTRoutes(server) { response = response.encoding('binary'); return response; - // return { - // q: request.query, - // }; }, }); @@ -76,7 +66,6 @@ export function initMVTRoutes(server) { const indexPattern = query.indexPattern; - const x = parseInt(query.x); const y = parseInt(query.y); const z = parseInt(query.z); @@ -89,7 +78,7 @@ export function initMVTRoutes(server) { // server.log('info',requestBodyDSL); const tile = await getGridTile({ server, - esClient, + request, size, geometryFieldName, fields, @@ -97,10 +86,9 @@ export function initMVTRoutes(server) { y, z, indexPattern, - requestBody: requestBodyDSL + requestBody: requestBodyDSL, }); - if (!tile) { return null; } From 6a4ccebc91e748e17422bab22cbe4f2fdbe08768 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sat, 1 Feb 2020 18:14:46 -0500 Subject: [PATCH 18/27] boilerplate --- .../es_mvt_geo_grid_source.js | 8 +- .../plugins/maps/server/mvt/get_tile.js | 75 ++++++++++++++----- .../legacy/plugins/maps/server/mvt_routes.js | 1 + 3 files changed, 62 insertions(+), 22 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js index abade816f07299..8c5df91038a90f 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js @@ -110,7 +110,7 @@ export class ESMVTGeoGridSource extends ESGeoGridSource { const indexPattern = await this.getIndexPattern(); - const geoField = await this._getGeoField(); + const geoFieldName = this._descriptor.geoField; const { searchSource, aggConfigs } = await this._makeSearchSourceWithAggConfigs(searchFilters); @@ -121,11 +121,13 @@ export class ESMVTGeoGridSource extends ESGeoGridSource { const risonDsl = rison.encode(dsl); console.log('r', risonDsl); - + const aggConfigNames = aggConfigs.aggs.map(config => config.id); + const aggNames = aggConfigNames.join(','); const ipTitle = indexPattern.title; + console.log('a', aggNames); - return `../${GIS_API_PATH}/${MVT_GETGRIDTILE_API_PATH}?x={x}&y={y}&z={z}&indexPattern=${ipTitle}&requestBody=${risonDsl}`; + return `../${GIS_API_PATH}/${MVT_GETGRIDTILE_API_PATH}?x={x}&y={y}&z={z}&geometryFieldName=${geoFieldName}&aggNames=${aggNames}&indexPattern=${ipTitle}&requestBody=${risonDsl}`; } getMvtSourceLayer() { diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index 149214631d359f..a4f75d519b40fe 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -137,31 +137,40 @@ export async function getTile({ export async function getGridTile({ server, + size, request, indexPattern, geometryFieldName, + aggNames, x, y, z, fields = [], requestBody = {}, }) { - // server.log('info', { indexPattern, size, geometryFieldName, x, y, z, fields }); + server.log('info', { indexPattern, aggNames, requestBody, geometryFieldName, x, y, z, fields }); const polygon = toBoundingBox(x, y, z); + const wLon = tile2long(x, z); + const sLat = tile2lat(y + 1, z); + const eLon = tile2long(x + 1, z); + const nLat = tile2lat(y, z); + try { let result; try { - const geoShapeFilter = { - geo_shape: { + const geoBoundingBox = { + geo_bounding_box: { [geometryFieldName]: { - shape: polygon, - relation: 'INTERSECTS', + top_left: [wLon, nLat], + bottom_right: [eLon, sLat], }, }, }; - requestBody.query.bool.filter.push(geoShapeFilter); + requestBody.query.bool.filter.push(geoBoundingBox); + + requestBody.aggs.grid.geotile_grid.precision = Math.min(z + 6, 24); const esQuery = { index: indexPattern, @@ -171,21 +180,49 @@ export async function getGridTile({ const { callWithRequest } = server.plugins.elasticsearch.getCluster('data'); result = await callWithRequest(request, 'search', esQuery); - server.log('grid result', JSON.stringify(result)); + + // server.log('info', JSON.stringify(result)); } catch (e) { - server.log('error', e.message); + server.log('warning', e.message); throw e; } - const ffeats = []; + result.aggregations.grid.buckets.forEach(bucket => { + const feature = { + type: 'Feature', + properties: {}, + geometry: null, + }; + + for (let i = 0; i < aggNames.length; i++) { + const aggName = aggNames[i]; + if (aggName === 'doc_count') { + feature.properties[aggName] = bucket[aggName]; + } else if (aggName === 'grid') { + //do nothing + } else { + feature.properties[aggName] = bucket[aggName].value; + } + } + + const centroid = { + type: 'Point', + coordinates: [bucket['1'].location.lon, bucket['1'].location.lat], + }; + + feature.geometry = centroid; + + ffeats.push(feature); + }); const featureCollection = { features: ffeats, type: 'FeatureCollection', }; - // server.log('info', `feature length ${featureCollection.features.length}`); + server.log('info', `feature length ${featureCollection.features.length}`); + // server.log('info', featureCollection.features); const tileIndex = geojsonvt(featureCollection, { maxZoom: 24, // max zoom to preserve detail on; can't be higher than 24 @@ -215,20 +252,20 @@ export async function getGridTile({ } function toBoundingBox(x, y, z) { - const w_lon = tile2long(x, z); - const s_lat = tile2lat(y + 1, z); - const e_lon = tile2long(x + 1, z); - const n_lat = tile2lat(y, z); + const wLon = tile2long(x, z); + const sLat = tile2lat(y + 1, z); + const eLon = tile2long(x + 1, z); + const nLat = tile2lat(y, z); const polygon = { type: 'Polygon', coordinates: [ [ - [w_lon, s_lat], - [w_lon, n_lat], - [e_lon, n_lat], - [e_lon, s_lat], - [w_lon, s_lat], + [wLon, sLat], + [wLon, nLat], + [eLon, nLat], + [eLon, sLat], + [wLon, sLat], ], ], }; diff --git a/x-pack/legacy/plugins/maps/server/mvt_routes.js b/x-pack/legacy/plugins/maps/server/mvt_routes.js index 655226e24625d5..8ad1ed0688b545 100644 --- a/x-pack/legacy/plugins/maps/server/mvt_routes.js +++ b/x-pack/legacy/plugins/maps/server/mvt_routes.js @@ -79,6 +79,7 @@ export function initMVTRoutes(server) { const tile = await getGridTile({ server, request, + aggNames: query.aggNames.split(','), size, geometryFieldName, fields, From d79e00ab7de92834d906d3ac92320f16af739233 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sat, 1 Feb 2020 18:32:59 -0500 Subject: [PATCH 19/27] add point support --- x-pack/legacy/plugins/maps/server/mvt/get_tile.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index a4f75d519b40fe..df989d138a50aa 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -59,6 +59,10 @@ export async function getTile({ geomType = 'LineString'; } else if (geometry.type === 'multilinestring' || geometry.type === 'MultiLineString') { geomType = 'MultiLineString'; + } else if (geometry.type === 'point' || geometry.type === 'Point') { + geomType = 'Point'; + } else if (geometry.type === 'MultiPoint' || geomType.type === 'multipoint') { + geomType = 'MultiPoint'; } else { return null; } From f2950fc7325b47601bca22a8e469424e4eff3682 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sat, 1 Feb 2020 18:53:05 -0500 Subject: [PATCH 20/27] run count first --- .../plugins/maps/server/mvt/get_tile.js | 131 ++++++++++-------- 1 file changed, 75 insertions(+), 56 deletions(-) diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index df989d138a50aa..6d60af3912bcf1 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -21,6 +21,8 @@ export async function getTile({ }) { const polygon = toBoundingBox(x, y, z); + let resultFeatures; + try { let result; try { @@ -41,70 +43,87 @@ export async function getTile({ }; const { callWithRequest } = server.plugins.elasticsearch.getCluster('data'); - result = await callWithRequest(request, 'search', esQuery); - } catch (e) { - server.log('info', e.message); - throw e; - } - - server.log('info', `result length ${result.hits.hits.length}`); - const feats = result.hits.hits.map(hit => { - let geomType; - const geometry = hit._source[geometryFieldName]; - if (geometry.type === 'polygon' || geometry.type === 'Polygon') { - geomType = 'Polygon'; - } else if (geometry.type === 'multipolygon' || geometry.type === 'MultiPolygon') { - geomType = 'MultiPolygon'; - } else if (geometry.type === 'linestring' || geometry.type === 'LineString') { - geomType = 'LineString'; - } else if (geometry.type === 'multilinestring' || geometry.type === 'MultiLineString') { - geomType = 'MultiLineString'; - } else if (geometry.type === 'point' || geometry.type === 'Point') { - geomType = 'Point'; - } else if (geometry.type === 'MultiPoint' || geomType.type === 'multipoint') { - geomType = 'MultiPoint'; - } else { - return null; - } - const geometryGeoJson = { - type: geomType, - coordinates: geometry.coordinates, + server.log('info', JSON.stringify(esQuery)); + const countQuery = { + index: indexPattern, + body: { + query: requestBody.query, + }, }; + const countResult = await callWithRequest(request, 'count', countQuery); + server.log('info', `count`); + server.log('info', countResult, requestBody.size); - const firstFields = {}; - if (hit.fields) { - const fields = hit.fields; - Object.keys(fields).forEach(key => { - const value = fields[key]; - if (Array.isArray(value)) { - firstFields[key] = value[0]; + if (countResult.count > requestBody.size) { + server.log('info', 'do NOT do search'); + resultFeatures = []; + } else { + server.log('do search'); + result = await callWithRequest(request, 'search', esQuery); + + server.log('info', `result length ${result.hits.hits.length}`); + const feats = result.hits.hits.map(hit => { + let geomType; + const geometry = hit._source[geometryFieldName]; + if (geometry.type === 'polygon' || geometry.type === 'Polygon') { + geomType = 'Polygon'; + } else if (geometry.type === 'multipolygon' || geometry.type === 'MultiPolygon') { + geomType = 'MultiPolygon'; + } else if (geometry.type === 'linestring' || geometry.type === 'LineString') { + geomType = 'LineString'; + } else if (geometry.type === 'multilinestring' || geometry.type === 'MultiLineString') { + geomType = 'MultiLineString'; + } else if (geometry.type === 'point' || geometry.type === 'Point') { + geomType = 'Point'; + } else if (geometry.type === 'MultiPoint' || geomType.type === 'multipoint') { + geomType = 'MultiPoint'; } else { - firstFields[key] = value; + return null; + } + const geometryGeoJson = { + type: geomType, + coordinates: geometry.coordinates, + }; + + const firstFields = {}; + if (hit.fields) { + const fields = hit.fields; + Object.keys(fields).forEach(key => { + const value = fields[key]; + if (Array.isArray(value)) { + firstFields[key] = value[0]; + } else { + firstFields[key] = value; + } + }); } - }); - } - - const properties = { - ...hit._source, - ...firstFields, - _id: hit._id, - _index: hit._index, - [FEATURE_ID_PROPERTY_NAME]: hit._id, - }; - delete properties[geometryFieldName]; - return { - type: 'Feature', - id: hit._id, - geometry: geometryGeoJson, - properties: properties, - }; - }); + const properties = { + ...hit._source, + ...firstFields, + _id: hit._id, + _index: hit._index, + [FEATURE_ID_PROPERTY_NAME]: hit._id, + }; + delete properties[geometryFieldName]; + + return { + type: 'Feature', + id: hit._id, + geometry: geometryGeoJson, + properties: properties, + }; + }); - const ffeats = feats.filter(f => !!f); + resultFeatures = feats.filter(f => !!f); + } + } catch (e) { + server.log('info', e.message); + throw e; + } const featureCollection = { - features: ffeats, + features: resultFeatures, type: 'FeatureCollection', }; From 54f735432082b61696bf8d6988cb32f663a3dea2 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sun, 2 Feb 2020 12:35:02 -0500 Subject: [PATCH 21/27] add too mny features --- x-pack/legacy/plugins/maps/common/constants.js | 1 + x-pack/legacy/plugins/maps/server/mvt/get_tile.js | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/maps/common/constants.js b/x-pack/legacy/plugins/maps/common/constants.js index 5f92a423e0d7b0..c1f1a3186afbaa 100644 --- a/x-pack/legacy/plugins/maps/common/constants.js +++ b/x-pack/legacy/plugins/maps/common/constants.js @@ -41,6 +41,7 @@ export function createMapPath(id) { } export const MVT_SOURCE_ID = 'geojsonLayer'; +export const KBN_TOO_MANY_FEATURES_PROPERTY = '__kbn_too_many_features__'; export const LAYER_TYPE = { TILE: 'TILE', diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index 6d60af3912bcf1..ffb88a48d61e7e 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -7,7 +7,7 @@ import geojsonvt from 'geojson-vt'; import vtpbf from 'vt-pbf'; import _ from 'lodash'; -import { FEATURE_ID_PROPERTY_NAME, MVT_SOURCE_ID } from '../../common/constants'; +import { FEATURE_ID_PROPERTY_NAME, MVT_SOURCE_ID, KBN_TOO_MANY_FEATURES_PROPERTY } from '../../common/constants'; export async function getTile({ server, @@ -56,9 +56,17 @@ export async function getTile({ if (countResult.count > requestBody.size) { server.log('info', 'do NOT do search'); - resultFeatures = []; + resultFeatures = [ + { + type: 'Feature', + properties: { + [KBN_TOO_MANY_FEATURES_PROPERTY]: true, + }, + geometry: polygon, + }, + ]; } else { - server.log('do search'); + server.log('info', 'do search'); result = await callWithRequest(request, 'search', esQuery); server.log('info', `result length ${result.hits.hits.length}`); From 0b7cd44bb2bc67e206505abf08bf039ed3954a10 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Sun, 2 Feb 2020 13:23:06 -0500 Subject: [PATCH 22/27] add hatchimage --- .../connected_components/map/mb/view.js | 20 +++--- .../public/layers/util/assign_feature_ids.js | 12 +++- .../layers/util/mb_filter_expressions.js | 62 +++++++++++++------ .../maps/public/layers/vector_layer.js | 35 +++++++++++ .../plugins/maps/server/mvt/get_tile.js | 1 + 5 files changed, 101 insertions(+), 29 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js index f78019bb66e423..f98f9dfd7ce504 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js @@ -143,6 +143,18 @@ export class MBMapContainer extends React.Component { mbMap.addControl(new mapboxgl.NavigationControl({ showCompass: false }), 'top-left'); } + const hatchImageBase64 = + 'data:image/png;base64,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'; + const hatchImage = new Image(); + hatchImage.onload = () => { + console.log('add image', hatchImage); + window._hatchimage = hatchImage; + mbMap.addImage('__kbn_too_many_features__', hatchImage); + }; + hatchImage.src = hatchImageBase64; + + + let emptyImage; mbMap.on('styleimagemissing', e => { if (emptyImage) { @@ -155,15 +167,9 @@ export class MBMapContainer extends React.Component { emptyImage.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII='; emptyImage.crossOrigin = 'anonymous'; - resolve(mbMap); - + resolve(mbMap); }); - - - - - }); } diff --git a/x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.js b/x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.js index a943b0b22a1891..1a447c24999b16 100644 --- a/x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.js +++ b/x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.js @@ -5,7 +5,10 @@ */ import _ from 'lodash'; -import { FEATURE_ID_PROPERTY_NAME } from '../../../common/constants'; +import { + FEATURE_ID_PROPERTY_NAME, + KBN_TOO_MANY_FEATURES_PROPERTY, +} from '../../../common/constants'; let idCounter = 0; @@ -36,17 +39,20 @@ export function assignFeatureIds(featureCollection) { for (let i = 0; i < featureCollection.features.length; i++) { const numericId = randomizedIds[i]; const feature = featureCollection.features[i]; - features.push({ + const nf = { type: 'Feature', geometry: feature.geometry, // do not copy geometry, this object can be massive properties: { // preserve feature id provided by source so features can be referenced across fetches [FEATURE_ID_PROPERTY_NAME]: feature.id == null ? numericId : feature.id, + [KBN_TOO_MANY_FEATURES_PROPERTY]: false, // create new object for properties so original is not polluted with kibana internal props ...feature.properties, }, id: numericId, // Mapbox feature state id, must be integer - }); + }; + console.log('n', nf); + features.push(nf); } return { diff --git a/x-pack/legacy/plugins/maps/public/layers/util/mb_filter_expressions.js b/x-pack/legacy/plugins/maps/public/layers/util/mb_filter_expressions.js index 36841dc727dd33..d96d0dd8627b41 100644 --- a/x-pack/legacy/plugins/maps/public/layers/util/mb_filter_expressions.js +++ b/x-pack/legacy/plugins/maps/public/layers/util/mb_filter_expressions.js @@ -4,44 +4,68 @@ * you may not use this file except in compliance with the Elastic License. */ -import { GEO_JSON_TYPE, FEATURE_VISIBLE_PROPERTY_NAME } from '../../../common/constants'; +import { + GEO_JSON_TYPE, + FEATURE_VISIBLE_PROPERTY_NAME, + KBN_TOO_MANY_FEATURES_PROPERTY, +} from '../../../common/constants'; -const VISIBILITY_FILTER_CLAUSE = ['all', ['==', ['get', FEATURE_VISIBLE_PROPERTY_NAME], true]]; +const VISIBILITY_FILTER_CLAUSE_PREFIX = [ + 'all', + ['==', ['get', FEATURE_VISIBLE_PROPERTY_NAME], true], +]; + +const TOO_MANY_FEATURES_FILTER = ['all', ['==', ['get', KBN_TOO_MANY_FEATURES_PROPERTY], false]]; const CLOSED_SHAPE_MB_FILTER = [ - 'any', - ['==', ['geometry-type'], GEO_JSON_TYPE.POLYGON], - ['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POLYGON], + ...TOO_MANY_FEATURES_FILTER, + [ + 'any', + ['==', ['geometry-type'], GEO_JSON_TYPE.POLYGON], + ['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POLYGON], + ], ]; -const VISIBLE_CLOSED_SHAPE_MB_FILTER = [...VISIBILITY_FILTER_CLAUSE, CLOSED_SHAPE_MB_FILTER]; +const VISIBLE_JOINED_CLOSED_SHAPE_MB_FILTER = [ + ...VISIBILITY_FILTER_CLAUSE_PREFIX, + CLOSED_SHAPE_MB_FILTER, +]; const ALL_SHAPE_MB_FILTER = [ - 'any', - ['==', ['geometry-type'], GEO_JSON_TYPE.POLYGON], - ['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POLYGON], - ['==', ['geometry-type'], GEO_JSON_TYPE.LINE_STRING], - ['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_LINE_STRING], + ...TOO_MANY_FEATURES_FILTER, + [ + 'any', + ['==', ['geometry-type'], GEO_JSON_TYPE.POLYGON], + ['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POLYGON], + ['==', ['geometry-type'], GEO_JSON_TYPE.LINE_STRING], + ['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_LINE_STRING], + ], ]; -const VISIBLE_ALL_SHAPE_MB_FILTER = [...VISIBILITY_FILTER_CLAUSE, ALL_SHAPE_MB_FILTER]; +const VISIBLE_JOINED_ALL_SHAPE_MB_FILTER = [ + ...VISIBILITY_FILTER_CLAUSE_PREFIX, + ALL_SHAPE_MB_FILTER, +]; const POINT_MB_FILTER = [ - 'any', - ['==', ['geometry-type'], GEO_JSON_TYPE.POINT], - ['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POINT], + ...TOO_MANY_FEATURES_FILTER, + [ + 'any', + ['==', ['geometry-type'], GEO_JSON_TYPE.POINT], + ['==', ['geometry-type'], GEO_JSON_TYPE.MULTI_POINT], + ], ]; -const VISIBLE_POINT_MB_FILTER = [...VISIBILITY_FILTER_CLAUSE, POINT_MB_FILTER]; +const VISIBLE_JOINED_POINT_MB_FILTER = [...VISIBILITY_FILTER_CLAUSE_PREFIX, POINT_MB_FILTER]; export function getFillFilterExpression(hasJoins) { - return hasJoins ? VISIBLE_CLOSED_SHAPE_MB_FILTER : CLOSED_SHAPE_MB_FILTER; + return hasJoins ? VISIBLE_JOINED_CLOSED_SHAPE_MB_FILTER : CLOSED_SHAPE_MB_FILTER; } export function getLineFilterExpression(hasJoins) { - return hasJoins ? VISIBLE_ALL_SHAPE_MB_FILTER : ALL_SHAPE_MB_FILTER; + return hasJoins ? VISIBLE_JOINED_ALL_SHAPE_MB_FILTER : ALL_SHAPE_MB_FILTER; } export function getPointFilterExpression(hasJoins) { - return hasJoins ? VISIBLE_POINT_MB_FILTER : POINT_MB_FILTER; + return hasJoins ? VISIBLE_JOINED_POINT_MB_FILTER : POINT_MB_FILTER; } diff --git a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js index a68990b596dc0a..293f5894940599 100644 --- a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js @@ -19,6 +19,7 @@ import { LAYER_TYPE, FIELD_ORIGIN, LAYER_STYLE_TYPE, + KBN_TOO_MANY_FEATURES_PROPERTY, } from '../../common/constants'; import _ from 'lodash'; import { JoinTooltipProperty } from './tooltips/join_tooltip_property'; @@ -752,6 +753,7 @@ export class VectorLayer extends AbstractLayer { const sourceId = this.getId(); const fillLayerId = this._getMbPolygonLayerId(); const lineLayerId = this._getMbLineLayerId(); + const tooManyFeaturesLayerId = this._getMbTooManyFeaturesLayerId(); const hasJoins = this._hasJoins(); if (!mbMap.getLayer(fillLayerId)) { const mbLayer = { @@ -777,6 +779,27 @@ export class VectorLayer extends AbstractLayer { } mbMap.addLayer(mbLayer); } + if (!mbMap.getLayer(tooManyFeaturesLayerId)) { + const mbLayer = { + id: tooManyFeaturesLayerId, + type: 'fill', + source: sourceId, + paint: {}, + }; + if (mvtSourceLayer) { + mbLayer['source-layer'] = mvtSourceLayer; + } + mbMap.addLayer(mbLayer); + mbMap.setFilter(tooManyFeaturesLayerId, [ + '==', + ['get', KBN_TOO_MANY_FEATURES_PROPERTY], + true, + ]); + // mbMap.setPaintProperty(tooManyFeaturesLayerId, 'fill-color', 'rgb(255,0,0)'); + mbMap.setPaintProperty(tooManyFeaturesLayerId, 'fill-pattern', '__kbn_too_many_features__'); + mbMap.setPaintProperty(tooManyFeaturesLayerId, 'fill-opacity', this.getAlpha(),); + } + this._style.setMBPaintProperties({ alpha: this.getAlpha(), mbMap, @@ -797,6 +820,13 @@ export class VectorLayer extends AbstractLayer { if (lineFilterExpr !== mbMap.getFilter(lineLayerId)) { mbMap.setFilter(lineLayerId, lineFilterExpr); } + + this.syncVisibilityWithMb(mbMap, tooManyFeaturesLayerId); + mbMap.setLayerZoomRange( + tooManyFeaturesLayerId, + this._descriptor.minZoom, + this._descriptor.maxZoom + ); } _syncStylePropertiesWithMb(mbMap) { @@ -840,6 +870,10 @@ export class VectorLayer extends AbstractLayer { return this.makeMbLayerId('fill'); } + _getMbTooManyFeaturesLayerId() { + return this.makeMbLayerId('toomanyfeatures'); + } + getMbLayerIds() { return [ this._getMbPointLayerId(), @@ -847,6 +881,7 @@ export class VectorLayer extends AbstractLayer { this._getMbSymbolLayerId(), this._getMbLineLayerId(), this._getMbPolygonLayerId(), + this._getMbTooManyFeaturesLayerId(), ]; } diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index ffb88a48d61e7e..52d549d763b9a4 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -112,6 +112,7 @@ export async function getTile({ _id: hit._id, _index: hit._index, [FEATURE_ID_PROPERTY_NAME]: hit._id, + [KBN_TOO_MANY_FEATURES_PROPERTY]: false, }; delete properties[geometryFieldName]; From 342445f418065a7460453e5601b81ed1dfaeb5a4 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Mon, 3 Feb 2020 11:54:16 -0500 Subject: [PATCH 23/27] ensure not empty tile --- x-pack/legacy/plugins/maps/server/mvt/get_tile.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index 52d549d763b9a4..b1a95992a5b3ad 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -7,7 +7,11 @@ import geojsonvt from 'geojson-vt'; import vtpbf from 'vt-pbf'; import _ from 'lodash'; -import { FEATURE_ID_PROPERTY_NAME, MVT_SOURCE_ID, KBN_TOO_MANY_FEATURES_PROPERTY } from '../../common/constants'; +import { + FEATURE_ID_PROPERTY_NAME, + MVT_SOURCE_ID, + KBN_TOO_MANY_FEATURES_PROPERTY, +} from '../../common/constants'; export async function getTile({ server, @@ -238,9 +242,11 @@ export async function getGridTile({ } } + feature.properties[KBN_TOO_MANY_FEATURES_PROPERTY] = false; + const centroid = { type: 'Point', - coordinates: [bucket['1'].location.lon, bucket['1'].location.lat], + coordinates: [parseFloat(bucket['1'].location.lon), parseFloat(bucket['1'].location.lat)], }; feature.geometry = centroid; @@ -254,7 +260,6 @@ export async function getGridTile({ }; server.log('info', `feature length ${featureCollection.features.length}`); - // server.log('info', featureCollection.features); const tileIndex = geojsonvt(featureCollection, { maxZoom: 24, // max zoom to preserve detail on; can't be higher than 24 From 0c87f572d635ca4e95431b2dec734082d530cbfa Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Mon, 3 Feb 2020 12:33:21 -0500 Subject: [PATCH 24/27] remove logs --- .../plugins/maps/public/connected_components/map/mb/view.js | 2 -- .../es_mvt_geo_grid_source/es_mvt_geo_grid_source.js | 6 ------ .../styles/vector/properties/dynamic_color_property.js | 6 ------ .../legacy/plugins/maps/public/layers/tiled_vector_layer.js | 3 --- .../plugins/maps/public/layers/util/assign_feature_ids.js | 1 - 5 files changed, 18 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js index f98f9dfd7ce504..32df4816f9cadd 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js @@ -147,8 +147,6 @@ export class MBMapContainer extends React.Component { 'data:image/png;base64,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'; const hatchImage = new Image(); hatchImage.onload = () => { - console.log('add image', hatchImage); - window._hatchimage = hatchImage; mbMap.addImage('__kbn_too_many_features__', hatchImage); }; hatchImage.src = hatchImageBase64; diff --git a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js index 8c5df91038a90f..e8959db9800fef 100644 --- a/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js +++ b/x-pack/legacy/plugins/maps/public/layers/sources/es_mvt_geo_grid_source/es_mvt_geo_grid_source.js @@ -68,7 +68,6 @@ export class ESMVTGeoGridSource extends ESGeoGridSource { const sourceDescriptor = ESMVTGeoGridSource.createDescriptor(sourceConfig); const source = new ESMVTGeoGridSource(sourceDescriptor, inspectorAdapters); - console.log('shoudl preview', source); onPreviewSource(source); }; @@ -106,7 +105,6 @@ export class ESMVTGeoGridSource extends ESGeoGridSource { } async getUrlTemplate(searchFilters) { - console.log('should get url template for sf', searchFilters); const indexPattern = await this.getIndexPattern(); @@ -114,18 +112,14 @@ export class ESMVTGeoGridSource extends ESGeoGridSource { const { searchSource, aggConfigs } = await this._makeSearchSourceWithAggConfigs(searchFilters); - console.log(searchSource); const dsl = await searchSource.getSearchRequestBody(); - console.log('dsl', dsl); const risonDsl = rison.encode(dsl); - console.log('r', risonDsl); const aggConfigNames = aggConfigs.aggs.map(config => config.id); const aggNames = aggConfigNames.join(','); const ipTitle = indexPattern.title; - console.log('a', aggNames); return `../${GIS_API_PATH}/${MVT_GETGRIDTILE_API_PATH}?x={x}&y={y}&z={z}&geometryFieldName=${geoFieldName}&aggNames=${aggNames}&indexPattern=${ipTitle}&requestBody=${risonDsl}`; } diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js index 59a912061616f5..0dfeb64b6dd5ef 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js @@ -127,12 +127,6 @@ export class DynamicColorProperty extends DynamicStyleProperty { let getFunction; let propFieldName; if (this._style.isBackedByTileSource()) { - console.log( - 'This style is backed by a tilesource, need to do some fuzzy shiat for ', - targetName, - fieldName - ); - const fieldMeta = this._getFieldMeta(fieldName); if (!fieldMeta) { return null; diff --git a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js index c7f28aacffeacc..37a7a1645626e3 100644 --- a/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/tiled_vector_layer.js @@ -75,10 +75,7 @@ export class TiledVectorLayer extends VectorLayer { nextMeta: searchFilters, }); if (canSkip) { - console.log('mvt Can skip update!'); return null; - } else { - console.log('mvt cannot skip'); } startLoading(SOURCE_DATA_ID_ORIGIN, requestToken, searchFilters); diff --git a/x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.js b/x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.js index 1a447c24999b16..bce4ff66e10f51 100644 --- a/x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.js +++ b/x-pack/legacy/plugins/maps/public/layers/util/assign_feature_ids.js @@ -51,7 +51,6 @@ export function assignFeatureIds(featureCollection) { }, id: numericId, // Mapbox feature state id, must be integer }; - console.log('n', nf); features.push(nf); } From d6f3143ffc537e29a8d2ca6b69c4f1ec54272910 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Wed, 5 Feb 2020 13:14:34 -0500 Subject: [PATCH 25/27] hack for count coloring --- .../maps/public/layers/fields/es_agg_field.js | 19 +++++-- .../properties/dynamic_color_property.js | 51 +++++++++++-------- .../properties/dynamic_style_property.js | 13 +++++ .../maps/public/layers/vector_layer.js | 7 +-- 4 files changed, 64 insertions(+), 26 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.js b/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.js index 65109cb99809fc..82ce2bce90437d 100644 --- a/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.js +++ b/x-pack/legacy/plugins/maps/public/layers/fields/es_agg_field.js @@ -5,7 +5,7 @@ */ import { AbstractField } from './field'; -import { COUNT_AGG_TYPE } from '../../../common/constants'; +import { COUNT_AGG_TYPE, METRIC_TYPE } from '../../../common/constants'; import { isMetricCountable } from '../util/is_metric_countable'; import { ESAggMetricTooltipProperty } from '../tooltips/es_aggmetric_tooltip_property'; @@ -79,10 +79,23 @@ export class ESAggMetricField extends AbstractField { supportsFieldMeta() { // count and sum aggregations are not within field bounds so they do not support field meta. - return !isMetricCountable(this.getAggType()); + // return !isMetricCountable(this.getAggType()); + return ![METRIC_TYPE.SUM, METRIC_TYPE.UNIQUE_COUNT].includes(this.getAggType()); } async getOrdinalFieldMetaRequest(config) { - return this._esDocField.getOrdinalFieldMetaRequest(config); + if (this._esDocField) { + return this._esDocField.getOrdinalFieldMetaRequest(config); + } else { + return { + type_count: { + value_count: { + script: { + source: '1', + }, + }, + }, + }; + } } } diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js index 0dfeb64b6dd5ef..51d5eb04d85466 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_color_property.js @@ -102,7 +102,8 @@ export class DynamicColorProperty extends DynamicStyleProperty { _getMbColor() { const isDynamicConfigComplete = - _.has(this._options, 'field.name') && _.has(this._options, 'color'); + _.has(this._options, 'field.name') && + (_.has(this._options, 'color') || _.has(this._options, 'useCustomColorRamp')); if (!isDynamicConfigComplete) { return null; } @@ -128,24 +129,30 @@ export class DynamicColorProperty extends DynamicStyleProperty { let propFieldName; if (this._style.isBackedByTileSource()) { const fieldMeta = this._getFieldMeta(fieldName); - if (!fieldMeta) { - return null; - } + if (this._options.useCustomColorRamp) { + getFunction = 'get'; + propFieldName = fieldName; + colorStops = this._getMbOrdinalColorStops(); - colorStops = this._getMbOrdinalColorStops((fieldMeta.max - fieldMeta.min), fieldMeta.min); - getFunction = 'get'; - propFieldName = fieldName; + } else { + if (!fieldMeta) { + return null; + } + + colorStops = this._getMbOrdinalColorStops(fieldMeta.max - fieldMeta.min, fieldMeta.min); + getFunction = 'get'; + propFieldName = fieldName; + } } else { colorStops = this._getMbOrdinalColorStops(); getFunction = 'feature-state'; propFieldName = targetName; } - - if (!colorStops) { - return null; - } + // if (!colorStops) { + // return null; + // } if (this._options.useCustomColorRamp) { const firstStopValue = colorStops[0]; @@ -157,16 +164,20 @@ export class DynamicColorProperty extends DynamicStyleProperty { 'rgba(0,0,0,0)', // MB will assign the base value to any features that is below the first stop value ...colorStops, ]; + } else { + if (!colorStops) { + return null; + } + return [ + 'interpolate', + ['linear'], + // ['coalesce', ['feature-state', targetName], -1], + ['coalesce', [getFunction, propFieldName], -1], + -1, + 'rgba(0,0,0,0)', + ...colorStops, + ]; } - return [ - 'interpolate', - ['linear'], - // ['coalesce', ['feature-state', targetName], -1], - ['coalesce', [getFunction, propFieldName], -1], - -1, - 'rgba(0,0,0,0)', - ...colorStops, - ]; } _getColorPaletteStops() { diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js index a1b711dffd0a9c..e15c884b9402c6 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js @@ -179,6 +179,19 @@ export class DynamicStyleProperty extends AbstractStyleProperty { const realFieldName = this._field.getESDocFieldName ? this._field.getESDocFieldName() : this._field.getName(); + + if (fieldMetaData.type_count && typeof fieldMetaData.type_count.value === 'number') { + const min = 0; + const max = Math.ceil(fieldMetaData.type_count.value / 1024); + return { + min: min, + max: max, + delta: max - min, + isMinOutsideStdRange: false, + isMaxOutsideStdRange: false, + }; + } + const stats = fieldMetaData[realFieldName]; if (!stats) { return null; diff --git a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js index 293f5894940599..e012381923d510 100644 --- a/x-pack/legacy/plugins/maps/public/layers/vector_layer.js +++ b/x-pack/legacy/plugins/maps/public/layers/vector_layer.js @@ -411,9 +411,9 @@ export class VectorLayer extends AbstractLayer { } async _syncSourceStyleMeta(syncContext) { - if (this._style.constructor.type !== LAYER_STYLE_TYPE.VECTOR) { - return; - } + // if (this._style.constructor.type !== LAYER_STYLE_TYPE.VECTOR) { + // return; + // } return this._syncStyleMeta({ source: this._source, @@ -460,6 +460,7 @@ export class VectorLayer extends AbstractLayer { onLoadError, registerCancelCallback, }) { + if (!source.isESSource() || dynamicStyleProps.length === 0) { return; } From a5163f60f1a02a33bc250c5891633dc8481d4e29 Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Mon, 10 Feb 2020 14:26:06 -0500 Subject: [PATCH 26/27] default countable scale --- x-pack/legacy/plugins/maps/common/constants.ts | 4 +++- .../styles/vector/properties/dynamic_style_property.js | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/maps/common/constants.ts b/x-pack/legacy/plugins/maps/common/constants.ts index db1f8a34b87cb3..73252860512807 100644 --- a/x-pack/legacy/plugins/maps/common/constants.ts +++ b/x-pack/legacy/plugins/maps/common/constants.ts @@ -56,7 +56,7 @@ export const SORT_ORDER = { DESC: 'desc', }; -//sources +// sources export const EMS_TMS = 'EMS_TMS'; export const EMS_FILE = 'EMS_FILE'; export const ES_GEO_GRID = 'ES_GEO_GRID'; @@ -168,3 +168,5 @@ export const SYMBOLIZE_AS_TYPES = { }; export const DEFAULT_ICON = 'airfield'; + +export const DEFAULT_COUNTABLE_SCALE = 2048; diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js index e15c884b9402c6..3a036740c3af9a 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/properties/dynamic_style_property.js @@ -7,7 +7,11 @@ import _ from 'lodash'; import { AbstractStyleProperty } from './style_property'; import { DEFAULT_SIGMA } from '../vector_style_defaults'; -import { COLOR_PALETTE_MAX_SIZE, STYLE_TYPE } from '../../../../../common/constants'; +import { + COLOR_PALETTE_MAX_SIZE, + DEFAULT_COUNTABLE_SCALE, + STYLE_TYPE, +} from '../../../../../common/constants'; import { scaleValue, getComputedFieldName } from '../style_util'; import React from 'react'; import { OrdinalLegend } from './components/ordinal_legend'; @@ -182,7 +186,7 @@ export class DynamicStyleProperty extends AbstractStyleProperty { if (fieldMetaData.type_count && typeof fieldMetaData.type_count.value === 'number') { const min = 0; - const max = Math.ceil(fieldMetaData.type_count.value / 1024); + const max = Math.ceil(fieldMetaData.type_count.value / DEFAULT_COUNTABLE_SCALE); return { min: min, max: max, From 439c96cd954a70e6a4e65ff9870ad3600a395eca Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Tue, 11 Feb 2020 16:39:30 -0500 Subject: [PATCH 27/27] stats --- .../connected_components/map/mb/view.js | 2 ++ .../plugins/maps/server/mvt/get_tile.js | 36 ++++++++++++++----- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js index 32df4816f9cadd..661078998d9d38 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/map/mb/view.js @@ -145,6 +145,8 @@ export class MBMapContainer extends React.Component { const hatchImageBase64 = 'data:image/png;base64,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'; + // 'data:image/png;base64,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'; + const hatchImage = new Image(); hatchImage.onload = () => { mbMap.addImage('__kbn_too_many_features__', hatchImage); diff --git a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js index b1a95992a5b3ad..011bbd06a31486 100644 --- a/x-pack/legacy/plugins/maps/server/mvt/get_tile.js +++ b/x-pack/legacy/plugins/maps/server/mvt/get_tile.js @@ -47,19 +47,23 @@ export async function getTile({ }; const { callWithRequest } = server.plugins.elasticsearch.getCluster('data'); - server.log('info', JSON.stringify(esQuery)); + // server.log('info', JSON.stringify(esQuery)); const countQuery = { index: indexPattern, body: { query: requestBody.query, }, }; + + // console.time('es-count') + const beforeCount = Date.now(); const countResult = await callWithRequest(request, 'count', countQuery); - server.log('info', `count`); - server.log('info', countResult, requestBody.size); + server.log('info', `count: ${Date.now() - beforeCount}`); + // server.log('info', `count`); + // server.log('info', countResult, requestBody.size); if (countResult.count > requestBody.size) { - server.log('info', 'do NOT do search'); + // server.log('info', 'do NOT do search'); resultFeatures = [ { type: 'Feature', @@ -70,10 +74,13 @@ export async function getTile({ }, ]; } else { - server.log('info', 'do search'); + // server.log('info', 'do search'); + const beforeSearch = Date.now(); result = await callWithRequest(request, 'search', esQuery); + server.log('info', `search ${Date.now() - beforeSearch}`); + + // server.log('info', `result length ${result.hits.hits.length}`); - server.log('info', `result length ${result.hits.hits.length}`); const feats = result.hits.hits.map(hit => { let geomType; const geometry = hit._source[geometryFieldName]; @@ -142,6 +149,7 @@ export async function getTile({ // server.log('info', `feature length ${featureCollection.features.length}`); + const beforeTile = Date.now(); const tileIndex = geojsonvt(featureCollection, { maxZoom: 24, // max zoom to preserve detail on; can't be higher than 24 tolerance: 3, // simplification tolerance (higher means simpler) @@ -155,10 +163,14 @@ export async function getTile({ indexMaxPoints: 100000, // max number of points per tile in the index }); const tile = tileIndex.getTile(z, x, y); + server.log('info', `tile ${Date.now() - beforeTile}`); if (tile) { + const beforeBuffer = Date.now(); + const pbf = vtpbf.fromGeojsonVt({ [MVT_SOURCE_ID]: tile }, { version: 2 }); const buffer = Buffer.from(pbf); + server.log('info', `buffer ${Date.now() - beforeBuffer}`); // server.log('info', `bytelength: ${buffer.byteLength}`); @@ -184,7 +196,7 @@ export async function getGridTile({ fields = [], requestBody = {}, }) { - server.log('info', { indexPattern, aggNames, requestBody, geometryFieldName, x, y, z, fields }); + // server.log('info', { indexPattern, aggNames, requestBody, geometryFieldName, x, y, z, fields }); const polygon = toBoundingBox(x, y, z); const wLon = tile2long(x, z); @@ -212,10 +224,12 @@ export async function getGridTile({ index: indexPattern, body: requestBody, }; - server.log('info', JSON.stringify(esQuery)); + // server.log('info', JSON.stringify(esQuery)); const { callWithRequest } = server.plugins.elasticsearch.getCluster('data'); + const beforeAgg = Date.now(); result = await callWithRequest(request, 'search', esQuery); + server.log('info', `geotile_search ${Date.now() - beforeAgg}`); // server.log('info', JSON.stringify(result)); } catch (e) { @@ -223,6 +237,7 @@ export async function getGridTile({ throw e; } + const beforeTile = Date.now(); const ffeats = []; result.aggregations.grid.buckets.forEach(bucket => { const feature = { @@ -259,7 +274,7 @@ export async function getGridTile({ type: 'FeatureCollection', }; - server.log('info', `feature length ${featureCollection.features.length}`); + // server.log('info', `feature length ${featureCollection.features.length}`); const tileIndex = geojsonvt(featureCollection, { maxZoom: 24, // max zoom to preserve detail on; can't be higher than 24 @@ -274,10 +289,13 @@ export async function getGridTile({ indexMaxPoints: 100000, // max number of points per tile in the index }); const tile = tileIndex.getTile(z, x, y); + server.log('info', `tile ${Date.now() - beforeTile}`); if (tile) { + const beforeBuff = Date.now(); const pbf = vtpbf.fromGeojsonVt({ [MVT_SOURCE_ID]: tile }, { version: 2 }); const buffer = Buffer.from(pbf); + server.log('info', `buffer ${Date.now() - beforeBuff}`); return buffer; } else {