mirror of
https://github.com/a-nyx/maputnik-with-pmtiles.git
synced 2024-11-10 11:07:45 +01:00
Merge pull request #444 from orangemug/feature/issue-433
Added color swatch to <FeatureLayerPopup/>
This commit is contained in:
commit
da456b08fe
3 changed files with 101 additions and 17 deletions
|
@ -1,6 +1,7 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import LayerIcon from '../icons/LayerIcon'
|
||||
import {latest, expression, function as styleFunction} from '@mapbox/mapbox-gl-style-spec'
|
||||
|
||||
function groupFeaturesBySourceLayer(features) {
|
||||
const sources = {}
|
||||
|
@ -28,7 +29,59 @@ function groupFeaturesBySourceLayer(features) {
|
|||
class FeatureLayerPopup extends React.Component {
|
||||
static propTypes = {
|
||||
onLayerSelect: PropTypes.func.isRequired,
|
||||
features: PropTypes.array
|
||||
features: PropTypes.array,
|
||||
zoom: PropTypes.number,
|
||||
}
|
||||
|
||||
_getFeatureColor(feature, zoom) {
|
||||
try {
|
||||
const paintProps = feature.layer.paint;
|
||||
let propName;
|
||||
|
||||
if(paintProps.hasOwnProperty("text-color") && paintProps["text-color"]) {
|
||||
propName = "text-color";
|
||||
}
|
||||
else if (paintProps.hasOwnProperty("fill-color") && paintProps["fill-color"]) {
|
||||
propName = "fill-color";
|
||||
}
|
||||
else if (paintProps.hasOwnProperty("line-color") && paintProps["line-color"]) {
|
||||
propName = "line-color";
|
||||
}
|
||||
else if (paintProps.hasOwnProperty("fill-extrusion-color") && paintProps["fill-extrusion-color"]) {
|
||||
propName = "fill-extrusion-color";
|
||||
}
|
||||
|
||||
if(propName) {
|
||||
const propertySpec = latest["paint_"+feature.layer.type][propName];
|
||||
|
||||
let color = feature.layer.paint[propName];
|
||||
|
||||
if(typeof(color) === "object") {
|
||||
if(color.stops) {
|
||||
color = styleFunction.convertFunction(color, propertySpec);
|
||||
}
|
||||
|
||||
const exprResult = expression.createExpression(color, propertySpec);
|
||||
const val = exprResult.value.evaluate({
|
||||
zoom: zoom
|
||||
}, feature);
|
||||
return val.toString();
|
||||
}
|
||||
else {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Default color
|
||||
return "black";
|
||||
}
|
||||
}
|
||||
// This is quite complex, just incase there's an edgecase we're missing
|
||||
// always return black if we get an unexpected error.
|
||||
catch (err) {
|
||||
console.error("Unable to get feature color, error:", err);
|
||||
return "black";
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -36,21 +89,31 @@ class FeatureLayerPopup extends React.Component {
|
|||
|
||||
const items = Object.keys(sources).map(vectorLayerId => {
|
||||
const layers = sources[vectorLayerId].map((feature, idx) => {
|
||||
return <label
|
||||
key={idx}
|
||||
className="maputnik-popup-layer"
|
||||
onClick={() => {
|
||||
this.props.onLayerSelect(feature.layer.id)
|
||||
}}
|
||||
const featureColor = this._getFeatureColor(feature, this.props.zoom);
|
||||
|
||||
return <div
|
||||
key={idx}
|
||||
className="maputnik-popup-layer"
|
||||
>
|
||||
<LayerIcon type={feature.layer.type} style={{
|
||||
width: 14,
|
||||
height: 14,
|
||||
paddingRight: 3
|
||||
}}/>
|
||||
{feature.layer.id}
|
||||
{feature.counter && <span> × {feature.counter}</span>}
|
||||
</label>
|
||||
<div
|
||||
className="maputnik-popup-layer__swatch"
|
||||
style={{background: featureColor}}
|
||||
></div>
|
||||
<label
|
||||
className="maputnik-popup-layer__label"
|
||||
onClick={() => {
|
||||
this.props.onLayerSelect(feature.layer.id)
|
||||
}}
|
||||
>
|
||||
<LayerIcon type={feature.layer.type} style={{
|
||||
width: 14,
|
||||
height: 14,
|
||||
paddingRight: 3
|
||||
}}/>
|
||||
{feature.layer.id}
|
||||
{feature.counter && <span> × {feature.counter}</span>}
|
||||
</label>
|
||||
</div>
|
||||
})
|
||||
return <div key={vectorLayerId}>
|
||||
<div className="maputnik-popup-layer-id">{vectorLayerId}</div>
|
||||
|
|
|
@ -166,14 +166,18 @@ export default class MapboxGlMap extends React.Component {
|
|||
if(this.props.inspectModeEnabled) {
|
||||
return renderPopup(<FeaturePropertyPopup features={features} />, tmpNode);
|
||||
} else {
|
||||
return renderPopup(<FeatureLayerPopup features={features} onLayerSelect={this.props.onLayerSelect} />, tmpNode);
|
||||
return renderPopup(<FeatureLayerPopup features={features} onLayerSelect={this.props.onLayerSelect} zoom={this.state.zoom} />, tmpNode);
|
||||
}
|
||||
}
|
||||
})
|
||||
map.addControl(inspect)
|
||||
|
||||
map.on("style.load", () => {
|
||||
this.setState({ map, inspect });
|
||||
this.setState({
|
||||
map,
|
||||
inspect,
|
||||
zoom: map.getZoom()
|
||||
});
|
||||
if(this.props.inspectModeEnabled) {
|
||||
inspect.toggleInspector();
|
||||
}
|
||||
|
@ -185,6 +189,12 @@ export default class MapboxGlMap extends React.Component {
|
|||
map: this.state.map
|
||||
})
|
||||
})
|
||||
|
||||
map.on("zoom", e => {
|
||||
this.setState({
|
||||
zoom: map.getZoom()
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
.maputnik-popup-layer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.maputnik-popup-layer__swatch {
|
||||
display: inline-block;
|
||||
width: 5px;
|
||||
align-content: stretch;
|
||||
}
|
||||
|
||||
.maputnik-popup-layer__label {
|
||||
display: block;
|
||||
color: $color-lowgray;
|
||||
cursor: pointer;
|
||||
|
|
Loading…
Reference in a new issue