Hi Robert Scheitlin, GISP / Experts,
I am trying to switch from 2D to 3D view and vice versa (followed the link Switch view from 2D to 3D | ArcGIS API for JavaScript 4.15 ) and facing some issues.
The layers are mainly oil pipelines, well pads, facilities, etc.
Each of the Feature Layer are added manually via FeatureService/0. Since the renderer is different for 2D and 3D, I need to be able to change the renderer to and re-render the map.
Snippet of code below:
var map = new Map({basemap: "topo-vector"});var switchButton = document.getElementById("switch-btn");var appConfig = {mapView: null,sceneView: null,activeView: null,container: "viewDiv",pipelineRenderer: null,wellpadRenderer: null,facilityRenderer: null};var initialViewParams = {zoom: 13,center: [-90.026, 20.745],container: appConfig.container,map: map};// create 2D view and and set activeappConfig.mapView = createView(initialViewParams, "2d");appConfig.activeView = appConfig.mapView;// create 3D view, won't initialize until container is setinitialViewParams.container = null;appConfig.sceneView = createView(initialViewParams, "3d");var view = appConfig.activeView;// Convenience function for creating a 2D or 3D viewfunction createView(params, type) {var view;var is2D = type === "2d";if (is2D) {view = new MapView(params);return view;} else {params.camera = {position: {x: -90.02,y: 20.745,z: 2000 // meters},tilt: 75};view = new SceneView(params);}return view;}................//Set inital RenderersappConfig.pipelineRenderer = pipelineRenderer;appConfig.wellpadRenderer = wellpadRenderer;appConfig.facilityRenderer = facilityRenderer;// Switch the view between 2D and 3D each time the button is clickedswitchButton.addEventListener("click", function () {switchView();});// Switches the view from 2D to 3D and vice versafunction switchView() {var is3D = appConfig.activeView.type === "3d";// var activeViewpoint = appConfig.activeView.viewpoint.clone();// Remove the reference to the container for the previous viewappConfig.activeView.container = null;if (is3D) {// if the input view is a SceneView, set the viewpoint on the// mapView instance. Set the container on the mapView and flag// it as the active view// appConfig.mapView.viewpoint = activeViewpoint;// appConfig.mapView.container = appConfig.container;appConfig.activeView = appConfig.mapView;switchButton.value = "3D";appConfig.pipelineRenderer = pipelineRenderer;appConfig.wellpadRenderer = wellpadRenderer;appConfig.facilityRenderer = facilityRenderer;} else {// appConfig.sceneView.viewpoint = activeViewpoint;appConfig.sceneView.container = appConfig.container;appConfig.activeView = appConfig.sceneView;switchButton.value = "2D";// var pipeLineLayer = map.findLayerById("idPipelineLayer");// var facilityLayer = map.findLayerById("idFacilityLayer");// var wellpadLayer = map.findLayerById("idWellpadLayer");// pipeLineLayer.set(pipelineRenderer3D);// pipeLineLayer.refresh();// facilityLayer.set(facilityRenderer3D);// facilityLayer.refresh();// wellpadLayer.set(wellpadRenderer3D);// wellpadLayer.refresh();appConfig.pipelineRenderer = pipelineRenderer3D;appConfig.wellpadRenderer = wellpadRenderer3D;appConfig.facilityRenderer = facilityRenderer3D;}}
The issue is right when it calls the
appConfig.activeView.container = null;
it starts throwing errors in the console as below:
and also below error on complete execution
And my 3D renderers don't come up.
NOTE:
Thanks in advance.
Solved! Go to Solution.
George,
In this sample I do not have any issue with that.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>Switch view from 2D to 3D - 4.15</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#infoDiv {
position: absolute;
top: 15px;
left: 60px;
}
#infoDiv input {
border: none;
box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 2px;
}
</style>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.15/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.15/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/views/SceneView",
"esri/layers/FeatureLayer"
], function(Map, MapView, SceneView, FeatureLayer) {
var switchButton = document.getElementById("switch-btn");
var appConfig = {
mapView: null,
sceneView: null,
activeView: null,
container: "viewDiv" // use same container for views
};
var initialViewParams = {
zoom: 12,
center: [-122.43759993450347, 37.772798684981126],
container: appConfig.container
};
var featureLayer = new FeatureLayer({
url:
"https://services.arcgis.com/Zs2aNLFN00jrS4gG/arcgis/rest/services/PedInjuryCounts_2013/FeatureServer/0"
});
// Create objectSymbol and add to renderer
var objectSymbol = {
type: "point-3d", // autocasts as new PointSymbol3D()
symbolLayers: [
{
type: "object", // autocasts as new ObjectSymbol3DLayer()
width: 50,
height: 500,
depth: 50,
resource: {
primitive: "cylinder"
},
material: {
color: "#FFD700"
}
}
]
};
var objectSymbolRenderer = {
type: "simple", // autocasts as new SimpleRenderer()
symbol: objectSymbol
};
var map = new Map({
basemap: "topo-vector",
ground: "world-elevation",
layers: [featureLayer]
});
// create 2D view and and set active
appConfig.mapView = createView(initialViewParams, "2d");
appConfig.mapView.map = map;
appConfig.activeView = appConfig.mapView;
appConfig.mapView.when(function(){
appConfig.injuryLayerRend2D = featureLayer.renderer;
})
// create 3D view, won't initialize until container is set
initialViewParams.container = null;
initialViewParams.map = map;
appConfig.sceneView = createView(initialViewParams, "3d");
// switch the view between 2D and 3D each time the button is clicked
switchButton.addEventListener("click", function() {
switchView();
});
// Switches the view from 2D to 3D and vice versa
function switchView() {
var is3D = appConfig.activeView.type === "3d";
var activeViewpoint = appConfig.activeView.viewpoint.clone();
// remove the reference to the container for the previous view
appConfig.activeView.container = null;
if (is3D) {
// if the input view is a SceneView, set the viewpoint on the
// mapView instance. Set the container on the mapView and flag
// it as the active view
featureLayer.renderer = appConfig.injuryLayerRend2D;
appConfig.mapView.viewpoint = activeViewpoint;
appConfig.mapView.container = appConfig.container;
appConfig.activeView = appConfig.mapView;
switchButton.value = "3D";
} else {
//featureLayer.renderer = objectSymbolRenderer;
appConfig.sceneView.viewpoint = activeViewpoint;
appConfig.sceneView.container = appConfig.container;
appConfig.activeView = appConfig.sceneView;
switchButton.value = "2D";
featureLayer.renderer = objectSymbolRenderer;
}
}
// convenience function for creating a 2D or 3D view
function createView(params, type) {
var view;
var is2D = type === "2d";
if (is2D) {
view = new MapView(params);
return view;
} else {
view = new SceneView(params);
}
return view;
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="infoDiv">
<input
class="esri-component esri-widget--button esri-widget esri-interactive"
type="button"
id="switch-btn"
value="3D"
/>
</div>
</body>
</html>
George,
In this sample I do not have any issue with that.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>Switch view from 2D to 3D - 4.15</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#infoDiv {
position: absolute;
top: 15px;
left: 60px;
}
#infoDiv input {
border: none;
box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 2px;
}
</style>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.15/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.15/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/views/SceneView",
"esri/layers/FeatureLayer"
], function(Map, MapView, SceneView, FeatureLayer) {
var switchButton = document.getElementById("switch-btn");
var appConfig = {
mapView: null,
sceneView: null,
activeView: null,
container: "viewDiv" // use same container for views
};
var initialViewParams = {
zoom: 12,
center: [-122.43759993450347, 37.772798684981126],
container: appConfig.container
};
var featureLayer = new FeatureLayer({
url:
"https://services.arcgis.com/Zs2aNLFN00jrS4gG/arcgis/rest/services/PedInjuryCounts_2013/FeatureServer/0"
});
// Create objectSymbol and add to renderer
var objectSymbol = {
type: "point-3d", // autocasts as new PointSymbol3D()
symbolLayers: [
{
type: "object", // autocasts as new ObjectSymbol3DLayer()
width: 50,
height: 500,
depth: 50,
resource: {
primitive: "cylinder"
},
material: {
color: "#FFD700"
}
}
]
};
var objectSymbolRenderer = {
type: "simple", // autocasts as new SimpleRenderer()
symbol: objectSymbol
};
var map = new Map({
basemap: "topo-vector",
ground: "world-elevation",
layers: [featureLayer]
});
// create 2D view and and set active
appConfig.mapView = createView(initialViewParams, "2d");
appConfig.mapView.map = map;
appConfig.activeView = appConfig.mapView;
appConfig.mapView.when(function(){
appConfig.injuryLayerRend2D = featureLayer.renderer;
})
// create 3D view, won't initialize until container is set
initialViewParams.container = null;
initialViewParams.map = map;
appConfig.sceneView = createView(initialViewParams, "3d");
// switch the view between 2D and 3D each time the button is clicked
switchButton.addEventListener("click", function() {
switchView();
});
// Switches the view from 2D to 3D and vice versa
function switchView() {
var is3D = appConfig.activeView.type === "3d";
var activeViewpoint = appConfig.activeView.viewpoint.clone();
// remove the reference to the container for the previous view
appConfig.activeView.container = null;
if (is3D) {
// if the input view is a SceneView, set the viewpoint on the
// mapView instance. Set the container on the mapView and flag
// it as the active view
featureLayer.renderer = appConfig.injuryLayerRend2D;
appConfig.mapView.viewpoint = activeViewpoint;
appConfig.mapView.container = appConfig.container;
appConfig.activeView = appConfig.mapView;
switchButton.value = "3D";
} else {
//featureLayer.renderer = objectSymbolRenderer;
appConfig.sceneView.viewpoint = activeViewpoint;
appConfig.sceneView.container = appConfig.container;
appConfig.activeView = appConfig.sceneView;
switchButton.value = "2D";
featureLayer.renderer = objectSymbolRenderer;
}
}
// convenience function for creating a 2D or 3D view
function createView(params, type) {
var view;
var is2D = type === "2d";
if (is2D) {
view = new MapView(params);
return view;
} else {
view = new SceneView(params);
}
return view;
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="infoDiv">
<input
class="esri-component esri-widget--button esri-widget esri-interactive"
type="button"
id="switch-btn"
value="3D"
/>
</div>
</body>
</html>