From d5b5261c1d508f6a567302a5cd895908d855474b Mon Sep 17 00:00:00 2001 From: lukasmartinelli Date: Fri, 25 Nov 2016 13:31:41 +0100 Subject: [PATCH] Split OL3 and GL map into separate files --- .editorconfig | 15 ---- src/app.jsx | 5 +- src/gl.jsx | 53 ++++++++++++ src/map.jsx | 124 ++++------------------------ src/ol3.jsx | 48 +++++++++++ webpack.production.config.js | 151 ++++++++++++++++++----------------- 6 files changed, 196 insertions(+), 200 deletions(-) delete mode 100644 .editorconfig create mode 100644 src/gl.jsx create mode 100644 src/ol3.jsx diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 2b6d1dc..0000000 --- a/.editorconfig +++ /dev/null @@ -1,15 +0,0 @@ -root = true - -# Unix-style newlines with a newline ending every file -[*] -end_of_line = lf -insert_final_newline = true - - -# Matches multiple files with brace expansion notation -# Set default charset -[*.{js,jsx,html,sass}] -charset = utf-8 -indent_style = tab -indent_size = 2 -trim_trailing_whitespace = true diff --git a/src/app.jsx b/src/app.jsx index 1339789..920ddb9 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -6,7 +6,8 @@ import Container from 'rebass/dist/Container' import Block from 'rebass/dist/Block' import Fixed from 'rebass/dist/Fixed' -import { MapboxGlMap, OpenLayer3Map } from './map.jsx' +import { MapboxGlMap } from './gl.jsx' +import { OpenLayers3Map } from './ol3.jsx' import {Toolbar} from './toolbar.jsx' import style from './style.js' import { loadDefaultStyle, SettingsStore, StyleStore } from './stylestore.js' @@ -110,7 +111,7 @@ export default class App extends React.Component { accessToken={this.state.accessToken} onAccessTokenChanged={this.onAccessTokenChanged.bind(this)} /> - diff --git a/src/gl.jsx b/src/gl.jsx new file mode 100644 index 0000000..965d899 --- /dev/null +++ b/src/gl.jsx @@ -0,0 +1,53 @@ +import React from 'react' +import MapboxGl from 'mapbox-gl'; +import { fullHeight } from './theme.js' +import style from './style.js' +import { Map } from './map.jsx' +import Immutable from 'immutable' +import validateColor from 'mapbox-gl-style-spec/lib/validate/validate_color' + +export class MapboxGlMap extends Map { + componentWillReceiveProps(nextProps) { + const tokenChanged = nextProps.accessToken !== MapboxGl.accessToken + + // If the id has changed a new style has been uplaoded and + // it is safer to do a full new render + // TODO: might already be handled in diff algorithm? + const mapIdChanged = this.props.mapStyle.get('id') !== nextProps.mapStyle.get('id') + + if(mapIdChanged || tokenChanged) { + this.state.map.setStyle(style.toJSON(nextProps.mapStyle)) + return + } + + // TODO: If there is no map yet we need to apply the changes later? + if(this.state.map) { + style.diffStyles(this.props.mapStyle, nextProps.mapStyle).forEach(change => { + + //TODO: Invalid outline color can cause map to freeze? + if(change.command === "setPaintProperty" && change.args[1] === "fill-outline-color" ) { + const value = change.args[2] + if(validateColor({value}).length > 0) { + return + } + } + + console.log(change.command, ...change.args) + this.state.map[change.command].apply(this.state.map, change.args); + }); + } + } + + componentDidMount() { + MapboxGl.accessToken = this.props.accessToken + + const map = new MapboxGl.Map({ + container: this.container, + style: style.toJSON(this.props.mapStyle), + }); + + map.on("style.load", (...args) => { + this.setState({ map }); + }); + } +} diff --git a/src/map.jsx b/src/map.jsx index 7e0dc25..5ab54e3 100644 --- a/src/map.jsx +++ b/src/map.jsx @@ -1,118 +1,24 @@ import React from 'react' -import MapboxGl from 'mapbox-gl'; import { fullHeight } from './theme.js' -import style from './style.js' import Immutable from 'immutable' -import validateColor from 'mapbox-gl-style-spec/lib/validate/validate_color' -import ol from 'openlayers' -import olms from 'ol-mapbox-style' export class Map extends React.Component { - static propTypes = { - mapStyle: React.PropTypes.instanceOf(Immutable.Map).isRequired, - accessToken: React.PropTypes.string, - } + static propTypes = { + mapStyle: React.PropTypes.instanceOf(Immutable.Map).isRequired, + accessToken: React.PropTypes.string, + } - shouldComponentUpdate(nextProps, nextState) { - //TODO: If we enable this React mixin for immutable comparison we can remove this? - return nextProps.mapStyle !== this.props.mapStyle - } + shouldComponentUpdate(nextProps, nextState) { + //TODO: If we enable this React mixin for immutable comparison we can remove this? + return nextProps.mapStyle !== this.props.mapStyle + } - render() { - return
this.container = x} - style={{ - ...fullHeight, - width: "100%", - }}>
- } -} - -export class MapboxGlMap extends Map { - componentWillReceiveProps(nextProps) { - const tokenChanged = nextProps.accessToken !== MapboxGl.accessToken - - // If the id has changed a new style has been uplaoded and - // it is safer to do a full new render - // TODO: might already be handled in diff algorithm? - const mapIdChanged = this.props.mapStyle.get('id') !== nextProps.mapStyle.get('id') - - if(mapIdChanged || tokenChanged) { - this.state.map.setStyle(style.toJSON(nextProps.mapStyle)) - return - } - - // TODO: If there is no map yet we need to apply the changes later? - if(this.state.map) { - style.diffStyles(this.props.mapStyle, nextProps.mapStyle).forEach(change => { - - //TODO: Invalid outline color can cause map to freeze? - if(change.command === "setPaintProperty" && change.args[1] === "fill-outline-color" ) { - const value = change.args[2] - if(validateColor({value}).length > 0) { - return - } - } - - console.log(change.command, ...change.args) - this.state.map[change.command].apply(this.state.map, change.args); - }); - } - } - - componentDidMount() { - MapboxGl.accessToken = this.props.accessToken - - const map = new MapboxGl.Map({ - container: this.container, - style: style.toJSON(this.props.mapStyle), - }); - - map.on("style.load", (...args) => { - this.setState({ map }); - }); + render() { + return
this.container = x} + style={{ + ...fullHeight, + width: "100%", + }}>
} } - -export class OpenLayer3Map extends Map { - constructor(props) { - super(props) - - const tilegrid = ol.tilegrid.createXYZ({tileSize: 512, maxZoom: 22}) - this.resolutions = tilegrid.getResolutions() - this.layer = new ol.layer.VectorTile({ - source: new ol.source.VectorTile({ - attributions: '© Mapbox ' + - '© ' + - 'OpenStreetMap contributors', - format: new ol.format.MVT(), - tileGrid: tilegrid, - tilePixelRatio: 8, - url: 'http://osm2vectortiles-0.tileserver.com/v2/{z}/{x}/{y}.pbf' - }) - }) - } - - componentWillReceiveProps(nextProps) { - const jsonStyle = style.toJSON(nextProps.mapStyle) - const styleFunc = olms.getStyleFunction(jsonStyle, 'mapbox', this.resolutions) - this.layer.setStyle(styleFunc) - this.state.map.render() - } - - - componentDidMount() { - const styleFunc = olms.getStyleFunction(style.toJSON(this.props.mapStyle), 'mapbox', this.resolutions) - this.layer.setStyle(styleFunc) - - const map = new ol.Map({ - target: this.container, - layers: [this.layer], - view: new ol.View({ - center: [949282, 6002552], - zoom: 4 - }) - }) - this.setState({ map }); - } -} diff --git a/src/ol3.jsx b/src/ol3.jsx new file mode 100644 index 0000000..903c1c4 --- /dev/null +++ b/src/ol3.jsx @@ -0,0 +1,48 @@ +import React from 'react' +import style from './style.js' +import { Map } from './map.jsx' +import ol from 'openlayers' +import olms from 'ol-mapbox-style' + +export class OpenLayers3Map extends Map { + constructor(props) { + super(props) + + const tilegrid = ol.tilegrid.createXYZ({tileSize: 512, maxZoom: 22}) + this.resolutions = tilegrid.getResolutions() + this.layer = new ol.layer.VectorTile({ + source: new ol.source.VectorTile({ + attributions: '© Mapbox ' + + '© ' + + 'OpenStreetMap contributors', + format: new ol.format.MVT(), + tileGrid: tilegrid, + tilePixelRatio: 8, + url: 'http://osm2vectortiles-0.tileserver.com/v2/{z}/{x}/{y}.pbf' + }) + }) + } + + componentWillReceiveProps(nextProps) { + const jsonStyle = style.toJSON(nextProps.mapStyle) + const styleFunc = olms.getStyleFunction(jsonStyle, 'mapbox', this.resolutions) + this.layer.setStyle(styleFunc) + this.state.map.render() + } + + + componentDidMount() { + const styleFunc = olms.getStyleFunction(style.toJSON(this.props.mapStyle), 'mapbox', this.resolutions) + this.layer.setStyle(styleFunc) + + const map = new ol.Map({ + target: this.container, + layers: [this.layer], + view: new ol.View({ + center: [949282, 6002552], + zoom: 4 + }) + }) + this.setState({ map }); + } +} diff --git a/webpack.production.config.js b/webpack.production.config.js index 8a9ef94..fbbfc71 100644 --- a/webpack.production.config.js +++ b/webpack.production.config.js @@ -8,88 +8,91 @@ var WebpackCleanupPlugin = require('webpack-cleanup-plugin'); // local css modules loaders.push({ - test: /[\/\\]src[\/\\].*\.css/, - loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]') + test: /[\/\\]src[\/\\].*\.css/, + loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]') }); // local scss modules loaders.push({ - test: /[\/\\]src[\/\\].*\.scss/, - loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]', 'sass') + test: /[\/\\]src[\/\\].*\.scss/, + loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]', 'sass') }); // global css files loaders.push({ - test: /[\/\\](node_modules|global)[\/\\].*\.css$/, - loader: ExtractTextPlugin.extract('style', 'css') + test: /[\/\\](node_modules|global)[\/\\].*\.css$/, + loader: ExtractTextPlugin.extract('style', 'css') }); module.exports = { - entry: { - app: './src/index.jsx', - vendor: [ - 'file-saver', - 'immutable', - 'mapbox-gl', - //TODO: Cannot resolve migrations file? - //"mapbox-gl-style-spec", - "randomcolor", - 'react', - "react-collapse", - "react-dom", - "react-file-reader-input", - "react-height", - //TODO: Icons raise multi vendor errors? - //"react-icons", - "react-motion", - "rebass", - ] - }, - output: { - path: path.join(__dirname, 'public'), - filename: '[chunkhash].app.js' - }, - resolve: { - alias: { - 'webworkify': 'webworkify-webpack', - }, - extensions: ['', '.js', '.jsx'] - }, - module: { - loaders, - postLoaders: [{ - include: /node_modules\/mapbox-gl-shaders/, - loader: 'transform', - query: 'brfs' - }] - }, - node: { - fs: "empty" - }, - plugins: [ - new webpack.NoErrorsPlugin(), - new webpack.optimize.CommonsChunkPlugin('vendor', '[chunkhash].vendor.js'), - new WebpackCleanupPlugin(), - new webpack.DefinePlugin({ - 'process.env': { - NODE_ENV: '"production"' - } - }), - new webpack.optimize.UglifyJsPlugin({ - compress: { - warnings: false, - screw_ie8: true, - drop_console: true, - drop_debugger: true - } - }), - new webpack.optimize.OccurenceOrderPlugin(), - new ExtractTextPlugin('[contenthash].css', { - allChunks: true - }), - new HtmlWebpackPlugin({ - template: './src/template.html', - title: 'Maputnik' - }), - new webpack.optimize.DedupePlugin() - ] + entry: { + app: './src/index.jsx', + vendor: [ + 'file-saver', + 'immutable', + 'mapbox-gl', + //TODO: Cannot resolve migrations file? + //"mapbox-gl-style-spec", + "randomcolor", + 'react', + "react-collapse", + "react-dom", + "react-file-reader-input", + "react-height", + //TODO: Icons raise multi vendor errors? + //"react-icons", + "react-motion", + "rebass", + // Open Layers + 'openlayers', + 'ol-mapbox-style' + ] + }, + output: { + path: path.join(__dirname, 'public'), + filename: '[chunkhash].app.js' + }, + resolve: { + alias: { + 'webworkify': 'webworkify-webpack', + }, + extensions: ['', '.js', '.jsx'] + }, + module: { + loaders, + postLoaders: [{ + include: /node_modules\/mapbox-gl-shaders/, + loader: 'transform', + query: 'brfs' + }] + }, + node: { + fs: "empty" + }, + plugins: [ + new webpack.NoErrorsPlugin(), + new webpack.optimize.CommonsChunkPlugin('vendor', '[chunkhash].vendor.js'), + new WebpackCleanupPlugin(), + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: '"production"' + } + }), + new webpack.optimize.UglifyJsPlugin({ + compress: { + warnings: false, + screw_ie8: true, + drop_console: true, + drop_debugger: true + } + }), + new webpack.optimize.OccurenceOrderPlugin(), + new ExtractTextPlugin('[contenthash].css', { + allChunks: true + }), + new HtmlWebpackPlugin({ + template: './src/template.html', + title: 'Maputnik' + }), + new webpack.optimize.DedupePlugin() + ] };