mirror of
https://github.com/maputnik/editor.git
synced 2026-01-02 11:30:00 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c15ac14f88 | ||
|
|
8f6006c19f | ||
|
|
16bedcf5b1 | ||
|
|
05349d8ffe | ||
|
|
a1e1895651 | ||
|
|
a111599850 | ||
|
|
121a95cee8 | ||
|
|
decd1f3ea2 | ||
|
|
c632718324 | ||
|
|
9509b59696 |
@@ -8,6 +8,8 @@ targeted at developers and map designers.
|
||||
- :link: Design your maps online at **http://maputnik.com/editor/** (all in local storage)
|
||||
- :link: Use the [Maputnik CLI](https://github.com/maputnik/editor/wiki/Maputnik-CLI) for local style development
|
||||
|
||||
Mapbox has built one of the best and most amazing OSS ecosystems. A key component to ensure its longevity and independance is an OSS map designer.
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation can be found in the [Wiki](https://github.com/maputnik/editor/wiki). You are welcome to collaborate!
|
||||
@@ -17,8 +19,6 @@ The documentation can be found in the [Wiki](https://github.com/maputnik/editor/
|
||||
|
||||
[](https://youtu.be/XoDh0gEnBQo)
|
||||
|
||||
Mapbox has built one of the best and most amazing OSS ecosystems. A key component to ensure its longevity and independance is an OSS map designer.
|
||||
|
||||
## Develop
|
||||
|
||||
Maputnik is written in ES6 and is using [React](https://github.com/facebook/react) and [Mapbox GL JS](https://www.mapbox.com/mapbox-gl-js/api/).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "maputnik",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"description": "A MapboxGL visual style editor",
|
||||
"main": "''",
|
||||
"scripts": {
|
||||
|
||||
@@ -132,7 +132,6 @@ export default class ZoomSpecProperty extends React.Component {
|
||||
if(this.props.fieldSpec['zoom-function']) {
|
||||
zoomBtn = <MakeZoomFunctionButton onClick={this.makeZoomFunction.bind(this)} />
|
||||
}
|
||||
|
||||
return <InputBlock
|
||||
doc={this.props.fieldSpec.doc}
|
||||
label={labelFromFieldName(this.props.fieldName)}
|
||||
@@ -143,11 +142,10 @@ export default class ZoomSpecProperty extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
if(isZoomField(this.props.value)) {
|
||||
return this.renderZoomProperty();
|
||||
} else {
|
||||
return this.renderProperty();
|
||||
}
|
||||
const propClass = this.props.fieldSpec.default === this.props.value ? "maputnik-default-property" : "maputnik-modified-property"
|
||||
return <div className={propClass}>
|
||||
{isZoomField(this.props.value) ? this.renderZoomProperty() : this.renderProperty()}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,12 @@ import StringInput from '../inputs/StringInput'
|
||||
import AutocompleteInput from '../inputs/AutocompleteInput'
|
||||
import SelectInput from '../inputs/SelectInput'
|
||||
|
||||
function tryParseInt(v) {
|
||||
if (v === '') return v
|
||||
if (isNaN(v)) return v
|
||||
return parseFloat(v)
|
||||
}
|
||||
|
||||
class SingleFilterEditor extends React.Component {
|
||||
static propTypes = {
|
||||
filter: React.PropTypes.array.isRequired,
|
||||
@@ -17,7 +23,12 @@ class SingleFilterEditor extends React.Component {
|
||||
}
|
||||
|
||||
onFilterPartChanged(filterOp, propertyName, filterArgs) {
|
||||
const newFilter = [filterOp, propertyName, ...filterArgs]
|
||||
let newFilter = [filterOp, propertyName, ...filterArgs.map(tryParseInt)]
|
||||
if(filterOp === 'has' || filterOp === '!has') {
|
||||
newFilter = [filterOp, propertyName]
|
||||
} else if(filterArgs.length === 0) {
|
||||
newFilter = [filterOp, propertyName, '']
|
||||
}
|
||||
this.props.onChange(newFilter)
|
||||
}
|
||||
|
||||
@@ -42,12 +53,14 @@ class SingleFilterEditor extends React.Component {
|
||||
options={otherFilterOps}
|
||||
/>
|
||||
</div>
|
||||
{filterArgs.length > 0 &&
|
||||
<div className="maputnik-filter-editor-args">
|
||||
<StringInput
|
||||
value={filterArgs.join(',')}
|
||||
onChange={ v=> this.onFilterPartChanged(filterOp, propertyName, v.split(','))}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ import PropertyGroup from '../fields/PropertyGroup'
|
||||
import LayerEditorGroup from './LayerEditorGroup'
|
||||
import LayerTypeBlock from './LayerTypeBlock'
|
||||
import LayerIdBlock from './LayerIdBlock'
|
||||
import MinZoomBlock from './MinZoomBlock'
|
||||
import MaxZoomBlock from './MaxZoomBlock'
|
||||
import LayerSourceBlock from './LayerSourceBlock'
|
||||
import LayerSourceLayerBlock from './LayerSourceLayerBlock'
|
||||
|
||||
@@ -130,6 +132,14 @@ export default class LayerEditor extends React.Component {
|
||||
onChange={v => this.changeProperty(null, 'source-layer', v)}
|
||||
/>
|
||||
}
|
||||
<MinZoomBlock
|
||||
value={this.props.layer.minzoom}
|
||||
onChange={v => this.changeProperty(null, 'minzoom', v)}
|
||||
/>
|
||||
<MaxZoomBlock
|
||||
value={this.props.layer.maxzoom}
|
||||
onChange={v => this.changeProperty(null, 'maxzoom', v)}
|
||||
/>
|
||||
</div>
|
||||
case 'filter': return <div>
|
||||
<div className="maputnik-filter-editor-wrapper">
|
||||
|
||||
26
src/components/layers/MaxZoomBlock.jsx
Normal file
26
src/components/layers/MaxZoomBlock.jsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import React from 'react'
|
||||
|
||||
import GlSpec from 'mapbox-gl-style-spec/reference/latest.js'
|
||||
import InputBlock from '../inputs/InputBlock'
|
||||
import NumberInput from '../inputs/NumberInput'
|
||||
|
||||
class MaxZoomBlock extends React.Component {
|
||||
static propTypes = {
|
||||
value: React.PropTypes.number.isRequired,
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
return <InputBlock label={"Max Zoom"} doc={GlSpec.layer.maxzoom.doc}>
|
||||
<NumberInput
|
||||
value={this.props.value}
|
||||
onChange={this.props.onChange}
|
||||
min={GlSpec.layer.maxzoom.minimum}
|
||||
max={GlSpec.layer.maxzoom.maximum}
|
||||
default={GlSpec.layer.maxzoom.maximum}
|
||||
/>
|
||||
</InputBlock>
|
||||
}
|
||||
}
|
||||
|
||||
export default MaxZoomBlock
|
||||
26
src/components/layers/MinZoomBlock.jsx
Normal file
26
src/components/layers/MinZoomBlock.jsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import React from 'react'
|
||||
|
||||
import GlSpec from 'mapbox-gl-style-spec/reference/latest.js'
|
||||
import InputBlock from '../inputs/InputBlock'
|
||||
import NumberInput from '../inputs/NumberInput'
|
||||
|
||||
class MinZoomBlock extends React.Component {
|
||||
static propTypes = {
|
||||
value: React.PropTypes.number.isRequired,
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
return <InputBlock label={"Min Zoom"} doc={GlSpec.layer.minzoom.doc}>
|
||||
<NumberInput
|
||||
value={this.props.value}
|
||||
onChange={this.props.onChange}
|
||||
min={GlSpec.layer.minzoom.minimum}
|
||||
max={GlSpec.layer.minzoom.maximum}
|
||||
default={GlSpec.layer.minzoom.minimum}
|
||||
/>
|
||||
</InputBlock>
|
||||
}
|
||||
}
|
||||
|
||||
export default MinZoomBlock
|
||||
@@ -101,7 +101,9 @@ class OpenModal extends React.Component {
|
||||
<p>
|
||||
Open one of the publicly available styles to start from.
|
||||
</p>
|
||||
<div className="maputnik-style-gallery-container">
|
||||
{styleOptions}
|
||||
</div>
|
||||
</section>
|
||||
</Modal>
|
||||
}
|
||||
|
||||
@@ -29,6 +29,15 @@ class TileURLSourceEditor extends React.Component {
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
changeTileUrl(idx, value) {
|
||||
const tiles = this.props.source.tiles.slice(0)
|
||||
tiles[idx] = value
|
||||
this.props.onChange({
|
||||
...this.props.source,
|
||||
tiles: tiles
|
||||
})
|
||||
}
|
||||
|
||||
renderTileUrls() {
|
||||
const prefix = ['1st', '2nd', '3rd', '4th', '5th', '6th', '7th']
|
||||
const tiles = this.props.source.tiles || []
|
||||
@@ -36,6 +45,7 @@ class TileURLSourceEditor extends React.Component {
|
||||
return <InputBlock key={tileIndex} label={prefix[tileIndex] + " Tile URL"} doc={GlSpec.source_tile.tiles.doc}>
|
||||
<StringInput
|
||||
value={tileUrl}
|
||||
onChange={this.changeTileUrl.bind(this, tileIndex)}
|
||||
/>
|
||||
</InputBlock>
|
||||
})
|
||||
|
||||
@@ -10,6 +10,5 @@
|
||||
"sources": { },
|
||||
"glyphs": "https://demo.tileserver.org/fonts/{fontstack}/{range}.pbf",
|
||||
"sprites": "https://demo.tileserver.org/fonts/{fontstack}/{range}.pbf",
|
||||
"layers": [],
|
||||
"id": "empty-style"
|
||||
"layers": []
|
||||
}
|
||||
|
||||
@@ -3,25 +3,25 @@
|
||||
"id": "klokantech-basic",
|
||||
"title": "Klokantech Basic",
|
||||
"url": "https://rawgit.com/openmaptiles/klokantech-basic-gl-style/gh-pages/style-cdn.json",
|
||||
"thumbnail": "https://camo.githubusercontent.com/08dcb3dd384c6083b02e6692c939d68c4114eb33/687474703a2f2f64656d6f2e74696c657365727665722e6f72672f7374796c65732f6b6c6f6b616e746563682d62617369632f7374617469632f382e3631393138342c34372e3333363230332c31302e30372f363030783430304032782e706e67"
|
||||
"thumbnail": "http://maputnik.com/thumbnails/klokantech-basic.png"
|
||||
},
|
||||
{
|
||||
"id": "dark-matter",
|
||||
"title": "Dark Matter",
|
||||
"url": "https://rawgit.com/openmaptiles/dark-matter-gl-style/gh-pages/style-cdn.json",
|
||||
"thumbnail": "https://camo.githubusercontent.com/258db708523e523782addeecdcc8697368a24df9/687474703a2f2f64656d6f2e74696c657365727665722e6f72672f7374796c65732f6461726b2d6d61747465722f7374617469632f382e3534303538372c34372e3337303535352c31352e30382f363030783430304032782e706e67"
|
||||
"thumbnail": "http://maputnik.com/thumbnails/dark-matter.png"
|
||||
},
|
||||
{
|
||||
"id": "positron",
|
||||
"title": "Positron",
|
||||
"url": "https://rawgit.com/openmaptiles/positron-gl-style/gh-pages/style-cdn.json",
|
||||
"thumbnail": "https://camo.githubusercontent.com/56df86562b6c36b7cc44ee6e8b91eb4d8e593b66/687474703a2f2f64656d6f2e74696c657365727665722e6f72672f7374796c65732f706f736974726f6e2f7374617469632f31302e3938373235382c34362e3435333135302c342e30322f363030783430304032782e706e67"
|
||||
"thumbnail": "http://maputnik.com/thumbnails/positron.png"
|
||||
},
|
||||
{
|
||||
"id": "osm-bright",
|
||||
"title": "OSM Bright",
|
||||
"url": "https://rawgit.com/openmaptiles/osm-bright-gl-style/gh-pages/style-cdn.json",
|
||||
"thumbnail": "https://camo.githubusercontent.com/0fdf9922c6b632f903e47b3dfbcfb65e62b25046/687474703a2f2f64656d6f2e74696c657365727665722e6f72672f7374796c65732f6f736d2d6272696768742f7374617469632f382e3234333936372c34362e3931363331352c372e32312f363030783430304032782e706e67"
|
||||
"thumbnail": "http://maputnik.com/thumbnails/osm-bright.png"
|
||||
},
|
||||
{
|
||||
"id": "osm-liberty",
|
||||
@@ -34,5 +34,29 @@
|
||||
"title": "Empty Style",
|
||||
"url": "https://rawgit.com/maputnik/editor/master/src/config/empty-style.json",
|
||||
"thumbnail": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAQAAAAHDYbIAAAAEUlEQVR42mP8/58BDhiJ4wAA974H/U5Xe1oAAAAASUVORK5CYII="
|
||||
},
|
||||
{
|
||||
"id": "mapbox-satellite",
|
||||
"title": "Mapbox Satellite",
|
||||
"url": "https://rawgit.com/mapbox/mapbox-gl-styles/master/styles/satellite-v9.json",
|
||||
"thumbnail": "http://maputnik.com/thumbnails/mapbox-satellite.png"
|
||||
},
|
||||
{
|
||||
"id": "mapbox-bright",
|
||||
"title": "Mapbox Bright",
|
||||
"url": "https://rawgit.com/mapbox/mapbox-gl-styles/master/styles/bright-v9.json",
|
||||
"thumbnail": "http://maputnik.com/thumbnails/mapbox-bright.png"
|
||||
},
|
||||
{
|
||||
"id": "mapbox-basic",
|
||||
"title": "Mapbox Basic",
|
||||
"url": "https://rawgit.com/mapbox/mapbox-gl-styles/master/styles/basic-v9.json",
|
||||
"thumbnail": "http://maputnik.com/thumbnails/mapbox-basic.png"
|
||||
},
|
||||
{
|
||||
"id": "tilezen",
|
||||
"title": "Tilezen",
|
||||
"url": "https://rawgit.com/lukasmartinelli/tilezen-gl-style/master/style.json",
|
||||
"thumbnail": "http://maputnik.com/thumbnails/tilezen.png"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -129,3 +129,8 @@
|
||||
background-color: $color-gray;
|
||||
}
|
||||
}
|
||||
|
||||
// PROPERTY
|
||||
.maputnik-default-property {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,11 @@
|
||||
@extend .maputnik-big-button;
|
||||
}
|
||||
|
||||
.maputnik-style-gallery-container {
|
||||
max-height: 400px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.maputnik-public-style {
|
||||
vertical-align: top;
|
||||
margin-top: 10px;
|
||||
|
||||
Reference in New Issue
Block a user