Select to view content in your preferred language

How to select a MapWidget by custom widget

648
5
Jump to solution
03-30-2024 04:59 PM
lmotta_ibama
Occasional Contributor

I would like to provide a list of maps for the user to choose the map where the layer will be added.

1) In the setting/setting.tsx file we provide the selection the map to work with custom widget, then, all layers are added in this map.

lmotta_ibama_0-1711842462187.png

2) I'd like you to be able to choose which map the image (satellite) is placed on in the custom widget.
At the moment, only ONE map can be used.

lmotta_ibama_0-1711843693312.png

* The satellite image is added when you click on the picture (Thumbnails)

0 Kudos
1 Solution

Accepted Solutions
lmotta_ibama
Occasional Contributor

lmotta_ibama_1-1712155609143.png

The answer is: Yes, we can select the MapWidget (map).

The figure shows two maps and there is a Select Widget (custom widget), in which we can select the map (MapRef or Map1) to add the desired images (cliking in the satellite picture inside ScrollList).


How?

The class (API) that allows you to manage MapWidgets is MapViewManager ('jimu-arcgis').
The instance of this class can be obtained by "MapViewManager.getInstance()", I preferred to obtain the instance by accessing one of the MapView [1].

 

[1] Code:

export default function Widget(props: AllWidgetProps<any>) {
...
  const createMapView = () => {
    const handlerViewsCreate = (views:{ [viewId: string]: JimuMapView }) => {
      if( !views) return;
      // Mapview Reference (use for "extension search" and "footprints")
      const viewId = Object.keys( views )[0];
      const wmvRef = views[ viewId ];
      // MapViews = { 'Map_Ref': wmvRef.view, 'Map_1': item1.view, ..., 'Map N': itemN.view ]
      const wmvIds = Object.keys( wmvRef.mapViewManager.jimuMapViewGroups ).filter( item => item !== wmvRef.mapWidgetId );
      const mvOthers = wmvIds.map( item => {
       const id = Object.keys( wmvRef.mapViewManager.jimuMapViewGroups[ item ].jimuMapViews )[0];
        return wmvRef.mapViewManager.jimuMapViewGroups[ item ].jimuMapViews[ id ].view;
      });
      const mvsRef = { 'MapRef': wmvRef.view };
      let idKey = 0;
      const mvsMap = Object.fromEntries( mvOthers.map( mv => [ 'Map' + ++idKey, mv ] ) );
      const mvs = { ...mvsRef, ...mvsMap };
      setMapViews( mvs );
    }
...

  if(
    ! props.hasOwnProperty('useMapWidgetIds') ||
    ! props.useMapWidgetIds ||
    props.useMapWidgetIds.length !== 1
  ) return;

  return(
    <JimuMapViewComponent
      useMapWidgetId={props.useMapWidgetIds[0]}
      onViewsCreate={handlerViewsCreate}
      onActiveViewChange={handlerActiveViewChange}
   />
  )
}


...

export default function Widget(props: AllWidgetProps<any>) { return (
<div style={divStyle}>
{ createMapView() }
<label className={css}>
...

 

View solution in original post

0 Kudos
5 Replies
JeffreyThompson2
MVP Regular Contributor

It looks like you have two side-by-side maps and you want to compare satellite images of different times. Have you looked at the Swipe Widget? https://doc.arcgis.com/en/experience-builder/latest/configure-widgets/swipe-widget.htm It is designed for this purpose.

GIS Developer
City of Arlington, Texas
0 Kudos
lmotta_ibama
Occasional Contributor

Thanks @JeffreyThompson2 ,

 

The Swipe Widget tool would be great, but this tool uses a previously defined data source (setting).

The my customized widget, the user can add and remove layers (WebTileLayer), which means that my data is dynamic and not fixed (necessary for the Swipe tool).

One solution is to make it so that we can select the MapView we want to add the layers to.

I discovered the MapViewManager class (jimu-arcgis), which allows you to identify MapViews. I think I'll be able to solve the problem.

GIS Developer & Environmental Analyst

Monitoring and Combat Division (DMV)
National Center to Prevent and Combat Forest fires (Prevfogo)
Brazilian Institute of Environment and Renewable Natural Resources (Ibama)

0 Kudos
JeffreyThompson2
MVP Regular Contributor

If you have found a solution you are happy with that way, go ahead, but if you would like to use a swipe here's another way.

Any of the features and widgets in the JavaScript API can also be used in Experience Builder. The API also has a Switch Widget. If you use the Switch from the API, it will be much easier to control programmatically. https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Swipe.html 

GIS Developer
City of Arlington, Texas
0 Kudos
lmotta_ibama
Occasional Contributor

This widget by JS API would solve the problem of comparing layers (images).

Conceptually, the widget I'm developing is for using the Planet's daily images (choose and add/remove), so its scope is defined.

Another custom widget using the JS API with Swipe would be wonderful.

Thanks again

GIS Developer & Environmental Analyst

Monitoring and Combat Division (DMV)
National Center to Prevent and Combat Forest fires (Prevfogo)
Brazilian Institute of Environment and Renewable Natural Resources (Ibama)

 

0 Kudos
lmotta_ibama
Occasional Contributor

lmotta_ibama_1-1712155609143.png

The answer is: Yes, we can select the MapWidget (map).

The figure shows two maps and there is a Select Widget (custom widget), in which we can select the map (MapRef or Map1) to add the desired images (cliking in the satellite picture inside ScrollList).


How?

The class (API) that allows you to manage MapWidgets is MapViewManager ('jimu-arcgis').
The instance of this class can be obtained by "MapViewManager.getInstance()", I preferred to obtain the instance by accessing one of the MapView [1].

 

[1] Code:

export default function Widget(props: AllWidgetProps<any>) {
...
  const createMapView = () => {
    const handlerViewsCreate = (views:{ [viewId: string]: JimuMapView }) => {
      if( !views) return;
      // Mapview Reference (use for "extension search" and "footprints")
      const viewId = Object.keys( views )[0];
      const wmvRef = views[ viewId ];
      // MapViews = { 'Map_Ref': wmvRef.view, 'Map_1': item1.view, ..., 'Map N': itemN.view ]
      const wmvIds = Object.keys( wmvRef.mapViewManager.jimuMapViewGroups ).filter( item => item !== wmvRef.mapWidgetId );
      const mvOthers = wmvIds.map( item => {
       const id = Object.keys( wmvRef.mapViewManager.jimuMapViewGroups[ item ].jimuMapViews )[0];
        return wmvRef.mapViewManager.jimuMapViewGroups[ item ].jimuMapViews[ id ].view;
      });
      const mvsRef = { 'MapRef': wmvRef.view };
      let idKey = 0;
      const mvsMap = Object.fromEntries( mvOthers.map( mv => [ 'Map' + ++idKey, mv ] ) );
      const mvs = { ...mvsRef, ...mvsMap };
      setMapViews( mvs );
    }
...

  if(
    ! props.hasOwnProperty('useMapWidgetIds') ||
    ! props.useMapWidgetIds ||
    props.useMapWidgetIds.length !== 1
  ) return;

  return(
    <JimuMapViewComponent
      useMapWidgetId={props.useMapWidgetIds[0]}
      onViewsCreate={handlerViewsCreate}
      onActiveViewChange={handlerActiveViewChange}
   />
  )
}


...

export default function Widget(props: AllWidgetProps<any>) { return (
<div style={divStyle}>
{ createMapView() }
<label className={css}>
...

 
0 Kudos