Add points layer; add filters to layers; colorize layers

dev
Platon Yasev 3 years ago
parent 9f74564319
commit a907802cd3

@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link href="/favicon.ico" rel="icon"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Постаматы by SpatialTeam</title>
</head>

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -3,12 +3,18 @@ import { gridLayer } from "./layers-config";
import { useGridSize } from "../stores/useGridSize";
import { useLayersVisibility } from "../stores/useLayersVisibility";
export const Grid = () => {
export const Grid = ({ rate }) => {
const { gridSize } = useGridSize();
const {
isVisible: { grid },
} = useLayersVisibility();
const filter = [
"all",
[">=", ["get", "rate"], rate[0]],
["<=", ["get", "rate"], rate[1]],
];
return (
<>
<Source
@ -27,6 +33,7 @@ export const Grid = () => {
...gridLayer.layout,
visibility: grid && gridSize === "net3" ? "visible" : "none",
}}
filter={filter}
/>
</Source>
<Source
@ -45,6 +52,7 @@ export const Grid = () => {
...gridLayer.layout,
visibility: grid && gridSize === "net4" ? "visible" : "none",
}}
filter={filter}
/>
</Source>
<Source
@ -63,6 +71,7 @@ export const Grid = () => {
...gridLayer.layout,
visibility: grid && gridSize === "net5" ? "visible" : "none",
}}
filter={filter}
/>
</Source>
</>

@ -1,28 +1,14 @@
import { Grid } from "./Grid";
import { useRating } from "../stores/useRating";
import { Points } from "./Points";
export const Layers = () => {
const { rate } = useRating();
console.log(rate);
return (
<>
<Grid />
{/*<Source*/}
{/* id="points"*/}
{/* type="vector"*/}
{/* tiles={[*/}
{/* "https://property.spatiality.website/public.service_geofeature/{z}/{x}/{y}.pbf",*/}
{/* ]}*/}
{/*>*/}
{/* <Layer*/}
{/* {...pointLayer}*/}
{/* layout={{*/}
{/* ...pointLayer.layout,*/}
{/* visibility: isPointsVisible ? "visible" : "none",*/}
{/* }}*/}
{/* />*/}
{/*</Source>*/}
<Grid rate={rate} />
<Points rate={rate} />
</>
);
};

