Skip to content

Commit

Permalink
feat: poi layer - replace default icons with custom icons, change ico…
Browse files Browse the repository at this point in the history
…n fill color
  • Loading branch information
baghdasarovnorayr committed Sep 7, 2023
1 parent 10dbd9f commit 761614d
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 27 deletions.
51 changes: 41 additions & 10 deletions apps/goat/app/[lng]/map/[projectId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,25 @@ import React, { useCallback, useEffect, useRef, useState } from "react";
import Map, { MapProvider, Layer, Source } from "react-map-gl";
import type { CSSObject } from "tss-react";
import Layers from "@/components/map/Layers";

import { ICON_NAME } from "@p4b/ui/components/Icon";
import { Fullscren } from "@/components/map/controls/Fullscreen";
import Geocoder from "@/components/map/controls/Geocoder";
import { useSelector } from "react-redux";
import type { IStore } from "@/types/store";
import { setActiveBasemapIndex } from "@/lib/store/styling/slice";
import { setActiveBasemapIndex, setIcon } from "@/lib/store/styling/slice";
import MapStyle from "@/components/map/panels/mapStyle/MapStyle";
import { fetchLayerData } from "@/lib/store/styling/actions";
import { useAppDispatch } from "@/hooks/useAppDispatch";
import { selectMapLayer } from '@/lib/store/styling/selectors'
import { selectMapLayer } from "@/lib/store/styling/selectors";

const sidebarWidth = 48;
const toolbarHeight = 52;

export default function MapPage({ params: { projectId } }) {
const { basemaps, activeBasemapIndex, initialViewState } =
useSelector((state: IStore) => state.styling);
const mapLayer = useSelector(selectMapLayer)
const { basemaps, activeBasemapIndex, initialViewState } = useSelector(
(state: IStore) => state.styling,
);
const mapLayer = useSelector(selectMapLayer);

const [activeLeft, setActiveLeft] = useState<MapSidebarItem | undefined>(
undefined,
Expand Down Expand Up @@ -272,17 +272,48 @@ export default function MapPage({ params: { projectId } }) {
mapStyle={basemaps[activeBasemapIndex[0]].url}
attributionControl={false}
mapboxAccessToken={MAPBOX_TOKEN}
onLoad={(e) => {
const changeIcon = (src: string) => {
const map = e.target

const newImage = new Image();
newImage.crossOrigin = "Anonymous";
newImage.src = src;

const xhr = new XMLHttpRequest();

xhr.open('GET', src, true)
xhr.onreadystatechange = () => {
if(xhr.readyState === 4 && xhr.status === 200) {

newImage.src = `data:image/svg+xml,${encodeURIComponent(xhr.responseText)}`

}
}

xhr.send()

newImage.onload = () => {
if (map.hasImage("dentist-15")) {
map.removeImage('dentist-15');
map.addImage("dentist-15", newImage, {sdf: true});
}
}
}



dispatch(setIcon(changeIcon))

}}
>
{mapLayer ? (
<Source
id={mapLayer.id}
type="vector"
url={mapLayer.sources.composite.url}
>
<Layer
{...mapLayer}
source-layer={mapLayer["source-layer"]}
/>
<Layer {...mapLayer} source-layer={mapLayer["source-layer"]} />
</Source>
) : null}
{/* todo check */}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Box from "@p4b/ui/components/Box";
import { Divider, TextField, Typography } from "@mui/material";
import React from "react";
import { useSelector } from "react-redux";
import { setLayerFillOutLineColor } from "@/lib/store/styling/slice";
import { setIconFillColor, setLayerFillOutLineColor } from "@/lib/store/styling/slice";
import { useAppDispatch } from "@/hooks/useAppDispatch";
import { selectMapLayer } from "@/lib/store/styling/selectors";

Expand All @@ -17,7 +17,7 @@ const ColorOptionSymbol = () => {
event: React.ChangeEvent<HTMLInputElement>
) => {
console.log("value", event.target.value);
// dispatch(setLayerFillColor(event.target.value));
dispatch(setIconFillColor(event.target.value));
};

const handleStrokeColorChange = (
Expand Down Expand Up @@ -48,7 +48,7 @@ const ColorOptionSymbol = () => {
type="color"
size="small"
className={classes.inputs}
value={mapLayer?.paint?.["fill-color"]}
value={mapLayer?.paint?.["icon-color"]}
onChange={handleFillColorChange}
/>
{/*<TextField*/}
Expand Down
45 changes: 43 additions & 2 deletions apps/goat/components/map/panels/mapStyle/MarkerOptionSymbol.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
import { FormControl, MenuItem, Select, Typography } from "@mui/material";
import BasicAccordion from "@p4b/ui/components/BasicAccordion";

import React from "react";
import React, { useState } from "react";
import { Icon, ICON_NAME } from "@p4b/ui/components/Icon";
import { makeStyles } from "@/lib/theme";
import { useTheme } from "@p4b/ui/components/theme";
import { useSelector } from "react-redux";
import type { IStore } from "@/types/store";
import star from "@/public/assets/poi-icons/star.svg";
import circle from "@/public/assets/poi-icons/circle.svg";

const MarkerOptionSymbol = () => {
const { changeIcon } = useSelector((state: IStore) => state.styling);
const { classes } = useStyles();
const theme = useTheme();
const [value, setValue] = useState("icon");

return (
<BasicAccordion title="Marker" variant="secondary">
<FormControl sx={{ m: 1, width: "100%" }}>
<Select size="small" className={classes.select}>
<Select
value={value}
size="small"
onChange={(e) => {
setValue(e.target.value);
}}
className={classes.select}
>
<MenuItem value="icon" className={classes.menuItem}>
<Icon
iconName={ICON_NAME.STAR}
Expand All @@ -31,6 +45,33 @@ const MarkerOptionSymbol = () => {
</MenuItem>
</Select>
</FormControl>
{value === "icon" && (
<div
style={{
paddingBlock: "10px",
border: "1px solid rgb(190, 190, 190)",
borderRadius: "4px",
marginLeft: "4px",
display: "flex",
justifyContent: "space-evenly",
}}
>
<Icon
iconName={ICON_NAME.STAR}
style={{
cursor: "pointer",
}}
onClick={() => changeIcon?.(star.src)}
/>
<Icon
iconName={ICON_NAME.CIRCLE}
style={{
cursor: "pointer",
}}
onClick={() => changeIcon?.(circle.src)}
/>
</div>
)}
</BasicAccordion>
);
};
Expand Down
3 changes: 3 additions & 0 deletions apps/goat/lib/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const store = configureStore({
styling: stylingReducer,
mapFilters: filtersReducer,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
serializableCheck: false
})
});

export type AppDispatch = typeof store.dispatch;
Expand Down
14 changes: 14 additions & 0 deletions apps/goat/lib/store/styling/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export interface IStylingState {
activeBasemapIndex: number[];
markers: IMarker[];
mapLayer: unknown;
changeIcon: null | ((src: string) => void);
}

const initialState: IStylingState = {
Expand Down Expand Up @@ -100,12 +101,16 @@ const initialState: IStylingState = {
markers: [],
//todo need get layer from db
mapLayer: null as TLayer,
changeIcon: null
};

const stylingSlice = createSlice({
name: "styling",
initialState,
reducers: {
setIcon: (state, action: PayloadAction<(src: string) => void>) => {
state.changeIcon = action.payload
},
setTabValue: (state, action: PayloadAction<number>) => {
state.tabValue = action.payload;
},
Expand Down Expand Up @@ -180,6 +185,13 @@ const stylingSlice = createSlice({
mapLayer.layout['icon-size'] = action.payload.val;
}
},
setIconFillColor: (state, action: PayloadAction<string>) => {
const mapLayer = state.mapLayer as TLayer;

if (mapLayer?.paint) {
mapLayer.paint["icon-color"] = action.payload;
}
}
// setLayerIconImage: (state, action: PayloadAction<string>) => {
// state.mapLayer.layers[0].layout["icon-image"] = action.payload;
// },
Expand All @@ -201,6 +213,8 @@ const stylingSlice = createSlice({
});

export const {
setIconFillColor,
setIcon,
setTabValue,
setActiveBasemapIndex,
addMarker,
Expand Down
16 changes: 4 additions & 12 deletions apps/goat/lib/utils/mockLayerData.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,13 @@ export const stylesObj = {
},
id: "cljxz3bl1003v01qy7k5m0apj",
type: "symbol",
paint: {},
paint: {
'icon-color': '#316940',
},
source: "composite",
"source-layer": "poi",
layout: {
"icon-image": [
"match",
["get", "category"],
["dentist"],
"dentist-15",
["bakery"],
"bakery-11",
["nursery"],
"hospital-15",
"",
],
"icon-image": "dentist-15",
},
},
aoi: {
Expand Down
3 changes: 3 additions & 0 deletions apps/goat/public/assets/poi-icons/circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions apps/goat/public/assets/poi-icons/star.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 761614d

Please sign in to comment.