kepler.gl 3.1.7 → 3.1.8

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 (136) hide show
  1. package/dist/src/actions/src/ui-state-actions.d.ts +0 -16
  2. package/dist/src/actions/src/vis-state-actions.d.ts +26 -0
  3. package/dist/src/ai-assistant/src/constants.d.ts +2 -5
  4. package/dist/src/ai-assistant/src/tools/geo-tools.d.ts +76 -25
  5. package/dist/src/ai-assistant/src/tools/tools.d.ts +76 -25
  6. package/dist/src/components/src/side-panel/add-by-dataset-button.d.ts +0 -1
  7. package/dist/src/duckdb/src/table/duckdb-table-utils.d.ts +8 -9
  8. package/dist/src/localization/src/translations/ca.d.ts +2 -0
  9. package/dist/src/localization/src/translations/cn.d.ts +2 -0
  10. package/dist/src/localization/src/translations/en.d.ts +2 -0
  11. package/dist/src/localization/src/translations/es.d.ts +2 -0
  12. package/dist/src/localization/src/translations/fi.d.ts +2 -0
  13. package/dist/src/localization/src/translations/ja.d.ts +2 -0
  14. package/dist/src/localization/src/translations/pt.d.ts +2 -0
  15. package/dist/src/localization/src/translations/ru.d.ts +2 -0
  16. package/dist/src/reducers/src/ui-state-updaters.d.ts +0 -10
  17. package/dist/src/reducers/src/vis-state-updaters.d.ts +16 -1
  18. package/dist/src/reducers/src/vis-state.d.ts +4 -0
  19. package/dist/src/schemas/src/vis-state-schema.d.ts +1 -0
  20. package/package.json +2 -2
  21. package/src/actions/dist/ui-state-actions.d.ts +0 -16
  22. package/src/actions/dist/ui-state-actions.js +2 -17
  23. package/src/actions/dist/vis-state-actions.d.ts +26 -0
  24. package/src/actions/dist/vis-state-actions.js +25 -1
  25. package/src/actions/package.json +8 -8
  26. package/src/actions/src/ui-state-actions.ts +0 -22
  27. package/src/actions/src/vis-state-actions.ts +30 -0
  28. package/src/ai-assistant/dist/components/ai-assistant-component.js +63 -4
  29. package/src/ai-assistant/dist/components/ai-assistant-config.js +55 -17
  30. package/src/ai-assistant/dist/constants.d.ts +2 -5
  31. package/src/ai-assistant/dist/constants.js +3 -21
  32. package/src/ai-assistant/dist/reducers/index.js +2 -2
  33. package/src/ai-assistant/dist/tools/geo-tools.d.ts +76 -25
  34. package/src/ai-assistant/dist/tools/geo-tools.js +44 -8
  35. package/src/ai-assistant/dist/tools/lisa-tool.js +17 -6
  36. package/src/ai-assistant/dist/tools/tools.d.ts +76 -25
  37. package/src/ai-assistant/package.json +19 -14
  38. package/src/ai-assistant/src/components/ai-assistant-component.tsx +34 -4
  39. package/src/ai-assistant/src/components/ai-assistant-config.tsx +64 -18
  40. package/src/ai-assistant/src/config/models.json +5 -24
  41. package/src/ai-assistant/src/constants.ts +21 -26
  42. package/src/ai-assistant/src/reducers/index.ts +1 -1
  43. package/src/ai-assistant/src/tools/geo-tools.tsx +70 -9
  44. package/src/ai-assistant/src/tools/lisa-tool.tsx +15 -4
  45. package/src/cloud-providers/package.json +2 -2
  46. package/src/common-utils/package.json +3 -3
  47. package/src/components/dist/kepler-gl.js +2 -2
  48. package/src/components/dist/map/map-popover.js +2 -2
  49. package/src/components/dist/map-container.js +2 -2
  50. package/src/components/dist/side-panel/add-by-dataset-button.d.ts +0 -1
  51. package/src/components/dist/side-panel/add-by-dataset-button.js +1 -3
  52. package/src/components/dist/side-panel/filter-panel/add-filter-button.js +1 -2
  53. package/src/components/dist/side-panel/layer-panel/add-layer-button.js +1 -2
  54. package/src/components/dist/side-panel/layer-panel/custom-picker.js +18 -5
  55. package/src/components/package.json +15 -15
  56. package/src/components/src/kepler-gl.tsx +1 -1
  57. package/src/components/src/map/map-popover.tsx +1 -1
  58. package/src/components/src/map-container.tsx +1 -1
  59. package/src/components/src/side-panel/add-by-dataset-button.tsx +0 -3
  60. package/src/components/src/side-panel/filter-panel/add-filter-button.tsx +0 -1
  61. package/src/components/src/side-panel/layer-panel/add-layer-button.tsx +0 -1
  62. package/src/components/src/side-panel/layer-panel/custom-picker.tsx +15 -1
  63. package/src/constants/dist/default-settings.js +1 -1
  64. package/src/constants/node_modules/.cache/terser-webpack-plugin/content-v2/sha512/e6/16/9fd3750f7cfc51cf980ec6937f88e24e5b03b144d0439efabdec6a028ce7442883abce42b76f97bffa8d37bfb65c10508e48d68a2b019c4b750a48374080 +1 -0
  65. package/src/constants/node_modules/.cache/terser-webpack-plugin/index-v5/b6/51/9b3488269917e0404a46b4db6235f226deef2d5b5b5ffb7414dafaa60b52 +2 -0
  66. package/src/constants/package.json +2 -2
  67. package/src/constants/umd/keplergl.min.js +1 -1
  68. package/src/deckgl-arrow-layers/package.json +2 -2
  69. package/src/deckgl-layers/package.json +4 -4
  70. package/src/duckdb/dist/components/sql-panel.js +34 -33
  71. package/src/duckdb/dist/table/duckdb-table-utils.d.ts +8 -9
  72. package/src/duckdb/dist/table/duckdb-table-utils.js +21 -23
  73. package/src/duckdb/dist/table/duckdb-table.js +20 -17
  74. package/src/duckdb/package.json +6 -6
  75. package/src/duckdb/src/components/sql-panel.tsx +3 -5
  76. package/src/duckdb/src/table/duckdb-table-utils.ts +19 -18
  77. package/src/duckdb/src/table/duckdb-table.ts +7 -4
  78. package/src/effects/package.json +5 -5
  79. package/src/layers/dist/geojson-layer/geojson-layer.js +5 -2
  80. package/src/layers/package.json +9 -9
  81. package/src/layers/src/geojson-layer/geojson-layer.ts +4 -1
  82. package/src/localization/dist/translations/ca.d.ts +2 -0
  83. package/src/localization/dist/translations/ca.js +3 -1
  84. package/src/localization/dist/translations/cn.d.ts +2 -0
  85. package/src/localization/dist/translations/cn.js +3 -1
  86. package/src/localization/dist/translations/en.d.ts +2 -0
  87. package/src/localization/dist/translations/en.js +4 -2
  88. package/src/localization/dist/translations/es.d.ts +2 -0
  89. package/src/localization/dist/translations/es.js +3 -1
  90. package/src/localization/dist/translations/fi.d.ts +2 -0
  91. package/src/localization/dist/translations/fi.js +3 -1
  92. package/src/localization/dist/translations/ja.d.ts +2 -0
  93. package/src/localization/dist/translations/ja.js +3 -1
  94. package/src/localization/dist/translations/pt.d.ts +2 -0
  95. package/src/localization/dist/translations/pt.js +3 -1
  96. package/src/localization/dist/translations/ru.d.ts +2 -0
  97. package/src/localization/dist/translations/ru.js +3 -1
  98. package/src/localization/package.json +1 -1
  99. package/src/localization/src/translations/ca.ts +2 -0
  100. package/src/localization/src/translations/cn.ts +2 -0
  101. package/src/localization/src/translations/en.ts +4 -2
  102. package/src/localization/src/translations/es.ts +2 -0
  103. package/src/localization/src/translations/fi.ts +2 -0
  104. package/src/localization/src/translations/ja.ts +2 -0
  105. package/src/localization/src/translations/pt.ts +2 -0
  106. package/src/localization/src/translations/ru.ts +2 -0
  107. package/src/processors/dist/file-handler.js +13 -14
  108. package/src/processors/package.json +7 -7
  109. package/src/processors/src/file-handler.ts +0 -1
  110. package/src/reducers/dist/combined-updaters.js +4 -2
  111. package/src/reducers/dist/ui-state-updaters.d.ts +0 -10
  112. package/src/reducers/dist/ui-state-updaters.js +2 -22
  113. package/src/reducers/dist/ui-state.js +2 -2
  114. package/src/reducers/dist/vis-state-updaters.d.ts +16 -1
  115. package/src/reducers/dist/vis-state-updaters.js +79 -45
  116. package/src/reducers/dist/vis-state.d.ts +4 -0
  117. package/src/reducers/dist/vis-state.js +2 -2
  118. package/src/reducers/package.json +16 -16
  119. package/src/reducers/src/combined-updaters.ts +1 -0
  120. package/src/reducers/src/ui-state-updaters.ts +0 -24
  121. package/src/reducers/src/ui-state.ts +1 -3
  122. package/src/reducers/src/vis-state-updaters.ts +74 -22
  123. package/src/reducers/src/vis-state.ts +3 -1
  124. package/src/schemas/dist/vis-state-schema.d.ts +1 -0
  125. package/src/schemas/dist/vis-state-schema.js +1 -1
  126. package/src/schemas/package.json +7 -7
  127. package/src/schemas/src/vis-state-schema.ts +1 -0
  128. package/src/styles/node_modules/.cache/terser-webpack-plugin/content-v2/sha512/f9/fc/86ccce4fa2c3e73042785814bc24476cb7cc9531d16a7c2ecb66bfc154f7b35d7416d852faa175d172da177931675cd2ba82e3b7898e8f4bf499921b00c2 +1 -0
  129. package/src/styles/node_modules/.cache/terser-webpack-plugin/index-v5/ba/31/d609a3a75657c3640471d5a925a4a64689ea3853d9379bdcd675dba816a2 +2 -0
  130. package/src/styles/package.json +2 -2
  131. package/src/styles/umd/keplergl.min.js +1 -1
  132. package/src/table/package.json +5 -5
  133. package/src/tasks/package.json +2 -2
  134. package/src/types/package.json +1 -1
  135. package/src/utils/package.json +4 -4
  136. package/umd/keplergl.min.js +1350 -1312