@ -2,7 +2,7 @@ import maplibregl from "maplibre-gl";
import Map, { useControl } from "react-map-gl";
import { useRef, useState } from "react";
import { Sidebar } from "../modules/Sidebar/Sidebar";
import { gridLayer, pointLayer } from "./layers-config";
import { pointLayer } from "./layers-config";
import { Layers } from "./Layers";
import { MapPopup } from "./Popup";
import {
@ -29,10 +29,18 @@ export const MapComponent = () => {
const [popupCoordinates, setPopupCoordinates] = useState(null);
const handleClick = (event) => {
if (!event.features) return;
if (!event.features) {
setPopupCoordinates(null);
setClickedFeature(null);
return;
}
const feature = event.features[0];
if (!feature) return;
if (!feature) {
setPopupCoordinates(null);
setClickedFeature(null);
return;
}
const { lng: pointLng, lat: pointLat } = event.lngLat;
@ -75,7 +83,7 @@ export const MapComponent = () => {
zoom: 10,
}}
ref={mapRef}
interactiveLayerIds={[pointLayer.id, gridLayer.id]}
interactiveLayerIds={[pointLayer.id, "grid3", "grid4", "grid5"]}
onClick={handleClick}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}

@ -0,0 +1,36 @@
import { Layer, Source } from "react-map-gl";
import { pointLayer } from "./layers-config";
import { useLayersVisibility } from "../stores/useLayersVisibility";
import { useActiveTypes } from "../stores/useActiveTypes";
export const Points = ({ rate }) => {
const { isVisible } = useLayersVisibility();
const { activeTypes } = useActiveTypes();
const getFilter = () => {
if (activeTypes.length) {
return ["in", "category", ...activeTypes];
} else {
return ["all"];
}
};
return (
<Source
id="points"
type="vector"
tiles={[
"https://postamates.spatiality.website/martin/public.point5/{z}/{x}/{y}.pbf",
]}
>
<Layer
{...pointLayer}
layout={{
...pointLayer.layout,
visibility: isVisible.points ? "visible" : "none",
}}
filter={getFilter()}
/>
</Source>
);
};

@ -1,11 +1,39 @@
//kiosk - городские киоски
// mfc - многофункциональные центры предоставления государственных и муниципальных услуг
// library - библиотеки
// dk - дома культуры и клубы
// sport - спортивные объекты
const pointColors = {
kiosk: "#112cda",
mfc: "#932301",
library: "#a51eda",
dk: "#e7dd24",
sport: "#138c44",
};
export const pointLayer = {
id: "points",
type: "circle",
source: "points",
"source-layer": "public.service_point",
"source-layer": "public.point5",
layout: {},
paint: {
"circle-color": "#da11b2",
"circle-color": [
"match",
["get", "category"],
"kiosk",
pointColors.kiosk,
"mfc",
pointColors.mfc,
"library",
pointColors.library,
"dk",
pointColors.dk,
"sport",
pointColors.sport,
"black",
],
"circle-radius": 4,
"circle-stroke-width": 1,
"circle-stroke-color": "#fff",
@ -16,7 +44,18 @@ export const gridLayer = {
type: "fill",
layout: {},
paint: {
"fill-color": "#26a2a2",
"fill-opacity": 0.2,
"fill-color": [
"interpolate",
["linear"],
["get", "rate"],
0,
"rgb(204,34,34)",
5,
"rgb(255,221,52)",
10,
"rgb(30,131,42)",
],
"fill-opacity": 0.3,
"fill-outline-color": "transparent",
},
};

@ -6,6 +6,22 @@ const Mark = ({ value }) => {
return <span className={"text-grey text-xs"}>{value}</span>;
};
const getInitialMarks = (fullRange, value) => {
if (Array.isArray(value)) {
const [min, max] = value;
return {
...fullRange,
[min]: <Mark value={min} />,
[max]: <Mark value={max} />,
};
} else {
return {
...fullRange,
[value]: <Mark value={value} />,
};
}
};
export const SliderComponent = ({
title,
value: initialValue,
@ -13,21 +29,31 @@ export const SliderComponent = ({
onAfterChange,
min = 0,
max = 100,
range = false,
}) => {
const fullRangeMarks = {
[min]: <Mark value={min} />,
[max]: <Mark value={max} />,
};
const [value, setValue] = useState(initialValue);
const [marks, setMarks] = useState(fullRangeMarks);
const [marks, setMarks] = useState(
getInitialMarks(fullRangeMarks, initialValue)
);
const handleAfterChange = (value) => {
if (Array.isArray(value)) {
const [min, max] = value;
setMarks({
...fullRangeMarks,
[min]: <Mark value={min} />,
[max]: <Mark value={max} />,
});
} else {
setMarks({
...fullRangeMarks,
[value]: <Mark value={value} />,
});
}
onAfterChange?.(value);
};
@ -41,11 +67,13 @@ export const SliderComponent = ({
<div>
<Title text={title} />
<Slider
range
range={range}
value={value}
marks={marks}
onChange={handleChange}
onAfterChange={handleAfterChange}
min={min}
max={max}
/>
</div>
);

@ -3,10 +3,18 @@ import { twMerge } from "tailwind-merge";
import { Title } from "../../components/Title";
import { useActiveTypes } from "../../stores/useActiveTypes";
//kiosk - городские киоски
// mfc - многофункциональные центры предоставления государственных и муниципальных услуг
// library - библиотеки
// dk - дома культуры и клубы
// sport - спортивные объекты
const types = [
{ id: "kiosk", name: "Городские киоски" },
{ id: "mfc", name: "МФЦ" },
{ id: "library", name: "Библиотеки" },
{ id: "dk", name: "Дома культуры и клубы" },
{ id: "sport", name: "Спортивные объекты" },
];
const SelectItem = ({ name, isActive, onClick }) => {

@ -1,5 +1,5 @@
import { useRating } from "../../stores/useRating";
import { SliderComponent as Slider } from "../../components/Slider";
import { SliderComponent as Slider } from "../../components/SliderComponent";
export const RatingSlider = () => {
const { rate, setRate } = useRating();
@ -11,6 +11,8 @@ export const RatingSlider = () => {
title={"Востребованность постамата, усл. ед."}
value={rate}
onAfterChange={handleAfterChange}
max={10}
range
/>
);
};

@ -1,13 +1,13 @@
import { SliderComponent as Slider } from "../../components/Slider";
import { SliderComponent as Slider } from "../../components/SliderComponent";
import { Button } from "antd";
export const Settings = () => {
return (
<div className={"space-y-2 min-w-[300px]"}>
<Slider title={"Количество жителей"} />
<Slider title={"Количество станций метро"} />
<Slider title={"Количество существующих постаматов"} />
<Slider title={"Whatever"} />
<Slider title={"Количество жителей"} value={50} />
<Slider title={"Количество станций метро"} value={50} />
<Slider title={"Количество существующих постаматов"} value={50} />
<Slider title={"Whatever"} value={50} />
<div>
<Button type="primary" block className={"mt-2"}>
Рассчитать

@ -2,7 +2,7 @@ import create from "zustand";
import { immer } from "zustand/middleware/immer";
const store = (set) => ({
gridSize: "net3",
gridSize: "net5",
setGridSize: (value) =>
set((state) => {
state.gridSize = value;

@ -2,7 +2,7 @@ import create from "zustand";
import { immer } from "zustand/middleware/immer";
const INITIAL_STATE = {
points: true,
points: false,
grid: true,
};

@ -2,7 +2,7 @@ import create from "zustand";
import { immer } from "zustand/middleware/immer";
const store = (set) => ({
rate: [0, 100],
rate: [0, 10],
setRate: (value) =>
set((state) => {
state.rate = value;

@ -6,7 +6,7 @@ module.exports = {
colors: {
primary: "#CC2222FF",
blue: "rgba(167,201,236,0.57)",
"white-background": "rgba(255, 255, 255, 0.8)",
"white-background": "rgba(255, 255, 255, 0.9)",
grey: "rgba(0,0, 0, 0.5)",
},
},

Loading…
Cancel
Save