mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-27 10:35:23 +01:00
Use OrderedMap for layers for perf
This commit is contained in:
parent
8566e9f424
commit
1d7294dc92
3 changed files with 35 additions and 40 deletions
|
@ -7,7 +7,7 @@ import scrollbars from '../scrollbars.scss'
|
||||||
// List of collapsible layer editors
|
// List of collapsible layer editors
|
||||||
export class LayerList extends React.Component {
|
export class LayerList extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
layers: React.PropTypes.instanceOf(Immutable.List),
|
layers: React.PropTypes.instanceOf(Immutable.OrderedMap),
|
||||||
onLayersChanged: React.PropTypes.func.isRequired
|
onLayersChanged: React.PropTypes.func.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,47 +16,25 @@ export class LayerList extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onLayerDestroyed(deletedLayer) {
|
onLayerDestroyed(deletedLayer) {
|
||||||
//TODO: That's just horrible...
|
const remainingLayers = this.props.layers.delete(deletedLayer.get('id'))
|
||||||
// Can we use a immutable ordered map to look up and guarantee order
|
this.props.onLayersChanged(remainingLayers)
|
||||||
// at the same time?
|
|
||||||
let deleteIdx = -1
|
|
||||||
for (let entry of this.props.layers.entries()) {
|
|
||||||
let [i, layer] = entry
|
|
||||||
if(layer.get('id') == deletedLayer.get('id')) {
|
|
||||||
deleteIdx = i
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.props.onLayersChanged(this.props.layers.delete(deleteIdx))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onLayerChanged(changedLayer) {
|
onLayerChanged(layer) {
|
||||||
//TODO: That's just horrible...
|
const changedLayers = this.props.layers.set(layer.get('id'), layer)
|
||||||
let changeIdx = -1
|
|
||||||
for (let entry of this.props.layers.entries()) {
|
|
||||||
let [i, layer] = entry
|
|
||||||
if(layer.get('id') == changedLayer.get('id')) {
|
|
||||||
changeIdx = i
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const changedLayers = this.props.layers.set(changeIdx, changedLayer)
|
|
||||||
this.props.onLayersChanged(changedLayers)
|
this.props.onLayersChanged(changedLayers)
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
var layerPanels = []
|
var layerPanels = []
|
||||||
|
layerPanels = this.props.layers.map(layer => {
|
||||||
for(let layer of this.props.layers) {
|
return <LayerEditor
|
||||||
layerPanels.push(<LayerEditor
|
|
||||||
key={layer.get('id')}
|
key={layer.get('id')}
|
||||||
layer={layer}
|
layer={layer}
|
||||||
onLayerDestroyed={this.onLayerDestroyed.bind(this)}
|
onLayerDestroyed={this.onLayerDestroyed.bind(this)}
|
||||||
onLayerChanged={this.onLayerChanged.bind(this)}
|
onLayerChanged={this.onLayerChanged.bind(this)}
|
||||||
/>)
|
/>
|
||||||
}
|
}).toIndexedSeq()
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
<Toolbar style={{marginRight: 20}}>
|
<Toolbar style={{marginRight: 20}}>
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react'
|
||||||
import MapboxGl from 'mapbox-gl';
|
import MapboxGl from 'mapbox-gl';
|
||||||
import diffStyles from 'mapbox-gl-style-spec/lib/diff'
|
import diffStyles from 'mapbox-gl-style-spec/lib/diff'
|
||||||
import { fullHeight } from './theme.js'
|
import { fullHeight } from './theme.js'
|
||||||
|
import { styleToJS } from './stylestore.js'
|
||||||
import Immutable from 'immutable'
|
import Immutable from 'immutable'
|
||||||
|
|
||||||
export class Map extends React.Component {
|
export class Map extends React.Component {
|
||||||
|
@ -18,7 +19,7 @@ export class Map extends React.Component {
|
||||||
const mapIdChanged = this.props.mapStyle.get('id') !== nextProps.mapStyle.get('id')
|
const mapIdChanged = this.props.mapStyle.get('id') !== nextProps.mapStyle.get('id')
|
||||||
|
|
||||||
if(mapIdChanged || tokenChanged) {
|
if(mapIdChanged || tokenChanged) {
|
||||||
this.state.map.setStyle(nextProps.mapStyle.toJS())
|
this.state.map.setStyle(styleToJS(nextProps.mapStyle))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ export class Map extends React.Component {
|
||||||
//TODO: Write own diff algo that operates on immutable collections
|
//TODO: Write own diff algo that operates on immutable collections
|
||||||
// Should be able to improve performance since we can only compare
|
// Should be able to improve performance since we can only compare
|
||||||
// by reference
|
// by reference
|
||||||
const changes = diffStyles(this.props.mapStyle.toJS(), nextProps.mapStyle.toJS())
|
const changes = diffStyles(styleToJS(this.props.mapStyle), styleToJS(nextProps.mapStyle))
|
||||||
changes.forEach(change => {
|
changes.forEach(change => {
|
||||||
this.state.map[change.command].apply(this.state.map, change.args);
|
this.state.map[change.command].apply(this.state.map, change.args);
|
||||||
});
|
});
|
||||||
|
@ -44,7 +45,7 @@ export class Map extends React.Component {
|
||||||
|
|
||||||
const map = new MapboxGl.Map({
|
const map = new MapboxGl.Map({
|
||||||
container: this.container,
|
container: this.container,
|
||||||
style: this.props.mapStyle.toJS(),
|
style: styleToJS(this.props.mapStyle),
|
||||||
});
|
});
|
||||||
|
|
||||||
map.on("style.load", (...args) => {
|
map.on("style.load", (...args) => {
|
||||||
|
|
|
@ -8,7 +8,7 @@ const storageKeys = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty style is always used if no style could be restored or fetched
|
// Empty style is always used if no style could be restored or fetched
|
||||||
const emptyStyle = ensureOptionalStyleProps(Immutable.fromJS({
|
const emptyStyle = ensureOptionalStyleProps(makeStyleImmutable({
|
||||||
version: 8,
|
version: 8,
|
||||||
sources: {},
|
sources: {},
|
||||||
layers: [],
|
layers: [],
|
||||||
|
@ -16,6 +16,20 @@ const emptyStyle = ensureOptionalStyleProps(Immutable.fromJS({
|
||||||
|
|
||||||
const defaultStyleUrl = "https://raw.githubusercontent.com/osm2vectortiles/mapbox-gl-styles/master/styles/basic-v9-cdn.json"
|
const defaultStyleUrl = "https://raw.githubusercontent.com/osm2vectortiles/mapbox-gl-styles/master/styles/basic-v9-cdn.json"
|
||||||
|
|
||||||
|
// TODO: Stop converting around so much.. we should make a module containing the immutable style stuff
|
||||||
|
export function styleToJS(mapStyle) {
|
||||||
|
const jsonStyle = mapStyle.toJS()
|
||||||
|
jsonStyle.layers = mapStyle.get('layers').toIndexedSeq().toJS()
|
||||||
|
return jsonStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeStyleImmutable(mapStyle) {
|
||||||
|
if(mapStyle instanceof Immutable.Map) return mapStyle
|
||||||
|
const style = Immutable.fromJS(mapStyle)
|
||||||
|
const orderdLayers = Immutable.OrderedMap(mapStyle.layers.map(l => [l.id, Immutable.fromJS(l)]))
|
||||||
|
return style.set('layers', orderdLayers)
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch a default style via URL and return it or a fallback style via callback
|
// Fetch a default style via URL and return it or a fallback style via callback
|
||||||
export function loadDefaultStyle(cb) {
|
export function loadDefaultStyle(cb) {
|
||||||
var request = new XMLHttpRequest();
|
var request = new XMLHttpRequest();
|
||||||
|
@ -23,7 +37,7 @@ export function loadDefaultStyle(cb) {
|
||||||
|
|
||||||
request.onload = () => {
|
request.onload = () => {
|
||||||
if (request.status >= 200 && request.status < 400) {
|
if (request.status >= 200 && request.status < 400) {
|
||||||
cb(Immutable.fromJS(JSON.parse(request.responseText)))
|
cb(makeStyleImmutable(JSON.parse(request.responseText)))
|
||||||
} else {
|
} else {
|
||||||
cb(emptyStyle)
|
cb(emptyStyle)
|
||||||
}
|
}
|
||||||
|
@ -102,20 +116,22 @@ export class StyleStore {
|
||||||
|
|
||||||
// Find the last edited style
|
// Find the last edited style
|
||||||
latestStyle() {
|
latestStyle() {
|
||||||
if(this.mapStyles.length == 0) return emptyStyle
|
if(this.mapStyles.length === 0) return emptyStyle
|
||||||
const styleId = window.localStorage.getItem(storageKeys.latest)
|
const styleId = window.localStorage.getItem(storageKeys.latest)
|
||||||
const styleItem = window.localStorage.getItem(styleKey(styleId))
|
const styleItem = window.localStorage.getItem(styleKey(styleId))
|
||||||
return Immutable.fromJS(JSON.parse(styleItem))
|
|
||||||
|
if(styleItem) return makeStyleImmutable(JSON.parse(styleItem))
|
||||||
|
return memptyStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save current style replacing previous version
|
// Save current style replacing previous version
|
||||||
save(mapStyle) {
|
save(mapStyle) {
|
||||||
if(!(mapStyle instanceof Immutable.Map)) {
|
if(!(mapStyle instanceof Immutable.Map)) {
|
||||||
mapStyle = Immutable.fromJS(mapStyle)
|
mapStyle = makeStyleImmutable(mapStyle)
|
||||||
}
|
}
|
||||||
mapStyle = ensureOptionalStyleProps(mapStyle)
|
mapStyle = ensureOptionalStyleProps(mapStyle)
|
||||||
const key = styleKey(mapStyle.get('id'))
|
const key = styleKey(mapStyle.get('id'))
|
||||||
window.localStorage.setItem(key, JSON.stringify(mapStyle.toJS()))
|
window.localStorage.setItem(key, JSON.stringify(styleToJS(mapStyle)))
|
||||||
window.localStorage.setItem(storageKeys.latest, mapStyle.get('id'))
|
window.localStorage.setItem(storageKeys.latest, mapStyle.get('id'))
|
||||||
return mapStyle
|
return mapStyle
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue