I need to add 3 types of elements to the map based on the existing array (point, line, polygon). For each of them, I want to output information from the tooltip field when clicked.
type Props = {
data: ReportWidget;
id: string | number;
readonly: boolean;
onRemoveWidget: (widget: ReportWidget, layoutId: string | number) => void;
onUpdateWidget: (widget: ReportWidget, layoutId: string | number) => void;
};
type Coordinates = number[];
type PointTooltip = {
fft_graph: string;
Address: string;
Engineer: string;
};
type MapElement = {
id: string;
type: string;
geometry: number | Coordinates | Coordinates[];
tooltip: PointTooltip;
colour_value: ColourValueType;
};
export type ColourValueType = 'small' | 'medium' | 'large' | 'CI' | '';
const ELEMENTS: MapElement[] = [
{
id: '1',
type: 'point',
geometry: [53.2158932855, -1.182028563872],
colour_value: 'large',
tooltip: {
fft_graph: 'url/link',
Address: 'Somewhere',
Engineer: 'Grant Holt',
},
},
{
id: '2',
type: 'point',
geometry: [53.2142438558, -1.1620287472],
colour_value: 'medium',
tooltip: {
fft_graph: 'url/link',
Address: 'Somewhere',
Engineer: 'Grant Holt',
},
},
{
id: '3',
type: 'polygon',
geometry: [
[53.2192662434484, -1.16776535930174],
[53.2187209479796, -1.16673989105553],
[53.2192662434484, -1.16776535930174],
],
colour_value: '',
tooltip: {
fft_graph: 'url/link',
Address: 'Somewhere',
Engineer: 'Grant Holt',
},
},
{
id: '4',
type: 'line',
geometry: [
[53.2158932438558, -1.16202856387472],
[53.2159096813233, -1.16198840796217],
],
colour_value: 'CI',
tooltip: {
fft_graph: 'url/link',
Address: 'Somewhere',
Engineer: 'Grant Holt',
},
},
];
const MapView: FC<Props> = ({ data, id, readonly, onRemoveWidget }) => {
const { ref } = useDragMove(data, id, Boolean(readonly));
const items = useMemo(() => [], []);
const [popupElementOpen, setPopupElementOpen] = useState<string | null>(null);
const defineMapElement = (item: MapElement) => {
switch (item.type) {
case 'point':
return (
<Marker
latitude={item.geometry[0]}
longitude={item.geometry[1]}
onClick={() => {
setPopupElementOpen(item.id);
}}
>
<Styled.Marker type={item.colour_value} />
</Marker>
);
case 'polygon':
return (
<Source
type="geojson"
data={{
type: 'Feature',
properties: {},
geometry: {
type: 'Polygon',
coordinates: [item.geometry],
},
}}
>
<Layer
id="zoneLayer"
type="fill"
paint={{
'fill-color': '#82D0F5',
'fill-opacity': 0.5,
}}
/>
<Layer
id="outlineLayer"
type="line"
paint={{
'line-color': '#007DBB',
'line-width': 3,
}}
/>
</Source>
);
case 'line':
return (
<Source
type="geojson"
data={{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: [item.geometry],
},
}}
>
<Layer
id="lineLayer"
type="line"
layout={{
'line-join': 'round',
'line-cap': 'round',
}}
paint={{
'line-color': '#007DBB',
'line-width': 5,
}}
/>
</Source>
);
}
};
return (
<WidgetLayout
dropRef={ref}
name="Map View"
readonly={readonly}
items={items}
onDelete={() => onRemoveWidget(data, id)}
>
<Styled.Container>
<Map
initialViewState={{
longitude: -0.118092,
latitude: 51.509865,
zoom: 5,
}}
style={{ height: 500, width: '100%' }}
mapStyle="mapbox://styles/mapbox/streets-v9"
mapboxAccessToken="pk.eyJ1Ijoic290bmlrMzMzIiwiYSI6ImNsYXZldWFuOTA1NnQzeHNqNzAwMjlyc2IifQ.inAD5RIWgxg-E05RC3aggQ"
>
{readonly &&
ELEMENTS.map((el: MapElement) => (
<Styled.Wrapper key={el.id}>
{defineMapElement(el)}
{popupElementOpen === el.id && (
<Popup
latitude={el.geometry[0]}
longitude={el.geometry[1]}
closeOnClick={false}
offset={10}
maxWidth="320px"
onClose={() => setPopupElementOpen(null)}
>
<Styled.Image />
<p>Adress: {el.tooltip.Address}</p>
<p>Engineer: {el.tooltip.Engineer}</p>
</Popup>
)}
</Styled.Wrapper>
))}
</Map>
</Styled.Container>
</WidgetLayout>
);
};
This is what I tried, but I get an error in the types. What is wrong with my types ? And how can I properly pass coordinates to Marker and Popup(because Popup is built on 2 coordinates if I understand correctly) ? And maybe I can do it more elegantly ?
I think, you need check the type of your element :
latitude={el.geometry[0]}
longitude={el.geometry[1]}
```
Because Here the type can be :
geometry: number | Coordinates | Coordinates[];