I am creating a viewshed analysis application using ArcGIS' Viewshed Sample. My application involves placing multiple markers at specific locations and computing each marker's viewshed on load:
function drawResultData(result) {
var resultFeatures = result.results[0].value.features;
// Assign each resulting graphic a symbol
var viewshedGraphics = resultFeatures.map(function(feature) {
feature.symbol = fillSymbol;
return feature;
});
// Add the resulting graphics to the graphics layer
graphicsLayer.addMany(viewshedGraphics);
The ArcGIS JS API has an example of scaling markers based on zoom, but it uses a SimpleRenderer that is passed into a FeatureLayer. Unfortunately, my application only uses GraphicsLayers, which do not support renderers.
Is there a way to make Graphics on a GraphicsLayer scale based on zoom? If not, how could I modify the viewshed sample to use a FeatureLayer instead?
Solved! Go to Solution.
Hi there,
You can use client-side FeatureLayer to achieve what you are asking. This sample shows you how to create a client-side feature layer and add/remove features from it at runtime with the use of FeatureLayer.applyEdits.
In any case, this is the workflow you can have.
1. Initialize an empty feature collection as shown below:
const layer = new FeatureLayer({
fields: [
{
name: "ObjectID",
alias: "ObjectID",
type: "oid"
},
{
name: "Name",
alias: "Name",
type: "string"
},
{
name: "Type",
alias: "Type",
type: "string"
}
],
objectIdField: "ObjectID",
geometryType: "point", // =>>> MATCH THE GEOMETRY TYPE
spatialReference: { wkid: 4326 },
source: [], // adding an empty feature collection
renderer: { // =>>> MATCH THE RENDERER TYPE
type: "simple",
symbol: {
type: "web-style", // =>>> MATCH THE SYMBOL TYPE
styleName: "Esri2DPointSymbolsStyle",
name: "landmark"
}
},
popupTemplate: {
title: "{Name}"
}
});
2. Then once you have the resultFeatures, use FeatureLayer.applyEdits to add the features.
const addEdits = {
addFeatures: graphics
};
layer.applyEdits(addEdits).then(function(results) {
// feature are added... Now you can query the features
})
.catch(function(error){
// apply edits error
});
Hope this helps,
-Undrral
Hi there,
You can use client-side FeatureLayer to achieve what you are asking. This sample shows you how to create a client-side feature layer and add/remove features from it at runtime with the use of FeatureLayer.applyEdits.
In any case, this is the workflow you can have.
1. Initialize an empty feature collection as shown below:
const layer = new FeatureLayer({
fields: [
{
name: "ObjectID",
alias: "ObjectID",
type: "oid"
},
{
name: "Name",
alias: "Name",
type: "string"
},
{
name: "Type",
alias: "Type",
type: "string"
}
],
objectIdField: "ObjectID",
geometryType: "point", // =>>> MATCH THE GEOMETRY TYPE
spatialReference: { wkid: 4326 },
source: [], // adding an empty feature collection
renderer: { // =>>> MATCH THE RENDERER TYPE
type: "simple",
symbol: {
type: "web-style", // =>>> MATCH THE SYMBOL TYPE
styleName: "Esri2DPointSymbolsStyle",
name: "landmark"
}
},
popupTemplate: {
title: "{Name}"
}
});
2. Then once you have the resultFeatures, use FeatureLayer.applyEdits to add the features.
const addEdits = {
addFeatures: graphics
};
layer.applyEdits(addEdits).then(function(results) {
// feature are added... Now you can query the features
})
.catch(function(error){
// apply edits error
});
Hope this helps,
-Undrral
> Is there a way to make Graphics on a GraphicsLayer scale based on zoom?
No. There is no way to efficiently scale the symbols of graphics in the view graphics or in a GraphicsLayer.
> If not, how could I modify the viewshed sample to use a FeatureLayer instead?
You will need to create a client-side feature layer and add a simple renderer to it using the code in the sample you referenced above. Undral's comment shows how you can create a feature layer using graphics. If this is only to display temporary results in the view, you can just construct the FeatureLayer and pass the graphics to the layer.source. When you want to clear the graphics, destroy the layer. That way you avoid using applyEdits.
The method of managing the graphics with applyEdits or creating a new layer every time is up to you.