-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(web): preset layer style (#1156)
- Loading branch information
1 parent
43ad72e
commit 67cad92
Showing
5 changed files
with
392 additions
and
16 deletions.
There are no files selected for viewing
159 changes: 159 additions & 0 deletions
159
web/src/beta/features/Editor/Map/LayerStylePanel/PresetLayerStyle/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
import { | ||
IconButton, | ||
PopupMenu, | ||
PopupMenuItem | ||
} from "@reearth/beta/lib/reearth-ui"; | ||
import { LayerStyle } from "@reearth/services/api/layerStyleApi/utils"; | ||
import { useT } from "@reearth/services/i18n"; | ||
import { useState, useEffect, FC, useCallback } from "react"; | ||
|
||
import { LayerStyleAddProps } from "../../../hooks/useLayerStyles"; | ||
|
||
import { | ||
defaultStyle, | ||
professionalStyle, | ||
pointStyle, | ||
pointWithLabelStyle, | ||
polylineStyle, | ||
polygonStyle, | ||
extrudedPolygonStyle, | ||
threeDTilesStyle, | ||
simpleStyle, | ||
colorBuildingsByHeight, | ||
getLayerStyleName | ||
} from "./presetLayerStyles"; | ||
|
||
type PresetLayerStyleProps = { | ||
layerStyles: LayerStyle[] | undefined; | ||
onLayerStyleAdd: (inp: LayerStyleAddProps) => void; | ||
onLayerStyleSelect: (id: string | undefined) => void; | ||
}; | ||
|
||
const PresetLayerStyle: FC<PresetLayerStyleProps> = ({ | ||
layerStyles, | ||
onLayerStyleAdd, | ||
onLayerStyleSelect | ||
}) => { | ||
const t = useT(); | ||
const [layerStyleAdded, setLayerStyleAdded] = useState<string | undefined>( | ||
undefined | ||
); | ||
|
||
const handleLayerStyleAddition = useCallback( | ||
(value?: Record<string, unknown>, styleName?: string) => { | ||
const name = getLayerStyleName( | ||
styleName ? styleName : t("Style"), | ||
layerStyles | ||
); | ||
onLayerStyleAdd({ | ||
name, | ||
value: value || {} | ||
}); | ||
setLayerStyleAdded(name); | ||
}, | ||
[t, layerStyles, onLayerStyleAdd] | ||
); | ||
|
||
useEffect(() => { | ||
if (layerStyleAdded && layerStyles) { | ||
const addedStyle = layerStyles.find( | ||
(style) => style.name === layerStyleAdded | ||
); | ||
onLayerStyleSelect(addedStyle?.id); | ||
} | ||
}, [layerStyles, onLayerStyleSelect, layerStyleAdded]); | ||
|
||
const menuItems: PopupMenuItem[] = [ | ||
{ | ||
id: "empty", | ||
title: t("Empty"), | ||
onClick: () => handleLayerStyleAddition({}) | ||
}, | ||
{ | ||
id: "default", | ||
title: t("Default"), | ||
onClick: () => handleLayerStyleAddition(defaultStyle, "Default") | ||
}, | ||
{ | ||
id: "professional", | ||
title: t("Professional"), | ||
onClick: () => handleLayerStyleAddition(professionalStyle, "Professional") | ||
}, | ||
{ | ||
id: "basicGeometry", | ||
title: t("Basic Geometry"), | ||
icon: "folderSimple", | ||
subItem: [ | ||
{ | ||
id: "point", | ||
title: t("Points"), | ||
onClick: () => handleLayerStyleAddition(pointStyle, "Points") | ||
}, | ||
{ | ||
id: "pointWithLabel", | ||
title: t("Point with label"), | ||
onClick: () => | ||
handleLayerStyleAddition(pointWithLabelStyle, "Point_with_label") | ||
}, | ||
{ | ||
id: "polyline", | ||
title: t("Polyline"), | ||
onClick: () => handleLayerStyleAddition(polylineStyle, "Polyline") | ||
}, | ||
{ | ||
id: "polygon", | ||
title: t("Polygon"), | ||
onClick: () => handleLayerStyleAddition(polygonStyle, "Polygon") | ||
}, | ||
{ | ||
id: "extrudedPolygon", | ||
title: t("Extruded polygon"), | ||
onClick: () => | ||
handleLayerStyleAddition(extrudedPolygonStyle, "Extruded_polygon") | ||
}, | ||
{ | ||
id: "threedTiles", | ||
title: t("3D Tiles"), | ||
onClick: () => handleLayerStyleAddition(threeDTilesStyle, "3D_tiles") | ||
} | ||
] | ||
}, | ||
{ | ||
id: "geometry", | ||
title: t("Geometry"), | ||
icon: "folderSimple", | ||
subItem: [ | ||
{ | ||
id: "simpleStyle", | ||
title: t("Simple Style"), | ||
onClick: () => handleLayerStyleAddition(simpleStyle, "Simple_style") | ||
} | ||
] | ||
}, | ||
{ | ||
id: "plateau", | ||
title: t("Plateau"), | ||
icon: "folderSimple", | ||
subItem: [ | ||
{ | ||
id: "colorBuilding", | ||
title: t("Color buildings by height"), | ||
onClick: () => | ||
handleLayerStyleAddition( | ||
colorBuildingsByHeight, | ||
"Color_buildings_by_height" | ||
) | ||
} | ||
] | ||
} | ||
]; | ||
|
||
return ( | ||
<PopupMenu | ||
menu={menuItems} | ||
label={<IconButton icon="plus" size="large" />} | ||
/> | ||
); | ||
}; | ||
|
||
export default PresetLayerStyle; |
200 changes: 200 additions & 0 deletions
200
web/src/beta/features/Editor/Map/LayerStylePanel/PresetLayerStyle/presetLayerStyles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
import { LayerStyle } from "@reearth/services/api/layerStyleApi/utils"; | ||
|
||
export const defaultStyle = { | ||
marker: { | ||
heightReference: "clamp" | ||
}, | ||
polygon: { | ||
extrudedHeight: { | ||
expression: "${extrudedHeight}" | ||
}, | ||
fillColor: { | ||
expression: "color('#ffffff',0.8)" | ||
}, | ||
heightReference: "clamp" | ||
}, | ||
polyline: { | ||
clampToGround: true, | ||
strokeColor: "#FFFFFF", | ||
strokeWidth: 2 | ||
} | ||
}; | ||
|
||
export const professionalStyle = { | ||
marker: { | ||
heightReference: "clamp", | ||
hideIndicator: false, | ||
pointColor: "#E9373D", | ||
pointOutlineColor: "white", | ||
pointOutlineWidth: 1, | ||
pointSize: 12, | ||
selectedFeatureColor: "#F1AF02", | ||
style: "point" | ||
}, | ||
polygon: { | ||
extrudedHeight: { | ||
expression: "${extrudedHeight}" | ||
}, | ||
fillColor: { | ||
expression: "color('#E9373D',0.6)" | ||
}, | ||
heightReference: "clamp", | ||
hideIndicator: false, | ||
selectedFeatureColor: { | ||
expression: "color('#F1AF02',0.6)" | ||
} | ||
}, | ||
polyline: { | ||
clampToGround: true, | ||
hideIndicator: false, | ||
selectedFeatureColor: "#F1AF02", | ||
strokeColor: "#E9373D", | ||
strokeWidth: 2 | ||
} | ||
}; | ||
|
||
export const pointStyle = { | ||
marker: { | ||
height: 0, | ||
heightReference: "relative", | ||
pointColor: "#E9373D", | ||
pointOutlineColor: "white", | ||
pointOutlineWidth: 1, | ||
pointSize: 12, | ||
style: "point" | ||
} | ||
}; | ||
|
||
export const pointWithLabelStyle = { | ||
marker: { | ||
height: 0, | ||
heightReference: "relative", | ||
label: true, | ||
labelPosition: "right", | ||
labelText: "text", | ||
pointColor: "#E9373D", | ||
pointOutlineColor: "white", | ||
pointOutlineWidth: 1, | ||
pointSize: 12, | ||
style: "point" | ||
} | ||
}; | ||
|
||
export const polylineStyle = { | ||
polyline: { | ||
clampToGround: true, | ||
hideIndicator: false, | ||
selectedFeatureColor: "#F1AF02", | ||
strokeColor: "#E9373D", | ||
strokeWidth: 2 | ||
} | ||
}; | ||
|
||
export const polygonStyle = { | ||
polygon: { | ||
fillColor: "#E9373D", | ||
heightReference: "clamp", | ||
hideIndicator: false, | ||
selectedFeatureColor: "#F1AF02" | ||
} | ||
}; | ||
|
||
export const extrudedPolygonStyle = { | ||
polygon: { | ||
extrudedHeight: { | ||
expression: "${extrudedHeight}" | ||
}, | ||
fillColor: "#E9373D", | ||
heightReference: "clamp", | ||
hideIndicator: false, | ||
selectedFeatureColor: "#F1AF02" | ||
} | ||
}; | ||
|
||
export const threeDTilesStyle = { | ||
"3dtiles": { | ||
color: "#FFFFFF", | ||
colorBlendMode: "highlight", | ||
pbr: false | ||
} | ||
}; | ||
|
||
export const simpleStyle = { | ||
marker: { | ||
pointColor: { | ||
expression: "${marker-color}" | ||
}, | ||
pointOutlineColor: { | ||
expression: "${marker-color}" | ||
}, | ||
pointSize: { | ||
expression: { | ||
conditions: [ | ||
["${marker-size}==='small'", "8"], | ||
["${marker-size}==='medium'", "12"], | ||
["${marker-size}==='large'", "16"] | ||
] | ||
} | ||
}, | ||
style: "point" | ||
}, | ||
polygon: { | ||
fillColor: { | ||
expression: "color(${fill},${fill-opacity})" | ||
}, | ||
heightReference: "clamp", | ||
stroke: "true", | ||
strokeColor: { | ||
expression: "${stroke}" | ||
}, | ||
strokeWidth: { | ||
expression: "${stroke-width}" | ||
} | ||
}, | ||
polyline: { | ||
clampToGround: true, | ||
strokeColor: { | ||
expression: "color(${stroke},${stroke-opacity})" | ||
}, | ||
strokeWidth: { | ||
expression: "${stroke-width}" | ||
} | ||
} | ||
}; | ||
|
||
export const colorBuildingsByHeight = { | ||
"3dtiles": { | ||
color: { | ||
expression: { | ||
conditions: [ | ||
["${計測高さ}>=180", "color('#F9FD4C')"], | ||
["${計測高さ}>=120", "color('#F6CD3D')"], | ||
["${計測高さ}>=60", "color('#EBD384')"], | ||
["${計測高さ}>=31", "color('#9E79BA')"], | ||
["${計測高さ}>=12", "color('#5230C2')"], | ||
["true", "color('#362C52')"] | ||
] | ||
} | ||
}, | ||
colorBlendMode: "highlight", | ||
pbr: false, | ||
shadows: "disabled" | ||
} | ||
}; | ||
|
||
export const getLayerStyleName = ( | ||
baseName: string, | ||
layerStyles?: LayerStyle[] | ||
) => { | ||
if (!layerStyles) return `${baseName}.01`; | ||
const nextNumber = | ||
layerStyles.reduce((max, style) => { | ||
const escapedBaseName = baseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); | ||
const match = style.name?.match( | ||
new RegExp(`^${escapedBaseName}\\.(\\d+)$`) | ||
); | ||
return match ? Math.max(max, parseInt(match[1], 10)) : max; | ||
}, 0) + 1; | ||
|
||
return `${baseName}.${nextNumber.toString().padStart(2, "0")}`; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.