diff --git a/src/components/App.jsx b/src/components/App.jsx
index 27a10cc..29d5305 100644
--- a/src/components/App.jsx
+++ b/src/components/App.jsx
@@ -2,7 +2,6 @@ import React from 'react'
import { saveAs } from 'file-saver'
import Mousetrap from 'mousetrap'
-import InspectionMap from './map/InspectionMap'
import MapboxGlMap from './map/MapboxGlMap'
import OpenLayers3Map from './map/OpenLayers3Map'
import LayerList from './layers/LayerList'
@@ -177,7 +176,9 @@ export default class App extends React.Component {
if(renderer === 'ol3') {
return
} else {
- return
+ return
}
}
diff --git a/src/components/map/InspectionMap.jsx b/src/components/map/InspectionMap.jsx
deleted file mode 100644
index d672698..0000000
--- a/src/components/map/InspectionMap.jsx
+++ /dev/null
@@ -1,126 +0,0 @@
-import React from 'react'
-import ReactDOM from 'react-dom'
-import MapboxGl from 'mapbox-gl/dist/mapbox-gl.js'
-import validateColor from 'mapbox-gl-style-spec/lib/validate/validate_color'
-import colors from '../../config/colors'
-import style from '../../libs/style'
-import FeaturePropertyPopup from './FeaturePropertyPopup'
-import { colorHighlightedLayer, generateColoredLayers } from '../../libs/stylegen'
-import 'mapbox-gl/dist/mapbox-gl.css'
-import '../../mapboxgl.css'
-
-function convertInspectStyle(mapStyle, sources, highlightedLayer) {
- const coloredLayers = generateColoredLayers(sources)
-
- const layer = colorHighlightedLayer(highlightedLayer)
- if(layer) {
- coloredLayers.push(layer)
- }
-
- const newStyle = {
- ...mapStyle,
- layers: [
- {
- "id": "background",
- "type": "background",
- "paint": {
- "background-color": colors.black,
- }
- },
- ...coloredLayers,
- ]
- }
- return newStyle
-}
-
-function renderPopup(features) {
- var mountNode = document.createElement('div');
- ReactDOM.render(, mountNode)
- return mountNode.innerHTML;
-}
-
-export default class InspectionMap extends React.Component {
- static propTypes = {
- onDataChange: React.PropTypes.func,
- sources: React.PropTypes.object,
- originalStyle: React.PropTypes.object,
- highlightedLayer: React.PropTypes.object,
- style: React.PropTypes.object,
- }
-
- static defaultProps = {
- onMapLoaded: () => {},
- onTileLoaded: () => {},
- }
-
- constructor(props) {
- super(props)
- this.state = { map: null }
- }
-
- componentWillReceiveProps(nextProps) {
- if(!this.state.map) return
-
- this.state.map.setStyle(convertInspectStyle(nextProps.mapStyle, this.props.sources, nextProps.highlightedLayer), { diff: true})
- }
-
- componentDidMount() {
- MapboxGl.accessToken = this.props.accessToken
-
- const map = new MapboxGl.Map({
- container: this.container,
- style: convertInspectStyle(this.props.mapStyle, this.props.sources, this.props.highlightedLayer),
- hash: true,
- })
-
- const nav = new MapboxGl.NavigationControl();
- map.addControl(nav, 'top-right');
-
- map.on("style.load", () => {
- this.setState({ map });
- })
-
- map.on("data", e => {
- if(e.dataType !== 'tile') return
- this.props.onDataChange({
- map: this.state.map
- })
- })
-
- map.on('click', this.displayPopup.bind(this))
- map.on('mousemove', function(e) {
- var features = map.queryRenderedFeatures(e.point, { layers: this.layers })
- map.getCanvas().style.cursor = (features.length) ? 'pointer' : ''
- })
- }
-
- displayPopup(e) {
- const features = this.state.map.queryRenderedFeatures(e.point, {
- layers: this.layers
- });
-
- if (!features.length) {
- return
- }
-
- // Populate the popup and set its coordinates
- // based on the feature found.
- const popup = new MapboxGl.Popup()
- .setLngLat(e.lngLat)
- .setHTML(renderPopup(features))
- .addTo(this.state.map)
- }
-
- render() {
- return
this.container = x}
- style={{
- position: "fixed",
- top: 0,
- bottom: 0,
- height: "100%",
- width: "100%",
- ...this.props.style,
- }}>
- }
-}
diff --git a/src/components/map/MapboxGlMap.jsx b/src/components/map/MapboxGlMap.jsx
index 794ad28..2599eeb 100644
--- a/src/components/map/MapboxGlMap.jsx
+++ b/src/components/map/MapboxGlMap.jsx
@@ -5,7 +5,9 @@ import MapboxInspect from 'mapbox-gl-inspect'
import FeatureLayerTable from './FeatureLayerTable'
import FeaturePropertyPopup from './FeaturePropertyPopup'
import validateColor from 'mapbox-gl-style-spec/lib/validate/validate_color'
+import colors from '../../config/colors'
import style from '../../libs/style.js'
+import { colorHighlightedLayer } from '../../libs/highlight'
import 'mapbox-gl/dist/mapbox-gl.css'
import '../../mapboxgl.css'
@@ -21,6 +23,27 @@ function renderPropertyPopup(features) {
return mountNode.innerHTML;
}
+function buildInspectStyle(originalMapStyle, coloredLayers, highlightedLayer) {
+ const backgroundLayer = {
+ "id": "background",
+ "type": "background",
+ "paint": {
+ "background-color": colors.black,
+ }
+ }
+
+ const layer = colorHighlightedLayer(highlightedLayer)
+ if(layer) {
+ coloredLayers.push(layer)
+ }
+
+ const inspectStyle = {
+ ...originalMapStyle,
+ layers: [backgroundLayer].concat(coloredLayers)
+ }
+ return inspectStyle
+}
+
export default class MapboxGlMap extends React.Component {
static propTypes = {
onDataChange: React.PropTypes.func,
@@ -28,6 +51,7 @@ export default class MapboxGlMap extends React.Component {
accessToken: React.PropTypes.string,
style: React.PropTypes.object,
inspectModeEnabled: React.PropTypes.bool.isRequired,
+ highlightedLayer: React.PropTypes.object,
}
static defaultProps = {
@@ -52,10 +76,6 @@ export default class MapboxGlMap extends React.Component {
if(!this.state.map) return
- if(this.props.inspectModeEnabled !== nextProps.inspectModeEnabled) {
- this.state.inspect.toggleInspector()
- }
-
if(!nextProps.inspectModeEnabled) {
//Mapbox GL now does diffing natively so we don't need to calculate
//the necessary operations ourselves!
@@ -63,6 +83,15 @@ export default class MapboxGlMap extends React.Component {
}
}
+ componentDidUpdate(prevProps) {
+ if(this.props.inspectModeEnabled !== prevProps.inspectModeEnabled) {
+ this.state.inspect.toggleInspector()
+ }
+ if(this.props.inspectModeEnabled) {
+ this.state.inspect._renderInspector()
+ }
+ }
+
componentDidMount() {
const map = new MapboxGl.Map({
container: this.container,
@@ -80,6 +109,7 @@ export default class MapboxGlMap extends React.Component {
}),
showMapPopup: true,
showInspectButton: false,
+ buildInspectStyle: (originalMapStyle, coloredLayers) => buildInspectStyle(originalMapStyle, coloredLayers, this.props.highlightedLayer),
renderPopup: features => {
if(this.props.inspectModeEnabled) {
return renderPropertyPopup(features)
diff --git a/src/libs/highlight.js b/src/libs/highlight.js
new file mode 100644
index 0000000..5e050ef
--- /dev/null
+++ b/src/libs/highlight.js
@@ -0,0 +1,36 @@
+import randomColor from 'randomcolor'
+import Color from 'color'
+
+import stylegen from 'mapbox-gl-inspect/lib/stylegen'
+import colors from 'mapbox-gl-inspect/lib/colors'
+
+export function colorHighlightedLayer(layer) {
+ if(!layer || layer.type === 'background' || layer.type === 'raster') return null
+
+ function changeLayer(l) {
+ if(layer.filter) {
+ l.filter = layer.filter
+ } else {
+ delete l['filter']
+ }
+ l.id = l.id + '_highlight'
+ return l
+ }
+
+ const color = colors.brightColor(layer.id, 1)
+ const layers = []
+
+ if(layer.type === "fill" || layer.type === 'fill-extrusion') {
+ return changeLayer(stylegen.polygonLayer(color, color, layer.source, layer['source-layer']))
+ }
+
+ if(layer.type === "symbol" || layer.type === 'circle') {
+ return changeLayer(stylegen.circleLayer(color, layer.source, layer['source-layer']))
+ }
+
+ if(layer.type === 'line') {
+ return changeLayer(stylegen.lineLayer(color, layer.source, layer['source-layer']))
+ }
+
+ return null
+}
diff --git a/src/libs/stylegen.js b/src/libs/stylegen.js
index f4decc5..e69de29 100644
--- a/src/libs/stylegen.js
+++ b/src/libs/stylegen.js
@@ -1,141 +0,0 @@
-import randomColor from 'randomcolor'
-import Color from 'color'
-
-function assignVectorLayerColor(layerId) {
- let hue = null
- if(/water|ocean|lake|sea|river/.test(layerId)) {
- hue = 'blue'
- }
-
- if(/road|highway|transport/.test(layerId)) {
- hue = 'orange'
- }
-
- if(/building/.test(layerId)) {
- hue = 'yellow'
- }
-
- if(/wood|forest|park|landcover|landuse/.test(layerId)) {
- hue = 'green'
- }
-
- return randomColor({
- luminosity: 'bright',
- hue: hue,
- seed: layerId,
- })
-}
-
-function circleLayer(source, vectorLayer, color) {
- const layer = {
- id: `${source}_${vectorLayer}_circle`,
- source: source,
- type: 'circle',
- paint: {
- 'circle-color': color,
- 'circle-radius': 2,
- },
- filter: ["==", "$type", "Point"]
- }
- if(vectorLayer) {
- layer['source-layer'] = vectorLayer
- }
- return layer
-}
-
-function polygonLayer(source, vectorLayer, color, fillColor) {
- const layer = {
- id: `${source}_${vectorLayer}_polygon`,
- source: source,
- type: 'fill',
- paint: {
- 'fill-color': fillColor,
- 'fill-antialias': true,
- 'fill-outline-color': color,
- },
- filter: ["==", "$type", "Polygon"]
- }
- if(vectorLayer) {
- layer['source-layer'] = vectorLayer
- }
- return layer
-}
-
-function lineLayer(source, vectorLayer, color) {
- const layer = {
- id: `${source}_${vectorLayer}_line`,
- source: source,
- layout: {
- 'line-join': 'round',
- 'line-cap': 'round'
- },
- type: 'line',
- paint: {
- 'line-color': color,
- },
- filter: ["==", "$type", "LineString"]
- }
- if(vectorLayer) {
- layer['source-layer'] = vectorLayer
- }
- return layer
-}
-
-export function colorHighlightedLayer(layer) {
- if(!layer || layer.type === 'background' || layer.type === 'raster') return null
-
- function changeLayer(l) {
- if(layer.filter) {
- l.filter = layer.filter
- } else {
- delete l['filter']
- }
- l.id = l.id + '_highlight'
- return l
- }
-
- const color = assignVectorLayerColor(layer.id)
- const layers = []
-
- if(layer.type === "fill" || layer.type === 'fill-extrusion') {
- return changeLayer(polygonLayer(layer.source, layer['source-layer'], color, Color(color).alpha(0.2).string()))
- }
-
- if(layer.type === "symbol" || layer.type === 'circle') {
- return changeLayer(circleLayer(layer.source, layer['source-layer'], color))
- }
-
- if(layer.type === 'line') {
- return changeLayer(lineLayer(layer.source, layer['source-layer'], color))
- }
-
- return null
-}
-
-export function generateColoredLayers(sources) {
- const polyLayers = []
- const circleLayers = []
- const lineLayers = []
-
- Object.keys(sources).forEach(sourceId => {
- const layers = sources[sourceId]
-
- // Deal with GeoJSON sources that do not have any source layers
- if(!layers) {
- const color = Color(assignVectorLayerColor(sourceId))
- circleLayers.push(circleLayer(sourceId, null, color.alpha(0.3).string()))
- lineLayers.push(lineLayer(sourceId, null, color.alpha(0.3).string()))
- polyLayers.push(polygonLayer(sourceId, null, color.alpha(0.2).string(), color.alpha(0.05).string()))
- return
- }
-
- layers.forEach(layerId => {
- const color = Color(assignVectorLayerColor(layerId))
- circleLayers.push(circleLayer(sourceId, layerId, color.alpha(0.3).string()))
- lineLayers.push(lineLayer(sourceId, layerId, color.alpha(0.3).string()))
- polyLayers.push(polygonLayer(sourceId, layerId, color.alpha(0.2).string(), color.alpha(0.05).string()))
- })
- })
-
- return polyLayers.concat(lineLayers).concat(circleLayers)
-}