mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-12-27 08:35:25 +01:00
Merge remote-tracking branch 'upstream/master' into fix/web-driver-tests-v7
Conflicts: config/webpack.production.config.js package-lock.json package.json
This commit is contained in:
commit
a3fa86f7ee
22 changed files with 5074 additions and 3603 deletions
|
@ -35,7 +35,7 @@ exports.config = {
|
|||
mochaOpts: {
|
||||
ui: 'bdd',
|
||||
// Because we don't know how long the initial build will take...
|
||||
timeout: 2*60*1000
|
||||
timeout: 4*60*1000
|
||||
},
|
||||
onPrepare: function (config, capabilities) {
|
||||
var compiler = webpack(webpackConfig);
|
||||
|
|
|
@ -25,8 +25,7 @@ module.exports = {
|
|||
},
|
||||
module: {
|
||||
noParse: [
|
||||
/mapbox-gl\/dist\/mapbox-gl.js/,
|
||||
/openlayers\/dist\/ol.js/
|
||||
/mapbox-gl\/dist\/mapbox-gl.js/
|
||||
],
|
||||
loaders: loaders
|
||||
},
|
||||
|
|
|
@ -4,9 +4,21 @@ module.exports = [
|
|||
exclude: /(node_modules|bower_components|public)/,
|
||||
loaders: ['react-hot-loader/webpack']
|
||||
},
|
||||
// HACK: This is a massive hack and reaches into the mapbox-gl private API.
|
||||
// We have to include this for access to `normalizeSourceURL`. We should
|
||||
// remove this ASAP, see <https://github.com/mapbox/mapbox-gl-js/issues/2416>
|
||||
{
|
||||
test: /.*node_modules[\/\\]mapbox-gl[\/\\]src[\/\\]util[\/\\].*\.js/,
|
||||
loader: 'babel-loader',
|
||||
query: {
|
||||
presets: ['env', 'react', 'flow'],
|
||||
plugins: ['transform-runtime', 'transform-decorators-legacy', 'transform-class-properties'],
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.jsx?$/,
|
||||
exclude: /(.*node_modules(?![\/\\]@mapbox[\/\\]mapbox-gl-style-spec)|bower_components|public)/,
|
||||
// Note: These modules aren't ES5 therefore we much compile them.
|
||||
exclude: /(.*node_modules(?![\/\\](@mapbox[\/\\]mapbox-gl-style-spec|ol|mapbox-to-ol-style))|bower_components|public)/,
|
||||
loader: 'babel-loader',
|
||||
query: {
|
||||
presets: ['env', 'react'],
|
||||
|
|
|
@ -7,6 +7,7 @@ var WebpackCleanupPlugin = require('webpack-cleanup-plugin');
|
|||
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
||||
var CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
var artifacts = require("../test/artifacts");
|
||||
var UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||
|
||||
var OUTPATH = artifacts.pathSync("/build");
|
||||
|
||||
|
@ -43,8 +44,7 @@ module.exports = {
|
|||
},
|
||||
module: {
|
||||
noParse: [
|
||||
/mapbox-gl\/dist\/mapbox-gl.js/,
|
||||
/openlayers\/dist\/ol.js/
|
||||
/mapbox-gl\/dist\/mapbox-gl.js/
|
||||
],
|
||||
loaders
|
||||
},
|
||||
|
@ -62,12 +62,7 @@ module.exports = {
|
|||
NODE_ENV: '"production"'
|
||||
}
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compress: {
|
||||
warnings: false,
|
||||
screw_ie8: true,
|
||||
}
|
||||
}),
|
||||
new UglifyJsPlugin(),
|
||||
new ExtractTextPlugin('[contenthash].css', {
|
||||
allChunks: true
|
||||
}),
|
||||
|
|
8311
package-lock.json
generated
8311
package-lock.json
generated
File diff suppressed because it is too large
Load diff
19
package.json
19
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "maputnik",
|
||||
"version": "1.1.0-beta3",
|
||||
"version": "1.1.0",
|
||||
"description": "A MapboxGL visual style editor",
|
||||
"main": "''",
|
||||
"scripts": {
|
||||
|
@ -10,7 +10,8 @@
|
|||
"test-watch": "cross-env NODE_ENV=test wdio config/wdio.conf.js --watch",
|
||||
"start": "webpack-dev-server --progress --profile --colors --config config/webpack.config.js",
|
||||
"lint": "eslint --ext js --ext jsx {src,test}",
|
||||
"lint-styles": "stylelint 'src/styles/*.scss'"
|
||||
"lint-styles": "stylelint 'src/styles/*.scss'",
|
||||
"nsp": "nsp check --reporter summary"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -21,7 +22,7 @@
|
|||
"homepage": "https://github.com/maputnik/editor#readme",
|
||||
"dependencies": {
|
||||
"@mapbox/mapbox-gl-rtl-text": "^0.1.1",
|
||||
"@mapbox/mapbox-gl-style-spec": "^10.0.1",
|
||||
"@mapbox/mapbox-gl-style-spec": "^11.1.1",
|
||||
"classnames": "^2.2.5",
|
||||
"codemirror": "^5.32.0",
|
||||
"color": "^2.0.0",
|
||||
|
@ -32,12 +33,12 @@
|
|||
"lodash.clonedeep": "^4.5.0",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"mapbox-gl": "^0.43.0",
|
||||
"mapbox-gl-inspect": "^1.2.6",
|
||||
"mapbox-gl": "^0.44.1",
|
||||
"mapbox-gl-inspect": "^1.3.0",
|
||||
"maputnik-design": "github:maputnik/design",
|
||||
"mousetrap": "^1.6.1",
|
||||
"ol-mapbox-style": "^1.0.1",
|
||||
"openlayers": "^4.4.2",
|
||||
"ol-mapbox-style": "^2.10.1",
|
||||
"ol": "^4.6.4",
|
||||
"prop-types": "^15.6.0",
|
||||
"react": "^16.2.0",
|
||||
"react-addons-pure-render-mixin": "^15.6.2",
|
||||
|
@ -97,6 +98,8 @@
|
|||
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"babel-preset-flow": "^6.23.0",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-register": "^6.26.0",
|
||||
"babel-runtime": "^6.26.0",
|
||||
|
@ -118,6 +121,7 @@
|
|||
"mkdirp": "^0.5.1",
|
||||
"mocha": "^4.0.1",
|
||||
"node-sass": "^4.6.0",
|
||||
"nsp": "^3.1.0",
|
||||
"react-hot-loader": "^3.1.1",
|
||||
"sass-loader": "^6.0.6",
|
||||
"selenium-standalone": "^6.11.0",
|
||||
|
@ -126,6 +130,7 @@
|
|||
"stylelint-config-standard": "^15.0.1",
|
||||
"transform-loader": "^0.2.4",
|
||||
"uuid": "^3.1.0",
|
||||
"uglifyjs-webpack-plugin": "^1.1.8",
|
||||
"wdio-mocha-framework": "^0.5.11",
|
||||
"wdio-phantomjs-service": "^0.2.2",
|
||||
"wdio-selenium-standalone-service": "0.0.9",
|
||||
|
|
|
@ -22,6 +22,10 @@ import tokens from '../config/tokens.json'
|
|||
import isEqual from 'lodash.isequal'
|
||||
import Debug from '../libs/debug'
|
||||
|
||||
import MapboxGl from 'mapbox-gl'
|
||||
import mapboxUtil from 'mapbox-gl/src/util/mapbox'
|
||||
|
||||
|
||||
function updateRootSpec(spec, fieldName, newValues) {
|
||||
return {
|
||||
...spec,
|
||||
|
@ -112,7 +116,9 @@ export default class App extends React.Component {
|
|||
updateFonts(urlTemplate) {
|
||||
const metadata = this.state.mapStyle.metadata || {}
|
||||
const accessToken = metadata['maputnik:openmaptiles_access_token'] || tokens.openmaptiles
|
||||
downloadGlyphsMetadata(urlTemplate.replace('{key}', accessToken), fonts => {
|
||||
|
||||
let glyphUrl = (typeof urlTemplate === 'string')? urlTemplate.replace('{key}', accessToken): urlTemplate;
|
||||
downloadGlyphsMetadata(glyphUrl, fonts => {
|
||||
this.setState({ spec: updateRootSpec(this.state.spec, 'glyphs', fonts)})
|
||||
})
|
||||
}
|
||||
|
@ -124,15 +130,17 @@ export default class App extends React.Component {
|
|||
}
|
||||
|
||||
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 = styleSpec.validate(newStyle, styleSpec.latest)
|
||||
if(errors.length === 0) {
|
||||
|
||||
if(newStyle.glyphs !== this.state.mapStyle.glyphs) {
|
||||
this.updateFonts(newStyle.glyphs)
|
||||
}
|
||||
if(newStyle.sprite !== this.state.mapStyle.sprite) {
|
||||
this.updateIcons(newStyle.sprite)
|
||||
}
|
||||
|
||||
this.revisionStore.addRevision(newStyle)
|
||||
if(save) this.saveStyle(newStyle)
|
||||
this.setState({
|
||||
|
@ -215,13 +223,23 @@ export default class App extends React.Component {
|
|||
layers: []
|
||||
};
|
||||
|
||||
if(!this.state.sources.hasOwnProperty(key) && val.type === "vector") {
|
||||
const url = val.url;
|
||||
if(!this.state.sources.hasOwnProperty(key) && val.type === "vector" && val.hasOwnProperty("url")) {
|
||||
let url = val.url;
|
||||
try {
|
||||
url = mapboxUtil.normalizeSourceURL(url, MapboxGl.accessToken);
|
||||
} catch(err) {
|
||||
console.warn("Failed to normalizeSourceURL: ", err);
|
||||
}
|
||||
|
||||
fetch(url)
|
||||
.then((response) => {
|
||||
return response.json();
|
||||
})
|
||||
.then((json) => {
|
||||
if(!json.hasOwnProperty("vector_layers")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create new objects before setState
|
||||
const sources = Object.assign({}, this.state.sources);
|
||||
|
||||
|
@ -250,7 +268,7 @@ export default class App extends React.Component {
|
|||
|
||||
mapRenderer() {
|
||||
const mapProps = {
|
||||
mapStyle: style.replaceAccessToken(this.state.mapStyle),
|
||||
mapStyle: style.replaceAccessToken(this.state.mapStyle, {allowFallback: true}),
|
||||
onDataChange: (e) => {
|
||||
this.layerWatcher.analyzeMap(e.map)
|
||||
this.fetchSources();
|
||||
|
|
|
@ -22,6 +22,7 @@ import SettingsModal from './modals/SettingsModal'
|
|||
import ExportModal from './modals/ExportModal'
|
||||
import SourcesModal from './modals/SourcesModal'
|
||||
import OpenModal from './modals/OpenModal'
|
||||
import pkgJson from '../../package.json'
|
||||
|
||||
import style from '../libs/style'
|
||||
|
||||
|
@ -137,7 +138,9 @@ export default class Toolbar extends React.Component {
|
|||
className="maputnik-toolbar-logo"
|
||||
>
|
||||
<img src={logoImage} alt="Maputnik" />
|
||||
<h1>Maputnik</h1>
|
||||
<h1>Maputnik
|
||||
<span className="maputnik-toolbar-version">v{pkgJson.version}</span>
|
||||
</h1>
|
||||
</ToolbarLink>
|
||||
<div className="maputnik-toolbar__actions">
|
||||
<ToolbarAction wdKey="nav:open" onClick={this.toggleModal.bind(this, 'open')}>
|
||||
|
|
|
@ -18,6 +18,8 @@ class LayerIcon extends React.Component {
|
|||
switch(this.props.type) {
|
||||
case 'fill-extrusion': return <BackgroundIcon {...iconProps} />
|
||||
case 'raster': return <FillIcon {...iconProps} />
|
||||
case 'hillshade': return <FillIcon {...iconProps} />
|
||||
case 'heatmap': return <FillIcon {...iconProps} />
|
||||
case 'fill': return <FillIcon {...iconProps} />
|
||||
case 'background': return <BackgroundIcon {...iconProps} />
|
||||
case 'line': return <LineIcon {...iconProps} />
|
||||
|
|
|
@ -112,6 +112,11 @@ export default class LayerEditor extends React.Component {
|
|||
comment = this.props.layer.metadata['maputnik:comment']
|
||||
}
|
||||
|
||||
let sourceLayerIds;
|
||||
if(this.props.sources.hasOwnProperty(this.props.layer.source)) {
|
||||
sourceLayerIds = this.props.sources[this.props.layer.source].layers;
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case 'layer': return <div>
|
||||
<LayerIdBlock
|
||||
|
@ -129,8 +134,9 @@ export default class LayerEditor extends React.Component {
|
|||
onChange={v => this.changeProperty(null, 'source', v)}
|
||||
/>
|
||||
}
|
||||
{this.props.layer.type !== 'raster' && this.props.layer.type !== 'background' && <LayerSourceLayerBlock
|
||||
sourceLayerIds={this.props.sources[this.props.layer.source].layers}
|
||||
{['background', 'raster', 'hillshade', 'heatmap'].indexOf(this.state.type) < 0 &&
|
||||
<LayerSourceLayerBlock
|
||||
sourceLayerIds={sourceLayerIds}
|
||||
value={this.props.layer['source-layer']}
|
||||
onChange={v => this.changeProperty(null, 'source-layer', v)}
|
||||
/>
|
||||
|
|
|
@ -25,6 +25,8 @@ class LayerTypeBlock extends React.Component {
|
|||
['raster', 'Raster'],
|
||||
['circle', 'Circle'],
|
||||
['fill-extrusion', 'Fill Extrusion'],
|
||||
['hillshade', 'Hillshade'],
|
||||
['heatmap', 'Heatmap'],
|
||||
]}
|
||||
onChange={this.props.onChange}
|
||||
value={this.props.value}
|
||||
|
|
|
@ -38,7 +38,7 @@ function buildInspectStyle(originalMapStyle, coloredLayers, highlightedLayer) {
|
|||
const sources = {}
|
||||
Object.keys(originalMapStyle.sources).forEach(sourceId => {
|
||||
const source = originalMapStyle.sources[sourceId]
|
||||
if(source.type !== 'raster') {
|
||||
if(source.type !== 'raster' && source.type !== 'raster-dem') {
|
||||
sources[sourceId] = source
|
||||
}
|
||||
})
|
||||
|
|
|
@ -3,66 +3,8 @@ import PropTypes from 'prop-types'
|
|||
import style from '../../libs/style.js'
|
||||
import isEqual from 'lodash.isequal'
|
||||
import { loadJSON } from '../../libs/urlopen'
|
||||
import 'openlayers/dist/ol.css'
|
||||
import 'ol/ol.css'
|
||||
|
||||
function suitableVectorSource(mapStyle) {
|
||||
const sources = Object.keys(mapStyle.sources)
|
||||
.map(sourceId => {
|
||||
return {
|
||||
id: sourceId,
|
||||
source: mapStyle.sources[sourceId]
|
||||
}
|
||||
})
|
||||
.filter(({source}) => (source.type === 'vector' || source.type === 'geojson'))
|
||||
return sources[0]
|
||||
}
|
||||
|
||||
function toVectorLayer(source, tilegrid, cb) {
|
||||
function newMVTLayer(tileUrl) {
|
||||
const ol = require('openlayers')
|
||||
return new ol.layer.VectorTile({
|
||||
source: new ol.source.VectorTile({
|
||||
format: new ol.format.MVT(),
|
||||
tileGrid: tilegrid,
|
||||
tilePixelRatio: 8,
|
||||
url: tileUrl
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function newGeoJSONLayer(sourceUrl) {
|
||||
const ol = require('openlayers')
|
||||
return new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
format: new ol.format.GeoJSON(),
|
||||
url: sourceUrl
|
||||
})
|
||||
})
|
||||
}
|
||||
if (source.type === 'vector') {
|
||||
if(!source.tiles) {
|
||||
sourceFromTileJSON(source.url, tileSource => {
|
||||
cb(newMVTLayer(tileSource.tiles[0]))
|
||||
})
|
||||
} else {
|
||||
cb(newMVTLayer(source.tiles[0]))
|
||||
}
|
||||
} else if (source.type === 'geojson') {
|
||||
cb(newGeoJSONLayer(source.data))
|
||||
}
|
||||
}
|
||||
|
||||
function sourceFromTileJSON(url, cb) {
|
||||
loadJSON(url, null, tilejson => {
|
||||
if(!tilejson) return
|
||||
cb({
|
||||
type: 'vector',
|
||||
tiles: tilejson.tiles,
|
||||
minzoom: tilejson.minzoom,
|
||||
maxzoom: tilejson.maxzoom,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
class OpenLayers3Map extends React.Component {
|
||||
static propTypes = {
|
||||
|
@ -79,49 +21,17 @@ class OpenLayers3Map extends React.Component {
|
|||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.tilegrid = null
|
||||
this.resolutions = null
|
||||
this.layer = null
|
||||
this.map = null
|
||||
}
|
||||
|
||||
updateStyle(newMapStyle) {
|
||||
const oldSource = suitableVectorSource(this.props.mapStyle)
|
||||
const newSource = suitableVectorSource(newMapStyle)
|
||||
const resolutions = this.resolutions
|
||||
|
||||
function setStyleFunc(map, layer) {
|
||||
const olms = require('ol-mapbox-style')
|
||||
const styleFunc = olms.getStyleFunction(newMapStyle, newSource.id, resolutions)
|
||||
layer.setStyle(styleFunc)
|
||||
//NOTE: We need to mark the source as changed in order
|
||||
//to trigger a rerender
|
||||
layer.getSource().changed()
|
||||
map.render()
|
||||
}
|
||||
|
||||
if(newSource) {
|
||||
if(this.layer && !isEqual(oldSource, newSource)) {
|
||||
this.map.removeLayer(this.layer)
|
||||
this.layer = null
|
||||
}
|
||||
|
||||
if(!this.layer) {
|
||||
var self = this
|
||||
toVectorLayer(newSource.source, this.tilegrid, vectorLayer => {
|
||||
self.layer = vectorLayer
|
||||
self.map.addLayer(self.layer)
|
||||
setStyleFunc(self.map, self.layer)
|
||||
})
|
||||
} else {
|
||||
setStyleFunc(this.map, this.layer)
|
||||
}
|
||||
}
|
||||
const olms = require('ol-mapbox-style');
|
||||
const styleFunc = olms.apply(this.map, newMapStyle)
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
require.ensure(["openlayers", "ol-mapbox-style"], () => {
|
||||
if(!this.map || !this.resolutions) return
|
||||
require.ensure(["ol", "ol-mapbox-style"], () => {
|
||||
if(!this.map) return
|
||||
this.updateStyle(nextProps.mapStyle)
|
||||
})
|
||||
}
|
||||
|
@ -129,24 +39,22 @@ class OpenLayers3Map extends React.Component {
|
|||
componentDidMount() {
|
||||
//Load OpenLayers dynamically once we need it
|
||||
//TODO: Make this more convenient
|
||||
require.ensure(["openlayers", "ol-mapbox-style"], ()=> {
|
||||
require.ensure(["ol", "ol/map", "ol/view", "ol/control/zoom", "ol-mapbox-style"], ()=> {
|
||||
console.log('Loaded OpenLayers3 renderer')
|
||||
|
||||
const ol = require('openlayers')
|
||||
const olms = require('ol-mapbox-style')
|
||||
const olMap = require('ol/map').default
|
||||
const olView = require('ol/view').default
|
||||
const olZoom = require('ol/control/zoom').default
|
||||
|
||||
this.tilegrid = ol.tilegrid.createXYZ({tileSize: 512, maxZoom: 22})
|
||||
this.resolutions = this.tilegrid.getResolutions()
|
||||
|
||||
const map = new ol.Map({
|
||||
const map = new olMap({
|
||||
target: this.container,
|
||||
layers: [],
|
||||
view: new ol.View({
|
||||
view: new olView({
|
||||
zoom: 2,
|
||||
center: [52.5, -78.4]
|
||||
})
|
||||
})
|
||||
map.addControl(new ol.control.Zoom())
|
||||
map.addControl(new olZoom())
|
||||
this.map = map
|
||||
this.updateStyle(this.props.mapStyle)
|
||||
})
|
||||
|
|
|
@ -142,7 +142,7 @@ class AddModal extends React.Component {
|
|||
onChange={v => this.setState({ source: v })}
|
||||
/>
|
||||
}
|
||||
{this.state.type !== 'background' && this.state.type !== 'raster' &&
|
||||
{['background', 'raster', 'hillshade', 'heatmap'].indexOf(this.state.type) < 0 &&
|
||||
<LayerSourceLayerBlock
|
||||
isFixed={true}
|
||||
sourceLayerIds={layers}
|
||||
|
|
|
@ -25,6 +25,7 @@ class Gist extends React.Component {
|
|||
super(props);
|
||||
this.state = {
|
||||
preview: false,
|
||||
public: false,
|
||||
saving: false,
|
||||
latestGist: null,
|
||||
}
|
||||
|
@ -42,7 +43,10 @@ class Gist extends React.Component {
|
|||
...this.state,
|
||||
saving: true
|
||||
});
|
||||
const preview = this.state.preview && (this.props.mapStyle.metadata || {})['maputnik:openmaptiles_access_token'];
|
||||
|
||||
const preview = this.state.preview;
|
||||
|
||||
const mapboxToken = (this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token'];
|
||||
|
||||
const mapStyleStr = preview ?
|
||||
styleSpec.format(stripAccessTokens(style.replaceAccessToken(this.props.mapStyle))) :
|
||||
|
@ -55,8 +59,8 @@ class Gist extends React.Component {
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>`+styleTitle+` Preview</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://api.mapbox.com/mapbox-gl-js/v0.43.0/mapbox-gl.css" />
|
||||
<script src="https://api.mapbox.com/mapbox-gl-js/v0.43.0/mapbox-gl.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="https://api.mapbox.com/mapbox-gl-js/v0.44.0/mapbox-gl.css" />
|
||||
<script src="https://api.mapbox.com/mapbox-gl-js/v0.44.0/mapbox-gl.js"></script>
|
||||
<style>
|
||||
body { margin:0; padding:0; }
|
||||
#map { position:absolute; top:0; bottom:0; width:100%; }
|
||||
|
@ -65,6 +69,7 @@ class Gist extends React.Component {
|
|||
<body>
|
||||
<div id='map'></div>
|
||||
<script>
|
||||
mapboxgl.accessToken = '${mapboxToken}';
|
||||
var map = new mapboxgl.Map({
|
||||
container: 'map',
|
||||
style: 'style.json',
|
||||
|
@ -89,7 +94,7 @@ class Gist extends React.Component {
|
|||
const gh = new GitHub();
|
||||
let gist = gh.getGist(); // not a gist yet
|
||||
gist.create({
|
||||
public: true,
|
||||
public: this.state.public,
|
||||
description: styleTitle,
|
||||
files: files
|
||||
}).then(function({data}) {
|
||||
|
@ -110,6 +115,13 @@ class Gist extends React.Component {
|
|||
})
|
||||
}
|
||||
|
||||
onPublicChange(value) {
|
||||
this.setState({
|
||||
...this.state,
|
||||
public: value
|
||||
})
|
||||
}
|
||||
|
||||
changeMetadataProperty(property, value) {
|
||||
const changedStyle = {
|
||||
...this.props.mapStyle,
|
||||
|
@ -162,13 +174,22 @@ class Gist extends React.Component {
|
|||
<MdFileDownload />
|
||||
Save to Gist (anonymous)
|
||||
</Button>
|
||||
{' '}
|
||||
<CheckboxInput
|
||||
value={this.state.preview}
|
||||
name='gist-style-preview'
|
||||
onChange={this.onPreviewChange.bind(this)}
|
||||
/>
|
||||
<span> Include preview</span>
|
||||
<div className="maputnik-modal-sub-section">
|
||||
<CheckboxInput
|
||||
value={this.state.public}
|
||||
name='gist-style-public'
|
||||
onChange={this.onPublicChange.bind(this)}
|
||||
/>
|
||||
<span> Public gist</span>
|
||||
</div>
|
||||
<div className="maputnik-modal-sub-section">
|
||||
<CheckboxInput
|
||||
value={this.state.preview}
|
||||
name='gist-style-preview'
|
||||
onChange={this.onPreviewChange.bind(this)}
|
||||
/>
|
||||
<span> Include preview</span>
|
||||
</div>
|
||||
{this.state.preview ?
|
||||
<div>
|
||||
<InputBlock
|
||||
|
@ -177,6 +198,12 @@ class Gist extends React.Component {
|
|||
value={(this.props.mapStyle.metadata || {})['maputnik:openmaptiles_access_token']}
|
||||
onChange={this.changeMetadataProperty.bind(this, "maputnik:openmaptiles_access_token")}/>
|
||||
</InputBlock>
|
||||
<InputBlock
|
||||
label={"Mapbox Access Token: "}>
|
||||
<StringInput
|
||||
value={(this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token']}
|
||||
onChange={this.changeMetadataProperty.bind(this, "maputnik:mapbox_access_token")}/>
|
||||
</InputBlock>
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://openmaptiles.com/hosting/">Get your free access token</a>
|
||||
</div>
|
||||
: null}
|
||||
|
|
|
@ -45,6 +45,10 @@ function editorMode(source) {
|
|||
if(source.tiles) return 'tilexyz_raster'
|
||||
return 'tilejson_raster'
|
||||
}
|
||||
if(source.type === 'raster-dem') {
|
||||
if(source.tiles) return 'tilexyz_raster-dem'
|
||||
return 'tilejson_raster-dem'
|
||||
}
|
||||
if(source.type === 'vector') {
|
||||
if(source.tiles) return 'tilexyz_vector'
|
||||
return 'tilejson_vector'
|
||||
|
@ -127,6 +131,16 @@ class AddSource extends React.Component {
|
|||
minzoom: source.minzoom || 0,
|
||||
maxzoom: source.maxzoom || 14
|
||||
}
|
||||
case 'tilejson_raster-dem': return {
|
||||
type: 'raster-dem',
|
||||
url: source.url || 'http://localhost:3000/tilejson.json'
|
||||
}
|
||||
case 'tilexyz_raster-dem': return {
|
||||
type: 'raster-dem',
|
||||
tiles: source.tiles || ['http://localhost:3000/{x}/{y}/{z}.pbf'],
|
||||
minzoom: source.minzoom || 0,
|
||||
maxzoom: source.maxzoom || 14
|
||||
}
|
||||
default: return {}
|
||||
}
|
||||
}
|
||||
|
@ -147,6 +161,8 @@ class AddSource extends React.Component {
|
|||
['tilexyz_vector', 'Vector (XYZ URLs)'],
|
||||
['tilejson_raster', 'Raster (TileJSON URL)'],
|
||||
['tilexyz_raster', 'Raster (XYZ URL)'],
|
||||
['tilejson_raster-dem', 'Raster DEM (TileJSON URL)'],
|
||||
['tilexyz_raster-dem', 'Raster DEM (XYZ URLs)'],
|
||||
]}
|
||||
onChange={mode => this.setState({mode: mode, source: this.defaultSource(mode)})}
|
||||
value={this.state.mode}
|
||||
|
|
|
@ -115,6 +115,8 @@ class SourceTypeEditor extends React.Component {
|
|||
case 'tilexyz_vector': return <TileURLSourceEditor {...commonProps} />
|
||||
case 'tilejson_raster': return <TileJSONSourceEditor {...commonProps} />
|
||||
case 'tilexyz_raster': return <TileURLSourceEditor {...commonProps} />
|
||||
case 'tilejson_raster-dem': return <TileJSONSourceEditor {...commonProps} />
|
||||
case 'tilexyz_raster-dem': return <TileURLSourceEditor {...commonProps} />
|
||||
default: return null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,7 +91,8 @@
|
|||
"circle-stroke-width",
|
||||
"circle-pitch-scale",
|
||||
"circle-translate",
|
||||
"circle-translate-anchor"
|
||||
"circle-translate-anchor",
|
||||
"circle-pitch-alignment"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -147,7 +148,9 @@
|
|||
"icon-rotate",
|
||||
"icon-padding",
|
||||
"icon-keep-upright",
|
||||
"icon-offset"
|
||||
"icon-offset",
|
||||
"icon-anchor",
|
||||
"icon-pitch-alignment"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -194,5 +197,35 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"hillshade": {
|
||||
"groups": [
|
||||
{
|
||||
"title": "Paint properties",
|
||||
"type": "properties",
|
||||
"fields": [
|
||||
"hillshade-illumination-direction",
|
||||
"hillshade-illumination-anchor",
|
||||
"hillshade-exaggeration",
|
||||
"hillshade-shadow-color",
|
||||
"hillshade-highlight-color",
|
||||
"hillshade-accent-color"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"heatmap": {
|
||||
"groups": [
|
||||
{
|
||||
"title": "Paint properties",
|
||||
"type": "properties",
|
||||
"fields": [
|
||||
"heatmap-radius",
|
||||
"heatmap-weight",
|
||||
"heatmap-intensity",
|
||||
"heatmap-opacity"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,12 +54,23 @@ function indexOfLayer(layers, layerId) {
|
|||
return null
|
||||
}
|
||||
|
||||
function replaceAccessToken(mapStyle) {
|
||||
function replaceAccessToken(mapStyle, opts={}) {
|
||||
const omtSource = mapStyle.sources.openmaptiles
|
||||
if(!omtSource) return mapStyle
|
||||
if(!omtSource.hasOwnProperty("url")) return mapStyle
|
||||
|
||||
const metadata = mapStyle.metadata || {}
|
||||
const accessToken = metadata['maputnik:openmaptiles_access_token'] || tokens.openmaptiles
|
||||
let accessToken = metadata['maputnik:openmaptiles_access_token'];
|
||||
|
||||
if(opts.allowFallback && !accessToken) {
|
||||
accessToken = tokens.openmaptiles;
|
||||
}
|
||||
|
||||
if(!accessToken) {
|
||||
// Early exit.
|
||||
return mapStyle;
|
||||
}
|
||||
|
||||
const changedSources = {
|
||||
...mapStyle.sources,
|
||||
openmaptiles: {
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
// BUTTON
|
||||
.maputnik-button {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
background-color: $color-midgray;
|
||||
color: $color-lowgray;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
background-color: $color-black;
|
||||
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.3);
|
||||
z-index: 3;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.maputnik-modal-section {
|
||||
|
@ -20,6 +21,10 @@
|
|||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.maputnik-modal-sub-section {
|
||||
margin-top: $margin-1;
|
||||
}
|
||||
|
||||
.maputnik-modal-section--shrink {
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
@ -75,6 +80,7 @@
|
|||
position: fixed;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 9;
|
||||
|
||||
@include flex-row;
|
||||
}
|
||||
|
|
|
@ -36,12 +36,24 @@
|
|||
cursor: pointer;
|
||||
color: $color-white;
|
||||
text-decoration: none;
|
||||
line-height: 20px;
|
||||
|
||||
h1 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $color-midgray;
|
||||
}
|
||||
}
|
||||
|
||||
.maputnik-toolbar-version {
|
||||
position: absolute;
|
||||
font-size: 10px;
|
||||
bottom: -2px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.maputnik-toolbar-action {
|
||||
@extend .maputnik-toolbar-link;
|
||||
}
|
||||
|
@ -56,7 +68,7 @@
|
|||
}
|
||||
|
||||
.maputnik-toolbar-logo {
|
||||
flex: 0 0 140px;
|
||||
flex: 0 0 170px;
|
||||
}
|
||||
|
||||
.maputnik-toolbar__inner {
|
||||
|
|
Loading…
Reference in a new issue