Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map object fails to initialize when called from an existing Item #2109

Open
ccone-pattern opened this issue Oct 14, 2024 · 1 comment
Open
Assignees
Labels

Comments

@ccone-pattern
Copy link

Describe the bug
Map object fails to populate given an Item of type: WebMap that was previously generated and saved from python. This map item is fully interactable within AGOL.

To Reproduce
Steps to reproduce the behavior:

class MapHandler(Handler):

    """
    A `Handler` object that creates and updates map items in AGOL.

    :Attributes:
    :gis: an authenticated `GIS` object.
    :map_id: a string representing the item-id of the web map to be handled.
    :map_properties: a dictionary containing map properties passed to [`arcgis.map.Map().save`](https://developers.arcgis.com/python/latest/api-reference/arcgis.map.toc.html#arcgis.map.Map.save)  
    :wdir: a string defining the folder to create or move the map within AGOL profile.
    """

    gis: GIS = None
    ":attribute gis: an authenticated `GIS` object."
    map_id: str = None
    ":attribute map_id: a string representing the item-id of the web map to be handled."
    map_properties: dict = None
    ":attribute map_properties: a dictionary containing map properties passed to [arcgis.map.Map().save](https://developers.arcgis.com/python/latest/api-reference/arcgis.map.toc.html#arcgis.map.Map.save)  "
    wdir: str = None
    ":attribute wdir: a string defining the folder to create or move the map within AGOL profile."
    basemap: str = "topo-vector"
 
@classmethod
    def update(cls, layer_items: List[Item]) -> Map:
        """
        Updates the web map by removing all existing layers and adding those provided as the argument `layers`.

        :param layers: List of `Item`, `FeatureLayer`, or `FeatureLayerCollection` objects to add to an existing map.
        :returns: Resulting `Map` created with the given `layers`.
        :rtype: :class:`arcgis.map.Map <https://developers.arcgis.com/python/latest/api-reference/arcgis.map.toc.html#arcgis.map.Map>`

        .. note::

            Given the complexity of the `arcgis` Python API, we chose to remove all layers instead of checking if each layer is contained within the provided list of layers to update the map.

            Testing with the following logic revealed that an `Item` added to a map will be transformed to its child entity (e.g., `FeatureLayer` or `GroupLayer`).

            .. code-block:: python
                
                if lyr not in map.content.layers:
                   map.content.add(lyr)
            
            
            Inconsistencies in the APIs across these implementations made it cumbersome to develop, and we saw no limitation in simply removing everything from the map and then re-adding.
            Users should provide *all* layers they want in the resulting map, not just those they want to add.
        """
        item = cls.gis.content.get(cls.map_id)
        if cls.wdir:
            folder_content = cls.gis.content.folders.get(cls.wdir).list() # Item object does not appear to contain a `folder` attribute as of arcgis 2.4.0 
            if item not in folder_content:
                item.move(cls.wdir)

        wm = Map(item)
        wm.basemap.basemap = cls.basemap
        wm.content.remove_all()
        for item in layer_items:
            # lyr = FeatureCollection.fromitem(item)
            wm.content.add(item)

        success = wm.update()
        if success:
            print(f"Successfully updated map: {cls.map_properties} with {len(wm.content.layers)} layers.")
        else:
            raise RuntimeError(f"Failed to update map item {cls.map_id}")
        return wm

error:

                ^^^^^^
  File "C:\Users\Charlie.Cone\repos\Field Maps Deployment Tool\deploy_field_maps\main.py", line 15, in main
    wm = MapHandler.upsert(layers)
         ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Charlie.Cone\repos\Field Maps Deployment Tool\deploy_field_maps\handlers.py", line 217, in upsert
    return cls.update(layers)
           ^^^^^^^^^^^^^^^^^^
  File "C:\Users\Charlie.Cone\repos\Field Maps Deployment Tool\deploy_field_maps\handlers.py", line 186, in update
    wm = Map(item)
         ^^^^^^^^^
  File "C:\Users\Charlie.Cone\AppData\Local\anaconda3\envs\esri-source\Lib\site-packages\arcgis\map\map_widget.py", line 254, in __init__
    self._setup_webmap_properties(item)
  File "C:\Users\Charlie.Cone\AppData\Local\anaconda3\envs\esri-source\Lib\site-packages\arcgis\map\map_widget.py", line 447, in _setup_webmap_properties
    self._update_source()
  File "C:\Users\Charlie.Cone\AppData\Local\anaconda3\envs\esri-source\Lib\site-packages\arcgis\map\map_widget.py", line 488, in _update_source
    self._webmap_dict = self._webmap.dict()
                        ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Charlie.Cone\AppData\Local\anaconda3\envs\esri-source\Lib\site-packages\arcgis\map\_dataclasses\_webmap_spec.py", line 73, in dict
    d = super().model_dump(
        ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Charlie.Cone\AppData\Local\anaconda3\envs\esri-source\Lib\site-packages\pydantic\main.py", line 364, in model_dump
    return self.__pydantic_serializer__.to_python(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'MockValSer' object cannot be converted to 'SchemaSerializer'

Screenshots
image
screenshot from vscode debugger displaying valid item fetched directly before initializing Map

Expected behavior
A valid Map object based on the item fetched from GIS.content
and/or
Explicit description of any invalid json syntax in WebMap's definition

Platform (please complete the following information):

  • OS: Windows 64x
  • Browser Edge
  • Python API Version 2.4.0
    Additional context
    Python 3.12.7
@ccone-pattern ccone-pattern changed the title Map object fails to initialize when called from an Item Map object fails to initialize when called from an existing Item Oct 14, 2024
@nanaeaubry
Copy link
Contributor

@ccone-pattern When you say the map was previously made with python do you mean this new version of mapping or with the older WebMap class?

Can you post a screenshot of the actual issue or provide an example item for this? The one you have posted suggests that something is being passed into the dataclasses that it does not recognize.

Also this may not be it but can you initialize the map with Map(item=item) ? The first parameter (by user demand) is location and not item. We have a check in the code but it's not always foolproof.

@nanaeaubry nanaeaubry self-assigned this Oct 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants