arcgis-media-layers

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

ArcGIS Media Layers

ArcGIS Media Layers

Use this skill for overlaying images, videos, and animated content on maps.
使用该技能可在地图上叠加图片、视频和动画内容。

MediaLayer Basics

MediaLayer 基础入门

Create MediaLayer with Images

创建含图片的MediaLayer

javascript
import MediaLayer from "@arcgis/core/layers/MediaLayer.js";
import ImageElement from "@arcgis/core/layers/support/ImageElement.js";
import ExtentAndRotationGeoreference from "@arcgis/core/layers/support/ExtentAndRotationGeoreference.js";
import Extent from "@arcgis/core/geometry/Extent.js";

const imageElement = new ImageElement({
  image: "https://example.com/historical-map.png",
  georeference: new ExtentAndRotationGeoreference({
    extent: new Extent({
      xmin: -10047456,
      ymin: 3486722,
      xmax: -10006982,
      ymax: 3514468,
      spatialReference: { wkid: 102100 }
    })
  })
});

const mediaLayer = new MediaLayer({
  source: [imageElement],
  title: "Historical Map"
});

map.add(mediaLayer);
javascript
import MediaLayer from "@arcgis/core/layers/MediaLayer.js";
import ImageElement from "@arcgis/core/layers/support/ImageElement.js";
import ExtentAndRotationGeoreference from "@arcgis/core/layers/support/ExtentAndRotationGeoreference.js";
import Extent from "@arcgis/core/geometry/Extent.js";

const imageElement = new ImageElement({
  image: "https://example.com/historical-map.png",
  georeference: new ExtentAndRotationGeoreference({
    extent: new Extent({
      xmin: -10047456,
      ymin: 3486722,
      xmax: -10006982,
      ymax: 3514468,
      spatialReference: { wkid: 102100 }
    })
  })
});

const mediaLayer = new MediaLayer({
  source: [imageElement],
  title: "Historical Map"
});

map.add(mediaLayer);

Multiple Images

多图片叠加

javascript
const imageInfos = [
  {
    url: "image1.png",
    extent: { xmin: -100, ymin: 30, xmax: -90, ymax: 40 }
  },
  {
    url: "image2.png",
    extent: { xmin: -95, ymin: 35, xmax: -85, ymax: 45 }
  }
];

const imageElements = imageInfos.map(info => new ImageElement({
  image: info.url,
  georeference: new ExtentAndRotationGeoreference({
    extent: new Extent({
      ...info.extent,
      spatialReference: { wkid: 4326 }
    })
  })
}));

const mediaLayer = new MediaLayer({
  source: imageElements
});
javascript
const imageInfos = [
  {
    url: "image1.png",
    extent: { xmin: -100, ymin: 30, xmax: -90, ymax: 40 }
  },
  {
    url: "image2.png",
    extent: { xmin: -95, ymin: 35, xmax: -85, ymax: 45 }
  }
];

const imageElements = imageInfos.map(info => new ImageElement({
  image: info.url,
  georeference: new ExtentAndRotationGeoreference({
    extent: new Extent({
      ...info.extent,
      spatialReference: { wkid: 4326 }
    })
  })
}));

const mediaLayer = new MediaLayer({
  source: imageElements
});

Georeferencing Methods

地理参考方法

Extent and Rotation

范围与旋转

javascript
const georeference = new ExtentAndRotationGeoreference({
  extent: new Extent({
    xmin: -122.5,
    ymin: 37.5,
    xmax: -122.0,
    ymax: 38.0,
    spatialReference: { wkid: 4326 }
  }),
  rotation: 15 // Degrees clockwise
});
javascript
const georeference = new ExtentAndRotationGeoreference({
  extent: new Extent({
    xmin: -122.5,
    ymin: 37.5,
    xmax: -122.0,
    ymax: 38.0,
    spatialReference: { wkid: 4326 }
  }),
  rotation: 15 // Degrees clockwise
});

Control Points (Corners)

控制点(四角定位)

javascript
import ControlPointsGeoreference from "@arcgis/core/layers/support/ControlPointsGeoreference.js";

const georeference = new ControlPointsGeoreference({
  controlPoints: [
    {
      sourcePoint: { x: 0, y: 0 },           // Top-left of image (pixels)
      mapPoint: { x: -122.5, y: 38.0 }       // Map coordinates
    },
    {
      sourcePoint: { x: 1000, y: 0 },        // Top-right
      mapPoint: { x: -122.0, y: 38.0 }
    },
    {
      sourcePoint: { x: 1000, y: 800 },      // Bottom-right
      mapPoint: { x: -122.0, y: 37.5 }
    },
    {
      sourcePoint: { x: 0, y: 800 },         // Bottom-left
      mapPoint: { x: -122.5, y: 37.5 }
    }
  ],
  width: 1000,  // Image width in pixels
  height: 800   // Image height in pixels
});
javascript
import ControlPointsGeoreference from "@arcgis/core/layers/support/ControlPointsGeoreference.js";

