Polyline with large SimpleLineSymbol looks blocky

277
4
06-27-2023 05:34 PM
CalvinLe360
New Contributor II

Hello everyone, I'm looking to have a polyline with a large graphic over another polyline following the same path, like this.

CalvinLe360_2-1687912352815.png

However, when the SimpleLineSymbol's width gets too large, it seems to get cropped with blocky chunks, like so:

CalvinLe360_0-1687912177949.png

Is there a way to not have this grey polyline get cropped like this?

0 Kudos
4 Replies
RichardMoussopo
Occasional Contributor III

can you post the code so we can better assist?

0 Kudos
CalvinLe360
New Contributor II

Sure, apologies for the vaguely-named variables.

This is split in two parts where the first part builds the grey polyline (the small blue one is drawn in a separate function, I'll deal with it some other time) and the second part updates the radius of the polyline upon mapview scale change.

 

    const drawLayer = useCallback(
        (id: Id, data: Data[]) => {
            if (!mapRef.current) return;

            const positions = data.map(({position}) => [
                radiansToDegrees(position.longitude),
                radiansToDegrees(position.latitude),
            ]);

            let layer = layerRecord.current[id]?.layer;

            if (!layer) {
                layer = new GraphicsLayer();

                if (!layerRecord.current[id]) {
                    layerRecord.current[id] = {};
                }

                layerRecord.current[id].layer = layer;

                mapRef.current.add(layer);
            }

            const existingPolylineGraphic = layer.graphics.find(
                graphic => graphic.geometry.type === 'polyline'
            );

            if (existingPolylineGraphic) {
                const existingPolyline =
                    existingPolylineGraphic.geometry as Polyline;

                existingPolylineGraphic.geometry = new Polyline({
                    paths: [
                        [
                            ...(existingPolyline?.paths?.flat() || []),
                            ...positions,
                        ],
                    ],
                });

                layer.remove(existingPolylineGraphic);
                layer.add(existingPolylineGraphic);
            } else {
                const polyline = new Polyline({
                    paths: [positions],
                });
                const simpleLineSymbol = new SimpleLineSymbol({
                    color: [100, 100, 100, 0.5],
                    width: 0,
                });

                const polylineGraphic = new Graphic({
                    geometry: polyline,
                    symbol: simpleLineSymbol,
                });

                layer.add(polylineGraphic);
            }
        },
        []
    );
    const radius = 20000;
    const updateLayer = (scale: number) => {
        if (!layerRecord.current) return;

        for (const layerString in layerRecord.current) {
            const layer = layerRecord.current[layerString].layer;
            if (!layer) continue;

            const existingPolylineGraphic = layer.graphics.find(
                graphic => graphic.geometry.type === 'polyline'
            );

            if (existingPolylineGraphic) {
                const multiplier = radius / scale;
                existingPolylineGraphic.symbol = new SimpleLineSymbol({
                    color: [100, 100, 100, 0.5],
                    width: (radius * multiplier).toString() + 'px',
                });

                layer.remove(existingPolylineGraphic);
                layer.add(existingPolylineGraphic);
            }
        }
    };

 

 Again, sorry for the vaguely-named variables, I'm open to clarify within reason.

0 Kudos
RichardMoussopo
Occasional Contributor III

Depending on what you are trying to achieve, you probably won't need the second part of the code to change the width on scale change if you just clone the first graphic and style the cloned graphic as you wish

// clone existing graphic to create a copy
const clonedGraphic = existingPolylineGraphic.clone();
clonedGraphic.symbol = {
   type: 'simple-line',
   color: [255, 0, 0, 0.4],
   width: 45, // you can make this a variable as well if needed
};
layer.add(clonedGraphic);
CalvinLe360
New Contributor II

I appreciate the improvement but I have chosen to instead use circle graphics since I was unable to find a way to not make these lines blocky.

0 Kudos