Skip to content

Simplify Symbology of Vectors #672

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 29 additions & 31 deletions packages/base/src/dialogs/symbology/symbologyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,37 @@ export namespace VectorUtils {
return [];
}

const prefix = layer.parameters.type === 'circle' ? 'circle-' : '';

if (!color[`${prefix}fill-color`]) {
return [];
}

const keys = ['fill-color', 'circle-fill-color'];
const valueColorPairs: IStopRow[] = [];

// So if it's not a string then it's an array and we parse
// Color[0] is the operator used for the color expression
switch (color[`${prefix}fill-color`][0]) {
case 'interpolate':
// First element is interpolate for linear selection
// Second element is type of interpolation (ie linear)
// Third is input value that stop values are compared with
// Fourth and on is value:color pairs
for (let i = 3; i < color[`${prefix}fill-color`].length; i += 2) {
const obj: IStopRow = {
stop: color[`${prefix}fill-color`][i],
output: color[`${prefix}fill-color`][i + 1]
};
valueColorPairs.push(obj);
}
break;
case 'case':
for (let i = 1; i < color[`${prefix}fill-color`].length - 1; i += 2) {
const obj: IStopRow = {
stop: color[`${prefix}fill-color`][i][2],
output: color[`${prefix}fill-color`][i + 1]
};
valueColorPairs.push(obj);
}
break;
for (const key of keys) {
if (!color[key]) {
continue;
}

switch (color[key][0]) {
case 'interpolate':
// First element is interpolate for linear selection
// Second element is type of interpolation (ie linear)
// Third is input value that stop values are compared with
// Fourth and on is value:color pairs
for (let i = 3; i < color[key].length; i += 2) {
valueColorPairs.push({
stop: color[key][i],
output: color[key][i + 1]
});
}
break;

case 'case':
for (let i = 1; i < color[key].length - 1; i += 2) {
valueColorPairs.push({
stop: color[key][i][2],
output: color[key][i + 1]
});
}
break;
}
}

return valueColorPairs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,11 @@ const Categorized = ({
colorExpr.push([0, 0, 0, 0.0]);

const newStyle = { ...layer.parameters.color };
newStyle['fill-color'] = colorExpr;

if (layer.parameters.type === 'fill') {
newStyle['fill-color'] = colorExpr;
}

if (layer.parameters.type === 'line') {
newStyle['stroke-color'] = colorExpr;
}
newStyle['stroke-color'] = colorExpr;

if (layer.parameters.type === 'circle') {
newStyle['circle-fill-color'] = colorExpr;
}
newStyle['circle-fill-color'] = colorExpr;

const symbologyState = {
renderType: 'Categorized',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,23 +126,15 @@ const Graduated = ({
const newStyle = { ...layer.parameters.color };

if (selectedMethodRef.current === 'color') {
if (layer.parameters.type === 'fill') {
newStyle['fill-color'] = colorExpr;
}
newStyle['fill-color'] = colorExpr;

if (layer.parameters.type === 'line') {
newStyle['stroke-color'] = colorExpr;
}
newStyle['stroke-color'] = colorExpr;

if (layer.parameters.type === 'circle') {
newStyle['circle-fill-color'] = colorExpr;
}
newStyle['circle-fill-color'] = colorExpr;
}

if (selectedMethodRef.current === 'radius') {
if (layer.parameters.type === 'circle') {
newStyle['circle-radius'] = colorExpr;
}
newStyle['circle-radius'] = colorExpr;
}

const symbologyState = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const SimpleSymbol = ({
}: ISymbologyDialogProps) => {
const styleRef = useRef<IParsedStyle>();

const [useCircleStuff, setUseCircleStuff] = useState(false);
const [style, setStyle] = useState<IParsedStyle>({
fillColor: '#3399CC',
joinStyle: 'round',
Expand All @@ -38,23 +37,16 @@ const SimpleSymbol = ({
return;
}

setUseCircleStuff(layer.parameters.type === 'circle');

// Mimicking QGIS here,
// Read values from file if we chose them using the single symbol thing
// but if we're switching to simple symbol, use defaults
const initStyle = async () => {
if (!layer.parameters) {
return;
}

const renderType = layer.parameters?.symbologyState.renderType;

if (renderType === 'Single Symbol') {
// Read from current color or use defaults
const parsedStyle = parseColor(
layer.parameters.type,
layer.parameters.color
);
// Parse with fallback logic inside
const parsedStyle = parseColor(layer.parameters.color);

if (parsedStyle) {
setStyle(parsedStyle);
Expand Down Expand Up @@ -83,19 +75,19 @@ const SimpleSymbol = ({
return;
}

const styleExpr: FlatStyle = {};

const prefix = layer.parameters.type === 'circle' ? 'circle-' : '';

if (layer.parameters.type === 'circle') {
styleExpr['circle-radius'] = styleRef.current?.radius;
}

styleExpr[`${prefix}fill-color`] = styleRef.current?.fillColor;
styleExpr[`${prefix}stroke-color`] = styleRef.current?.strokeColor;
styleExpr[`${prefix}stroke-width`] = styleRef.current?.strokeWidth;
styleExpr[`${prefix}stroke-line-join`] = styleRef.current?.joinStyle;
styleExpr[`${prefix}stroke-line-cap`] = styleRef.current?.capStyle;
const styleExpr: FlatStyle = {
'circle-radius': styleRef.current?.radius,
'circle-fill-color': styleRef.current?.fillColor,
'circle-stroke-color': styleRef.current?.strokeColor,
'circle-stroke-width': styleRef.current?.strokeWidth,
'circle-stroke-line-join': styleRef.current?.joinStyle,
'circle-stroke-line-cap': styleRef.current?.capStyle,
'fill-color': styleRef.current?.fillColor,
'stroke-color': styleRef.current?.strokeColor,
'stroke-width': styleRef.current?.strokeWidth,
'stroke-line-join': styleRef.current?.joinStyle,
'stroke-line-cap': styleRef.current?.capStyle
};

const symbologyState = {
renderType: 'Single Symbol'
Expand All @@ -111,22 +103,20 @@ const SimpleSymbol = ({

return (
<div className="jp-gis-layer-symbology-container">
{useCircleStuff ? (
<div className="jp-gis-symbology-row">
<label htmlFor={'vector-value-select'}>Radius:</label>
<input
type="number"
value={style.radius}
className="jp-mod-styled"
onChange={event =>
setStyle(prevState => ({
...prevState,
radius: +event.target.value
}))
}
/>
</div>
) : null}
<div className="jp-gis-symbology-row">
<label htmlFor={'vector-value-select'}>Radius:</label>
<input
type="number"
value={style.radius}
className="jp-mod-styled"
onChange={event =>
setStyle(prevState => ({
...prevState,
radius: +event.target.value
}))
}
/>
</div>
<div className="jp-gis-symbology-row">
<label htmlFor={'vector-value-select'}>Fill Color:</label>
<input
Expand Down Expand Up @@ -181,48 +171,38 @@ const SimpleSymbol = ({
}))
}
className="jp-mod-styled"
value={style.joinStyle}
>
{joinStyleOptions.map((method, index) => (
<option
key={index}
value={method}
selected={method === style.joinStyle}
className="jp-mod-styled"
>
<option key={index} value={method} className="jp-mod-styled">
{method}
</option>
))}
</select>
</div>
</div>
{useCircleStuff ? (
<div className="jp-gis-symbology-row">
<label htmlFor={'vector-cap-select'}>Cap Style:</label>
<div className="jp-select-wrapper">
<select
name={'vector-cap-select'}
onChange={event =>
setStyle(prevState => ({
...prevState,
capStyle: event.target.value
}))
}
className="jp-mod-styled"
>
{capStyleOptions.map((cap, index) => (
<option
key={index}
value={cap}
selected={cap === style.capStyle}
className="jp-mod-styled"
>
{cap}
</option>
))}
</select>
</div>
<div className="jp-gis-symbology-row">
<label htmlFor={'vector-cap-select'}>Cap Style:</label>
<div className="jp-select-wrapper">
<select
name={'vector-cap-select'}
onChange={event =>
setStyle(prevState => ({
...prevState,
capStyle: event.target.value
}))
}
className="jp-mod-styled"
value={style.capStyle}
>
{capStyleOptions.map((cap, index) => (
<option key={index} value={cap} className="jp-mod-styled">
{cap}
</option>
))}
</select>
</div>
) : null}
</div>
</div>
);
};
Expand Down
43 changes: 12 additions & 31 deletions packages/base/src/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,42 +300,23 @@ export interface IParsedStyle {
radius?: number;
}

export function parseColor(type: string, style: any) {
if (!type || !style) {
export function parseColor(style: any): IParsedStyle | undefined {
if (!style) {
return;
}

const type2 = type === 'circle' ? 'circle' : 'default';

const shapeStyles: any = {
circle: {
radius: style['circle-radius'] ?? 5,
fillColor: style['circle-fill-color'] ?? '#3399CC',
strokeColor: style['circle-stroke-color'] ?? '#3399CC',
strokeWidth: style['circle-stroke-width'] ?? 1.25,
joinStyle: style['circle-stroke-line-join'] ?? 'round',
capStyle: style['circle-stroke-line-cap'] ?? 'round'
},
default: {
fillColor: style['fill-color'] ?? '[255, 255, 255, 0.4]',
strokeColor: style['stroke-color'] ?? '#3399CC',
strokeWidth: style['stroke-width'] ?? 1.25,
capStyle: style['stroke-line-cap'] ?? 'round',
joinStyle: style['stroke-line-join'] ?? 'round'
}
const parsedStyle: IParsedStyle = {
radius: style['circle-radius'] ?? 5,
fillColor: style['circle-fill-color'] ?? style['fill-color'] ?? '#3399CC',
strokeColor:
style['circle-stroke-color'] ?? style['stroke-color'] ?? '#3399CC',
strokeWidth: style['circle-stroke-width'] ?? style['stroke-width'] ?? 1.25,
joinStyle:
style['circle-stroke-line-join'] ?? style['stroke-line-join'] ?? 'round',
capStyle:
style['circle-stroke-line-cap'] ?? style['stroke-line-cap'] ?? 'round'
};

const parsedStyle: IParsedStyle = shapeStyles[type2];

Object.assign(parsedStyle, {
radius: parsedStyle.radius,
fillColor: parsedStyle.fillColor,
strokeColor: parsedStyle.strokeColor,
strokeWidth: parsedStyle.strokeWidth,
joinStyle: parsedStyle.joinStyle,
capStyle: parsedStyle.capStyle
});

return parsedStyle;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,13 @@
"type": "object",
"description": "VectorTileLayer",
"title": "IVectorTileLayer",
"required": ["source", "type"],
"required": ["source"],
"additionalProperties": false,
"properties": {
"source": {
"type": "string",
"description": "The id of the source"
},
"type": {
"type": "string",
"enum": ["circle", "fill", "line"],
"default": "line",
"description": "The type of vector layer"
},
"color": {
"type": "object",
"description": "The color of the the object"
Expand Down
8 changes: 1 addition & 7 deletions packages/schema/src/schema/project/layers/vectorlayer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,13 @@
"type": "object",
"description": "VectorLayer",
"title": "IVectorLayer",
"required": ["source", "type"],
"required": ["source"],
"additionalProperties": false,
"properties": {
"source": {
"type": "string",
"description": "The id of the source"
},
"type": {
"type": "string",
"enum": ["circle", "fill", "line"],
"default": "line",
"description": "The type of vector layer"
},
"color": {
"type": "object",
"description": "The color of the the object"
Expand Down
Loading
Loading