This sample demonstrates how to add two different static images to a MediaLayer in a 2D MapView by specifying their geographic locations using ControlPointsGeoreference.
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 images in map space.
The first image is a historic geology map of Telluride Colorado downloaded from the USGS. The geology map is georeferenced with an array of four control points. The latitude and longitude (North American Datum 1927) are labeled on the corners of the map frame, facilitating defining control points.
The second image is a historic fire insurance map of downtown Denver Colorado downloaded from wikimedia.org. The historic Denver map was georeferenced with an array of four control points.
How it works
First, an array of control points is defined.
// four points representing known map coordinates on the MediaLayer's ImageElement
const swCornerMapPoint = new Point({ x: -107.875, y: 37.875, spatialReference });
const nwCornerMapPoint = new Point({ x: -107.875, y: 38, spatialReference });
const neCornerMapPoint = new Point({ x: -107.75, y: 38, spatialReference });
const seCornerMapPoint = new Point({ x: -107.75, y: 37.875, spatialReference });
// create a GraphicsLayer to show the four points on the Map
const graphicsLayer = new GraphicsLayer({
graphics: [
createGraphic(swCornerMapPoint, "green", 0),
createGraphic(nwCornerMapPoint, "purple", 1),
createGraphic(neCornerMapPoint, "blue", 2),
createGraphic(seCornerMapPoint, "red", 3)
]
});
// 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 space
const swCornerControlPoint = {
sourcePoint: { x: 89, y: 1918 },
mapPoint: swCornerMapPoint
};
const nwCornerControlPoint = {
sourcePoint: { x: 83, y: 101 },
mapPoint: nwCornerMapPoint
};
const neCornerControlPoint = {
sourcePoint: { x: 1508, y: 97 },
mapPoint: neCornerMapPoint
};
const seCornerControlPoint = {
sourcePoint: { x: 1517, y: 1906 },
mapPoint: seCornerMapPoint
};
const controlPoints = [
swCornerControlPoint,
nwCornerControlPoint,
neCornerControlPoint,
seCornerControlPoint
];
Then, the MediaLayer is initialized with the ImageElement and ControlPointsGeoreference as shown below:
// georeference for the imageElement using the control points,
// image width, and image height
const controlPointsGeoreference = new ControlPointsGeoreference({ controlPoints, width: 1585, height: 2048 });
const imageElement = new ImageElement({
image:
"https://arcgis.github.io/arcgis-samples-javascript/sample-data/media-layer/telluride/TellurideQuad.webp",
georeference: controlPointsGeoreference
});
const mediaLayer = new MediaLayer({
source: [imageElement],
title: "Geologic Map of the Telluride Quadrangle, Southwestern Colorado",
copyright: "Wilbur S Burbank and Robert G. Luedke, 1966",
spatialReference
});
Using the SketchViewModel and setting
updateOnGraphicClick to true
allows the user to move the control points on the map.
// use the SketchViewModel to allow updating the graphics and control points
sketch.layer = graphicsLayer;
sketch.on("update", (event) => {
if (event.toolEventInfo?.type === "move-start") {
imageElement.opacity = 0.3;
}
if (event.toolEventInfo?.type === "move-stop") {
imageElement.opacity = 0.9;
}
updateGeoreference(graphicsLayer.graphics, controlPointsGeoreference);
});
sketch.on("redo", () => {
updateGeoreference(graphicsLayer.graphics, controlPointsGeoreference);
});
sketch.on("undo", () => {
updateGeoreference(graphicsLayer.graphics, controlPointsGeoreference);
});
Switching between the locations of the two different MediaLayers is easy using the Bookmarks widget. The sample uses the bookmark-select event listener to add the appropriate MediaLayer to the map after removing the initial MediaLayer.
// when a bookmark is selected add the appropriate MediaLayer
bookmarks.on("bookmark-select", (event) => {
if (event.bookmark.name === "Telluride Geology") {
map.removeAll();
addTellurideGeologyMediaLayer();
}
if (event.bookmark.name === "Sanborn Fire Insurance Map from Denver (1887)") {
map.removeAll();
addDenverInsuranceMediaLayer();
}
});