mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-28 16:51:20 +01:00
Load icon and font metadata from endpoint
This commit is contained in:
parent
09b6b2dffe
commit
0fb59ca544
5 changed files with 80 additions and 17 deletions
|
@ -10,6 +10,7 @@ import Toolbar from './Toolbar'
|
|||
import AppLayout from './AppLayout'
|
||||
import MessagePanel from './MessagePanel'
|
||||
|
||||
import { downloadGlyphsMetadata, downloadSpriteMetadata } from '../libs/metadata'
|
||||
import GlSpec from 'mapbox-gl-style-spec/reference/latest.js'
|
||||
import validateStyleMin from 'mapbox-gl-style-spec/lib/validate_style.min'
|
||||
import formatStyle from 'mapbox-gl-style-spec/lib/format'
|
||||
|
@ -21,6 +22,18 @@ import { ApiStyleStore } from '../libs/apistore'
|
|||
import { RevisionStore } from '../libs/revisions'
|
||||
import LayerWatcher from '../libs/layerwatcher'
|
||||
|
||||
function updateRootSpec(spec, fieldName, newValues) {
|
||||
return {
|
||||
...spec,
|
||||
$root: {
|
||||
...spec.$root,
|
||||
[fieldName]: {
|
||||
...spec.$root[fieldName],
|
||||
values: newValues
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default class App extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -52,6 +65,7 @@ export default class App extends React.Component {
|
|||
sources: {},
|
||||
vectorLayers: {},
|
||||
inspectModeEnabled: false,
|
||||
spec: GlSpec,
|
||||
}
|
||||
|
||||
this.layerWatcher = new LayerWatcher({
|
||||
|
@ -85,7 +99,26 @@ export default class App extends React.Component {
|
|||
this.styleStore.save(snapshotStyle)
|
||||
}
|
||||
|
||||
updateFonts(urlTemplate) {
|
||||
downloadGlyphsMetadata(urlTemplate, fonts => {
|
||||
this.setState({ spec: updateRootSpec(this.state.spec, 'glyphs', fonts)})
|
||||
})
|
||||
}
|
||||
|
||||
updateIcons(baseUrl) {
|
||||
downloadSpriteMetadata(baseUrl, icons => {
|
||||
this.setState({ spec: updateRootSpec(this.state.spec, 'sprite', icons)})
|
||||
})
|
||||
}
|
||||
|
||||
onStyleChanged(newStyle, save=true) {
|
||||
if(newStyle.glyphs !== this.state.mapStyle.glyphs) {
|
||||
this.updateFonts(newStyle.glyphs)
|
||||
}
|
||||
if(newStyle.sprite !== this.state.mapStyle.sprite) {
|
||||
this.updateIcons(newStyle.sprite)
|
||||
}
|
||||
|
||||
const errors = validateStyleMin(newStyle, GlSpec)
|
||||
if(errors.length === 0) {
|
||||
this.revisionStore.addRevision(newStyle)
|
||||
|
@ -212,6 +245,7 @@ export default class App extends React.Component {
|
|||
layer={selectedLayer}
|
||||
sources={this.state.sources}
|
||||
vectorLayers={this.state.vectorLayers}
|
||||
spec={this.state.spec}
|
||||
onLayerChanged={this.onLayerChanged.bind(this)}
|
||||
onLayerIdChange={this.onLayerIdChange.bind(this)}
|
||||
/> : null
|
||||
|
|
|
@ -1,20 +1,34 @@
|
|||
import React from 'react'
|
||||
import GlSpec from 'mapbox-gl-style-spec/reference/latest.js'
|
||||
|
||||
import ZoomSpecField from './ZoomSpecField'
|
||||
import colors from '../../config/colors'
|
||||
import { margins } from '../../config/scales'
|
||||
|
||||
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
|
||||
|
||||
/** Extract field spec by {@fieldName} from the {@layerType} in the
|
||||
* style specification from either the paint or layout group */
|
||||
function getFieldSpec(layerType, fieldName) {
|
||||
const groupName = getGroupName(layerType, fieldName)
|
||||
const group = GlSpec[groupName + '_' + layerType]
|
||||
return group[fieldName]
|
||||
function getFieldSpec(spec, layerType, fieldName) {
|
||||
const groupName = getGroupName(spec, layerType, fieldName)
|
||||
const group = spec[groupName + '_' + layerType]
|
||||
const fieldSpec = group[fieldName]
|
||||
if(iconProperties.indexOf(fieldName) >= 0) {
|
||||
return {
|
||||
...fieldSpec,
|
||||
values: spec.$root.sprite.values
|
||||
}
|
||||
}
|
||||
if(fieldName === 'text-font') {
|
||||
return {
|
||||
...fieldSpec,
|
||||
values: spec.$root.glyphs.values
|
||||
}
|
||||
}
|
||||
return fieldSpec
|
||||
}
|
||||
|
||||
function getGroupName(layerType, fieldName) {
|
||||
const paint = GlSpec['paint_' + layerType] || {}
|
||||
function getGroupName(spec, layerType, fieldName) {
|
||||
const paint = spec['paint_' + layerType] || {}
|
||||
if (fieldName in paint) {
|
||||
return 'paint'
|
||||
} else {
|
||||
|
@ -27,16 +41,17 @@ export default class PropertyGroup extends React.Component {
|
|||
layer: React.PropTypes.object.isRequired,
|
||||
groupFields: React.PropTypes.array.isRequired,
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
spec: React.PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
onPropertyChange(property, newValue) {
|
||||
const group = getGroupName(this.props.layer.type, property)
|
||||
const group = getGroupName(this.props.spec, this.props.layer.type, property)
|
||||
this.props.onChange(group , property, newValue)
|
||||
}
|
||||
|
||||
render() {
|
||||
const fields = this.props.groupFields.map(fieldName => {
|
||||
const fieldSpec = getFieldSpec(this.props.layer.type, fieldName)
|
||||
const fieldSpec = getFieldSpec(this.props.spec, this.props.layer.type, fieldName)
|
||||
|
||||
const paint = this.props.layer.paint || {}
|
||||
const layout = this.props.layer.layout || {}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React from 'react'
|
||||
import color from 'color'
|
||||
|
||||
import GlSpec from 'mapbox-gl-style-spec/reference/latest.min.js'
|
||||
import ColorField from './ColorField'
|
||||
import NumberInput from '../inputs/NumberInput'
|
||||
import CheckboxInput from '../inputs/CheckboxInput'
|
||||
|
@ -10,8 +9,10 @@ import SelectInput from '../inputs/SelectInput'
|
|||
import MultiButtonInput from '../inputs/MultiButtonInput'
|
||||
import ArrayInput from '../inputs/ArrayInput'
|
||||
import FontInput from '../inputs/FontInput'
|
||||
import IconInput from '../inputs/IconInput'
|
||||
import capitalize from 'lodash.capitalize'
|
||||
|
||||
const iconProperties = ['background-pattern', 'fill-pattern', 'line-pattern', 'fill-extrusion-pattern', 'icon-image']
|
||||
|
||||
import input from '../../config/input.js'
|
||||
|
||||
|
@ -78,11 +79,17 @@ export default class SpecField extends React.Component {
|
|||
options={options}
|
||||
/>
|
||||
}
|
||||
case 'string': return (
|
||||
<StringInput
|
||||
case 'string':
|
||||
if(iconProperties.indexOf(this.props.fieldName) >= 0) {
|
||||
return <IconInput
|
||||
{...commonProps}
|
||||
icons={this.props.fieldSpec.values}
|
||||
/>
|
||||
} else {
|
||||
return <StringInput
|
||||
{...commonProps}
|
||||
/>
|
||||
)
|
||||
}
|
||||
case 'color': return (
|
||||
<ColorField
|
||||
{...commonProps}
|
||||
|
@ -97,6 +104,7 @@ export default class SpecField extends React.Component {
|
|||
if(this.props.fieldName === 'text-font') {
|
||||
return <FontInput
|
||||
{...commonProps}
|
||||
fonts={this.props.fieldSpec.values}
|
||||
/>
|
||||
} else {
|
||||
return <ArrayInput
|
||||
|
|
|
@ -9,10 +9,15 @@ import fontStacks from '../../config/fontstacks.json'
|
|||
class FontInput extends React.Component {
|
||||
static propTypes = {
|
||||
value: React.PropTypes.array.isRequired,
|
||||
fonts: React.PropTypes.array,
|
||||
style: React.PropTypes.object,
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
fonts: []
|
||||
}
|
||||
|
||||
get values() {
|
||||
return this.props.value || this.props.default.slice(1) || []
|
||||
}
|
||||
|
@ -28,7 +33,7 @@ class FontInput extends React.Component {
|
|||
return <AutocompleteInput
|
||||
key={i}
|
||||
value={value}
|
||||
options={fontStacks.map(f => [f, f])}
|
||||
options={this.props.fonts.map(f => [f, f])}
|
||||
onChange={this.changeFont.bind(this, i)}
|
||||
wrapperStyle={{
|
||||
display: 'block',
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react'
|
||||
|
||||
import GlSpec from 'mapbox-gl-style-spec/reference/latest.js'
|
||||
import JSONEditor from './JSONEditor'
|
||||
import FilterEditor from '../filter/FilterEditor'
|
||||
import PropertyGroup from '../fields/PropertyGroup'
|
||||
|
@ -47,6 +46,7 @@ export default class LayerEditor extends React.Component {
|
|||
layer: React.PropTypes.object.isRequired,
|
||||
sources: React.PropTypes.object,
|
||||
vectorLayers: React.PropTypes.object,
|
||||
spec: React.PropTypes.object.isRequired,
|
||||
onLayerChanged: React.PropTypes.func,
|
||||
onLayerIdChange: React.PropTypes.func,
|
||||
}
|
||||
|
@ -146,6 +146,7 @@ export default class LayerEditor extends React.Component {
|
|||
case 'properties': return <PropertyGroup
|
||||
layer={this.props.layer}
|
||||
groupFields={fields}
|
||||
spec={this.props.spec}
|
||||
onChange={this.changeProperty.bind(this)}
|
||||
/>
|
||||
case 'jsoneditor': return <JSONEditor
|
||||
|
|
Loading…
Reference in a new issue