kepler.gl 3.1.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/README.md +27 -132
  2. package/dist/src/common-utils/src/data-type.d.ts +9 -1
  3. package/dist/src/components/src/common/data-table/header-cell.d.ts +1 -0
  4. package/dist/src/components/src/common/data-table/index.d.ts +1 -0
  5. package/dist/src/components/src/common/file-uploader/file-drop.d.ts +1 -32
  6. package/dist/src/components/src/common/item-selector/dropdown-list.d.ts +2 -2
  7. package/dist/src/components/src/common/item-selector/item-selector.d.ts +1 -1
  8. package/dist/src/components/src/common/item-selector/typeahead.d.ts +1 -1
  9. package/dist/src/components/src/geocoder/geocoder.d.ts +7 -0
  10. package/dist/src/components/src/geocoder-panel.d.ts +2 -2
  11. package/dist/src/components/src/hooks/use-fetch-vector-tile-metadata.d.ts +4 -3
  12. package/dist/src/constants/src/default-settings.d.ts +14 -1
  13. package/dist/src/deckgl-arrow-layers/src/constants.d.ts +0 -12
  14. package/dist/src/deckgl-arrow-layers/src/index.d.ts +0 -1
  15. package/dist/src/deckgl-arrow-layers/src/utils/utils.d.ts +12 -1
  16. package/dist/src/duckdb/src/components/preview-data-panel.d.ts +7 -2
  17. package/dist/src/duckdb/src/components/schema-panel.d.ts +12 -3
  18. package/dist/src/duckdb/src/processors/data-processor.d.ts +1 -0
  19. package/dist/src/duckdb/src/table/duckdb-table-utils.d.ts +106 -0
  20. package/dist/src/duckdb/src/table/duckdb-table.d.ts +5 -3
  21. package/dist/src/processors/src/data-processor.d.ts +15 -1
  22. package/dist/src/reducers/src/provider-state-updaters.d.ts +1 -0
  23. package/dist/src/reducers/src/vis-state-updaters.d.ts +1 -1
  24. package/dist/src/table/src/dataset-utils.d.ts +1 -1
  25. package/dist/src/table/src/tileset/vector-tile-utils.d.ts +17 -1
  26. package/dist/src/utils/src/application-config.d.ts +4 -3
  27. package/dist/src/utils/src/data-utils.d.ts +9 -3
  28. package/dist/src/utils/src/indexed-data-container.d.ts +2 -2
  29. package/dist/src/utils/src/map-style-utils/mapbox-utils.d.ts +1 -1
  30. package/dist/src/utils/src/map-utils.d.ts +1 -1
  31. package/dist/src/utils/src/plot.d.ts +2 -2
  32. package/package.json +5 -5
  33. package/src/actions/package.json +8 -8
  34. package/src/ai-assistant/dist/components/ai-assistant-component.js +2 -1
  35. package/src/ai-assistant/package.json +7 -7
  36. package/src/ai-assistant/src/components/ai-assistant-component.tsx +1 -0
  37. package/src/cloud-providers/package.json +2 -2
  38. package/src/common-utils/dist/data-type.d.ts +9 -1
  39. package/src/common-utils/dist/data-type.js +50 -1
  40. package/src/common-utils/package.json +3 -3
  41. package/src/common-utils/src/data-type.ts +49 -1
  42. package/src/components/dist/common/data-table/header-cell.d.ts +1 -0
  43. package/src/components/dist/common/data-table/header-cell.js +2 -2
  44. package/src/components/dist/common/data-table/index.d.ts +1 -0
  45. package/src/components/dist/common/data-table/index.js +5 -1
  46. package/src/components/dist/common/file-uploader/file-drop.d.ts +1 -32
  47. package/src/components/dist/common/file-uploader/file-drop.js +152 -167
  48. package/src/components/dist/common/item-selector/dropdown-list.d.ts +2 -2
  49. package/src/components/dist/common/item-selector/dropdown-list.js +2 -3
  50. package/src/components/dist/common/item-selector/item-selector.d.ts +1 -1
  51. package/src/components/dist/common/item-selector/typeahead.d.ts +1 -1
  52. package/src/components/dist/common/range-brush.js +3 -3
  53. package/src/components/dist/geocoder/geocoder.d.ts +7 -0
  54. package/src/components/dist/geocoder/geocoder.js +19 -11
  55. package/src/components/dist/geocoder-panel.d.ts +2 -2
  56. package/src/components/dist/geocoder-panel.js +64 -91
  57. package/src/components/dist/hooks/use-fetch-vector-tile-metadata.d.ts +4 -3
  58. package/src/components/dist/hooks/use-fetch-vector-tile-metadata.js +35 -26
  59. package/src/components/dist/hooks/use-legend-position.js +8 -4
  60. package/src/components/dist/map/map-legend-panel.js +2 -3
  61. package/src/components/dist/modal-container.js +8 -8
  62. package/src/components/dist/modals/tilesets-modals/tileset-vector-form.js +31 -12
  63. package/src/components/dist/side-panel/layer-panel/color-palette-preset.js +2 -2
  64. package/src/components/dist/side-panel/layer-panel/color-range-selector.js +10 -11
  65. package/src/components/dist/side-panel/layer-panel/color-selector.js +3 -3
  66. package/src/components/dist/side-panel/layer-panel/custom-palette.js +1 -2
  67. package/src/components/dist/side-panel/layer-panel/layer-configurator.js +6 -8
  68. package/src/components/dist/side-panel/layer-panel/vector-tile-layer-configurator.js +1 -2
  69. package/src/components/package.json +16 -16
  70. package/src/components/src/common/data-table/header-cell.tsx +2 -1
  71. package/src/components/src/common/data-table/index.tsx +4 -0
  72. package/src/components/src/common/file-uploader/file-drop.tsx +186 -161
  73. package/src/components/src/common/item-selector/dropdown-list.tsx +1 -6
  74. package/src/components/src/common/range-brush.tsx +2 -2
  75. package/src/components/src/geocoder/geocoder.tsx +16 -8
  76. package/src/components/src/geocoder-panel.tsx +95 -85
  77. package/src/components/src/hooks/use-fetch-vector-tile-metadata.ts +27 -25
  78. package/src/components/src/hooks/use-legend-position.ts +5 -2
  79. package/src/components/src/map/map-legend-panel.tsx +1 -2
  80. package/src/components/src/modal-container.tsx +7 -7
  81. package/src/components/src/modals/tilesets-modals/tileset-vector-form.tsx +12 -3
  82. package/src/components/src/side-panel/layer-panel/color-palette-preset.tsx +1 -1
  83. package/src/components/src/side-panel/layer-panel/color-range-selector.tsx +6 -11
  84. package/src/components/src/side-panel/layer-panel/color-selector.tsx +2 -2
  85. package/src/components/src/side-panel/layer-panel/custom-palette.tsx +0 -1
  86. package/src/components/src/side-panel/layer-panel/layer-configurator.tsx +23 -33
  87. package/src/components/src/side-panel/layer-panel/vector-tile-layer-configurator.tsx +0 -1
  88. package/src/constants/dist/default-settings.d.ts +14 -1
  89. package/src/constants/dist/default-settings.js +20 -5
  90. package/src/constants/node_modules/.cache/terser-webpack-plugin/content-v2/sha512/91/4f/6c65f3a1eba584ffd2d892cabc25ab5804d4a9ef53694c98707372a83e56343a274bec04f15927a6fe7602615f0f23f73ccf599f524ef97ad6c77c8832ea +1 -0
  91. package/src/constants/node_modules/.cache/terser-webpack-plugin/index-v5/a6/b2/5424aa4477192fb44cc90fd80892efdc96731f2ff0f48e8f28abf64243cc +2 -0
  92. package/src/constants/package.json +2 -2
  93. package/src/constants/src/default-settings.ts +16 -1
  94. package/src/constants/umd/keplergl.min.js +2 -2
  95. package/src/deckgl-arrow-layers/dist/constants.d.ts +0 -12
  96. package/src/deckgl-arrow-layers/dist/constants.js +4 -15
  97. package/src/deckgl-arrow-layers/dist/index.d.ts +0 -1
  98. package/src/deckgl-arrow-layers/dist/index.js +1 -8
  99. package/src/deckgl-arrow-layers/dist/layers/geo-arrow-scatterplot-layer.js +4 -4
  100. package/src/deckgl-arrow-layers/dist/layers/geo-arrow-text-layer.js +5 -5
  101. package/src/deckgl-arrow-layers/dist/utils/utils.d.ts +12 -1
  102. package/src/deckgl-arrow-layers/dist/utils/utils.js +7 -5
  103. package/src/deckgl-arrow-layers/package.json +2 -1
  104. package/src/deckgl-arrow-layers/src/constants.ts +0 -13
  105. package/src/deckgl-arrow-layers/src/index.ts +0 -2
  106. package/src/deckgl-arrow-layers/src/layers/geo-arrow-scatterplot-layer.ts +5 -3
  107. package/src/deckgl-arrow-layers/src/layers/geo-arrow-text-layer.ts +8 -4
  108. package/src/deckgl-arrow-layers/src/utils/utils.ts +7 -5
  109. package/src/deckgl-layers/dist/deckgl-extensions/filter-arrow-layer.d.ts +1 -1
  110. package/src/deckgl-layers/dist/deckgl-extensions/filter-shader-module.d.ts +1 -1
  111. package/src/deckgl-layers/dist/deckgl-extensions/filter-shader-module.js +3 -3
  112. package/src/deckgl-layers/package.json +5 -5
  113. package/src/deckgl-layers/src/deckgl-extensions/filter-shader-module.ts +4 -3
  114. package/src/duckdb/dist/components/monaco-editor.js +4 -5
  115. package/src/duckdb/dist/components/preview-data-panel.d.ts +7 -2
  116. package/src/duckdb/dist/components/preview-data-panel.js +7 -8
  117. package/src/duckdb/dist/components/schema-panel.d.ts +12 -3
  118. package/src/duckdb/dist/components/schema-panel.js +41 -24
  119. package/src/duckdb/dist/components/sql-panel.js +245 -56
  120. package/src/duckdb/dist/init.js +20 -14
  121. package/src/duckdb/dist/processors/data-processor.d.ts +1 -0
  122. package/src/duckdb/dist/processors/data-processor.js +4 -4
  123. package/src/duckdb/dist/table/duckdb-table-utils.d.ts +106 -0
  124. package/src/duckdb/dist/table/duckdb-table-utils.js +493 -2
  125. package/src/duckdb/dist/table/duckdb-table.d.ts +5 -3
  126. package/src/duckdb/dist/table/duckdb-table.js +153 -261
  127. package/src/duckdb/package.json +6 -6
  128. package/src/duckdb/src/components/monaco-editor.tsx +3 -3
  129. package/src/duckdb/src/components/preview-data-panel.tsx +15 -8
  130. package/src/duckdb/src/components/schema-panel.tsx +92 -21
  131. package/src/duckdb/src/components/sql-panel.tsx +160 -22
  132. package/src/duckdb/src/init.ts +4 -1
  133. package/src/duckdb/src/processors/data-processor.ts +2 -2
  134. package/src/duckdb/src/table/duckdb-table-utils.ts +407 -1
  135. package/src/duckdb/src/table/duckdb-table.ts +61 -92
  136. package/src/effects/package.json +5 -5
  137. package/src/layers/dist/arc-layer/arc-layer.d.ts +1 -1
  138. package/src/layers/dist/arc-layer/arc-layer.js +2 -3
  139. package/src/layers/dist/base-layer.d.ts +7 -6
  140. package/src/layers/dist/base-layer.js +36 -19
  141. package/src/layers/dist/geojson-layer/geojson-layer.js +4 -2
  142. package/src/layers/dist/geojson-layer/geojson-utils.js +10 -3
  143. package/src/layers/dist/heatmap-layer/heatmap-layer.d.ts +2 -0
  144. package/src/layers/dist/heatmap-layer/heatmap-layer.js +16 -9
  145. package/src/layers/dist/icon-layer/icon-layer.d.ts +6 -3
  146. package/src/layers/dist/icon-layer/icon-layer.js +19 -11
  147. package/src/layers/dist/index.d.ts +1 -1
  148. package/src/layers/dist/index.js +1 -1
  149. package/src/layers/dist/layer-text-label.d.ts +9 -0
  150. package/src/layers/dist/layer-text-label.js +51 -6
  151. package/src/layers/dist/layer-utils.d.ts +39 -30
  152. package/src/layers/dist/layer-utils.js +69 -9
  153. package/src/layers/dist/line-layer/line-layer.d.ts +1 -1
  154. package/src/layers/dist/line-layer/line-layer.js +2 -3
  155. package/src/layers/dist/point-layer/point-layer.d.ts +10 -7
  156. package/src/layers/dist/point-layer/point-layer.js +16 -8
  157. package/src/layers/dist/trip-layer/trip-layer.d.ts +2 -2
  158. package/src/layers/dist/trip-layer/trip-layer.js +4 -2
  159. package/src/layers/dist/vector-tile/abstract-tile-layer.d.ts +3 -7
  160. package/src/layers/dist/vector-tile/abstract-tile-layer.js +7 -6
  161. package/src/layers/dist/vector-tile/vector-tile-layer.d.ts +5 -7
  162. package/src/layers/dist/vector-tile/vector-tile-layer.js +23 -2
  163. package/src/layers/package.json +11 -10
  164. package/src/layers/src/arc-layer/arc-layer.ts +1 -1
  165. package/src/layers/src/base-layer.ts +50 -9
  166. package/src/layers/src/geojson-layer/geojson-layer.ts +3 -1
  167. package/src/layers/src/geojson-layer/geojson-utils.ts +4 -1
  168. package/src/layers/src/heatmap-layer/heatmap-layer.ts +17 -12
  169. package/src/layers/src/icon-layer/icon-layer.ts +7 -3
  170. package/src/layers/src/index.ts +1 -2
  171. package/src/layers/src/layer-text-label.ts +53 -4
  172. package/src/layers/src/layer-utils.ts +88 -9
  173. package/src/layers/src/line-layer/line-layer.ts +1 -1
  174. package/src/layers/src/point-layer/point-layer.ts +15 -11
  175. package/src/layers/src/trip-layer/trip-layer.ts +4 -2
  176. package/src/layers/src/vector-tile/abstract-tile-layer.ts +11 -5
  177. package/src/layers/src/vector-tile/vector-tile-layer.ts +33 -4
  178. package/src/localization/package.json +1 -1
  179. package/src/processors/dist/data-processor.d.ts +15 -1
  180. package/src/processors/dist/data-processor.js +104 -11
  181. package/src/processors/package.json +8 -7
  182. package/src/processors/src/data-processor.ts +116 -13
  183. package/src/reducers/dist/export-utils.js +2 -2
  184. package/src/reducers/dist/layer-utils.js +1 -1
  185. package/src/reducers/dist/provider-state-updaters.d.ts +1 -0
  186. package/src/reducers/dist/provider-state-updaters.js +5 -2
  187. package/src/reducers/dist/vis-state-updaters.d.ts +1 -1
  188. package/src/reducers/dist/vis-state-updaters.js +23 -12
  189. package/src/reducers/package.json +16 -16
  190. package/src/reducers/src/export-utils.ts +1 -1
  191. package/src/reducers/src/layer-utils.ts +2 -1
  192. package/src/reducers/src/provider-state-updaters.ts +4 -1
  193. package/src/reducers/src/vis-state-updaters.ts +45 -10
  194. package/src/schemas/dist/dataset-schema.js +35 -6
  195. package/src/schemas/package.json +7 -7
  196. package/src/schemas/src/dataset-schema.ts +36 -8
  197. package/src/styles/node_modules/.cache/terser-webpack-plugin/content-v2/sha512/a3/a9/7f26bbc52905b0e21e9366a30ef0ba98f4ccf9aa8dd8326d90ba90191ba2e305323f505bf134c825356156c793bf9386ed2cef2aeb48eb327c26d106f69a +1 -0
  198. package/src/styles/node_modules/.cache/terser-webpack-plugin/index-v5/7e/51/b8756555a0e2e696d944445ac23f7febf769006013fbc8419f39a701649d +2 -0
  199. package/src/styles/package.json +2 -2
  200. package/src/styles/umd/keplergl.min.js +2 -2
  201. package/src/table/dist/dataset-utils.js +23 -14
  202. package/src/table/dist/src/table/src/dataset-utils.d.ts +1 -1
  203. package/src/table/dist/src/table/src/tileset/vector-tile-utils.d.ts +17 -1
  204. package/src/table/dist/tileset/vector-tile-utils.js +122 -2
  205. package/src/table/package.json +5 -5
  206. package/src/table/src/dataset-utils.ts +16 -6
  207. package/src/table/src/tileset/vector-tile-utils.ts +131 -8
  208. package/src/tasks/package.json +2 -2
  209. package/src/types/actions.d.ts +1 -0
  210. package/src/types/layers.d.ts +1 -0
  211. package/src/types/package.json +1 -1
  212. package/src/types/types.d.ts +17 -0
  213. package/src/utils/dist/application-config.d.ts +4 -3
  214. package/src/utils/dist/application-config.js +3 -2
  215. package/src/utils/dist/data-scale-utils.js +4 -4
  216. package/src/utils/dist/data-utils.d.ts +9 -3
  217. package/src/utils/dist/data-utils.js +40 -7
  218. package/src/utils/dist/dataset-utils.js +23 -8
  219. package/src/utils/dist/indexed-data-container.d.ts +2 -2
  220. package/src/utils/dist/indexed-data-container.js +1 -1
  221. package/src/utils/dist/map-style-utils/mapbox-utils.d.ts +1 -1
  222. package/src/utils/dist/map-style-utils/mapbox-utils.js +3 -3
  223. package/src/utils/dist/plot.d.ts +2 -2
  224. package/src/utils/dist/plot.js +6 -6
  225. package/src/utils/map-utils.spec.js +1 -2
  226. package/src/utils/package.json +5 -4
  227. package/src/utils/src/application-config.ts +11 -8
  228. package/src/utils/src/data-scale-utils.ts +3 -3
  229. package/src/utils/src/data-utils.ts +36 -7
  230. package/src/utils/src/dataset-utils.ts +41 -9
  231. package/src/utils/src/indexed-data-container.ts +1 -1
  232. package/src/utils/src/map-style-utils/mapbox-utils.ts +2 -2
  233. package/src/utils/src/plot.ts +5 -5
  234. package/umd/keplergl.min.js +1279 -1295