@@ -5,7 +5,7 @@ import React, {useEffect, useState} from 'react';
5
5
  import {useDispatch, useSelector} from 'react-redux';
6
6
  import styled from 'styled-components';
7
7
  import {textColorLT, theme} from '@kepler.gl/styles';
8
- import {MessageModel} from '@openassistant/core';
8
+ import {MessageModel, useAssistant} from '@openassistant/core';
9
9
  import {AiAssistant} from '@openassistant/ui';
10
10
  import '@openassistant/echarts/dist/index.css';
11
11
  import '@openassistant/ui/dist/index.css';
@@ -57,17 +57,46 @@ export function AiAssistantComponent() {
57
57
 
58
58
  const [datasetMetaData, setDatasetMetaData] = useState<string>('');
59
59
 
60
- // get dataset meta data
60
+ const [ideas, setIdeas] = useState<{title: string; description: string}[]>([]);
61
+
62
+ // get dataset meta data and re-initialize assistant when datasets or layers change
61
63
  useEffect(() => {
62
64
  const metaData = getDatasetContext(visState?.datasets, visState?.layers || []);
63
65
  setDatasetMetaData(metaData);
64
- // re-initialize assistant when datasets or layers change
65
66
  // eslint-disable-next-line react-hooks/exhaustive-deps
66
67
  }, [visState?.datasets, visState?.layers]);
67
68
 
68
69
  // use dataset meta data in LLM instructions
69
70
  const instructions = `${INSTRUCTIONS}\n\n${datasetMetaData}`;
70
71
 
72
+ // generate ideas from LLM
73
+ const {temporaryPrompt} = useAssistant({...assistantProps, instructions});
74
+
75
+ const generateIdeas = async () => {
76
+ try {
77
+ const response = await temporaryPrompt({
78
+ prompt: PROMPT_IDEAS,
79
+ temperature: 1.0
80
+ });
81
+ // find [{},{}...] in the text and parse it as json, handling whitespace
82
+ const match = response?.match(/\[\s*\{.*\}\s*\]/s);
83
+ if (match) {
84
+ const json = JSON.parse(match[0]);
85
+ setIdeas(json);
86
+ }
87
+ } catch (error) {
88
+ console.error('Error generating ideas', error);
89
+ }
90
+ };
91
+
92
+ useEffect(() => {
93
+ // get ideas UI component
94
+ if (ideas.length === 0 && datasetMetaData.length > 0) {
95
+ generateIdeas();
96
+ }
97
+ // eslint-disable-next-line react-hooks/exhaustive-deps
98
+ }, [datasetMetaData]);
99
+
71
100
  const onRestartAssistant = () => {
72
101
  // clean up aiAssistant state
73
102
  dispatch(updateAiAssistantMessages([]));
@@ -105,7 +134,8 @@ export function AiAssistantComponent() {
105
134
  fontSize={'text-tiny'}
106
135
  botMessageClassName={''}
107
136
  githubIssueLink={'https://github.com/keplergl/kepler.gl/issues'}
108
- ideas={PROMPT_IDEAS}
137
+ ideas={ideas}
138
+ onRefreshIdeas={generateIdeas}
109
139
  />
110
140
  </StyledAiAssistantComponent>
111
141
  );
@@ -11,7 +11,8 @@ import {
11
11
  RangeSliderFactory,
12
12
  Button,
13
13
  LoadingSpinner,
14
- appInjector
14
+ appInjector,
15
+ Checkbox
15
16
  } from '@kepler.gl/components';
16
17
  import {State} from '../index';
17
18
  import ApiKey from '../icons/api-key';
@@ -58,6 +59,15 @@ const StyledAiAssistantConfig = styled.div`
58
59
  }
59
60
  `;
60
61
 
62
+ // Ollama model input wrapper: checkbox + 'Input Model Name:' + input
63
+ // all children element have width based on the content
64
+ const OllamaModelInputWrapper = styled.div`
65
+ display: flex;
66
+ flex-direction: row;
67
+ gap: 4px;
68
+ align-items: center;
69
+ `;
70
+
61
71
  const StyledWrapper = styled.div`
62
72
  display: flex;
63
73
  justify-content: space-between;
@@ -142,12 +152,14 @@ export function AiAssistantConfig() {
142
152
  const [topP, setTopP] = useLocalStorage('ai-assistant-top-p', aiAssistantConfig.topP || 1.0);
143
153
  const [baseUrl, setBaseUrl] = useLocalStorage(
144
154
  'ai-assistant-base-url',
145
- aiAssistantConfig.baseUrl || 'http://localhost:11434'
155
+ aiAssistantConfig.baseUrl || 'http://localhost:11434/api'
146
156
  );
147
157
  const [mapboxToken, setMapboxToken] = useLocalStorage(
148
158
  'ai-assistant-mapbox-token',
149
159
  aiAssistantConfig.mapboxToken || ''
150
160
  );
161
+ const [ollamaModelInputChecked, setOllamaModelInputChecked] = useState(false);
162
+ const [ollamaModelInputValue, setOllamaModelInputValue] = useState('');
151
163
  const [connectionError, setConnectionError] = useState(false);
152
164
  const [errorMessage, setErrorMessage] = useState('');
153
165
  const [isRunning, setIsRunning] = useState(false);
@@ -192,6 +204,19 @@ export function AiAssistantConfig() {
192
204
  setMapboxToken(e.target.value);
193
205
  };
194
206
 
207
+ const onOllamaModelInputChecked = (e: React.ChangeEvent<HTMLInputElement>) => {
208
+ setOllamaModelInputChecked(e.target.checked);
209
+ if (!e.target.checked) {
210
+ // use model from selector
211
+ setModel('');
212
+ }
213
+ };
214
+
215
+ const onOllamaModelInputValueChange = (e: React.ChangeEvent<HTMLInputElement>) => {
216
+ setOllamaModelInputValue(e.target.value);
217
+ setModel(e.target.value);
218
+ };
219
+
195
220
  const onStartChat = async () => {
196
221
  setIsRunning(true);
197
222
  try {
@@ -261,21 +286,42 @@ export function AiAssistantConfig() {
261
286
  <FormattedMessage id="aiAssistantManager.llmModel.title" />
262
287
  </SectionTitle>
263
288
  </PanelLabelWrapper>
264
- <StyledWrapper>
265
- <StyledItemSelector
266
- selectedItems={model}
267
- options={PROVIDER_MODELS[provider]}
268
- multiSelect={false}
269
- disabled={false}
270
- placeholder="Select LLM Model"
271
- onChange={onLLMModelSelect}
272
- filterOption="name"
273
- getOptionValue={op => op}
274
- displayOption={op => op}
275
- searchable={false}
276
- showArrow={true}
277
- />
278
- </StyledWrapper>
289
+ {((provider === 'ollama' && !ollamaModelInputChecked) || provider !== 'ollama') && (
290
+ <StyledWrapper>
291
+ <StyledItemSelector
292
+ selectedItems={model}
293
+ options={PROVIDER_MODELS[provider]}
294
+ multiSelect={false}
295
+ disabled={provider === 'ollama' ? ollamaModelInputChecked : false}
296
+ placeholder="Select LLM Model"
297
+ onChange={onLLMModelSelect}
298
+ filterOption="name"
299
+ getOptionValue={op => op}
300
+ displayOption={op => op}
301
+ searchable={false}
302
+ showArrow={true}
303
+ />
304
+ </StyledWrapper>
305
+ )}
306
+ {provider === 'ollama' && (
307
+ <OllamaModelInputWrapper>
308
+ <div style={{width: '250px'}}>
309
+ <Checkbox
310
+ id="ollama-model-input"
311
+ label="Input Model Name"
312
+ onChange={onOllamaModelInputChecked}
313
+ checked={ollamaModelInputChecked}
314
+ />
315
+ </div>
316
+ <Input
317
+ type="text"
318
+ onChange={onOllamaModelInputValueChange}
319
+ placeholder="Enter Model Name"
320
+ value={ollamaModelInputValue}
321
+ disabled={!ollamaModelInputChecked}
322
+ />
323
+ </OllamaModelInputWrapper>
324
+ )}
279
325
  {provider !== 'ollama' ? (
280
326
  <>
281
327
  <PanelLabelWrapper>
@@ -352,7 +398,7 @@ export function AiAssistantConfig() {
352
398
  </StyleSliderWrapper>
353
399
  <>
354
400
  <PanelLabelWrapper>
355
- <SectionTitle>Mapbox Token (optional: route/isochrone)</SectionTitle>
401
+ <SectionTitle>Mapbox Token (optional for route/isochrone)</SectionTitle>
356
402
  </PanelLabelWrapper>
357
403
  <div className="api-key-input">
358
404
  <div className="api-key-input__icon">
@@ -10,11 +10,11 @@
10
10
  "o1-mini"
11
11
  ],
12
12
  "google": [
13
- "gemini-2.5-pro-exp-03-25",
13
+ "gemini-2.5-flash-preview-04-17",
14
+ "gemini-2.5-pro-preview-05-06",
14
15
  "gemini-2.0-flash",
15
16
  "gemini-1.5-flash",
16
- "gemini-1.5-pro",
17
- "gemini-1.0-pro"
17
+ "gemini-1.5-pro"
18
18
  ],
19
19
  "deepseek": ["deepseek-chat"],
20
20
  "anthropic": [
@@ -25,25 +25,6 @@
25
25
  "claude-3-sonnet",
26
26
  "claude-3-haiku"
27
27
  ],
28
- "xai": [
29
- "grok-3",
30
- "grok-3-fast",
31
- "grok-3-mini",
32
- "grok-3-mini-fast"
33
- ],
34
- "ollama": [
35
- "deepseek-coder",
36
- "deepseek-coder:6.7b",
37
- "deepseek-coder:33b",
38
- "phi-2",
39
- "qwen:14b",
40
- "qwen:72b",
41
- "llama2",
42
- "llama2:70b",
43
- "llava",
44
- "mistral",
45
- "gemma:2b",
46
- "gemma:7b",
47
- "phi-3"
48
- ]
28
+ "xai": ["grok-3", "grok-3-fast", "grok-3-mini", "grok-3-mini-fast"],
29
+ "ollama": ["deepseek-r1", "gemma3", "llama4", "llama3.3", "mistral", "phi4", "qwen3", "qwen2.5"]
49
30
  }
@@ -5,7 +5,7 @@ export const WELCOME_MESSAGE = `Hi, I am Kepler.gl AI Assistant!`;
5
5
 
6
6
  export const INSTRUCTIONS = `You are a Kepler.gl AI Assistant.
7
7
  Note:
8
- - Make a plan to answer the question before calling tools
8
+ - IMPORTANT: make a plan if tools can be used to answer the question before calling tools
9
9
  - Add emojis to your responses to make them more engaging
10
10
 
11
11
  - For tool usage:
@@ -32,6 +32,12 @@ Note:
32
32
  3. For spatial joins:
33
33
  a. Use the points dataset as the first (left) dataset
34
34
  b. Explain the join operation and its purpose
35
+ 4. For using road or line dataset in spatial analysis (e.g. local moran, spatial weights, and spatial join):
36
+ a. buffer the road by 1 meter first
37
+ b. save the buffered road as a new dataset
38
+ c. if needed, spatial join by buffered road (left) with points (right)
39
+ d. if needed, create a spatial weights using the buffered road
40
+ e. apply spatial analysis using the count in the result of spatial join
35
41
 
36
42
  - For spatial filtering:
37
43
  1. IMPORTANT: when use spatial filter to filter the points within polygons, please follow the steps:
@@ -45,32 +51,21 @@ Note:
45
51
  1. Please use the dataset name or dataset label as the datasetName argument, not the dataset id
46
52
  `;
47
53
 
48
- export const PROMPT_IDEAS = [
49
- {
50
- title: 'Data Insight',
51
- description: 'What is the distribution of the variable?'
52
- },
53
- {
54
- title: 'Spatial Analysis',
55
- description: 'Is the variable spatially clustered?'
56
- },
57
- {
58
- title: 'GeoTools',
59
- description: 'How many events in California?'
60
- },
61
- {
62
- title: 'Load Data',
63
- description: 'load data from https://geodacenter.github.io/data-and-lab/data/lehd.geojson'
64
- },
65
- {
66
- title: 'Create a Map Layer',
67
- description: 'update its color inspired by Van Gogh Starry Night'
68
- },
69
- {
70
- title: 'Change Basemap ',
71
- description: 'use Positron style'
72
- }
54
+ export const PROMPT_IDEAS = `Return ONLY a JSON array of 5 ideas based on the tools in current context.
55
+ IMPORTANT: please mention tool in a user-friendly title, and use actual field name in the description.
56
+ Do not include any other text or explanation.
57
+ Randomly pick 5 tools.
58
+ Format:
59
+ [{
60
+ "title": "Data Insight",
61
+ "description": "What is the distribution of HR60?"
62
+ },
63
+ {
64
+ "title": "Spatial Analysis",
65
+ "description": "Is HR60 spatially clustered?"
66
+ },
73
67
  ];
68
+ `;
74
69
 
75
70
  export const ASSISTANT_NAME = 'kepler-gl-ai-assistant';
76
71
 
@@ -28,7 +28,7 @@ const initialConfig: AiAssistantConfig = {
28
28
  provider: 'openai',
29
29
  model: 'gpt-4o',
30
30
  apiKey: '',
31
- baseUrl: 'http://localhost:11434',
31
+ baseUrl: 'http://localhost:11434/api',
32
32
  temperature: 0.0,
33
33
  topP: 1.0
34
34
  };
@@ -23,7 +23,10 @@ import {
23
23
  dissolve,
24
24
  length,
25
25
  area,
26
- perimeter
26
+ perimeter,
27
+ BufferTool,
28
+ CentroidTool,
29
+ DissolveTool
27
30
  } from '@openassistant/geoda';
28
31
  import {
29
32
  getUsStateGeojson,
@@ -35,7 +38,8 @@ import {
35
38
  isochrone,
36
39
  getCachedData,
37
40
  IsochroneTool,
38
- RoutingTool
41
+ RoutingTool,
42
+ roads
39
43
  } from '@openassistant/osm';
40
44
  import {Datasets} from '@kepler.gl/table';
41
45
  import {Layer} from '@kepler.gl/layers';
@@ -155,6 +159,62 @@ export function getGeoTools(
155
159
  }
156
160
  };
157
161
 
162
+ const bufferTool: BufferTool = {
163
+ ...buffer,
164
+ context: {
165
+ ...buffer.context,
166
+ getGeometries
167
+ }
168
+ };
169
+
170
+ const centroidTool: CentroidTool = {
171
+ ...centroid,
172
+ context: {
173
+ ...centroid.context,
174
+ getGeometries
175
+ }
176
+ };
177
+
178
+ const dissolveTool: DissolveTool = {
179
+ ...dissolve,
180
+ context: {
181
+ ...dissolve.context,
182
+ getGeometries
183
+ }
184
+ };
185
+
186
+ const lengthTool = {
187
+ ...length,
188
+ context: {
189
+ ...length.context,
190
+ getGeometries
191
+ }
192
+ };
193
+
194
+ const areaTool = {
195
+ ...area,
196
+ context: {
197
+ ...area.context,
198
+ getGeometries
199
+ }
200
+ };
201
+
202
+ const perimeterTool = {
203
+ ...perimeter,
204
+ context: {
205
+ ...perimeter.context,
206
+ getGeometries
207
+ }
208
+ };
209
+
210
+ const roadsTool = {
211
+ ...roads,
212
+ context: {
213
+ ...roads.context,
214
+ getGeometries
215
+ }
216
+ };
217
+
158
218
  return {
159
219
  classifyTool,
160
220
  weightsTool,
@@ -163,19 +223,20 @@ export function getGeoTools(
163
223
  lisaTool,
164
224
  spatialJoinTool,
165
225
  spatialFilterTool,
166
- buffer,
167
- centroid,
168
- dissolve,
169
- length,
170
- area,
171
- perimeter,
226
+ bufferTool,
227
+ centroidTool,
228
+ dissolveTool,
229
+ lengthTool,
230
+ areaTool,
231
+ perimeterTool,
172
232
  getUsStateGeojson,
173
233
  getUsCountyGeojson,
174
234
  getUsZipcodeGeojson,
175
235
  queryUSZipcodes,
176
236
  geocoding,
177
237
  routing: routingTool,
178
- isochrone: isochroneTool
238
+ isochrone: isochroneTool,
239
+ roads: roadsTool
179
240
  };
180
241
  }
181
242
 
@@ -81,6 +81,7 @@ export function LisaToolComponent({
81
81
  for (let i = 0; i < colors.length; i++) {
82
82
  colorLegends[colors[i]] = labels[i];
83
83
  }
84
+ const colorMap = colors.map((color, index) => [index, color]);
84
85
  const newLayer = {
85
86
  id: layerId,
86
87
  type: layer.type,
@@ -93,17 +94,27 @@ export function LisaToolComponent({
93
94
  }, {}),
94
95
  colorScale: 'customOrdinal',
95
96
  colorField,
96
- strokeColorField: null,
97
+ strokeColorDomain: colorDomain,
98
+ strokeColorField: colorField,
99
+ strokeColorScale: 'customOrdinal',
97
100
  visConfig: {
98
101
  ...layer.config.visConfig,
99
102
  colorRange: {
100
103
  ...layer.config.visConfig.colorRange,
101
104
  colorDomain,
102
- colors: colors,
103
- colorMap: colors.map((color, index) => [index, color]),
105
+ colors,
106
+ colorMap,
104
107
  colorLegends
105
108
  },
106
- stroked: false
109
+ strokeColorRange: {
110
+ category: 'Custom',
111
+ name: 'custom',
112
+ colors,
113
+ colorMap
114
+ },
115
+ strokeOpacity: 1,
116
+ stroked: true,
117
+ strokedWidth: 0.5
107
118
  }
108
119
  }
109
120
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kepler.gl/cloud-providers",
3
3
  "author": "Shan He <shan@uber.com>",
4
- "version": "3.1.7",
4
+ "version": "3.1.8",
5
5
  "description": "kepler.gl constants used by kepler.gl components, actions and reducers",
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
@@ -30,7 +30,7 @@
30
30
  "umd"
31
31
  ],
32
32
  "dependencies": {
33
- "@kepler.gl/types": "3.1.7",
33
+ "@kepler.gl/types": "3.1.8",
34
34
  "react": "^18.2.0"
35
35
  },
36
36
  "nyc": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kepler.gl/common-utils",
3
3
  "author": "Shan He <heshan0131@gmail.com>",
4
- "version": "3.1.7",
4
+ "version": "3.1.8",
5
5
  "description": "kepler.gl common utils",
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
@@ -30,8 +30,8 @@
30
30
  "umd"
31
31
  ],
32
32
  "dependencies": {
33
- "@kepler.gl/constants": "3.1.7",
34
- "@kepler.gl/types": "3.1.7",
33
+ "@kepler.gl/constants": "3.1.8",
34
+ "@kepler.gl/types": "3.1.8",
35
35
  "d3-array": "^2.8.0",
36
36
  "global": "^4.3.0",
37
37
  "h3-js": "^3.1.0",