Skip to content

Commit

Permalink
Another one bites the dust
Browse files Browse the repository at this point in the history
  • Loading branch information
HarelM committed Dec 23, 2023
1 parent 5a62f4a commit 90b6921
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 58 deletions.
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
import React from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import MapLibreGl from 'maplibre-gl'
import MapLibreGl, {LayerSpecification, Map, MapOptions, SourceSpecification, StyleSpecification} from 'maplibre-gl'
// @ts-ignore
import MapboxInspect from 'mapbox-gl-inspect'
import MapMaplibreGlLayerPopup from './MapMaplibreGlLayerPopup'
import MapMaplibreGlFeaturePropertyPopup from './MapMaplibreGlFeaturePropertyPopup'
import tokens from '../config/tokens.json'
// @ts-ignore
import colors from 'mapbox-gl-inspect/lib/colors'
import MapMaplibreGlLayerPopup from './MapMaplibreGlLayerPopup'
import MapMaplibreGlFeaturePropertyPopup, { InspectFeature } from './MapMaplibreGlFeaturePropertyPopup'
import Color from 'color'
import ZoomControl from '../libs/zoomcontrol'
import { colorHighlightedLayer } from '../libs/highlight'
import { HighlightedLayer, colorHighlightedLayer } from '../libs/highlight'
import 'maplibre-gl/dist/maplibre-gl.css'
import '../maplibregl.css'
import '../libs/maplibre-rtl'


const IS_SUPPORTED = MapLibreGl.supported();

