Compare commits

...

40 Commits

Author SHA1 Message Date
orangemug
b966fae926 1.5.0 2018-09-10 13:18:21 +01:00
orangemug
f1ddf4e57e 1.5.0-beta3 2018-09-03 21:17:50 +01:00
Orange Mug
64e65dc7d3 Merge pull request #377 from orangemug/fix/glyphs-for-tilehosting
Updated regex to tilehosting.com
2018-09-03 21:15:01 +01:00
orangemug
1e07a88aed Updated regex to tilehosting.com, partial revert of #367 2018-09-03 21:02:38 +01:00
orangemug
6e49cc65a9 1.5.0-beta2 2018-09-03 20:37:16 +01:00
Orange Mug
06d579118a Merge pull request #367 from loicgasser/bugfix/default-token
Fix glyph access key for openmaptiles
2018-09-03 20:34:01 +01:00
orangemug
f0e4b5b930 1.5.0-beta 2018-09-01 11:09:19 +01:00
Loïc Gasser
088127a9a5 Fix glyph access key for openmaptiles 2018-08-27 16:18:43 -04:00
Orange Mug
98c235bc21 Merge pull request #363 from orangemug/feature/added-show-collision-boxes
Added 'show-collision-boxes' query parameter
2018-08-19 19:48:03 +01:00
orangemug
70f1f9ffac Added 'show-collision-boxes' query parameter 2018-08-19 17:32:18 +01:00
Orange Mug
c5ea9494df Merge pull request #357 from chriswhong/356-zoom-button-fix
find correct zoom attribute in spec
2018-08-04 09:20:31 +01:00
Chris Whong
9a34db7008 find correct zoom attribute in spec 2018-08-03 15:25:05 -04:00
Orange Mug
988b7fca0f Merge pull request #355 from orangemug/fix/failing-tests
Disable survey in test runner
2018-08-01 22:14:36 +01:00
orangemug
bdc6489db4 Disable survey in test runner, which was making the tests fail. 2018-08-01 20:59:42 +01:00
Orange Mug
49b096b601 Merge pull request #352 from orangemug/feature/add-thunderforest-source-v2
Added thunderforest source
2018-08-01 20:48:12 +01:00
Orange Mug
31d83f6a26 Merge pull request #354 from orangemug/maintenance/updated-mapbox-deps
Updated mapbox dependencies
2018-08-01 20:47:39 +01:00
orangemug
03e52b7a72 Added support for 'raster-resampling' 2018-08-01 20:34:26 +01:00
orangemug
551e950c39 Updated mapbox dependencies 2018-08-01 20:33:33 +01:00
orangemug
a7620f83a6 Fixed broken token replacer function. 2018-07-28 16:36:01 +01:00
orangemug
0384181ee1 Added final bits for thunderforest integration 2018-07-27 16:25:53 +01:00
orangemug
fd59f42819 Merge remote-tracking branch 'upstream/master' into feature/add-thunderforest-source
Conflicts:
	src/components/App.jsx