const georeference = new ControlPointsGeoreference({
  controlPoints: [
    {
      sourcePoint: { x: 0, y: 0 },           // Top-left of image (pixels)
      mapPoint: { x: -122.5, y: 38.0 }       // Map coordinates
    },
    {
      sourcePoint: { x: 1000, y: 0 },        // Top-right
      mapPoint: { x: -122.0, y: 38.0 }
    },
    {
      sourcePoint: { x: 1000, y: 800 },      // Bottom-right
      mapPoint: { x: -122.0, y: 37.5 }
    },
    {
      sourcePoint: { x: 0, y: 800 },         // Bottom-left
      mapPoint: { x: -122.5, y: 37.5 }
    }
  ],
  width: 1000,  // Image width in pixels
  height: 800   // Image height in pixels
});

Video Elements

视频元素

javascript
import VideoElement from "@arcgis/core/layers/support/VideoElement.js";

const videoElement = new VideoElement({
  video: "https://example.com/timelapse.mp4",
  georeference: new ExtentAndRotationGeoreference({
    extent: new Extent({
      xmin: -122.5,
      ymin: 37.5,
      xmax: -122.0,
      ymax: 38.0,
      spatialReference: { wkid: 4326 }
    })
  })
});

const mediaLayer = new MediaLayer({
  source: [videoElement]
});

// Control video playback
videoElement.content.play();
videoElement.content.pause();
videoElement.content.currentTime = 30; // Seek to 30 seconds
javascript
import VideoElement from "@arcgis/core/layers/support/VideoElement.js";

const videoElement = new VideoElement({
  video: "https://example.com/timelapse.mp4",
  georeference: new ExtentAndRotationGeoreference({
    extent: new Extent({
      xmin: -122.5,
      ymin: 37.5,
      xmax: -122.0,
      ymax: 38.0,
      spatialReference: { wkid: 4326 }
    })
  })
});

const mediaLayer = new MediaLayer({
  source: [videoElement]
});

// Control video playback
videoElement.content.play();
videoElement.content.pause();
videoElement.content.currentTime = 30; // Seek to 30 seconds

Animated GIF

GIF动图

javascript
// Animated GIFs work like regular images
const gifElement = new ImageElement({
  image: "https://example.com/weather-animation.gif",
  georeference: new ExtentAndRotationGeoreference({
    extent: new Extent({
      xmin: -130,
      ymin: 25,
      xmax: -65,
      ymax: 50,
      spatialReference: { wkid: 4326 }
    })
  })
});

const mediaLayer = new MediaLayer({
  source: [gifElement]
});
javascript
// Animated GIFs work like regular images
const gifElement = new ImageElement({
  image: "https://example.com/weather-animation.gif",
  georeference: new ExtentAndRotationGeoreference({
    extent: new Extent({
      xmin: -130,
      ymin: 25,
      xmax: -65,
      ymax: 50,
      spatialReference: { wkid: 4326 }
    })
  })
});

const mediaLayer = new MediaLayer({
  source: [gifElement]
});

Layer Configuration

图层配置

Opacity and Blend Mode

透明度与混合模式

javascript
const mediaLayer = new MediaLayer({
  source: [imageElement],
  opacity: 0.7,
  blendMode: "multiply" // normal, multiply, luminosity, etc.
});

// Change opacity dynamically
mediaLayer.opacity = 0.5;

// Change blend mode
mediaLayer.blendMode = "luminosity";
javascript
const mediaLayer = new MediaLayer({
  source: [imageElement],
  opacity: 0.7,
  blendMode: "multiply" // normal, multiply, luminosity, etc.
});

// Change opacity dynamically
mediaLayer.opacity = 0.5;

// Change blend mode
mediaLayer.blendMode = "luminosity";

Element Opacity

元素透明度

javascript
// Individual element opacity
imageElement.opacity = 0.8;

// Update dynamically
document.getElementById("opacitySlider").addEventListener("input", (e) => {
  imageElement.opacity = e.target.value / 100;
});
javascript
// Individual element opacity
imageElement.opacity = 0.8;

// Update dynamically
document.getElementById("opacitySlider").addEventListener("input", (e) => {
  imageElement.opacity = e.target.value / 100;
});

Managing Source Elements

源元素管理

javascript
// Access source
const source = mediaLayer.source;

// Add elements
source.elements.add(newImageElement);
source.elements.addMany([element1, element2]);

// Remove elements
source.elements.remove(imageElement);
source.elements.removeAll();

// Get all elements
source.elements.forEach(element => {
  console.log(element.image || element.video);
});
javascript
// Access source
const source = mediaLayer.source;

