Skip to content

[WIP] Use Uber react-map-gl for better reactive map #96

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: next
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [2.0.0-beta.1] - 2019-02-07

### Changed

- [BREAKING] If using a map style hosted by Mapbox you must pass a [valid Mapbox
Access Token](https://docs.mapbox.com/help/how-mapbox-works/access-tokens/)
with the prop `mapboxToken`.
- [BREAKING] The `mapPosition` and `onChangeMapPosition` props have been
removed, and replaced by `mapViewState` and `onChangeMapViewState`.

## [1.1.0] - 2018-06-21

### Added
5 changes: 5 additions & 0 deletions example/index.html
Original file line number Diff line number Diff line change
@@ -27,6 +27,11 @@
padding: 0;
overflow: hidden;
}
#root {
width: 100vw;
height: 100vh;
position: absolute;
}
</style>
</head>

48 changes: 31 additions & 17 deletions example/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
const React = require('react')
const ReactDOM = require('react-dom')
const MapFilter = require('../src/index.js').default
const MapView = require('../src/components/MapView').default
const createHistory = require('history').createBrowserHistory
const { MuiThemeProvider, createMuiTheme } = require('@material-ui/core/styles')
const blue = require('@material-ui/core/colors/blue').default
const pink = require('@material-ui/core/colors/pink').default
const mapboxgl = require('mapbox-gl')
const MenuItem = require('@material-ui/core/MenuItem').default
const { randomPoint } = require('@turf/random')
const {LinearInterpolator, FlyToInterpolator} = require('react-map-gl')
const d3 = require('d3-ease')