2018-07-27 15:43:02 +01:00
orangemug
cc51774259 1.4.0 2018-07-27 13:19:14 +01:00
Orange Mug
5a19245ee0 Merge pull request #349 from orangemug/fix/react-codemirror-overflow
Fix to prevent contents of react-codemirror being hidden
2018-07-18 19:16:14 +01:00
orangemug
45f45b7547 Fix to prevent contents of react-codemirror being hidden 2018-07-18 08:07:35 +01:00
Orange Mug
530bfaf3b3 Merge pull request #348 from orangemug/fix/color-filter-undefined
Undefined filter fix (color accessibility)
2018-07-17 21:51:54 +01:00
orangemug
6ea70ab9cf Fix what I believe to be a 'first boot' error. 2018-07-17 20:45:12 +01:00
orangemug
a0e2d68dae Only apply filter if defined. 2018-07-17 20:40:23 +01:00
Orange Mug
1447e8bfb5 Merge pull request #345 from orangemug/feature/option-to-download-with-own-tokens
Option to download styles with your own tokens
2018-07-16 08:10:43 +01:00
orangemug
c0480a50ea Option to download styles with own tokens. 2018-07-15 22:51:57 +01:00
Orange Mug
09ba2be416 Merge pull request #344 from orangemug/fix/map-overflow-zoom-issues
Fixed map width so it no longer overflows
2018-07-15 22:44:51 +01:00
Orange Mug
115ce3305d Merge pull request #343 from orangemug/fix/disable-bounce-scroll
Prevent bounce scroll on <body/>
2018-07-15 22:11:18 +01:00
orangemug
960b2022ed Fixed map width (fixes #260) 2018-07-15 22:08:06 +01:00
orangemug
252b442ca9 The UI is 100% height so prevent bounce scroll on OSX 2018-07-15 21:51:25 +01:00
Orange Mug
03b9ddda9c Merge pull request #342 from orangemug/fix/layer-editor-overflow
Fixed <LayerEditor/> overflow issues
2018-07-15 21:49:17 +01:00
orangemug
968d7d7fda Fixed <LayerEditor/> overflow issues. 2018-07-15 13:17:47 +01:00
orangemug
b211f1cd12 1.3.0 2018-07-12 15:54:01 +01:00
Orange Mug
870d4349f4 Merge pull request #341 from orangemug/fix/normalizeSourceURL-import-error
Fixed normalizeSourceURL import issue
2018-07-12 14:23:16 +01:00
orangemug
d88bc59720 Fixed normalizeSourceURL import issue. 2018-07-12 12:33:40 +01:00
orangemug
45bdf53a41 Added thunderforest maputnik token. 2018-04-11 16:20:23 +01:00
orangemug
00e94212bd Added initial thunderforest source integration 2018-04-11 15:53:40 +01:00
20 changed files with 3332 additions and 3221 deletions

6378
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "maputnik",
"version": "1.3.0-beta",
"version": "1.5.0",
"description": "A MapboxGL visual style editor",
"main": "''",
"scripts": {
@@ -21,8 +21,8 @@
"license": "MIT",
"homepage": "https://github.com/maputnik/editor#readme",
"dependencies": {
"@mapbox/mapbox-gl-rtl-text": "^0.1.2",
"@mapbox/mapbox-gl-style-spec": "^12.0.0",
"@mapbox/mapbox-gl-rtl-text": "^0.2.0",
"@mapbox/mapbox-gl-style-spec": "^13.1.0",
"classnames": "^2.2.5",
"codemirror": "^5.37.0",
"color": "^3.0.0",
@@ -34,7 +34,7 @@
"lodash.clonedeep": "^4.5.0",
"lodash.isequal": "^4.5.0",
"lodash.throttle": "^4.1.1",
"mapbox-gl": "^0.45.0",
"mapbox-gl": "^0.47.0",
"mapbox-gl-inspect": "^1.3.1",
"maputnik-design": "github:maputnik/design",
"mousetrap": "^1.6.1",

View File

@@ -22,7 +22,7 @@ import SurveyModal from './modals/SurveyModal'
import { downloadGlyphsMetadata, downloadSpriteMetadata } from '../libs/metadata'
import * as styleSpec from '@mapbox/mapbox-gl-style-spec/style-spec'
import style from '../libs/style.js'
import style from '../libs/style'
import { initialStyleUrl, loadStyleUrl } from '../libs/urlopen'
import { undoMessages, redoMessages } from '../libs/diffmessage'
import { loadDefaultStyle, StyleStore } from '../libs/stylestore'
@@ -35,7 +35,7 @@ import Debug from '../libs/debug'
import queryUtil from '../libs/query-util'
import MapboxGl from 'mapbox-gl'
import mapboxUtil from 'mapbox-gl/src/util/mapbox'
import { normalizeSourceURL } from 'mapbox-gl/src/util/mapbox'
function updateRootSpec(spec, fieldName, newValues) {
@@ -176,7 +176,8 @@ export default class App extends React.Component {
survey: localStorage.hasOwnProperty('survey') ? false : true
},
mapOptions: {
showTileBoundaries: queryUtil.asBool(queryObj, "show-tile-boundaries")
showTileBoundaries: queryUtil.asBool(queryObj, "show-tile-boundaries"),
showCollisionBoxes: queryUtil.asBool(queryObj, "show-collision-boxes")
},
mapFilter: queryObj["color-blindness-emulation"],
}
@@ -365,7 +366,7 @@ export default class App extends React.Component {
if(!this.state.sources.hasOwnProperty(key) && val.type === "vector" && val.hasOwnProperty("url")) {
let url = val.url;
try {
url = mapboxUtil.normalizeSourceURL(url, MapboxGl.accessToken);
url = normalizeSourceURL(url, MapboxGl.accessToken);
} catch(err) {
console.warn("Failed to normalizeSourceURL: ", err);
}
@@ -407,7 +408,7 @@ export default class App extends React.Component {
mapRenderer() {
const mapProps = {
mapStyle: style.replaceAccessToken(this.state.mapStyle, {allowFallback: true}),
mapStyle: style.replaceAccessTokens(this.state.mapStyle, {allowFallback: true}),
options: this.state.mapOptions,
onDataChange: (e) => {
this.layerWatcher.analyzeMap(e.map)
@@ -430,9 +431,10 @@ export default class App extends React.Component {
onLayerSelect={this.onLayerSelect.bind(this)} />
}
const elementStyle = {
"filter": `url('#${this.state.mapFilter}')`
};
const elementStyle = {};
if(this.state.mapFilter) {
elementStyle.filter = `url('#${this.state.mapFilter}')`;
}
return <div style={elementStyle}>
{mapElement}

View File

@@ -16,7 +16,7 @@ export default class FunctionButtons extends React.Component {
render() {
let makeZoomButton, makeDataButton
if (this.props.fieldSpec['zoom-function']) {
if (this.props.fieldSpec.expression.parameters.includes('zoom')) {
makeZoomButton = <Button
className="maputnik-make-zoom-function"
onClick={this.props.onZoomClick}

View File

@@ -66,6 +66,7 @@ export default class MapboxGlMap extends React.Component {
onDataChange: () => {},
onLayerSelect: () => {},
mapboxAccessToken: tokens.mapbox,
options: {},
}
constructor(props) {
@@ -103,6 +104,7 @@ export default class MapboxGlMap extends React.Component {
}
map.showTileBoundaries = this.props.options.showTileBoundaries;
map.showCollisionBoxes = this.props.options.showCollisionBoxes;
}
componentDidMount() {
@@ -116,6 +118,7 @@ export default class MapboxGlMap extends React.Component {
const map = new MapboxGl.Map(mapOpts);
map.showTileBoundaries = mapOpts.showTileBoundaries;
map.showCollisionBoxes = mapOpts.showCollisionBoxes;
const zoom = new ZoomControl;
map.addControl(zoom, 'top-right');

View File

@@ -10,7 +10,7 @@ import Button from '../Button'
import Modal from './Modal'
import MdFileDownload from 'react-icons/lib/md/file-download'
import TiClipboard from 'react-icons/lib/ti/clipboard'
import style from '../../libs/style.js'
import style from '../../libs/style'
import GitHub from 'github-api'
import { CopyToClipboard } from 'react-copy-to-clipboard'
@@ -49,7 +49,7 @@ class Gist extends React.Component {
const mapboxToken = (this.props.mapStyle.metadata || {})['maputnik:mapbox_access_token'];
const mapStyleStr = preview ?
styleSpec.format(stripAccessTokens(style.replaceAccessToken(this.props.mapStyle))) :
styleSpec.format(stripAccessTokens(style.replaceAccessTokens(this.props.mapStyle))) :
styleSpec.format(stripAccessTokens(this.props.mapStyle));
const styleTitle = this.props.mapStyle.name || 'Style';
const htmlStr = `
@@ -235,10 +235,24 @@ class ExportModal extends React.Component {
}
downloadStyle() {
const blob = new Blob([styleSpec.format(stripAccessTokens(this.props.mapStyle))], {type: "application/json;charset=utf-8"});
const tokenStyle = styleSpec.format(stripAccessTokens(style.replaceAccessTokens(this.props.mapStyle)));
const blob = new Blob([tokenStyle], {type: "application/json;charset=utf-8"});
saveAs(blob, this.props.mapStyle.id + ".json");
}
changeMetadataProperty(property, value) {
const changedStyle = {
...this.props.mapStyle,
metadata: {
...this.props.mapStyle.metadata,
[property]: value
}
}
this.props.onStyleChanged(changedStyle)
}
render() {
return <Modal
data-wd-key="export-modal"
@@ -252,6 +266,28 @@ class ExportModal extends React.Component {
<p>
Download a JSON style to your computer.
</p>
<p>
<InputBlock label={"OpenMapTiles Access Token: "}>
<StringInput
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>
<InputBlock label={"Thunderforest Access Token: "}>
<StringInput
value={(this.props.mapStyle.metadata || {})['maputnik:thunderforest_access_token']}
onChange={this.changeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")}
/>
</InputBlock>
</p>
<Button onClick={this.downloadStyle.bind(this)}>
<MdFileDownload />
Download

View File

@@ -94,6 +94,14 @@ class SettingsModal extends React.Component {
/>
</InputBlock>
<InputBlock label={"Thunderforest Access Token"} doc={"Public access token for Thunderforest services."}>
<StringInput {...inputProps}
data-wd-key="modal-settings.maputnik:thunderforest_access_token"
value={metadata['maputnik:thunderforest_access_token']}
onChange={this.changeMetadataProperty.bind(this, "maputnik:thunderforest_access_token")}
/>
</InputBlock>
<InputBlock label={"Style Renderer"} doc={"Choose the default Maputnik renderer for this style."}>
<SelectInput {...inputProps}
data-wd-key="modal-settings.maputnik:renderer"

View File

@@ -236,9 +236,12 @@ class SourcesModal extends React.Component {
<p>
Add one of the publicly available sources to your style.
</p>
<div style={{maxwidth: 500}}>
<div className="maputnik-public-sources" style={{maxwidth: 500}}>
{tilesetOptions}
</div>
<p>
<strong>Note:</strong> Some of the tilesets are not optimised for online use, and as a result the file sizes of the tiles can be quite large (heavy) for online vector rendering. Please review any tilesets before use.
</p>
</div>
<div className="maputnik-modal-section">

View File

@@ -193,7 +193,8 @@
"raster-brightness-max",
"raster-saturation",
"raster-contrast",
"raster-fade-duration"
"raster-fade-duration",
"raster-resampling"
]
}
]

View File

@@ -8,5 +8,15 @@
"type": "vector",
"url": "https://free.tilehosting.com/data/v3.json?key={key}",
"title": "OpenMapTiles"
},
"thunderforest_transport": {
"type": "vector",
"url": "https://tile.thunderforest.com/thunderforest.transport-v1.json?apikey={key}",
"title": "Thunderforest Transport (heavy)"
},
"thunderforest_outdoors": {
"type": "vector",
"url": "https://tile.thunderforest.com/thunderforest.outdoors-v1.json?apikey={key}",
"title": "Thunderforest Outdoors (heavy)"
}
}

View File

@@ -1,4 +1,5 @@
{
"mapbox": "pk.eyJ1IjoibW9yZ2Vua2FmZmVlIiwiYSI6ImNpeHJmNXNmZTAwNHIycXBid2NqdTJibjMifQ.Dv1-GDpTWi0NP6xW9Fct1w",
"openmaptiles": "Og58UhhtiiTaLVlPtPgs"
"openmaptiles": "Og58UhhtiiTaLVlPtPgs",
"thunderforest": "b71f7f0ba4064f5eb9e903859a9cf5c6"
}

View File

@@ -54,18 +54,28 @@ function indexOfLayer(layers, layerId) {
return null
}
function replaceAccessToken(mapStyle, opts={}) {
const omtSource = mapStyle.sources.openmaptiles
if(!omtSource) return mapStyle
if(!omtSource.hasOwnProperty("url")) return mapStyle
function getAccessToken(sourceName, mapStyle, opts) {
if(sourceName === "thunderforest_transport" || sourceName === "thunderforest_outdoors") {
sourceName = "thunderforest"
}
const metadata = mapStyle.metadata || {}
let accessToken = metadata['maputnik:openmaptiles_access_token'];
let accessToken = metadata[`maputnik:${sourceName}_access_token`]
if(opts.allowFallback && !accessToken) {
accessToken = tokens.openmaptiles;
accessToken = tokens[sourceName]
}
return accessToken;
}
function replaceSourceAccessToken(mapStyle, sourceName, opts={}) {
const source = mapStyle.sources[sourceName]
if(!source) return mapStyle
if(!source.hasOwnProperty("url")) return mapStyle
const accessToken = getAccessToken(sourceName, mapStyle, opts)
if(!accessToken) {
// Early exit.
return mapStyle;
@@ -73,16 +83,31 @@ function replaceAccessToken(mapStyle, opts={}) {
const changedSources = {
...mapStyle.sources,
openmaptiles: {
...omtSource,
url: omtSource.url.replace('{key}', accessToken)
[sourceName]: {
...source,
url: source.url.replace('{key}', accessToken)
}
}
const changedStyle = {
...mapStyle,
glyphs: mapStyle.glyphs ? mapStyle.glyphs.replace('{key}', accessToken) : mapStyle.glyphs,
sources: changedSources
}
return changedStyle
}
function replaceAccessTokens(mapStyle, opts={}) {
let changedStyle = mapStyle
Object.keys(mapStyle.sources).forEach((sourceName) => {
changedStyle = replaceSourceAccessToken(changedStyle, sourceName, opts);
})
if (mapStyle.glyphs && mapStyle.glyphs.match(/\.tilehosting\.com/)) {
changedStyle = {
...changedStyle,
glyphs: mapStyle.glyphs.replace('{key}', getAccessToken("openmaptiles", mapStyle, opts))
}
}
return changedStyle
}
@@ -92,5 +117,5 @@ export default {
emptyStyle,
indexOfLayer,
generateId,
replaceAccessToken,
replaceAccessTokens,
}

View File

@@ -18,6 +18,11 @@ html {
box-sizing: border-box;
}
body {
// The UI is 100% height so prevent bounce scroll on OSX
overflow: hidden;
}
*,
*::before,
*::after {

View File

@@ -5,7 +5,11 @@
right: 0;
bottom: 0;
height: calc(100% - #{$toolbar-height + $toolbar-offset});
width: 75%;
width: calc(
100%
- 200px /* layer list */
- 350px /* layer editor */
);
}
// DOC LABEL

View File

@@ -1,6 +1,6 @@
//SCROLLING
.maputnik-scroll-container {
overflow-x: visible;
overflow-x: hidden;
overflow-y: scroll;
bottom: 0;
left: 0;

View File

@@ -125,6 +125,10 @@
}
//SOURCE MODAL
.maputnik-public-sources {
margin-bottom: 1.5%;
}
.maputnik-public-source {
vertical-align: top;
margin-top: 1.5%;
@@ -150,6 +154,7 @@
.maputnik-public-source-id {
font-weight: 400;
text-align: left;
}
.maputnik-active-source-type-editor {

View File

@@ -0,0 +1,3 @@
.react-codemirror2 {
max-width: 100%;
}

View File

@@ -1,6 +1,7 @@
// See <https://github.com/nkbt/react-collapse/commit/4f4fbce7c6c07b082dc62062338c9294c656f9df>
.react-collapse-container {
display: flex;
max-width: 100%;
> * {
flex: 1;

View File

@@ -38,6 +38,7 @@ $toolbar-offset: 0;
@import 'popup';
@import 'map';
@import 'react-collapse';
@import 'react-codemirror';
/**
* Hacks for webdriverio isVisibleWithinViewport

View File

@@ -13,6 +13,9 @@ describe('maputnik', function() {
"geojson:example",
"raster:raster"
]));
browser.execute(function() {
localStorage.setItem("survey", true);
});
browser.waitForExist(".maputnik-toolbar-link");
browser.flushReactUpdates();
});