function renderPopup(popup, mountNode) {
function renderPopup(popup: JSX.Element, mountNode: ReactDOM.Container) {
ReactDOM.render(popup, mountNode);
return mountNode;
}

function buildInspectStyle(originalMapStyle, coloredLayers, highlightedLayer) {
function buildInspectStyle(originalMapStyle: StyleSpecification, coloredLayers: HighlightedLayer[], highlightedLayer?: HighlightedLayer) {
const backgroundLayer = {
"id": "background",
"type": "background",
"paint": {
"background-color": '#1c1f24',
}
}
} as LayerSpecification

const layer = colorHighlightedLayer(highlightedLayer)
if(layer) {
coloredLayers.push(layer)
}

const sources = {}
const sources: {[key:string]: SourceSpecification} = {}
Object.keys(originalMapStyle.sources).forEach(sourceId => {
const source = originalMapStyle.sources[sourceId]
if(source.type !== 'raster' && source.type !== 'raster-dem') {
Expand All @@ -47,40 +47,51 @@ function buildInspectStyle(originalMapStyle, coloredLayers, highlightedLayer) {
const inspectStyle = {
...originalMapStyle,
sources: sources,
layers: [backgroundLayer].concat(coloredLayers)
layers: [backgroundLayer].concat(coloredLayers as LayerSpecification[])
}
return inspectStyle
}

export default class MapMaplibreGl extends React.Component {
static propTypes = {
onDataChange: PropTypes.func,
onLayerSelect: PropTypes.func.isRequired,
mapStyle: PropTypes.object.isRequired,
inspectModeEnabled: PropTypes.bool.isRequired,
highlightedLayer: PropTypes.object,
options: PropTypes.object,
replaceAccessTokens: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
type MapMaplibreGlProps = {
onDataChange?(...args: unknown[]): unknown
onLayerSelect(...args: unknown[]): unknown
mapStyle: StyleSpecification
inspectModeEnabled: boolean
highlightedLayer?: HighlightedLayer
options?: MapOptions & {
showTileBoundaries?: boolean
showCollisionBoxes?: boolean
showOverdrawInspector?: boolean
}
replaceAccessTokens(mapStyle: StyleSpecification): StyleSpecification
onChange(...args: unknown[]): unknown
};

type MapMaplibreGlState = {
map: Map | null
inspect: MapboxInspect | null
zoom?: number
};

export default class MapMaplibreGl extends React.Component<MapMaplibreGlProps, MapMaplibreGlState> {
static defaultProps = {
onMapLoaded: () => {},
onDataChange: () => {},
onLayerSelect: () => {},
onChange: () => {},
options: {},
options: {} as MapOptions,
}
container: HTMLDivElement | null = null

constructor(props) {
constructor(props: MapMaplibreGlProps) {
super(props)
this.state = {
map: null,
inspect: null,
}
}

updateMapFromProps(props) {
updateMapFromProps(props: MapMaplibreGlProps) {
if(!IS_SUPPORTED) return;

if(!this.state.map) return
Expand All @@ -93,7 +104,7 @@ export default class MapMaplibreGl extends React.Component {
)
}

shouldComponentUpdate(nextProps, nextState) {
shouldComponentUpdate(nextProps: MapMaplibreGlProps, nextState: MapMaplibreGlState) {
let should = false;
try {
should = JSON.stringify(this.props) !== JSON.stringify(nextProps) || JSON.stringify(this.state) !== JSON.stringify(nextState);
Expand All @@ -103,7 +114,7 @@ export default class MapMaplibreGl extends React.Component {
return should;
}

componentDidUpdate(prevProps, prevState, snapshot) {
componentDidUpdate() {
if(!IS_SUPPORTED) return;

const map = this.state.map;
Expand All @@ -128,9 +139,9 @@ export default class MapMaplibreGl extends React.Component {
}
}

map.showTileBoundaries = this.props.options.showTileBoundaries;
map.showCollisionBoxes = this.props.options.showCollisionBoxes;
map.showOverdrawInspector = this.props.options.showOverdrawInspector;
map.showTileBoundaries = this.props.options?.showTileBoundaries!;
map.showCollisionBoxes = this.props.options?.showCollisionBoxes!;
map.showOverdrawInspector = this.props.options?.showOverdrawInspector!;
}
}

Expand All @@ -139,7 +150,7 @@ export default class MapMaplibreGl extends React.Component {

const mapOpts = {
...this.props.options,
container: this.container,
container: this.container!,
style: this.props.mapStyle,
hash: true,
maxZoom: 24
Expand All @@ -154,9 +165,9 @@ export default class MapMaplibreGl extends React.Component {
}
mapViewChange();

map.showTileBoundaries = mapOpts.showTileBoundaries;
map.showCollisionBoxes = mapOpts.showCollisionBoxes;
map.showOverdrawInspector = mapOpts.showOverdrawInspector;
map.showTileBoundaries = mapOpts.showTileBoundaries!;
map.showCollisionBoxes = mapOpts.showCollisionBoxes!;
map.showOverdrawInspector = mapOpts.showOverdrawInspector!;

const zoomControl = new ZoomControl;
map.addControl(zoomControl, 'top-right');
Expand All @@ -175,11 +186,11 @@ export default class MapMaplibreGl extends React.Component {
showInspectMapPopupOnHover: true,
showInspectButton: false,
blockHoverPopupOnClick: true,
assignLayerColor: (layerId, alpha) => {
assignLayerColor: (layerId: string, alpha: number) => {
return Color(colors.brightColor(layerId, alpha)).desaturate(0.5).string()
},
buildInspectStyle: (originalMapStyle, coloredLayers) => buildInspectStyle(originalMapStyle, coloredLayers, this.props.highlightedLayer),
renderPopup: features => {
buildInspectStyle: (originalMapStyle: StyleSpecification, coloredLayers: HighlightedLayer[]) => buildInspectStyle(originalMapStyle, coloredLayers, this.props.highlightedLayer),
renderPopup: (features: InspectFeature[]) => {
if(this.props.inspectModeEnabled) {
return renderPopup(<MapMaplibreGlFeaturePropertyPopup features={features} />, tmpNode);
} else {
Expand All @@ -199,7 +210,7 @@ export default class MapMaplibreGl extends React.Component {

map.on("data", e => {
if(e.dataType !== 'tile') return
this.props.onDataChange({
this.props.onDataChange!({
map: this.state.map
})
})
Expand All @@ -208,7 +219,7 @@ export default class MapMaplibreGl extends React.Component {
console.log("ERROR", e);
})

map.on("zoom", e => {
map.on("zoom", _e => {
this.setState({
zoom: map.getZoom()
});
Expand All @@ -218,7 +229,7 @@ export default class MapMaplibreGl extends React.Component {
map.on("zoomend", mapViewChange);
}

onLayerSelectById = (id) => {
onLayerSelectById = (id: string) => {
const index = this.props.mapStyle.layers.findIndex(layer => layer.id === id);
this.props.onLayerSelect(index);
}
Expand Down
40 changes: 21 additions & 19 deletions src/libs/highlight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,40 @@ import stylegen from 'mapbox-gl-inspect/lib/stylegen'
import colors from 'mapbox-gl-inspect/lib/colors'
import {FilterSpecification,LayerSpecification } from '@maplibre/maplibre-gl-style-spec'

export function colorHighlightedLayer(layer: LayerSpecification) {
if(!layer || layer.type === 'background' || layer.type === 'raster') return null
export type HighlightedLayer = LayerSpecification & {filter?: FilterSpecification};

function changeLayer(l: HighlightedLayer, layer: LayerSpecification) {
if(l.type === 'circle') {
l.paint!['circle-radius'] = 3
} else if(l.type === 'line') {
l.paint!['line-width'] = 2
}

function changeLayer(l: LayerSpecification & {filter?: FilterSpecification}) {
if(l.type === 'circle') {
l.paint!['circle-radius'] = 3
} else if(l.type === 'line') {
l.paint!['line-width'] = 2
}

if("filter" in layer) {
l.filter = layer.filter
} else {
delete l['filter']
}
l.id = l.id + '_highlight'
return l
if("filter" in layer) {
l.filter = layer.filter
} else {
delete l['filter']
}
l.id = l.id + '_highlight'
return l
}

export function colorHighlightedLayer(layer?: LayerSpecification): HighlightedLayer | null {
if(!layer || layer.type === 'background' || layer.type === 'raster') return null

const sourceLayerId = layer['source-layer'] || ''
const color = colors.brightColor(sourceLayerId, 1);

if(layer.type === "fill" || layer.type === 'fill-extrusion') {
return changeLayer(stylegen.polygonLayer(color, color, layer.source, layer['source-layer']))
return changeLayer(stylegen.polygonLayer(color, color, layer.source, layer['source-layer']), layer)
}

if(layer.type === "symbol" || layer.type === 'circle') {
return changeLayer(stylegen.circleLayer(color, layer.source, layer['source-layer']))
return changeLayer(stylegen.circleLayer(color, layer.source, layer['source-layer']), layer)
}

if(layer.type === 'line') {
return changeLayer(stylegen.lineLayer(color, layer.source, layer['source-layer']))
return changeLayer(stylegen.lineLayer(color, layer.source, layer['source-layer']), layer)
}

return null
Expand Down

0 comments on commit 90b6921

Please sign in to comment.