Skip to content

Commit

Permalink
Add image marker options to insert-layer menu
Browse files Browse the repository at this point in the history
  • Loading branch information
underbluewaters committed Aug 9, 2023
1 parent c7941d3 commit 028226f
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 10 deletions.
27 changes: 20 additions & 7 deletions packages/client/src/admin/data/GLStyleEditor/GLStyleEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,6 @@ export default function GLStyleEditor(props: GLStyleEditorProps) {
const [value] = useState(formatGLStyle(props.initialStyle || ""));
const onChange = useDebouncedFn(props.onChange || (() => {}), 100, {});
const editorRef = useRef<ReactCodeMirrorRef>(null);
const jsonCompletions = useMemo(() => {
return jsonLanguage.data.of({
autocomplete: glStyleAutocomplete(props.geostats),
});
}, [props.geostats]);

const type = props.type || "vector";

Expand All @@ -80,6 +75,15 @@ export default function GLStyleEditor(props: GLStyleEditorProps) {
},
});

const jsonCompletions = useMemo(() => {
return jsonLanguage.data.of({
autocomplete: glStyleAutocomplete(
props.geostats,
spriteQuery?.data?.publicSprites || []
),
});
}, [props.geostats, spriteQuery.data?.publicSprites]);

const [spriteState, setSpriteState] = useState<null | {
from: number;
to: number;
Expand Down Expand Up @@ -175,15 +179,24 @@ export default function GLStyleEditor(props: GLStyleEditorProps) {
);

const { layerTypes, insertOptions } = useMemo(() => {
const options = props.geostats ? getInsertLayerOptions(props.geostats) : [];
const options = props.geostats
? getInsertLayerOptions(props.geostats, [
...(spriteQuery.data?.publicSprites || []),
...(spriteQuery.data?.projectBySlug?.sprites || []),
])
: [];
const layerTypes: string[] = [];
for (const option of options) {
if (!layerTypes.includes(option.layer.type)) {
layerTypes.push(option.layer.type);
}
}
return { layerTypes, insertOptions: options };
}, [props.geostats]);
}, [
props.geostats,
spriteQuery.data?.publicSprites,
spriteQuery.data?.projectBySlug?.sprites,
]);

const mapContext = useContext(MapContext);
const visibleLayers = mapContext.manager?.getVisibleLayerReferenceIds();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
schemeTableau10,
interpolatePlasma as interpolateColorScale,
} from "d3-scale-chromatic";
import { SpriteDetailsFragment } from "../../../../generated/graphql";

export interface GeostatsAttribute {
attribute: string;
Expand Down Expand Up @@ -176,7 +177,8 @@ export interface InsertLayerOption {
}

export const glStyleAutocomplete =
(layer?: GeostatsLayer) => (context: CompletionContext) => {
(layer?: GeostatsLayer, sprites?: SpriteDetailsFragment[]) =>
(context: CompletionContext) => {
let word = context.matchBefore(/[\w-]*/);
let { state, pos } = context,
around = syntaxTree(state).resolveInner(pos),
Expand Down Expand Up @@ -206,6 +208,7 @@ export const glStyleAutocomplete =
if (evaluatedContext) {
const completions = getCompletionsForEvaluatedContext(
evaluatedContext,
sprites || [],
layer
);
if (completions && completions.length) {
Expand Down Expand Up @@ -872,6 +875,7 @@ let colorChoiceCounter = 9;

function getCompletionsForEvaluatedContext(
styleContext: EvaluatedStyleContext,
sprites: SpriteDetailsFragment[],
layer?: GeostatsLayer
) {
const completions: Completion[] = [];
Expand Down Expand Up @@ -1569,7 +1573,10 @@ function getRoot(
}
}

export function getInsertLayerOptions(layer: GeostatsLayer) {
export function getInsertLayerOptions(
layer: GeostatsLayer,
sprites: SpriteDetailsFragment[]
) {
const options: InsertLayerOption[] = [];
if (layer.geometry === "Point" || layer.geometry === "MultiPoint") {
// Add circle types
Expand Down Expand Up @@ -1948,6 +1955,54 @@ export function getInsertLayerOptions(layer: GeostatsLayer) {
});
}
}
if (
sprites.length &&
(layer.geometry === "MultiPoint" || layer.geometry === "Point")
) {
options.push({
type: "symbol",
label: "Image Symbol",
layer: {
type: "symbol",
layout: {
"icon-image": `seasketch://sprites/${sprites[0].id}`,
},
paint: {},
},
});
}
for (const attribute of (layer.attributes || []).filter(
(a) => a.type === "string"
)) {
options.push({
type: "symbol",
label: "Different image for each string value",
propertyChoice: {
property: attribute.attribute,
...attribute,
},
layer: {
type: "symbol",
layout: {
"icon-image": [
"match",
["get", attribute.attribute],
...attribute.values
.filter((v) => v !== null)
.map((v, i) => {
return [
v,
`seasketch://sprites/${sprites[i % sprites.length].id}`,
];
})
.flat(),
`seasketch://sprites/${sprites[0].id}`,
],
},
paint: {},
},
});
}
}
return options;
}
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,10 @@ export default function LayerTableOfContentsItemEditor(
</a>
. Don't specify a <code>source</code> or <code>id</code>{" "}
property on your layers, those will be managed for you by
SeaSketch.
SeaSketch. Press{" "}
<span className="font-mono">Control+Space</span> to
autocomplete string values and property names, and hover
over properties to see documentation.
</Trans>
</p>
{updateGLStyleMutationState.error && (
Expand Down

0 comments on commit 028226f

Please sign in to comment.