diff --git a/src/components/inputs/StringInput.jsx b/src/components/inputs/StringInput.jsx index 8efa95f..6d8a60e 100644 --- a/src/components/inputs/StringInput.jsx +++ b/src/components/inputs/StringInput.jsx @@ -5,6 +5,7 @@ class StringInput extends React.Component { static propTypes = { value: React.PropTypes.string, style: React.PropTypes.object, + default: React.PropTypes.number, onChange: React.PropTypes.func, } @@ -15,6 +16,7 @@ class StringInput extends React.Component { ...this.props.style }} value={this.props.value} + placeholder={this.props.default} onChange={e => this.props.onChange(e.target.value)} /> } diff --git a/src/components/modals/SourcesModal.jsx b/src/components/modals/SourcesModal.jsx index 8bc845f..b13e979 100644 --- a/src/components/modals/SourcesModal.jsx +++ b/src/components/modals/SourcesModal.jsx @@ -118,19 +118,30 @@ class AddSource extends React.Component { super(props) this.state = { mode: 'tilejson', - source: { - id: style.generateId(), - } + sourceId: style.generateId(), + source: this.defaultSource('tilejson'), } } - onSourceIdChange(newId) { - this.setState({ - source: { - ...this.state.source, - id: newId, + defaultSource(mode) { + const source = (this.state || {}).source || {} + switch(mode) { + case 'geojson': return { + type: 'geojson', + data: source.data || 'http://localhost:3000/geojson.json' } - }) + case 'tilejson': return { + type: 'vector', + url: source.url || 'http://localhost:3000/tilejson.json' + } + case 'tilexyz': return { + type: 'vector', + tiles: source.tiles || ['http://localhost:3000/{x}/{y}/{z}.pbf'], + minZoom: source.minZoom || 0, + maxZoom: source.maxZoom || 14 + } + default: return {} + } } onSourceChange(source) { @@ -143,8 +154,8 @@ class AddSource extends React.Component { return
this.setState({ sourceId: v})} /> @@ -154,7 +165,7 @@ class AddSource extends React.Component { ['tilejson', 'Vector (TileJSON URL)'], ['tilexyz', 'Vector (XYZ URLs)'], ]} - onChange={v => this.setState({mode: v})} + onChange={mode => this.setState({mode: mode, source: this.defaultSource(mode)})} value={this.state.mode} /> @@ -163,7 +174,7 @@ class AddSource extends React.Component { mode={this.state.mode} source={this.state.source} /> -
@@ -178,10 +189,10 @@ class SourcesModal extends React.Component { onStyleChanged: React.PropTypes.func.isRequired, } - onSourceAdd(source) { + onSourceAdd(sourceId, source) { const changedSources = { ...this.props.mapStyle.sources, - [source.id]: source + [sourceId]: source } const changedStyle = { @@ -203,6 +214,12 @@ class SourcesModal extends React.Component { this.props.onStyleChanged(changedStyle) } + stripTitle(source) { + const strippedSource = {...source} + delete strippedSource['title'] + return strippedSource + } + render() { const activeSources = Object.keys(this.props.mapStyle.sources).map(sourceId => { const source = this.props.mapStyle.sources[sourceId] @@ -214,14 +231,14 @@ class SourcesModal extends React.Component { /> }) - const tilesetOptions = publicSources.filter(source => !(source.id in this.props.mapStyle.sources)).map(source => { + const tilesetOptions = Object.keys(publicSources).filter(sourceId => !(sourceId in this.props.mapStyle.sources)).map(sourceId => { + const source = publicSources[sourceId] return this.onSourceAdd(source)} + onSelect={() => this.onSourceAdd(sourceId, this.stripTitle(source))} /> }) diff --git a/src/components/sources/SourceTypeEditor.jsx b/src/components/sources/SourceTypeEditor.jsx index 3c71f4b..a755450 100644 --- a/src/components/sources/SourceTypeEditor.jsx +++ b/src/components/sources/SourceTypeEditor.jsx @@ -1,18 +1,22 @@ import React from 'react' import InputBlock from '../inputs/InputBlock' import StringInput from '../inputs/StringInput' +import NumberInput from '../inputs/NumberInput' class TileJSONSourceEditor extends React.Component { static propTypes = { - url: React.PropTypes.string.isRequired, + source: React.PropTypes.object.isRequired, onChange: React.PropTypes.func, } render() { return this.props.onChange({ + ...this.props.source, + url: url + })} /> } @@ -20,15 +24,14 @@ class TileJSONSourceEditor extends React.Component { class TileURLSourceEditor extends React.Component { static propTypes = { - tiles: React.PropTypes.array.isRequired, - minZoom: React.PropTypes.number.isRequired, - maxZoom: React.PropTypes.number.isRequired, + source: React.PropTypes.object.isRequired, onChange: React.PropTypes.func, } renderTileUrls() { const prefix = ['1st', '2nd', '3rd', '4th', '5th', '6th', '7th'] - return this.props.tiles.map((tileUrl, tileIndex) => { + const tiles = this.props.source.tiles || [] + return tiles.map((tileUrl, tileIndex) => { return {this.renderTileUrls()} - this.props.onChange({ + ...this.props.source, + minZoom: minZoom + })} /> - this.props.onChange({ + ...this.props.source, + maxZoom: maxZoom + })} /> @@ -58,15 +68,18 @@ class TileURLSourceEditor extends React.Component { class GeoJSONSourceEditor extends React.Component { static propTypes = { - data: React.PropTypes.string.isRequired, + source: React.PropTypes.object.isRequired, onChange: React.PropTypes.func, } render() { return this.props.onChange({ + ...this.props.source, + data: data + })} /> } @@ -80,11 +93,14 @@ class SourceTypeEditor extends React.Component { } render() { - const source = this.props.source + const commonProps = { + source: this.props.source, + onChange: this.props.onChange, + } switch(this.props.mode) { - case 'geojson': return - case 'tilejson': return - case 'tilexyz': return + case 'geojson': return + case 'tilejson': return + case 'tilexyz': return default: return null } } diff --git a/src/config/tilesets.json b/src/config/tilesets.json index 3eaffdd..49beffa 100644 --- a/src/config/tilesets.json +++ b/src/config/tilesets.json @@ -1,12 +1,10 @@ -[ - { - "id": "mapbox-streets", +{ + "mapbox-streets": { "type": "vector", "url": "mapbox://mapbox.mapbox-streets-v7", "title": "Mapbox Streets" }, - { - "id": "tilezen", + "tilezen": { "type": "vector", "tiles": [ "http://tile.mapzen.com/mapzen/vector/v1/{layers}/{z}/{x}/{y}.pbf?api_key=mapzen-RVcyVL7" @@ -15,16 +13,14 @@ "maxZoom": 15, "title": "Mapzen Vector Tile Service" }, - { - "id": "openmaptiles", + "openmaptiles": { "type": "vector", "url": "https://free.tilehosting.com/data/v3.json?key=25ItXg7aI5wurYDtttD", "title": "OpenMapTiles CDN" }, - { - "id": "swissnames-landscape", + "swissnames-landscape": { "type": "geojson", "data": "http://swissnames.lukasmartinelli.ch/data/landscape.geojson", "title": "Landscape Names GeoJSON" } -] +}