diff --git a/src/app/regionen/[regionSlug]/_components/Map/Map.tsx b/src/app/regionen/[regionSlug]/_components/Map/Map.tsx index bf313c355..f0a0445fa 100644 --- a/src/app/regionen/[regionSlug]/_components/Map/Map.tsx +++ b/src/app/regionen/[regionSlug]/_components/Map/Map.tsx @@ -135,6 +135,7 @@ export const Map: React.FC = () => { style={{ width: '100%', height: '100%' }} mapStyle={process.env.NEXT_PUBLIC_APP_ORIGIN + '/api/map/style'} interactiveLayerIds={interactiveLayerIds} + // reuseMaps={true} // onMouseMove={} // onLoad={handleInspect} cursor={cursorStyle} diff --git a/src/app/regionen/[regionSlug]/_components/Map/SourcesAndLayers/LayerVerificationStatus.tsx b/src/app/regionen/[regionSlug]/_components/Map/SourcesAndLayers/LayerVerificationStatus.tsx deleted file mode 100644 index 62b943c1d..000000000 --- a/src/app/regionen/[regionSlug]/_components/Map/SourcesAndLayers/LayerVerificationStatus.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react' -import { Layer, LayerProps } from 'react-map-gl/maplibre' -import { useMapStateInteraction } from '../../../_hooks/mapStateInteraction/useMapStateInteraction' - -let errorLogged = false - -export const LayerVerificationStatus = (parentLayerProps: LayerProps) => { - const { localUpdates } = useMapStateInteraction() - - const props = { - ...parentLayerProps, - paint: structuredClone(parentLayerProps.paint), - } - - let colorApproved: string, colorRejected: string, colorNull: string - try { - const [_0, _1, _a, _2, _r, _n] = props.paint!['line-color'] - colorApproved = _a || 'hsl(107, 88%, 57%)' - colorRejected = _r || 'hsl(0, 100%, 41%)' - colorNull = _n || '#fa7fe2' - } catch (e) { - if (!errorLogged) { - console.error(e) - errorLogged = true - } - return - } - - const currentValues = new Map() - - localUpdates.forEach(({ osm_id, verified }) => currentValues.set(osm_id, verified === 'approved')) - - const cond: any[] = (props.paint!['line-color'] = ['case']) - currentValues.forEach((approved, osmId) => { - cond.push(['==', ['get', 'osm_id'], osmId], approved ? colorApproved : colorRejected) - }) - - cond.push( - ['==', ['get', 'verified'], 'approved'], - colorApproved, - ['==', ['get', 'verified'], 'rejected'], - colorRejected, - colorNull, - ) - - return -} diff --git a/src/app/regionen/[regionSlug]/_components/Map/SourcesAndLayers/SourcesAndLayers.tsx b/src/app/regionen/[regionSlug]/_components/Map/SourcesAndLayers/SourcesAndLayers.tsx index 2fa98f816..ed4a8e1b7 100644 --- a/src/app/regionen/[regionSlug]/_components/Map/SourcesAndLayers/SourcesAndLayers.tsx +++ b/src/app/regionen/[regionSlug]/_components/Map/SourcesAndLayers/SourcesAndLayers.tsx @@ -1,6 +1,6 @@ import { FilterSpecification } from 'maplibre-gl' import React from 'react' -import { Layer, LayerProps, Source } from 'react-map-gl/maplibre' +import { Layer, Source } from 'react-map-gl/maplibre' import { useMapDebugState } from 'src/app/regionen/[regionSlug]/_hooks/mapStateInteraction/useMapDebugState' import { useBackgroundParam } from 'src/app/regionen/[regionSlug]/_hooks/useQueryState/useBackgroundParam' import { useCategoriesConfig } from 'src/app/regionen/[regionSlug]/_hooks/useQueryState/useCategoriesConfig/useCategoriesConfig' @@ -12,7 +12,6 @@ import { } from '../../utils/createKeyUtils/createKeyUtils' import { layerVisibility } from '../utils/layerVisibility' import { LayerHighlight } from './LayerHighlight' -import { LayerVerificationStatus } from './LayerVerificationStatus' import { beforeId } from './utils/beforeId' import { wrapFilterWithAll } from './utils/filterUtils/wrapFilterWithAll' @@ -103,19 +102,9 @@ export const SourcesAndLayers = () => { ...(layer.maxzoom ? { maxzoom: layer.maxzoom } : {}), } - // The verification style layer in Mapbox Studio has to include this string - const isVerificationStatusLayer = layer.id.search('verification-status') != -1 - return ( - {isVerificationStatusLayer ? ( - - ) : ( - - )} + } & Pick) { + const { mainMap } = useMap() const user = useCurrentUser() const regionSlug = useRegionSlug() const [createBikelaneVerificationMutation] = useMutation(createBikelaneVerification) // Reminder: We cannot use useForm() here. Instead we need to use useFormContext() from a child component of
- const { addLocalUpdate } = useMapStateInteraction() const handleSubmit = async (values) => { try { invariant(user) @@ -44,7 +45,17 @@ export function VerificationFormWithQuery({ comment: values.comment?.trim(), } await createBikelaneVerificationMutation({ regionSlug: regionSlug!, ...newVerificationItem }) - addLocalUpdate(newVerificationItem) + + mainMap?.getMap().setFeatureState( + { + source: 'cat:bikelanes--source:atlas_bikelanes--subcat:bikelanes_plus_verification', + sourceLayer: 'bikelanes_verified', + // id: values.osm_id, + }, + // { source: subcatBikelanesPlusVerificationSource, id: values.osm_id }, + { hover: false }, + ) + refetchVerifications() } catch (error: any) { console.error(error) diff --git a/src/app/regionen/[regionSlug]/_mapData/mapDataCategories/categories.const.ts b/src/app/regionen/[regionSlug]/_mapData/mapDataCategories/categories.const.ts index 8eb9a5641..81ba27c30 100644 --- a/src/app/regionen/[regionSlug]/_mapData/mapDataCategories/categories.const.ts +++ b/src/app/regionen/[regionSlug]/_mapData/mapDataCategories/categories.const.ts @@ -5,6 +5,7 @@ import { subcat_bikelanesStatistics } from '../mapDataSubcategories/subcat_bikel import { subcat_bikelanes_plus_presence } from '../mapDataSubcategories/subcat_bikelanes_plus_presence.const' import { subcat_bikelanes_plus_signs } from '../mapDataSubcategories/subcat_bikelanes_plus_signs.const' import { subcat_bikelanes_plus_surface_text } from '../mapDataSubcategories/subcat_bikelanes_plus_surface_text.const' +import { subcat_bikelanes_plus_verification } from '../mapDataSubcategories/subcat_bikelanes_plus_verification.const' import { subcat_bikelanes_plus_width_text } from '../mapDataSubcategories/subcat_bikelanes_plus_width_text.const' import { subcat_lit } from '../mapDataSubcategories/subcat_lit.const' import { subcat_lit_plus_completeness } from '../mapDataSubcategories/subcat_lit_plus_completeness.const' @@ -102,7 +103,7 @@ export const categories: StaticMapDataCategory[] = [ { ...subcat_bikelanes_plus_surface_text, defaultStyle: 'hidden' }, // { id: 'bikelanesOneway', defaultStyle: 'default' }, { ...subcat_bikelanes_plus_signs, defaultStyle: 'hidden' }, - // { ...subcat_bikelanes_plus_verification, defaultStyle: 'hidden' }, // WARNING: We nee permission per subcat first before we add this layer + { ...subcat_bikelanes_plus_verification, defaultStyle: 'hidden' }, // WARNING: We nee permission per subcat first before we add this layer // LATER // { id: 'bikelanesProtection', defaultStyle: 'hidden' }, // { id: 'tram', defaultStyle: 'hidden' }, diff --git a/src/app/regionen/[regionSlug]/_mapData/mapDataSubcategories/subcat_bikelanes_plus_verification.const.ts b/src/app/regionen/[regionSlug]/_mapData/mapDataSubcategories/subcat_bikelanes_plus_verification.const.ts index 8590c8f50..97ecf46fe 100644 --- a/src/app/regionen/[regionSlug]/_mapData/mapDataSubcategories/subcat_bikelanes_plus_verification.const.ts +++ b/src/app/regionen/[regionSlug]/_mapData/mapDataSubcategories/subcat_bikelanes_plus_verification.const.ts @@ -3,7 +3,7 @@ import { mapboxStyleGroupLayers_atlas_bikelanes_plus_verification } from './mapb import { mapboxStyleLayers } from './mapboxStyles/mapboxStyleLayers' const subcatId = 'bikelanes_plus_verification' -const source = 'atlas_bikelanes' +export const subcatBikelanesPlusVerificationSource = 'atlas_bikelanes' const sourceLayer = 'bikelanes_verified' export type SubcatBikelanesPlusVerificationId = typeof subcatId export type SubcatBikelanesPlusVerificationStyleIds = 'default' @@ -19,14 +19,60 @@ export const subcat_bikelanes_plus_verification: FileMapDataSubcategory = { id: 'default', name: 'Verkehrszeichen', desc: null, - layers: mapboxStyleLayers({ - layers: mapboxStyleGroupLayers_atlas_bikelanes_plus_verification, - source, - sourceLayer, - }), + layers: [ + mapboxStyleLayers({ + layers: mapboxStyleGroupLayers_atlas_bikelanes_plus_verification, + source: subcatBikelanesPlusVerificationSource, + sourceLayer, + }), + mapboxStyleLayers({ + layers: [ + { + minzoom: 7, + filter: ['has', 'category'], + type: 'line', + id: 'bikelanes-verification-optimitic-update', + paint: { + 'line-width': ['interpolate', ['linear'], ['zoom'], 9, 5, 13, 8, 18, 20], + // 'line-color': [ + // 'case', + // ['==', ['get', 'verified'], 'approved'], + // 'hsl(107, 88%, 57%)', + // ['==', ['get', 'verified'], 'rejected'], + // 'hsl(0, 100%, 41%)', + // '#fa7fe2', + // ], + 'line-color': [ + 'case', + ['boolean', ['feature-state', 'hover'], true], + 'blue', + ['boolean', ['feature-state', 'hover'], false], + 'yellow', + 'gray', + ], + 'line-opacity': [ + 'interpolate', + ['linear'], + ['zoom'], + 11.6, + 0, + 11.8, + 1, + 12.2, + 1, + 18, + 1, + ], + }, + }, + ], + source: subcatBikelanesPlusVerificationSource, + sourceLayer, + }), + ].flat(), legends: [ { - id: 'missing', + id: 'good', name: 'BestÃĪtigt', style: { type: 'line', @@ -34,7 +80,7 @@ export const subcat_bikelanes_plus_verification: FileMapDataSubcategory = { }, }, { - id: 'missing', + id: 'bad', name: 'Zu korrgieren', style: { type: 'line',