This sample demonstrates adding a historical map as a MediaLayer in a Map Component. The map represents the First Battle of Manassas during the US Civil War on July 21, 1861. It's georeferenced using control points to align it with the modern basemap.
A control point is composed of a sourcePoint, representing a point on the element measured in pixels from the top left corner, and a mapPoint, a known geographic location. This allows us to position the image in map space.
We also set the MediaLayerView interactive property to true
to enable users to reposition the media layer on the map. When you click on the media layer view, the reshape tool will be active and allow you to move the individual control points. You can also activate the transform tool by clicking on the appropriate action at the bottom of the screen, allowing you to resize and rotate the whole image. Several keyboard shortcuts are available to help place the image and are described in a table in the top right corner of the map.
How it works
First, an array of control points is defined.
// Define four points representing known map coordinates on the MediaLayer's ImageElement.
const mapPoint0 = new Point({
x: -8635420,
y: 4693931,
spatialReference: { wkid: 102100 }
});
const mapPoint1 = new Point({
x: -8631401,
y: 4699148,
spatialReference: { wkid: 102100 }
});
const mapPoint2 = new Point({
x: -8619568,
y: 4700860,
spatialReference: { wkid: 102100 }
});
const mapPoint3 = new Point({
x: -8620170,
y: 4692018,
spatialReference: { wkid: 102100 }
});
// Create an array of four control points composed of a sourcePoint, a point
// on the image element in pixels, and a mapPoint which is the location of the
// sourcePoint in map coordinates.
const controlPoint0 = {
sourcePoint: { x: 2108, y: 3070 },
mapPoint: mapPoint0
};
const controlPoint1 = {
sourcePoint: { x: 3425, y: 1365 },
mapPoint: mapPoint1
};
const controlPoint2 = {
sourcePoint: { x: 7313, y: 794 },
mapPoint: mapPoint2
};
const controlPoint3 = {
sourcePoint: { x: 7120, y: 3685 },
mapPoint: mapPoint3
};
const controlPoints = [controlPoint0, controlPoint1, controlPoint2, controlPoint3];
Then, the MediaLayer is initialized with the ImageElement and ControlPointsGeoreference.
// Create a georeference for the image element using the control points,
// image height, and image width.
const georeference = new ControlPointsGeoreference({
controlPoints,
height: 5636,
width: 8891
});
// Create a new image element with the image url and georeference.
const imageElement = new ImageElement({
image:
"https://arcgis.github.io/arcgis-samples-javascript/sample-data/media-layer/battle-of-first-manassas.jpg",
georeference
});
// Create a new MediaLayer with the image element.
const mediaLayer = new MediaLayer({
source: imageElement,
title: "The Battle of First Manassas",
copyright: "United States. National Park Service, Public domain, via Wikimedia Commons"
});
After the map is ready, we add the media layer to the map and set the MediaLayerView interactive property to true
to enable interactive placement of the media layer.
// If the map is not ready, add an event listener to wait for the map to be ready
// and call the handleArcgisMapReady function. Otherwise, call
// the handleArcgisMapReady function immediately.
if (!arcgisMap?.ready) {
arcgisMap?.addEventListener("arcgisViewReadyChange", handleArcgisMapReady, {
once: true
});
} else {
handleArcgisMapReady();
}
// Define a function that executes after the map is ready.
async function handleArcgisMapReady() {
// Add the media layer to the map.
arcgisMap?.addLayer(mediaLayer);
// Wait for the media layer view to be available and set it to the
// mediaLayerView variable.
mediaLayerView = await arcgisMap?.whenLayerView(mediaLayer);
// Set the interaction options tool to reshape.
mediaLayerView.interactionOptions.tool = "reshape";
// Set the media layer view's interactive property to true and when users
// click on the layer view the reshape tool will activate.
mediaLayerView.interactive = true;
}