Add Image to Map for both 2D and 3D

683
2
12-29-2021 06:57 AM
kjtrottier
New Contributor II

Hello,

I'm looking at trying to add a geolocated image to a map using the JS API 4.x that works in both 2d and 3d.  Previously we only needed 2d and used a BaseDynamicLayer subclass to accomplish the task, however we are now working on implementing 3d to the map and need the image to display there as well.  Currently the BaseDynamicLayer is not supported in 3d and I was unable to find a suitable replacement which did what we needed in both 2d and 3d.

I've tried to implement other layer types and was unable to get them to work.  Is there a specific layer type I should direct my attention to or any plans to support the BaseDynamicLayer in 3d in the near future.

EDIT:

I realize I didn't include this in the original post but the image used is actually a string (data:image/png;base64,...) and the following is the subclass created to add it to the map

const CustomImageOverlay = BaseDynamicLayer.createSubclass({
        getImageUrl() {
          // Create a canvas DOM element and set its width and height to be the same as the picture
          if (!this.canvas) {
            this.canvas = document.createElement('canvas')
          }
          this.canvas.width = newImage.width;
          this.canvas.height = newImage.height;

          // The geographic coordinates of the upper left corner are converted to screen coordinates,
          // in order to obtain the starting point of the canvas drawing picture
          const upperLeftMapPoint = {
            x: xmin,
            y: ymax,
            spatialReference
          };
          const upperLeftScreenPoint = mapView.toScreen(upperLeftMapPoint);

          //Calculate the width and height of the canvas drawn picture according to the extent range
          //Lower left corner
          const lowerLeftMapPoint = {
            x: xmin,
            y: ymin,
            spatialReference
          };
          const lowerLeftScreenPoint = mapView.toScreen(lowerLeftMapPoint);

          //Upper right corner
          const upperRightMapPoint = {
            x: xmax,
            y: ymax,
            spatialReference
          };
          const upperRightScreenPoint = mapView.toScreen(upperRightMapPoint);

          this.canvas.getContext('2d').drawImage(
            newImage,
            upperLeftScreenPoint.x,
            upperLeftScreenPoint.y,
            Math.abs(upperRightScreenPoint.x - lowerLeftScreenPoint.x),
            Math.abs(upperRightScreenPoint.y - lowerLeftScreenPoint.y)
          );
          return this.canvas;
        },
        fetchImage(){
          const canvas = this.getImageUrl();
          return canvas;
        }
      });

newImage is the string, and xmin, xmax, ymin, ymax are all defined previously based on location.

I know canvas.getContext('2d').drawImage() renders a 2d image and could be the reason this doesn't work but I haven't found a way to actually get it work (in either 2D or 3D) trying a different approach with the subclass methods or with any other layer within the Esri API.

Any advice or tips would be greatly appreciated

Thank You

0 Kudos
2 Replies
JohnGrayson
Esri Regular Contributor

I don't see in the doc where it says the BaseDynamicLayer is not supported in a SceneView.  I modified one of the samples to load it in a SceneView and it worked: https://codepen.io/john-grayson/pen/LYzQWPg 

kjtrottier
New Contributor II

Sorry for the late response,

It mentions no 3D support in the Layer page in the table titled "Layers for querying, visualizing, analyzing data" if you scroll down to where it mentions the BaseDynamicLayer and look in the limitations column.

EDIT:

I was able to get your example working in both 2d and 3d, so it appears as though the layer page needs to be updated, unless I'm misinterpreting what it means when it says 3d is not supported.

However I apologize for not including as much info as I should in the base question which I have now updated as the situation I am in is a little more complicated and different due to the nature of the image I need to display, if anyone has any ideas please let me know.

0 Kudos