@@ -11,6 +11,7 @@ import {KeyEvent} from '@kepler.gl/constants';
11
11
  import {Input} from '../common/styled-components';
12
12
  import {Search, Delete} from '../common/icons';
13
13
  import {Viewport} from '@kepler.gl/types';
14
+ import {isTest} from '@kepler.gl/utils';
14
15
 
15
16
  type StyledContainerProps = {
16
17
  width?: number;
@@ -18,13 +19,21 @@ type StyledContainerProps = {
18
19
 
19
20
  // matches only valid coordinates
20
21
  const COORDINATE_REGEX_STRING =
21
- '^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?),\\s*[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)';
22
+ '(^[-+]?(?:[1-8]?\\d(?:\\.\\d+)?|90(?:\\.0+)?)),\\s*([-+]?(?:180(?:\\.0+)?|(?:(?:1[0-7]\\d)|(?:[1-9]?\\d))(?:\\.\\d+)?))$';
23
+
22
24
  const COORDINATE_REGEX = RegExp(COORDINATE_REGEX_STRING);
23
25
 
24
26
  const PLACEHOLDER = 'Enter an address or coordinates, ex 37.79,-122.40';
25
27
 
26
28
  let debounceTimeout: NodeJS.Timeout | null = null;
27
29
 
30
+ /**
31
+ * Tests if a given query string contains valid coordinates.
32
+ * @param query The input string to test for coordinates.
33
+ * @returns A tuple where:
34
+ * - If valid, returns `[true, longitude, latitude]`.
35
+ * - If invalid, returns `[false, query]`.
36
+ */
28
37
  export const testForCoordinates = (query: string): [true, number, number] | [false, string] => {
29
38
  const isValid = COORDINATE_REGEX.test(query.trim());
30
39
 
@@ -33,8 +42,10 @@ export const testForCoordinates = (query: string): [true, number, number] | [fal
33
42
  }
34
43
 
35
44
  const tokens = query.trim().split(',');
45
+ const latitude = Number(tokens[0]);
46
+ const longitude = Number(tokens[1]);
36
47
 
37
- return [isValid, Number(tokens[0]), Number(tokens[1])];
48
+ return [isValid, longitude, latitude];
38
49
  };
39
50
 
40
51
  const StyledContainer = styled.div<StyledContainerProps>`
@@ -121,7 +132,6 @@ type IntlProps = {
121
132
  intl: IntlShape;
122
133
  };
123
134
 
124
- /** @type {import('./geocoder').GeocoderComponent} */
125
135
  const GeoCoder: React.FC<GeocoderProps & IntlProps> = ({
126
136
  mapboxApiAccessToken,
127
137
  className = '',
@@ -139,13 +149,12 @@ const GeoCoder: React.FC<GeocoderProps & IntlProps> = ({
139
149
  const [inputValue, setInputValue] = useState('');
140
150
  const [showResults, setShowResults] = useState(false);
141
151
  const [showDelete, setShowDelete] = useState(false);
142
- /** @type {import('./geocoder').Results} */
143
152
  const initialResults: Result[] = [];
144
153
  const [results, setResults] = useState(initialResults);
145
154
  const [selectedIndex, setSelectedIndex] = useState(0);
146
155
 
147
156
  const client = useMemo(
148
- () => geocoderService({accessToken: mapboxApiAccessToken}),
157
+ () => (isTest() ? null : geocoderService({accessToken: mapboxApiAccessToken})),
149
158
  [mapboxApiAccessToken]
150
159
  );
151
160
 
@@ -155,9 +164,8 @@ const GeoCoder: React.FC<GeocoderProps & IntlProps> = ({
155
164
  setInputValue(queryString);
156
165
  const resultCoordinates = testForCoordinates(queryString);
157
166
  if (resultCoordinates[0]) {
158
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
159
- const [_, latitude, longitude] = resultCoordinates;
160
- setResults([{center: [latitude, longitude], place_name: queryString}]);
167
+ const [_isValid, longitude, latitude] = resultCoordinates;
168
+ setResults([{center: [longitude, latitude], place_name: queryString}]);
161
169
  } else {
162
170
  if (debounceTimeout) {
163
171
  clearTimeout(debounceTimeout);
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  // Copyright contributors to the kepler.gl project
3
3
 
4
- import React, {Component, ComponentType} from 'react';
4
+ import React, {useCallback} from 'react';
5
5
  import styled, {IStyledComponent} from 'styled-components';
6
6
  import classnames from 'classnames';
7
7
  import {processRowObject} from '@kepler.gl/processors';
@@ -138,90 +138,100 @@ interface GeocoderPanelProps {
138
138
  unsyncedViewports: boolean;
139
139
  }
140
140
 
141
- export default function GeocoderPanelFactory(): ComponentType<GeocoderPanelProps> {
142
- class GeocoderPanel extends Component<GeocoderPanelProps> {
143
- defaultProps = {
144
- transitionDuration: 3000
145
- };
146
-
147
- removeGeocoderDataset() {
148
- this.props.removeDataset(GEOCODER_DATASET_NAME);
149
- }
150
-
151
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
152
- onSelected = (viewport: Viewport | null = null, geoItem: Result) => {
153
- const {
154
- center: [lon, lat],
155
- text,
156
- bbox
157
- } = geoItem;
158
- const {layerOrder} = this.props;
159
-
160
- const updateVisDataPayload = getUpdateVisDataPayload(lat, lon, text);
161
- if (updateVisDataPayload) {
162
- this.removeGeocoderDataset();
163
- this.props.updateVisData(...updateVisDataPayload, generateConfig(layerOrder));
164
- }
165
-
166
- const bounds = bbox || [
167
- lon - GEOCODER_GEO_OFFSET,
168
- lat - GEOCODER_GEO_OFFSET,
169
- lon + GEOCODER_GEO_OFFSET,
170
- lat + GEOCODER_GEO_OFFSET
171
- ];
172
- const centerAndZoom = getCenterAndZoomFromBounds(bounds, {
173
- width: this.props.mapState.width,
174
- height: this.props.mapState.height
175
- });
176
-
177
- if (!centerAndZoom) {
178
- // failed to fit bounds
179
- return;
180
- }
181
-
182
- this.props.updateMap(
183
- {
184
- latitude: centerAndZoom.center[1],
185
- longitude: centerAndZoom.center[0],
186
- // For marginal or invalid bounds, zoom may be NaN. Make sure to provide a valid value in order
187
- // to avoid corrupt state and potential crashes as zoom is expected to be a number
188
- ...(Number.isFinite(centerAndZoom.zoom) ? {zoom: centerAndZoom.zoom} : {}),
189
- pitch: 0,
190
- bearing: 0,
191
- transitionDuration: this.props.transitionDuration,
192
- transitionInterpolator: new FlyToInterpolator()
193
- },
194
- this.props.index
195
- );
196
- };
197
-
198
- removeMarker = () => {
199
- this.removeGeocoderDataset();
200
- };
201
-
202
- render() {
203
- const {className, isGeocoderEnabled, mapboxApiAccessToken, width, index, unsyncedViewports} =
204
- this.props;
205
- return (
206
- <StyledGeocoderPanel
207
- className={classnames('geocoder-panel', className)}
208
- width={width}
209
- index={index}
210
- unsyncedViewports={unsyncedViewports}
211
- style={{display: isGeocoderEnabled ? 'block' : 'none'}}
212
- >
213
- {isValid(mapboxApiAccessToken) && (
214
- <Geocoder
215
- mapboxApiAccessToken={mapboxApiAccessToken}
216
- onSelected={this.onSelected}
217
- onDeleteMarker={this.removeMarker}
218
- width={width}
219
- />
220
- )}
221
- </StyledGeocoderPanel>
222
- );
223
- }
224
- }
141
+ export default function GeocoderPanelFactory(): React.FC<GeocoderPanelProps> {
142
+ const GeocoderPanel = ({
143
+ isGeocoderEnabled,
144
+ mapState,
145
+ mapboxApiAccessToken,
146
+ updateVisData,
147
+ removeDataset,
148
+ updateMap,
149
+ layerOrder,
150
+ transitionDuration = 3000,
151
+ width,
152
+ className,
153
+ index,
154
+ unsyncedViewports
155
+ }: GeocoderPanelProps) => {
156
+ const removeGeocoderDataset = useCallback(() => {
157
+ removeDataset(GEOCODER_DATASET_NAME);
158
+ }, [removeDataset]);
159
+
160
+ const onSelected = useCallback(
161
+ (_viewport: Viewport | null = null, geoItem: Result) => {
162
+ const {
163
+ center: [lon, lat],
164
+ text,
165
+ bbox
166
+ } = geoItem;
167
+
168
+ const updateVisDataPayload = getUpdateVisDataPayload(lat, lon, text);
169
+ if (updateVisDataPayload) {
170
+ removeGeocoderDataset();
171
+ updateVisData(...updateVisDataPayload, generateConfig(layerOrder));
172
+ }
173
+
174
+ const bounds = bbox || [
175
+ lon - GEOCODER_GEO_OFFSET,
176
+ lat - GEOCODER_GEO_OFFSET,
177
+ lon + GEOCODER_GEO_OFFSET,
178
+ lat + GEOCODER_GEO_OFFSET
179
+ ];
180
+ const centerAndZoom = getCenterAndZoomFromBounds(bounds, {
181
+ width: mapState.width,
182
+ height: mapState.height
183
+ });
184
+
185
+ if (!centerAndZoom) {
186
+ // failed to fit bounds
187
+ return;
188
+ }
189
+
190
+ updateMap(
191
+ {
192
+ latitude: centerAndZoom.center[1],
193
+ longitude: centerAndZoom.center[0],
194
+ // For marginal or invalid bounds, zoom may be NaN. Make sure to provide a valid value in order
195
+ // to avoid corrupt state and potential crashes as zoom is expected to be a number
196
+ ...(Number.isFinite(centerAndZoom.zoom) ? {zoom: centerAndZoom.zoom} : {}),
197
+ pitch: 0,
198
+ bearing: 0,
199
+ transitionDuration,
200
+ transitionInterpolator: new FlyToInterpolator()
201
+ },
202
+ index
203
+ );
204
+ },
205
+ [
206
+ index,
207
+ layerOrder,
208
+ mapState,
209
+ removeGeocoderDataset,
210
+ transitionDuration,
211
+ updateMap,
212
+ updateVisData
213
+ ]
214
+ );
215
+
216
+ return (
217
+ <StyledGeocoderPanel
218
+ className={classnames('geocoder-panel', className)}
219
+ width={width}
220
+ index={index}
221
+ unsyncedViewports={unsyncedViewports}
222
+ style={{display: isGeocoderEnabled ? 'block' : 'none'}}
223
+ >
224
+ {isValid(mapboxApiAccessToken) && (
225
+ <Geocoder
226
+ mapboxApiAccessToken={mapboxApiAccessToken}
227
+ onSelected={onSelected}
228
+ onDeleteMarker={removeGeocoderDataset}
229
+ width={width}
230
+ />
231
+ )}
232
+ </StyledGeocoderPanel>
233
+ );
234
+ };
225
235
 
226
236
  return GeocoderPanel;
227
237
  }
@@ -1,16 +1,17 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  // Copyright contributors to the kepler.gl project
3
3
 
4
- import {useCallback, useEffect, useState} from 'react';
4
+ import {useEffect, useState} from 'react';
5
5
 
6
- import {/* MVTSource,*/ TileJSON} from '@loaders.gl/mvt';
6
+ import {TileJSON} from '@loaders.gl/mvt';
7
7
  import {PMTilesSource, PMTilesMetadata} from '@loaders.gl/pmtiles';
8
8
 
9
9
  import {RemoteTileFormat} from '@kepler.gl/constants';
10
- import {getMVTMetadata, VectorTileMetadata} from '@kepler.gl/table';
10
+ import {getMVTMetadata, VectorTileMetadata, getFieldsFromTile} from '@kepler.gl/table';
11
11
 
12
12
  type FetchVectorTileMetadataProps = {
13
- url: string | null;
13
+ metadataUrl: string | null;
14
+ tilesetUrl: string | null;
14
15
  remoteTileFormat: RemoteTileFormat;
15
16
  process?: (json: PMTilesMetadata | TileJSON) => VectorTileMetadata | Error | null;
16
17
  };
@@ -36,39 +37,25 @@ type FetchVectorTileMetadataReturn = {
36
37
  /** Hook to fetch and return mvt or pmtiles metadata. */
37
38
  export default function useFetchVectorTileMetadata({
38
39
  remoteTileFormat,
39
- url,
40
+ tilesetUrl,
41
+ metadataUrl,
40
42
  process = DEFAULT_PROCESS_FUNCTION
41
43
  }: FetchVectorTileMetadataProps): FetchVectorTileMetadataReturn {
42
44
  const [error, setError] = useState<Error | null>(null);
43
45
  const [data, setData] = useState<VectorTileMetadata | null>(null);
44
46
  const [loading, setLoading] = useState<boolean>(false);
45
47
 
46
- const setProcessedData = useCallback(
47
- (value: PMTilesMetadata | TileJSON | null) => {
48
- if (!value) {
49
- return setError(value);
50
- }
51
- const processedData = process(value);
52
- if (processedData instanceof Error) {
53
- setError(processedData);
54
- } else {
55
- setData(processedData);
56
- }
57
- },
58
- [setError, setData, process]
59
- );
60
-
61
48
  useEffect(() => {
62
49
  const getAndProcessMetadata = async () => {
63
50
  setError(null);
64
51
  setData(null);
65
- if (url) {
52
+ if (metadataUrl) {
66
53
  setLoading(true);
67
54
 
68
55
  try {
69
56
  let metadata: PMTilesMetadata | TileJSON | null = null;
70
57
  if (remoteTileFormat === RemoteTileFormat.MVT) {
71
- metadata = await getMVTMetadata(url);
58
+ metadata = await getMVTMetadata(metadataUrl);
72
59
 
73
60
  // MVTSource returns messy partial metadata
74
61
  // MVTSource.createDataSource('', {
@@ -77,7 +64,7 @@ export default function useFetchVectorTileMetadata({
77
64
  // }
78
65
  // })
79
66
  } else {
80
- const tileSource = PMTilesSource.createDataSource(url, {});
67
+ const tileSource = PMTilesSource.createDataSource(metadataUrl, {});
81
68
  metadata = await tileSource.metadata;
82
69
  }
83
70
 
@@ -85,7 +72,22 @@ export default function useFetchVectorTileMetadata({
85
72
  if (!metadata) {
86
73
  throw new Error('Failed to fetch metadata');
87
74
  }
88
- setProcessedData(metadata);
75
+
76
+ const processedMetadata = process(metadata);
77
+ if (processedMetadata instanceof Error) {
78
+ setError(processedMetadata);
79
+ } else {
80
+ setError(null);
81
+
82
+ await getFieldsFromTile({
83
+ remoteTileFormat,
84
+ tilesetUrl,
85
+ metadataUrl,
86
+ metadata: processedMetadata
87
+ });
88
+
89
+ setData(processedMetadata);
90
+ }
89
91
  } catch (metadataError) {
90
92
  setError(metadataError as any);
91
93
  }
@@ -94,7 +96,7 @@ export default function useFetchVectorTileMetadata({
94
96
  };
95
97
 
96
98
  getAndProcessMetadata();
97
- }, [url, remoteTileFormat, setProcessedData]);
99
+ }, [metadataUrl, tilesetUrl, remoteTileFormat, setError, setData, process]);
98
100
 
99
101
  return {data, loading, error};
100
102
  }
@@ -81,7 +81,8 @@ export function useCalcLegendPosition({
81
81
  ? {y: topOffset, anchorY: 'top'}
82
82
  : {y: bottomOffset, anchorY: 'bottom'})
83
83
  };
84
- }, [isSidePanelShown, legendContentRef?.current, sidePanelWidth]);
84
+ // eslint-disable-next-line react-hooks/exhaustive-deps
85
+ }, [isSidePanelShown, sidePanelWidth]);
85
86
  }
86
87
 
87
88
  /**
@@ -116,6 +117,7 @@ export default function useLegendPosition({
116
117
  if (content instanceof HTMLElement) {
117
118
  startHeightRef.current = content.offsetHeight;
118
119
  }
120
+ // eslint-disable-next-line react-hooks/exhaustive-deps
119
121
  }, []);
120
122
  const resize = useCallback(
121
123
  deltaY => {
@@ -133,6 +135,7 @@ export default function useLegendPosition({
133
135
  }
134
136
  }
135
137
  },
138
+ // eslint-disable-next-line react-hooks/exhaustive-deps
136
139
  [contentHeight, pos, onChangeSettings]
137
140
  );
138
141
 
@@ -152,7 +155,7 @@ export default function useLegendPosition({
152
155
  });
153
156
  }
154
157
  }
155
- }, [isSidePanelShown, onChangeSettings]);
158
+ }, [isSidePanelShown, onChangeSettings, sidePanelWidth]);
156
159
 
157
160
  return {positionStyles, updatePosition, contentHeight, startResize, resize};
158
161
  }
@@ -300,7 +300,6 @@ const MapLegendPanelComponent = ({
300
300
  onClickControlBtn,
301
301
  isViewportUnsyncAllowed = true,
302
302
  className,
303
- interactionConfig,
304
303
  MapControlTooltip,
305
304
  MapControlPanel,
306
305
  MapLegend
@@ -387,7 +386,7 @@ function MapLegendPanelFactory(
387
386
  ): MapLegendPanelComponentType {
388
387
  const MapLegendPanel = withState(
389
388
  [uiStateLens],
390
- state => {
389
+ _state => {
391
390
  return {
392
391
  MapControlTooltip,
393
392
  MapControlPanel,
@@ -60,7 +60,6 @@ import {
60
60
  } from '@kepler.gl/actions';
61
61
  import {ModalDialogProps} from './common/modal';
62
62
  import {Provider} from '@kepler.gl/cloud-providers';
63
- import {findDOMNode} from 'react-dom';
64
63
  import {VisState} from '@kepler.gl/schemas';
65
64
 
66
65
  const DataTableModalStyle = css`
@@ -195,7 +194,8 @@ export default function ModalContainerFactory(
195
194
  disableDataOperation: true
196
195
  },
197
196
  {
198
- autoCreateLayers: true
197
+ autoCreateLayers: true,
198
+ centerMap: true
199
199
  }
200
200
  );
201
201
  this._closeModal();
@@ -228,12 +228,12 @@ export default function ModalContainerFactory(
228
228
  const toSave = exportMap(this.props);
229
229
 
230
230
  this.props.providerActions.exportFileToCloud({
231
- // @ts-ignore
232
231
  mapData: toSave,
233
232
  provider,
234
233
  options: {
235
234
  isPublic,
236
- overwrite
235
+ overwrite,
236
+ mapIdToOverwrite: this.props.providerState.savedMapId
237
237
  },
238
238
  closeModal,
239
239
  onSuccess: this.props.onExportToCloudSuccess,
@@ -250,8 +250,8 @@ export default function ModalContainerFactory(
250
250
  });
251
251
  };
252
252
 
253
- _onOverwriteMap = () => {
254
- this._onSaveMap(true);
253
+ _onOverwriteMap = provider => {
254
+ this._onSaveMap(provider, true);
255
255
  };
256
256
 
257
257
  _onShareMapUrl = provider => {
@@ -532,7 +532,7 @@ export default function ModalContainerFactory(
532
532
 
533
533
  return rootNode ? (
534
534
  <ModalDialog
535
- parentSelector={() => findDOMNode(rootNode) as HTMLElement}
535
+ parentSelector={() => rootNode as HTMLElement}
536
536
  isOpen={Boolean(currentModal)}
537
537
  onCancel={this._closeModal}
538
538
  {...modalProps}
@@ -95,10 +95,13 @@ const TilesetVectorForm: React.FC<TilesetVectorFormProps> = ({setResponse}) => {
95
95
  event.preventDefault();
96
96
  const newTileUrl = event.target.value;
97
97
  setTileUrl(newTileUrl);
98
- const potentialMetadataUrl = isPMTilesUrl(newTileUrl) ? newTileUrl : getMetaUrl(newTileUrl);
98
+
99
+ const usePMTiles = isPMTilesUrl(newTileUrl);
100
+ const potentialMetadataUrl = usePMTiles ? newTileUrl : getMetaUrl(newTileUrl);
99
101
  if (!metadataUrl && potentialMetadataUrl) {
100
102
  // check if URL exists before setting it as the metadata URL
101
- const resp = await fetch(potentialMetadataUrl);
103
+ // Note: The {method: HEAD} request often fails, likely due to individual storage settings.
104
+ const resp = usePMTiles ? ({ok: true} as Response) : await fetch(potentialMetadataUrl);
102
105
  if (resp.ok) {
103
106
  setInitialFetchError(null);
104
107
  setMetadataUrl(potentialMetadataUrl);
@@ -127,11 +130,17 @@ const TilesetVectorForm: React.FC<TilesetVectorFormProps> = ({setResponse}) => {
127
130
  loading,
128
131
  error: metaError
129
132
  } = useFetchVectorTileMetadata({
130
- url: metadataUrl,
133
+ metadataUrl,
134
+ tilesetUrl: tileUrl,
131
135
  remoteTileFormat: isPMTilesUrl(metadataUrl) ? RemoteTileFormat.PMTILES : RemoteTileFormat.MVT,
132
136
  process
133
137
  });
134
138
 
139
+ // reset initial fetch error if the metadata is available
140
+ if (metadata && initialFetchError) {
141
+ setInitialFetchError(null);
142
+ }
143
+
135
144
  useEffect(() => {
136
145
  if (tileName && tileUrl) {
137
146
  const dataset = getDatasetAttributesFromVectorTile({
@@ -54,7 +54,7 @@ const PresetColorPalette: React.FC<PresetColorPaletteProps> = ({
54
54
  <StyledColorPalette>
55
55
  {themes.map(theme => (
56
56
  <StyledColorColumn key={theme} className="single-color-palette__column">
57
- {range(1, ROWS + 1, 1).map((key, i) => (
57
+ {range(1, ROWS + 1, 1).map(key => (
58
58
  <StyledColorBlock
59
59
  className="single-color-palette__block"
60
60
  style={{
@@ -105,16 +105,19 @@ const CONFIG_SETTINGS = {
105
105
  };
106
106
  const displayOption = d => capitalizeFirstLetter(d);
107
107
  const getOptionValue = d => d;
108
+ const noop = () => {
109
+ // do nothing
110
+ };
108
111
 
109
112
  ColorRangeSelectorFactory.deps = [CustomPaletteFactory];
110
113
  function ColorRangeSelectorFactory(
111
114
  CustomPalette: ReturnType<typeof CustomPaletteFactory>
112
115
  ): React.FC<ColorRangeSelectorProps> {
113
116
  const ColorRangeSelector: React.FC<ColorRangeSelectorProps> = ({
114
- colorPalettes,
117
+ colorPalettes = KEPLER_COLOR_PALETTES,
115
118
  colorPaletteUI,
116
- setColorPaletteUI,
117
- onSelectColorRange,
119
+ setColorPaletteUI = noop,
120
+ onSelectColorRange = noop,
118
121
  selectedColorRange
119
122
  }) => {
120
123
  const {customPalette, showSketcher, colorRangeConfig} = colorPaletteUI;
@@ -214,14 +217,6 @@ function ColorRangeSelectorFactory(
214
217
  );
215
218
  };
216
219
 
217
- ColorRangeSelector.defaultProps = {
218
- colorPalettes: KEPLER_COLOR_PALETTES,
219
- // eslint-disable-next-line @typescript-eslint/no-empty-function
220
- onSelectColorRange: () => {},
221
- // eslint-disable-next-line @typescript-eslint/no-empty-function
222
- setColorPaletteUI: () => {}
223
- };
224
-
225
220
  return ColorRangeSelector;
226
221
  }
227
222
 
@@ -168,7 +168,7 @@ function ColorSelectorFactory(
168
168
  setColor(colorSet, color, colorSet.selectedColor[3]);
169
169
  }
170
170
  },
171
- [colorSets, editingColorSet, setColor]
171
+ [editingColorSet, setColor]
172
172
  );
173
173
 
174
174
  const onSelectOpacity = useCallback(
@@ -179,7 +179,7 @@ function ColorSelectorFactory(
179
179
  setColor(colorSet, colorSet.selectedColor, Math.round(opacity[1] * 255));
180
180
  }
181
181
  },
182
- [colorSets, editingColorSet, setColor]
182
+ [editingColorSet, setColor]
183
183
  );
184
184
 
185
185
  const onToggleDropdown = useCallback(
@@ -714,7 +714,6 @@ export const CategoricalCustomPaletteInput: React.FC<CategoricalCustomPaletteInp
714
714
  actionIcons = defaultActionIcons,
715
715
  onDelete,
716
716
  disableDelete,
717
- onAdd,
718
717
  onToggleSketcher,
719
718
  addColorMapValue,
720
719
  removeColorMapValue,