<script type="module" src="https://js.arcgis.com/calcite-components/1.0.7/calcite.esm.js"></script>
<link rel="stylesheet" type="text/css" href="https://js.arcgis.com/calcite-components/1.0.7/calcite.css" />
<link rel="stylesheet" href="https://js.arcgis.com/4.31/esri/themes/light/main.css" />
<div id="viewDiv"></div>
<div id="componentWrapper">
  <calcite-radio-button-group name="Options" layout="vertical">
    <calcite-label layout="inline">
      <calcite-radio-button value="webMercator" checked="true"></calcite-radio-button>
      Web Mercator
    </calcite-label>
    <calcite-label layout="inline">
      <calcite-radio-button value="wgs84" shrubs></calcite-radio-button>
      WGS84
    </calcite-label>
  </calcite-radio-button-group>
</div>
html,
body,
#viewDiv {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}

#componentWrapper {
  padding: 10px 10px 0;
  background-color: white;
}

.esri-view-root .esri-ui .esri-attribution {
  left: auto;
}
import MapView from "https://js.arcgis.com/4.31/@arcgis/core/views/MapView.js";
import Basemap from "https://js.arcgis.com/4.31/@arcgis/core/Basemap.js";
import esriConfig from "https://js.arcgis.com/4.31/@arcgis/core/config.js";
import BasemapGallery from "https://js.arcgis.com/4.31/@arcgis/core/widgets/BasemapGallery.js";
import Expand from "https://js.arcgis.com/4.31/@arcgis/core/widgets/Expand.js";
// import SpatialReference from "https://js.arcgis.com/4.26/@arcgis/core/geometry/SpatialReference.js";
import SpatialReference from "https://js.arcgis.com/4.31/@arcgis/core/geometry/SpatialReference.js";
import Portal from "https://js.arcgis.com/4.31/@arcgis/core/portal/Portal.js";
import PortalItem from "https://js.arcgis.com/4.31/@arcgis/core/portal/PortalItem.js";
import PortalGroup from "https://js.arcgis.com/4.31/@arcgis/core/portal/PortalGroup.js";
import PortalQueryParams from "https://js.arcgis.com/4.31/@arcgis/core/portal/PortalQueryParams.js";
import * as b from "https://js.arcgis.com/4.31/@arcgis/core/Basemap.js";

esriConfig.apiKey =
  "AAPKd48c17fd604143f8895d3ed7c29fc670j-DR5bdRcOjWhwc-DCJKc41knqlRUm-WPyucggCPorG53QswuIpPAEvo65fZ5pps";

const getWGS84Equivalent = (title) => {
  console.log(
    "getWGS84Equivalent",
    title,
    basemaps.map((x) => [x.portalItem.title, x.portalItem.tags])
  );
  const found = basemaps.find(
    (x) =>
      x.portalItem?.title
        ?.split(" (WGS84)")
        .join("")
        .split(" - WGS84")
        .join("") == title
  );
  console.log("found", found);
  return found;
};

const getWebMercatorEquivalent = (title) => {
  console.log("getWebMercatorEquivalent", title, b.e);
  const found = Object.entries(b.e).find(
    ([k, v]) =>
      v.title == title.split(" (WGS84)").join("").split(" - WGS84").join("")
  );
  if (found) {
    const [foundKey, foundValue] = found;
    console.log("found", foundKey);
    const foundBasemap = Basemap.fromId(foundKey);
    return foundBasemap;
  } else {
    return false;
  }
};

const swapWGS84WebMercator = (basemap) => {
  let retBasemap;
  console.log("swap", basemap);
  let spatialReference = basemap.spatialReference;
  if (!spatialReference || !spatialReference.wkid) {
    // get the spatial reference elsewhere
    if (basemap.referenceLayers && basemap.baseLayers.length > 0) {
      spatialReference = basemap.baseLayers.at(0).spatialReference;
    }
  }
  console.log("spatialReference.wkid", spatialReference.wkid);
  if (spatialReference.wkid === 4326) {
    // switch to web mercator!
    console.log("switch to web mercator!", basemap);
    retBasemap = getWebMercatorEquivalent(basemap.title);
  } else {
    // switch to WGS84!
    console.log("switch to wgs84!", basemap);
    retBasemap = getWGS84Equivalent(basemap.title);
  }
  console.log("swapping to", retBasemap);
  return retBasemap;
};

const getPortalItems = async () => {
  const g = new PortalGroup({
    id: "4c790318395940c18a16e8acd721de25",
    portal: new Portal()
  });

  const portalQueryResult = await g.queryItems(
    new PortalQueryParams({
      num: 100
    })
  );

  const results = portalQueryResult.results;

  // only work on vector tiles for now
  const webMapResults = results.filter((x) => x.type === "Web Map");
  // const ids = webMapResults.map((x) => x.id);
  return webMapResults;
};

const loadAll = async (basemps) => {
  const promises = basemaps.map((x) => x.loadAll());
  return Promise.all(promises);
};

const basemapItemItems = await getPortalItems();
const basemapItemIds = basemapItemItems.map((x) => x.id);
const basemaps = basemapItemIds.map((x) => {
  return new Basemap({
    portalItem: {
      id: x
    }
  });
});

let webMercatorBasemapSource;

await loadAll(basemaps);

const viewOptions = {
  container: "viewDiv",
  map: {
    basemap: "streets-vector"
  },
  center: [-98.35, 39.5],
  zoom: 2
};
const view = new MapView(viewOptions);

view.when(() => {
  view.ui.add(componentWrapper, "top-right");

  let basemapGallery = new BasemapGallery({
    view: view
    // source: basemaps,
    // container: "basemapGalleryWrapper"
  });
  // Place the Basemap Gallery widget within the Expand widget.
  const expand = new Expand({
    view: view,
    content: basemapGallery,
    expandTooltip: "Change Basemap"
  });
  view.ui.add(expand, "top-right");

  // When a basemap is selected, hide the expand widge
  // ("Auto-close" the menu)
  basemapGallery.watch("activeBasemap", function () {
    expand.expanded = false;
  });

  componentWrapper.addEventListener("calciteRadioButtonChange", (evt) => {
    if (evt.target.value === "wgs84") {
      webMercatorBasemapSource = basemapGallery.source;
      basemapGallery.source = basemaps;
      view.spatialReference = new SpatialReference({
        wkid: 4326
      });
    } else {
      // web mercator
      basemapGallery.source = webMercatorBasemapSource;
      view.spatialReference = new SpatialReference({
        wkid: 102100
      });
    }
    const newB = swapWGS84WebMercator(view.map.basemap);
    if (newB) {
      view.map.basemap = newB;
    }
  });
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.