const theme = createMuiTheme({
palette: {
@@ -15,6 +17,8 @@ const theme = createMuiTheme({
}
})

const MAPBOX_TOKEN = require('../config.json').mapboxToken

const features = require('./sample.json').features

const history = createHistory()
@@ -60,10 +64,25 @@ class Example extends React.Component {
this.unlisten = history.listen(this.handleHistoryChange)
this.state = {
ui: uiFromPath(history.location.pathname),
features: features,
mapPosition: {center: [-59.43943162023362, 2.6563784112334616], zoom: 10}
features: features
}
}
componentDidMount () {
this.intervalId = setInterval(() => {
const coords = randomPoint(1, {bbox: [-76.65, -16.96, -51.92, 6.64]}).features[0].geometry.coordinates
console.log('fly to', coords)
console.log('from', this.state.mapViewState)
this.setState(state => ({
mapViewState: Object.assign({}, this.state.mapViewState, {
longitude: coords[0],
latitude: coords[1],
zoom: 7 + (Math.random() * 5),
transitionInterpolator: new FlyToInterpolator(),
transitionDuration: 2000
})
}))
}, 5000)
}
handleHistoryChange = (location, action) => {
if (action === 'POP') {
this.setState({ui: uiFromPath(location.pathname)})
@@ -77,22 +96,17 @@ class Example extends React.Component {
handleChangeFeatures = (_) => {
this.setState({features: _})
}
handleChangeMapPosition = (pos) => {
this.setState({mapPosition: pos})
handleChangeMapViewState = (pos) => {
this.setState({mapViewState: pos})
}
render () {
return <MuiThemeProvider theme={theme}>
<MapFilter
mapPosition={this.state.mapPosition}
onChangeMapPosition={this.handleChangeMapPosition}
resizer={resizer}
features={this.state.features}
fieldOrder={{caption: 1, public: 0}}
ui={this.state.ui}
mapControls={[new mapboxgl.FullscreenControl()]}
onChangeUi={this.handleChangeUi}
onChangeFeatures={this.handleChangeFeatures}
appBarMenuItems={[MyMenuItem]} />
<MapView
viewport={this.state.mapViewState}
mapboxToken={MAPBOX_TOKEN}
mapStyle='mapbox://styles/mapbox/streets-v9'
moveMap={this.handleChangeMapViewState}
features={features} />
</MuiThemeProvider>
}
}
122 changes: 122 additions & 0 deletions example/prev-index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
const React = require('react')
const ReactDOM = require('react-dom')
const MapFilter = require('../src/index.js').default
const createHistory = require('history').createBrowserHistory
const { MuiThemeProvider, createMuiTheme } = require('@material-ui/core/styles')
const blue = require('@material-ui/core/colors/blue').default
const pink = require('@material-ui/core/colors/pink').default
const MenuItem = require('@material-ui/core/MenuItem').default
const { randomPoint } = require('@turf/random')
const {LinearInterpolator, FlyToInterpolator} = require('react-map-gl')
const d3 = require('d3-ease')

const theme = createMuiTheme({
palette: {
primary: blue,
secondary: pink
}
})

const fieldOrder = {caption: 1, public: 0}

const MAPBOX_TOKEN = require('../config.json').mapboxToken

const features = require('./sample.json').features

const history = createHistory()

const pathRegExp = /^(?:\/((?:[^/]+?)))?(?:\/((?:[^/]+?)))?(?:\/((?:[^/]+?)))?(?:\/(?=$))?$/

function uiFromPath (path) {
const match = pathRegExp.exec(path)
if (!match) return {}
return {
activeView: match[1],
activeModal: match[2] && match[2].replace('features', 'feature'),
settingsTab: match[2] === 'settings' && match[3],
featureId: match[2] === 'features' && match[3]
}
}

function pathFromUi (ui) {
let path = '/'
if (ui.activeView) path += ui.activeView + '/'
if (ui.activeModal === 'settings') path += 'settings/' + ui.settingsTab + '/'
if (ui.activeModal === 'feature') path += 'features/' + ui.featureId + '/'
return path
}

function resizer (src, size) {
return 'https://resizer.digital-democracy.org/{width}/{height}/{url}'
.replace('{width}', size)
.replace('{height}', size)
.replace('{url}', src)
}

const MyMenuItem = () => (
<MenuItem onClick={() => console.log('click myMenu')}>
Custom Menu Item
</MenuItem>
)

class Example extends React.Component {
constructor (props) {
super(props)
this.history = createHistory()
this.unlisten = history.listen(this.handleHistoryChange)
this.state = {
ui: uiFromPath(history.location.pathname),
features: features
}
}
componentDidMount () {
this.intervalId = setTimeout(() => {
const coords = randomPoint(1, {bbox: [-76.65, -16.96, -51.92, 6.64]}).features[0].geometry.coordinates
console.log('fly to', coords)
console.log('from', this.state.mapViewState)
this.setState(state => ({
mapViewState: Object.assign({}, this.state.mapViewState, {
longitude: coords[0],
latitude: coords[1],
zoom: 10,
transitionInterpolator: new LinearInterpolator(),
transitionDuration: 1000,
transitionEasing: d3.easeCubic
})
}))
}, 10000)
}
handleHistoryChange = (location, action) => {
if (action === 'POP') {
this.setState({ui: uiFromPath(location.pathname)})
}
}
handleChangeUi = (ui) => {
const path = pathFromUi(ui)
ui.amberirect ? history.replace(path) : history.push(path)
this.setState({ui})
}
handleChangeFeatures = (_) => {
this.setState({features: _})
}
handleChangeMapViewState = (pos) => {
this.setState({mapViewState: pos})
}
render () {
return <MuiThemeProvider theme={theme}>
<MapFilter
mapViewState={this.state.mapViewState}
mapboxToken={MAPBOX_TOKEN}
onChangeMapViewState={this.handleChangeMapViewState}
resizer={resizer}
features={this.state.features}
fieldOrder={fieldOrder}
ui={this.state.ui}
onChangeUi={this.handleChangeUi}
onChangeFeatures={this.handleChangeFeatures}
appBarMenuItems={[MyMenuItem]} />
</MuiThemeProvider>
}
}

ReactDOM.render(<Example />, document.getElementById('root'))
Loading