I have a simple map with polygons on graphics layer, i need to fade map outside that polygon and show polygon as a hole in the map. I get some relative answer in older version, but it is not helpful.
I want to show like this image
My code is below
<script>
require(["esri/views/MapView",
"esri/WebMap",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"esri/geometry/Polygon",
"esri/geometry/SpatialReference"
], function (MapView, WebMap, Graphic, GraphicsLayer, Polygon, SpatialReference) {
let validSymbol,
newDevelopmentGraphic;
/************************************************************
* Creates a new WebMap instance. A WebMap must reference
* a PortalItem ID that represents a WebMap saved to
* arcgis.com or an on-premise portal.
*
* To load a WebMap from an on-premise portal, set the portal
* url with esriConfig.portalUrl.
************************************************************/
var webmap = new WebMap({
portalItem: {
// autocasts as new PortalItem()
id: ""
}
});
/************************************************************
* Set the WebMap instance to the map property in a MapView.
************************************************************/
var view = new MapView({
map: webmap,
container: "viewDiv",
center: ['<?=$map_xy_coordinate['x']?>', '<?=$map_xy_coordinate['y']?>'],
zoom: 15
});
var graphicsLayer = new GraphicsLayer();
webmap.add(graphicsLayer);
view.when(function() {
// Add the boundary polygon and new lot polygon graphics
addGraphics();
});
function addGraphics() {
//pass geographic vertices
const vertices = <?php echo json_encode($map_ring_coordinate);?>;
const polygon = createGeometry(vertices);
//console.log(polygon);
validSymbol = createSymbol([0, 170, 255, 0.2], "solid", 2, [
255,
255,
255
]);
newDevelopmentGraphic = new Graphic({
geometry: polygon,
symbol: validSymbol,
attributes: {
newDevelopment: "new store"
}
});
graphicsLayer.addMany([newDevelopmentGraphic]);
}
function createGeometry(vertices) {
return new Polygon({
rings: vertices,
spatialReference: new SpatialReference({wkid:4326})
});
}
function createSymbol(color, style, width, outlineColor) {
return {
type: "simple-fill",
style: style,
color: color,
outline: {
color: outlineColor,
width: width
}
};
}
});
</script>
Solved! Go to Solution.
Rajni,
You can do something like this:
...
graphicsLayer.add(newDevelopmentGraphic);
var mapExtent = view.extent.expand(9);
var overlayGeom = geometryEngine.difference(mapExtent, newDevelopmentGraphic.geometry);
var symbol2 = {
type: "simple-fill",
style: "solid",
color: [129, 129, 129, 0.8],
outline: {
color: [255, 255, 255, 0],
width: 0
}
};
overLayGra = new Graphic({
geometry: overlayGeom,
symbol: symbol2
});
graphicsLayer.add(overLayGra);
}
But you would have to figure out how to update the overlay when the newDevelopmentGraphic is being moved or reshaped. I don't have any input on this since I do not think this is a good workflow. Of course you will have to add geometryEngine to your apps require array.
Rajni,
I get some relative answer in older version, but it is not helpful.
What relative answer in older version. A link would help. And why is it not helpful?
I find this link and it uses shape files that i don't use, and couldn't understand how to do it
Rajni,
You can do something like this:
...
graphicsLayer.add(newDevelopmentGraphic);
var mapExtent = view.extent.expand(9);
var overlayGeom = geometryEngine.difference(mapExtent, newDevelopmentGraphic.geometry);
var symbol2 = {
type: "simple-fill",
style: "solid",
color: [129, 129, 129, 0.8],
outline: {
color: [255, 255, 255, 0],
width: 0
}
};
overLayGra = new Graphic({
geometry: overlayGeom,
symbol: symbol2
});
graphicsLayer.add(overLayGra);
}
But you would have to figure out how to update the overlay when the newDevelopmentGraphic is being moved or reshaped. I don't have any input on this since I do not think this is a good workflow. Of course you will have to add geometryEngine to your apps require array.
Its not working, It only show overlay on whole map.
like this my polygon also covered with overlay
This is my code:
function addGraphics() {
//pass geographic vertices
const vertices = <?php echo json_encode($map_ring_coordinate);?>;
const polygon = createGeometry(vertices);
//console.log(polygon);
validSymbol = createSymbol([255, 121, 25, 0.0], "solid", 2, [
255, 121, 25
]);
newDevelopmentGraphic = new Graphic({
geometry: polygon,
symbol: validSymbol,
attributes: {
newDevelopment: "new store"
}
});
graphicsLayer.add(newDevelopmentGraphic);
var mapExtent = view.extent.expand(9);
var overlayGeom = geometryEngine.difference(mapExtent, newDevelopmentGraphic.geometry);
var symbol2 = {
type: "simple-fill",
style: "solid",
color: [129, 129, 129, 0.5],
outline: {
color: [255, 255, 255, 0],
width: 0
}
};
overLayGra = new Graphic({
geometry: overlayGeom,
symbol: symbol2
});
graphicsLayer.add(overLayGra);
}
I don't want to move and reshape the graphics so their is no need to think of it
Rajni,
Works fine for me. Compare the code to find your mistake.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Intro to MapView - Create a 2D map - 4.14</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.14/"></script>
<script>
require(["esri/views/MapView",
"esri/WebMap",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"esri/widgets/Sketch/SketchViewModel",
"esri/geometry/Polygon",
"esri/geometry/SpatialReference",
"esri/geometry/support/webMercatorUtils",
"esri/geometry/geometryEngine"
], function (MapView, WebMap, Graphic, GraphicsLayer, SketchViewModel, Polygon, SpatialReference, webMercatorUtils, geometryEngine) {
let sketchViewModel,
validSymbol,
newDevelopmentGraphic,
overLayGra;
/************************************************************
* Creates a new WebMap instance. A WebMap must reference
* a PortalItem ID that represents a WebMap saved to
* arcgis.com or an on-premise portal.
*
* To load a WebMap from an on-premise portal, set the portal
* url with esriConfig.portalUrl.
************************************************************/
var webmap = new WebMap({
portalItem: {
// autocasts as new PortalItem()
id: "a8e76ad6641b46978f148cba03ab3e2d"
}
});
/************************************************************
* Set the WebMap instance to the map property in a MapView.
************************************************************/
var view = new MapView({
map: webmap,
container: "viewDiv",
center: [175.9258624, -37.55590445],
zoom: 20
});
var graphicsLayer = new GraphicsLayer();
webmap.add(graphicsLayer);
setUpGraphicClickHandler();
view.when(function () {
// Add the boundary polygon and new lot polygon graphics
addGraphics();
// Create a new instance of sketchViewModel
sketchViewModel = new SketchViewModel({
view: view,
layer: graphicsLayer,
updateOnGraphicClick: false,
defaultUpdateOptions: {
// set the default options for the update operations
toggleToolOnClick: false // only reshape operation will be enabled
}
});
// Listen to sketchViewModel's update event to do
// graphic reshape or move validation
sketchViewModel.on(["update", "undo", "redo"], onGraphicUpdate);
sketchViewModel.update([newDevelopmentGraphic], {tool: "reshape"});
});
function onGraphicUpdate(event) {
// get the graphic as it is being updated
const graphic = event.graphics[0];
// check if the update event's the toolEventInfo.type is move-stop or reshape-stop
// then it means user finished moving or reshaping the graphic, call complete method.
// this will change update event state to complete and we will check the validity of the graphic location.
if (
event.toolEventInfo &&
(event.toolEventInfo.type === "move-stop" ||
event.toolEventInfo.type === "reshape-stop")
) {
sketchViewModel.complete();
} else if (event.state === "cancel" || event.state === "complete") {
// graphic moving or reshaping has been completed or cancelled
// if the graphic is in an illegal spot, call sketchviewmodel's update method again
// giving user a chance to correct the location of the graphic
sketchViewModel.update([graphic], {
tool: "reshape"
});
} else {
graphic.symbol = validSymbol;
}
}
// This function is called when a user clicks on the view.
function setUpGraphicClickHandler() {
view.on("click", function (event) {
// check if the sketch's state active if it is then that means
// the graphic is already being updated, no action required.
if (sketchViewModel.state === "active") {
return;
}
view.hitTest(event).then(function (response) {
var results = response.results;
// Check if the new development graphic was clicked and pass
// the graphic to sketchViewModel.update() with reshape tool.
//console.log(results);
results.forEach(function (result) {
console.log(result.mapPoint);
if (
result.graphic.layer === sketchViewModel.layer &&
result.graphic.attributes &&
result.graphic.attributes.newDevelopment
) {
sketchViewModel.update([result.graphic], {
tool: "reshape"
});
}
});
});
});
}
function addGraphics() {
const vertices = [
[175.9258624, -37.55590445],
[175.9258630667, -37.55587745],
[175.9258671333, -37.5557153],
[175.92626316670004, -37.5557216],
[175.92625955, -37.5558657],
[175.9262584333, -37.5559107333],
[175.9258624, -37.55590445]
];
const polygon = createGeometry(vertices);
validSymbol = createSymbol([255, 255, 255, 0.3], "solid", 2, [
255,121,5]);
newDevelopmentGraphic = new Graphic({
geometry: webMercatorUtils.geographicToWebMercator(polygon),
symbol: validSymbol,
attributes: {
newDevelopment: "new store"
}
});
graphicsLayer.add(newDevelopmentGraphic);
var mapExtent = view.extent.expand(9);
var overlayGeom = geometryEngine.difference(mapExtent, newDevelopmentGraphic.geometry);
var symbol2 = {
type: "simple-fill",
style: "solid",
color: [129, 129, 129, 0.8],
outline: {
color: [255, 255, 255, 0],
width: 0
}
};
overLayGra = new Graphic({
geometry: overlayGeom,
symbol: symbol2
});
graphicsLayer.add(overLayGra);
}
function createGeometry(vertices) {
return new Polygon({
rings: vertices,
spatialReference: new SpatialReference({
wkid: 4326
})
});
}
function createSymbol(color, style, width, outlineColor) {
return {
type: "simple-fill",
style: style,
color: color,
outline: {
color: outlineColor,
width: width,
style: "dash"
}
};
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>