Select to view content in your preferred language

MapViewConstraints: maxScale below finest LOD breaks effectiveLOD

396
3
03-20-2026 03:53 PM
QAAccount
Emerging Contributor

Using the code below, if I set minScale = 500000 and maxScale = 200, the results look correct and effectiveLODs fall within the expected range. But when I change maxScale to 50, it flips and I get:

effectiveMinScale: 591,657,528

effectiveMaxScale: 288,895

I expected effectiveLODs to remain between 50–500,000. Is this expected, why does setting maxScale below the finest LOD cause the effective min/max/LODs to jump this way?


<!
doctype html>
<html lang="en">

 

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>Sample</title>
    <script type="module" src="https://js.arcgis.com/5.0/"></script>

 

    <style>
        html,
        body {
            height: 100%;
            margin: 0;
        }
    </style>
</head>

 

<body>
    <label>
        Min scale
        <input id="minScaleInput" type="number" value="0" />
    </label>
    <label>
        Max scale
        <input id="maxScaleInput" type="number" value="0" />
    </label>
    <div>effectiveMinScale: <span id="effectiveMinScale">-</span></div>
    <div>effectiveMaxScale: <span id="effectiveMaxScale">-</span></div>
    <div>effectiveLODs:
        <pre id="effectiveLODs">-</pre>
    </div>

 

    <arcgis-map center="-82.441933, 35.611474" zoom="18" />
    <script type="module">
        const Map = await $arcgis.import(
            "@arcgis/core/Map.js",
        );
        const mapElement = document.querySelector("arcgis-map");
        const minScaleInput = document.getElementById("minScaleInput");
        const maxScaleInput = document.getElementById("maxScaleInput");
        const effectiveMinScaleOutput = document.getElementById("effectiveMinScale");
        const effectiveMaxScaleOutput = document.getElementById("effectiveMaxScale");
        const effectiveLODsOutput = document.getElementById("effectiveLODs");
        let view;

 

        const toNumber = (value) => {
            const parsed = Number(value);
            return Number.isFinite(parsed) ? parsed : 0;
        };

 

        const formatScale = (value) => (value ? Math.round(value).toLocaleString() : "0");
        const formatLods = (lods) =>
            lods && lods.length
                ? lods.map((lod) => `${formatScale(lod.scale)}`).join(", ")
                : "none";

 

        const renderOutputs = () => {
            if (!view) return;
            const { effectiveMinScale, effectiveMaxScale, effectiveLODs } = view.constraints;
            effectiveMinScaleOutput.textContent = formatScale(effectiveMinScale);
            effectiveMaxScaleOutput.textContent = formatScale(effectiveMaxScale);
            effectiveLODsOutput.textContent = formatLods(effectiveLODs);
        };

 

        const applyScaleInputs = () => {
            if (!view) return;
            view.constraints.minScale = toNumber(minScaleInput.value);
            view.constraints.maxScale = toNumber(maxScaleInput.value);
            renderOutputs();
        };

 

        minScaleInput.addEventListener("input", applyScaleInputs);
        maxScaleInput.addEventListener("input", applyScaleInputs);



        document.querySelector("arcgis-map").map = new Map({
            basemap: "topo-vector",
        });

 

        mapElement.addEventListener("arcgisViewReadyChange", () => {
            view = mapElement.view;
            minScaleInput.value = String(view.constraints.minScale ?? 0);
            maxScaleInput.value = String(view.constraints.maxScale ?? 0);
            view.watch("constraints.effectiveMinScale", renderOutputs);
            view.watch("constraints.effectiveMaxScale", renderOutputs);
            view.watch("constraints.effectiveLODs", renderOutputs);
            renderOutputs();
        });
    </script>
</body>

 

</html>
0 Kudos
3 Replies
MatthewDriscoll
MVP Alum

The LOD level is 22 at 141 scale so the effective max scale will not go past 141.  If the requested maxScale is finer then the LOD then replace it with the lowest possible without going out of bounds.  It also seemed to want to fight the inputs as they changed, I think it is because you are setting the constraints separately, so I set them at the same time instead.  

let finestAvailableScale = 0;

const applyScaleInputs = () => {  
  if (!view) return;
  const requestedMax =
    toNumber(maxScaleInput.value);
  const safeMax =
    (finestAvailableScale > 0 &&
     requestedMax > 0 &&
     requestedMax < finestAvailableScale)
    ? finestAvailableScale
    : requestedMax;
  view.constraints = {
    ...view.constraints,
    minScale: toNumber(minScaleInput.value),
    maxScale: safeMax,
  };
  renderOutputs();
};

mapElement.addEventListener(       
 "arcgisViewReadyChange", () => {
  view = mapElement.view;
  const initLODs =
    view.constraints.effectiveLODs;
  if (initLODs?.length) {
    finestAvailableScale =
      Math.min(...initLODs.map(
        l => l.scale));
  }
  minScaleInput.value = String(
    view.constraints.minScale ?? 0);
  maxScaleInput.value = String(
    view.constraints.maxScale ?? 0);
  view.watch(...);
  renderOutputs();
});

 

QAAccount
Emerging Contributor

Thanks Matthew, the workaround seems to be working.

But I’m wondering if this is the expected behavior? When I set maxScale = 50 (finer than the most detailed LOD), I’d expect the effective max scale to clamp to the layer’s finest scale (~70.5) and the effective LODs to include all levels from that min scale up to that finest scale. Instead, the SDK jumps to an effective max range of 288,895 - 591,657,528. That seems like a bug in how the constraints are being resolved internally.

Would the underlying issue be fixed in a future release?

Thanks again.

MatthewDriscoll
MVP Alum

In my opinion it is not expected behavior.   Worth reporting.

0 Kudos