Initial work to add maplibre-gl-inspect

This commit is contained in:
HarelM
2024-03-13 16:11:17 +02:00
parent 5f54dd0ccf
commit 180e470689
7 changed files with 75 additions and 345 deletions

View File

@@ -1,10 +1,8 @@
import React, {type JSX} from 'react'
import ReactDOM from 'react-dom'
import MapLibreGl, {LayerSpecification, LngLat, Map, MapOptions, SourceSpecification, StyleSpecification} from 'maplibre-gl'
// @ts-ignore
import MapboxInspect from 'mapbox-gl-inspect'
// @ts-ignore
import colors from 'mapbox-gl-inspect/lib/colors'
import MaplibreInspect from '@maplibre/maplibre-gl-inspect'
import colors from '@maplibre/maplibre-gl-inspect/lib/colors'
import MapMaplibreGlLayerPopup from './MapMaplibreGlLayerPopup'
import MapMaplibreGlFeaturePropertyPopup, { InspectFeature } from './MapMaplibreGlFeaturePropertyPopup'
import Color from 'color'
@@ -17,9 +15,9 @@ import '../libs/maplibre-rtl'
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder';
import '@maplibre/maplibre-gl-geocoder/dist/maplibre-gl-geocoder.css';
function renderPopup(popup: JSX.Element, mountNode: ReactDOM.Container) {
function renderPopup(popup: JSX.Element, mountNode: ReactDOM.Container): HTMLElement {
ReactDOM.render(popup, mountNode);
return mountNode;
return mountNode as HTMLElement;
}
function buildInspectStyle(originalMapStyle: StyleSpecification, coloredLayers: HighlightedLayer[], highlightedLayer?: HighlightedLayer) {
@@ -37,6 +35,7 @@ function buildInspectStyle(originalMapStyle: StyleSpecification, coloredLayers:
}
const sources: {[key:string]: SourceSpecification} = {}
Object.keys(originalMapStyle.sources).forEach(sourceId => {
const source = originalMapStyle.sources[sourceId]
if(source.type !== 'raster' && source.type !== 'raster-dem') {
@@ -69,7 +68,7 @@ type MapMaplibreGlProps = {
type MapMaplibreGlState = {
map: Map | null
inspect: MapboxInspect | null
inspect: MaplibreInspect | null
zoom?: number
};
@@ -96,6 +95,13 @@ export default class MapMaplibreGl extends React.Component<MapMaplibreGlProps, M
//Maplibre GL now does diffing natively so we don't need to calculate
//the necessary operations ourselves!
if (props?.mapStyle) {
if (!props.mapStyle.metadata) {
props.mapStyle.metadata = {};
}
(props.mapStyle.metadata as any)['maplibregl-inspect:inspect'] = false;
}
console.log('setting style', props.mapStyle.metadata);
this.state.map.setStyle(
this.props.replaceAccessTokens(props.mapStyle),
{diff: true}
@@ -129,7 +135,7 @@ export default class MapMaplibreGl extends React.Component<MapMaplibreGlProps, M
// this error. I'm assuming an issue with maplibre-gl update and
// mapbox-gl-inspect.
try {
this.state.inspect.render();
//this.state.inspect.render();
} catch(err) {
console.error("FIXME: Caught error", err);
}
@@ -173,7 +179,7 @@ export default class MapMaplibreGl extends React.Component<MapMaplibreGlProps, M
const tmpNode = document.createElement('div');
const inspect = new MapboxInspect({
const inspect = new MaplibreInspect({
popup: new MapLibreGl.Popup({
closeOnClick: false
}),
@@ -183,7 +189,7 @@ export default class MapMaplibreGl extends React.Component<MapMaplibreGlProps, M
showInspectButton: false,
blockHoverPopupOnClick: true,
assignLayerColor: (layerId: string, alpha: number) => {
return Color(colors.brightColor(layerId, alpha)).desaturate(0.5).string()
return Color(colors.brightColor(layerId, alpha as any)).desaturate(0.5).string()
},
buildInspectStyle: (originalMapStyle: StyleSpecification, coloredLayers: HighlightedLayer[]) => buildInspectStyle(originalMapStyle, coloredLayers, this.props.highlightedLayer),
renderPopup: (features: InspectFeature[]) => {

View File

@@ -1,16 +1,12 @@
import React from 'react'
import type { GeoJSONFeatureWithSourceLayer } from '@maplibre/maplibre-gl-inspect'
export type InspectFeature = {
id: string
properties: {[key:string]: any}
layer: {[key:string]: any}
geometry: GeoJSON.Geometry
sourceLayer: string
export type InspectFeature = GeoJSONFeatureWithSourceLayer & {
inspectModeCounter?: number
counter?: number
}
function displayValue(value: string | number | Date | object) {
function displayValue(value: string | number | Date | object | undefined) {
if (typeof value === 'undefined' || value === null) return value;
if (value instanceof Date) return value.toLocaleString();
if (typeof value === 'object' ||
@@ -19,7 +15,7 @@ function displayValue(value: string | number | Date | object) {
return value;
}
function renderKeyValueTableRow(key: string, value: string) {
function renderKeyValueTableRow(key: string, value: string | undefined) {
return <tr key={key}>
<td className="maputnik-popup-table-cell">{key}</td>
<td className="maputnik-popup-table-cell">{value}</td>

View File

@@ -8,15 +8,16 @@ function groupFeaturesBySourceLayer(features: InspectFeature[]) {
const returnedFeatures: {[key: string]: number} = {}
features.forEach(feature => {
const sourceKey = feature.layer['source-layer'] as string;
if(Object.prototype.hasOwnProperty.call(returnedFeatures, feature.layer.id)) {
returnedFeatures[feature.layer.id]++
const featureObject = sources[feature.layer['source-layer']].find((f: InspectFeature) => f.layer.id === feature.layer.id)
const featureObject = sources[sourceKey].find((f: InspectFeature) => f.layer.id === feature.layer.id)
featureObject!.counter = returnedFeatures[feature.layer.id]
} else {
sources[feature.layer['source-layer']] = sources[feature.layer['source-layer']] || []
sources[feature.layer['source-layer']].push(feature)
sources[sourceKey] = sources[sourceKey] || []
sources[sourceKey].push(feature)
returnedFeatures[feature.layer.id] = 1
}
@@ -40,29 +41,21 @@ class FeatureLayerPopup extends React.Component<FeatureLayerPopupProps> {
try {
const paintProps = feature.layer.paint;
let propName;
if(Object.prototype.hasOwnProperty.call(paintProps, "text-color") && paintProps["text-color"]) {
propName = "text-color";
if("text-color" in paintProps && paintProps["text-color"]) {
return String(paintProps["text-color"]);
}
else if (Object.prototype.hasOwnProperty.call(paintProps, "fill-color") && paintProps["fill-color"]) {
propName = "fill-color";
if ("fill-color" in paintProps && paintProps["fill-color"]) {
return String(paintProps["fill-color"]);
}
else if (Object.prototype.hasOwnProperty.call(paintProps, "line-color") && paintProps["line-color"]) {
propName = "line-color";
if ("line-color" in paintProps && paintProps["line-color"]) {
return String(paintProps["line-color"]);
}
else if (Object.prototype.hasOwnProperty.call(paintProps, "fill-extrusion-color") && paintProps["fill-extrusion-color"]) {
propName = "fill-extrusion-color";
}
if(propName) {
const color = feature.layer.paint[propName];
return String(color);
}
else {
// Default color
return "black";
if ("fill-extrusion-color" in paintProps && paintProps["fill-extrusion-color"]) {
return String(paintProps["fill-extrusion-color"]);
}
// 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.

View File

@@ -1,7 +1,5 @@
// @ts-ignore
import stylegen from 'mapbox-gl-inspect/lib/stylegen'
// @ts-ignore
import colors from 'mapbox-gl-inspect/lib/colors'
import stylegen from '@maplibre/maplibre-gl-inspect/lib/stylegen'
import colors from '@maplibre/maplibre-gl-inspect/lib/colors'
import type {FilterSpecification,LayerSpecification } from 'maplibre-gl'
export type HighlightedLayer = LayerSpecification & {filter?: FilterSpecification};
@@ -26,7 +24,7 @@ export function colorHighlightedLayer(layer?: LayerSpecification): HighlightedLa
if(!layer || layer.type === 'background' || layer.type === 'raster') return null
const sourceLayerId = layer['source-layer'] || ''
const color = colors.brightColor(sourceLayerId, 1);
const color = colors.brightColor(sourceLayerId, 1 as any);
if(layer.type === "fill" || layer.type === 'fill-extrusion') {
return changeLayer(stylegen.polygonLayer(color, color, layer.source, layer['source-layer']), layer)