// Add elements
source.elements.add(newImageElement);
source.elements.addMany([element1, element2]);

// Remove elements
source.elements.remove(imageElement);
source.elements.removeAll();

// Get all elements
source.elements.forEach(element => {
  console.log(element.image || element.video);
});

Interactive Control Points

交互式控制点

javascript
// Enable editing of georeference control points
const mediaLayerView = await view.whenLayerView(mediaLayer);

// Start editing
mediaLayerView.startEditing(imageElement);

// Stop editing
mediaLayerView.stopEditing();

// Listen for georeference changes
imageElement.watch("georeference", (newGeoreference) => {
  console.log("Georeference updated:", newGeoreference);
});
javascript
// Enable editing of georeference control points
const mediaLayerView = await view.whenLayerView(mediaLayer);

// Start editing
mediaLayerView.startEditing(imageElement);

// Stop editing
mediaLayerView.stopEditing();

// Listen for georeference changes
imageElement.watch("georeference", (newGeoreference) => {
  console.log("Georeference updated:", newGeoreference);
});

Complete Example

完整示例

html
<arcgis-map center="-89.93, 29.97" zoom="10">
  <arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-map>

<script type="module">
  import MediaLayer from "@arcgis/core/layers/MediaLayer.js";
  import ImageElement from "@arcgis/core/layers/support/ImageElement.js";
  import ExtentAndRotationGeoreference from "@arcgis/core/layers/support/ExtentAndRotationGeoreference.js";
  import Extent from "@arcgis/core/geometry/Extent.js";
  import Map from "@arcgis/core/Map.js";

  const viewElement = document.querySelector("arcgis-map");

  // Create image elements for historical maps
  const imageElements = [
    {
      name: "1891 Map",
      url: "https://example.com/map-1891.png",
      extent: { xmin: -10047456, ymin: 3486722, xmax: -10006982, ymax: 3514468 }
    },
    {
      name: "1920 Map",
      url: "https://example.com/map-1920.png",
      extent: { xmin: -10045000, ymin: 3488000, xmax: -10008000, ymax: 3516000 }
    }
  ].map(info => new ImageElement({
    image: info.url,
    georeference: new ExtentAndRotationGeoreference({
      extent: new Extent({
        ...info.extent,
        spatialReference: { wkid: 102100 }
      })
    })
  }));

  const mediaLayer = new MediaLayer({
    source: imageElements,
    title: "Historical Maps",
    blendMode: "normal"
  });

  viewElement.map = new Map({
    basemap: "topo-vector",
    layers: [mediaLayer]
  });
</script>
html
<arcgis-map center="-89.93, 29.97" zoom="10">
  <arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-map>

<script type="module">
  import MediaLayer from "@arcgis/core/layers/MediaLayer.js";
  import ImageElement from "@arcgis/core/layers/support/ImageElement.js";
  import ExtentAndRotationGeoreference from "@arcgis/core/layers/support/ExtentAndRotationGeoreference.js";
  import Extent from "@arcgis/core/geometry/Extent.js";
  import Map from "@arcgis/core/Map.js";

  const viewElement = document.querySelector("arcgis-map");

  // Create image elements for historical maps
  const imageElements = [
    {
      name: "1891 Map",
      url: "https://example.com/map-1891.png",
      extent: { xmin: -10047456, ymin: 3486722, xmax: -10006982, ymax: 3514468 }
    },
    {
      name: "1920 Map",
      url: "https://example.com/map-1920.png",
      extent: { xmin: -10045000, ymin: 3488000, xmax: -10008000, ymax: 3516000 }
    }
  ].map(info => new ImageElement({
    image: info.url,
    georeference: new ExtentAndRotationGeoreference({
      extent: new Extent({
        ...info.extent,
        spatialReference: { wkid: 102100 }
      })
    })
  }));

  const mediaLayer = new MediaLayer({
    source: imageElements,
    title: "Historical Maps",
    blendMode: "normal"
  });

  viewElement.map = new Map({
    basemap: "topo-vector",
    layers: [mediaLayer]
  });
</script>

Common Pitfalls

常见注意事项

  1. Coordinate systems: Ensure extent coordinates match the spatial reference
  2. Image loading: Large images may take time to load - consider using smaller/optimized images
  3. Control point order: Control points must be in correct order (top-left, top-right, bottom-right, bottom-left)
  4. CORS: Images from external servers need CORS headers
  5. Video autoplay: Browsers may block autoplay - require user interaction first
  1. 坐标系:确保范围坐标与空间参考匹配
  2. 图片加载:大图片加载耗时较长,建议使用优化后的小尺寸图片
  3. 控制点顺序:控制点必须按正确顺序排列(左上、右上、右下、左下)
  4. CORS设置:来自外部服务器的图片需要配置CORS请求头
  5. 视频自动播放:浏览器可能会阻止自动播放,需先触发用户交互