kepler.gl是一种基于数据的高性能Web应用程序,用于可视化大规模地理位置数据集。 kepler.gl建立在Maplibre GL和Deck.gl的顶部,可以使数百万分,代表数千个旅行,并随时执行空间聚集。
kepler.gl也是一种使用Redux来管理其状态和数据流的反应组件。它可以嵌入其他React-Redux应用程序中,并且非常可定制。有关如何在应用中嵌入kepler.gl的信息,请查看有关Vis.Academy的分步教程。
使用节点18.18.2或更高版本,尚未支持/测试较旧的节点版本。为了获得最佳结果,请使用NVM nvm install
。
安装节点( > 18.18.2
),纱线和项目依赖项
npm install --save kepler.gl
// or
yarn add kepler.gl
kepler.gl是在mapbox上构建的。您将需要一个Mapbox访问令牌才能使用它。
如果您不使用模块捆绑器,那也很好。 kepler.gl NPM软件包包括在UMD文件夹中预编译的UMD构建。您可以将脚本标签添加到以下内容的HTML文件中:
< script src =" https://unpkg.com/kepler.gl/umd/keplergl.min.js " />
或者,如果愿意,可以加载特定版本
< script src =" https://unpkg.com/[email protected]/umd/keplergl.min.js " />
查看本地开发kepler.gl的开发指南。
这是将kepler.gl导入应用程序的基本步骤。您还要查看示例文件夹。文件夹中的每个示例都可以在本地安装并运行。
Kepler.gl使用Redux以及React-Palm中间件来管理其内部状态,以处理副作用。
您也需要将react-palm
的taskMiddleware
添加到您的商店中。我们正在积极地研究不需要react-palm
解决方案,但是它仍然是一种非常轻巧的副作用管理工具,比反应thunk更容易测试。
import { createStore , combineReducers , applyMiddleware , compose } from 'redux' ;
import keplerGlReducer from '@kepler.gl/reducers' ;
import { enhanceReduxMiddleware } from '@kepler.gl/middleware' ;
const initialState = { } ;
const reducers = combineReducers ( {
// <-- mount kepler.gl reducer in your app
keplerGl : keplerGlReducer ,
// Your other reducers here
app : appReducer
} ) ;
// using createStore
export default createStore (
reducer ,
initialState ,
applyMiddleware (
enhanceReduxMiddleware ( [
/* Add other middlewares here */
] )
)
) ;
或使用增强剂:
// using enhancers
const initialState = { } ;
const middlewares = enhanceReduxMiddleware ( [
// Add other middlewares here
] ) ;
const enhancers = [ applyMiddleware ( ... middlewares ) ] ;
export default createStore ( reducer , initialState , compose ( ... enhancers ) ) ;
如果将kepler.gl还原固定在另一个地址而不是keplerGl
,或者kepler.gl降低器未安装在状态的根部,则需要在使用getState
Prop安装组件时指定其路径。
阅读有关还原器的更多信息。
import KeplerGl from '@kepler.gl/components' ;
const Map = props => (
< KeplerGl id = "foo" width = { width } mapboxApiAccessToken = { token } height = { height } / >
) ;
id
(字符串,必需)map
此Keplergl实例的ID。如果您的应用中有多个KeplerGL实例,则需要id
。它定义了存储在keplergl还原器中的开plergl状态的道具名称。例如,具有ID foo
的Keplergl组件的状态存储在state.keplerGl.foo
中。
如果您使用相同的ID创建多个kepler.gl实例,则该条目定义的kepler.gl状态将被最新实例覆盖并重置为空白状态。
mapboxApiAccessToken
(字符串,必需*)undefined
默认情况下,kepler.gl使用mapbox-gl.js呈现其基本地图。您可以在Mapbox上创建一个免费帐户,并在www.mapbox.com/account/access-tokens上创建一个令牌。
如果您用自己的默认地图样式替换了kepler.gl,则不是Mapbox样式。不需要mapboxApiAccessToken
。
阅读有关自定义地图样式的更多信息。
getState
(功能,可选)state => state.keplerGl
您还原器中的根开蛋白酶状态的路径。
width
(数字,可选)800
开头UI的宽度。
height
(数字,可选)800
appName
(字符串,可选)Kepler.Gl
侧面面板标题显示的应用程序名称
version
(字符串,可选)v1.0
版本显示在侧面板标题中
onSaveMap
(功能,可选)undefined
在单击侧面面板标题中单击“保存地图URL”时调用的操作。
onViewStateChange
(功能,可选)undefined
viewState
更新的视图状态对象,其中包含经度,纬度,缩放等参数MAP视口更新时触发操作。
getMapboxRef(mapbox, index)
(功能,可选)undefined
当KeplerGL
添加或删除具有内部MAPBOX映射的MapContainer
组件时,调用的函数。
mapbox
参数是添加时添加时MapRef
或删除时为null
。
单个映射index
参数为0,对于附加地图,索引参数为1(因为KeplerGL
支持可选的拆分映射视图)。
actions
(对象,可选){}
动作创建者替换默认kepler.gl动作创建者。仅在要修改操作有效载荷时才使用自定义操作。
mint
(布尔,可选)true
安装组件时是否加载新鲜的空状态。当解析mint: true
kepler.gl组件将始终加载新的状态时,重新安装相同的组件时,该组件内部内部的状态一旦其卸载后将被破坏。通过解析mint: false
kepler.gl即使将组件状态保存在商店中,即使它被卸载,并在重新重新安装时将其用作初始状态。在将Kepler.gl安装在模态中时,这很有用,并在重新打开时保留相同的地图。
阅读有关组件的更多信息。
theme
(对象|字符串,可选)null
"dark"
, "light"
或"base"
之一,您可以传递用于自定义kepler.gl样式的主题名称或对象。 kepler.gl除了默认的“黑暗”主题外,还提供了一个'light'
主题。当传递到主题对象时,kepler.gl将使用传递的值作为输入来覆盖主题的值。
阅读有关自定义主题的更多信息
mapboxApiUrl
(字符串,可选)https://api.mapbox.com
如果您使用自己的Mapbox Tile Server,则可以传递自己的图块服务器API URL。
mapStylesReplaceDefault
(布尔,可选)false
kepler.gl提供4种地图样式可供选择。如果您想提供自己的mapStyles
请通过true
。见下文。
mapStyles
(数组,可选)[]
您可以提供以地图样式选择面板显示的其他地图样式。默认情况下,将添加其他地图样式中的默认地图样式。如果通过mapStylesReplaceDefault: true
,它们将替换默认情况。 kepler.gl将尝试根据其id
命名约定对您的样式进行分组,并使用它允许基本映射层的可见性。提供自己的layerGroups
以覆盖默认值以进行更准确的图层分组。
每个mapStyles
都应具有以下属性:
id
(字符串,必需)独特的字符串,不应muted
这些保留的dark
light
之一。 muted_night
label
(字符串,必需)将显示在地图样式选择面板中url
(字符串,必需)MAPBOX样式URL或指向MAP样式JSON对象用Mapbox GL样式规范编写的URL。icon
(字符串,可选)样式的图像图标,可以是URL或图像数据URLlayerGroups
(数组,可选) const mapStyles = [
{
id : 'my_dark_map' ,
label : 'Dark Streets 9' ,
url : 'mapbox://styles/mapbox/dark-v9' ,
icon : ` ${ apiHost } /styles/v1/mapbox/dark-v9/static/-122.3391,37.7922,9.19,0,0/400x300?access_token= ${ accessToken } &logo=false&attribution=false` ,
layerGroups : [
{
slug : 'label' ,
filter : ( { id } ) => id . match ( / (?=(label|place-|poi-)) / ) ,
defaultVisibility : true
} ,
{
// adding this will keep the 3d building option
slug : '3d building' ,
filter : ( ) => false ,
defaultVisibility : false
}
]
}
] ;
阅读有关自定义地图样式的更多信息。
initialUiState
(对象,可选)undefined
应用于uistate还原器的Intial UI状态,值将与默认的INITIAL_UI_STATE
合并。
localeMessages
(对象,可选)undefined
修改默认翻译或添加新的翻译阅读有关本地化的更多信息。
keplerGl
还原器进行定制操作。使用还原器比React组件状态处理Keplergl状态的优点是自定义其行为的灵活性。如果您的应用程序中只有一个KeplerGl
实例,或者从不打算从组件本身外部派遣操作来开头,则无需担心转发调度并可以继续进行下一节。但是生活充满了自定义,我们希望使您的生活尽可能愉快。
有多种方法可以将操作派遣到特定的KeplerGl
实例。
每个操作都映射到kepler.gl中的简化器更新程序。您可以导入与特定操作相对应的还原更新程序,并使用先前的状态和有效载荷来调用它以获取更新的状态。例如, updateVisDataUpdater
是ActionTypes.UPDATE_VIS_DATA
的更新程序(请查看每个reducers/vis-state.js
以进行更新映射的操作)。这是一个示例,您可以如何收听应用程序Action QUERY_SUCCESS
并调用updateVisDataUpdater
将数据加载到Kepler.gl中。
import { keplerGlReducer , visStateUpdaters } from '@kepler.gl/reducers' ;
// Root Reducer
const reducers = combineReducers ( {
keplerGl : keplerGlReducer ,
app : appReducer
} ) ;
const composedReducer = ( state , action ) => {
switch ( action . type ) {
case 'QUERY_SUCCESS' :
return {
... state ,
keplerGl : {
... state . keplerGl ,
// 'map' is the id of the keplerGl instance
map : {
... state . keplerGl . map ,
visState : visStateUpdaters . updateVisDataUpdater ( state . keplerGl . map . visState , {
datasets : action . payload
} )
}
}
} ;
}
return reducers ( state , action ) ;
} ;
export default composedReducer ;
阅读有关使用更新程序修改kepler.gl状态的更多信息
connect
您可以使用CONNECT将派遣功能添加到组件中,该功能将操作分配给特定的keplerGl
组件。
// component
import KeplerGl from '@kepler.gl/components' ;
// action and forward dispatcher
import { toggleFullScreen , forwardTo } from '@kepler.gl/actions' ;
import { connect } from 'react-redux' ;
const MapContainer = props => (
< div >
< button onClick = { ( ) => props . keplerGlDispatch ( toggleFullScreen ( ) ) } / >
< KeplerGl
id = "foo"
/ >
< / div >
)
const mapStateToProps = state => state
const mapDispatchToProps = ( dispatch , props ) => ( {
dispatch ,
keplerGlDispatch : forwardTo ( ‘foo’ , dispatch )
} ) ;
export default connect (
mapStateToProps ,
mapDispatchToProps
) ( MapContainer ) ;
您也可以简单地将动作与wrapTo
Helper一起进行前进动作
// component
import KeplerGl from '@kepler.gl/components' ;
// action and forward dispatcher
import { toggleFullScreen , wrapTo } from '@kepler.gl/actions' ;
// create a function to wrapper action payload to 'foo'
const wrapToMap = wrapTo ( 'foo' ) ;
const MapContainer = ( { dispatch } ) => (
< div >
< button onClick = { ( ) => dispatch ( wrapToMap ( toggleFullScreen ( ) ) } / >
< KeplerGl
id = "foo"
/ >
< / div >
) ;
阅读有关前进派遣动作的更多信息
Kepler.gl使用样式组件实现CSS样式。通过使用上述框架Kepler.gl提供了使用以下方法自定义其样式/主题的能力:
本主题列出了要自定义的可用属性。
自定义主题示例。
您可以通过将主题道具传递给kepler.gl react组件来自定义kepler.gl主题:
const white = '#ffffff' ;
const customTheme = {
sidePanelBg : white ,
titleTextColor : '#000000' ,
sidePanelHeaderBg : '#f7f7F7' ,
subtextColorActive : '#2473bd'
} ;
return (
< KeplerGl
mapboxApiAccessToken = { MAPBOX_TOKEN }
id = "map"
width = { 800 }
height = { 800 }
theme = { customTheme }
/ >
) ;
如您所见,castheme对象定义了某些属性,这些属性将覆盖kepler.gl默认样式规则。
为了使用theaprovider自定义kepler.gl主题,您可以使用theprovider在以下内容中简单地包装kepler.gl。
import { ThemeProvider } from 'styled-components' ;
const white = '#ffffff' ;
const customTheme = {
sidePanelBg : white ,
titleTextColor : '#000000' ,
sidePanelHeaderBg : '#f7f7F7' ,
subtextColorActive : '#2473bd'
} ;
return (
< ThemeProvider theme = { customTheme } >
< KeplerGl mapboxApiAccessToken = { MAPBOX_TOKEN } id = "map" width = { 800 } height = { 800 } / >
< / ThemeProvider >
) ;
每个人都希望灵活地渲染自定义kepler.gl组件。 kepler.gl具有依赖项注入系统,可让您注入组件来替换现有的注入系统。您需要做的就是为要替换的组件创建一个组件工厂,导入原始组件工厂,并在安装KeplerGl
的应用程序组件上调用injectComponents
。查看examples/demo-app/src/app.js
,看看它如何在kepler.gl中呈现自定义的侧面面板标头
import { injectComponents , PanelHeaderFactory } from '@kepler.gl/components' ;
// define custom header
const CustomHeader = ( ) => < div > My kepler.gl app < / div > ;
const myCustomHeaderFactory = ( ) => CustomHeader ;
// Inject custom header into Kepler.gl, replacing default
const KeplerGl = injectComponents ( [ [ PanelHeaderFactory , myCustomHeaderFactory ] ] ) ;
// render KeplerGl, it will render your custom header instead of the default
const MapContainer = ( ) => (
< div >
< KeplerGl id = "foo" / >
< / div >
) ;
使用withState
助手将还原状态和动作添加到自定义组件中作为其他道具。
import { withState , injectComponents , PanelHeaderFactory } from '@kepler.gl/components' ;
import { visStateLens } from '@kepler.gl/reducers' ;
// custom action wrap to mounted instance
const addTodo = text =>
wrapTo ( 'map' , {
type : 'ADD_TODO' ,
text
} ) ;
// define custom header
const CustomHeader = ( { visState , addTodo } ) => (
< div onClick = { ( ) => addTodo ( 'hello' ) } > { ` ${
Object . keys ( visState . datasets ) . length
} dataset loaded` } < / div >
) ;
// now CustomHeader will receive `visState` and `addTodo` as additional props.
const myCustomHeaderFactory = ( ) =>
withState (
// keplerGl state lenses
[ visStateLens ] ,
// customMapStateToProps
headerStateToProps ,
// actions
{ addTodo }
) ( CustomHeader ) ;
阅读有关更换UI组件的更多信息
要与kepler.gl实例进行交互并向其添加新数据,您可以从应用程序中的任何地方派遣addDataToMap
操作。它将数据集或多个数据集添加到kepler.gl实例,并更新完整的配置(MapState,MapStyle,visstate)。
data
对象*必需
datasets
(Array <Object> |对象) *所需的数据集可以是每个数据集对象需要具有info
和data
属性的数据集或数据集数组。
datasets.info
对象- 数据集的infodatasets.info.id
字符串ID。如果定义了配置,则id
应匹配config中的dataId
。datasets.info.label
字符串此数据集的显示名称datasets.data
对象*需要数据对象,以2个属性fields
和rows
表格格式datasets.data.fields
数组<Object> *必需的字段数组,datasets.data.fields.name
string *所需字段的名称,datasets.data.rows
数组<Array> *所需的行,以表格格式,带有fields
和rows
options
对象
options.centerMap
boolean default: true
如果将centerMap
设置为true
Kepler.gl将将映射视图放置在数据点边界中options.readOnly
boolean default: false
如果将readOnly
设置为true
则左设置面板将被隐藏options.keepExistingConfig
boolean default: false
是否继续退出地图配置,包括层,过滤器和拆分映射。 config
对象此对象将包含完整的kepler.gl实例配置{mapstate,mapstyle,visstate}
kepler.gl提供了一个简单的API KeplerGlSchema.getConfigToSave
以生成当前Kepler实例配置的JSON BLOB。
// app.js
import { addDataToMap } from '@kepler.gl/actions' ;
const sampleTripData = {
fields : [
{ name : 'tpep_pickup_datetime' , format : 'YYYY-M-D H:m:s' , type : 'timestamp' } ,
{ name : 'pickup_longitude' , format : '' , type : 'real' } ,
{ name : 'pickup_latitude' , format : '' , type : 'real' }
] ,
rows : [
[ '2015-01-15 19:05:39 +00:00' , - 73.99389648 , 40.75011063 ] ,
[ '2015-01-15 19:05:39 +00:00' , - 73.97642517 , 40.73981094 ] ,
[ '2015-01-15 19:05:40 +00:00' , - 73.96870422 , 40.75424576 ]
]
} ;
const sampleConfig = {
visState : {
filters : [
{
id : 'me' ,
dataId : 'test_trip_data' ,
name : 'tpep_pickup_datetime' ,
type : 'timeRange' ,
view : 'enlarged'
}
]
}
} ;
this . props . dispatch (
addDataToMap ( {
datasets : {
info : {
label : 'Sample Taxi Trips in New York City' ,
id : 'test_trip_data'
} ,
data : sampleTripData
} ,
option : {
centerMap : true ,
readOnly : false
} ,
config : sampleConfig
} )
) ;
阅读有关AddDatatoMap的更多信息,并使用Schema Manager保存和加载地图。