I am trying to modify the renderer on a FeatureLayer from a local geodatabase and have not had much success. I can see my modifications to the renderer when I console.log its json, but the changes do not get applied to the layer in the map. FeatureLayer does not have a refresh like dynamic map layers do, so I'm not sure how to update the layer in the map so it reflects the changes I made to the renderer. I have included my code below. Does anyone have any ideas?
import QtQuick 2.3
import QtQuick.Controls 1.2
import ArcGIS.Runtime 10.25
import ArcGIS.Extras 1.0
ApplicationWindow {
id: appWindow
width: 800
height: 600
title: "SmallSymbolFix"
property string m_LocalDataPath: System.userHomeFolder.path + "/Documents"
Map {
id: appMap
anchors.fill: parent
wrapAroundEnabled: true
ArcGISTiledMapServiceLayer {
url: "http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer"
}
onStatusChanged: {
if (status === Enums.MapStatusReady)
damageGdb.path = m_LocalDataPath + "/EpochField/Data/DamageAssessment/WorkAssignments.geodatabase"
}
FeatureLayer {
id: featLyr
featureTable: featTab
onStatusChanged: {
if (status === Enums.LayerStatusInitialized) {
var newRenderer = ArcGISRuntime.createObject("UniqueValueRenderer");
var oldRenderer = featLyr.renderer;
for (var l = 0; l < oldRenderer.uniqueValues.length; ++l) {
var newSym = ArcGISRuntime.createObject("PictureMarkerSymbol");
newSym = oldRenderer.uniqueValues
newSym.height = 40;
newSym.width = 40;
var newUVI = ArcGISRuntime.createObject("UniqueValueInfo");
newUVI = oldRenderer.uniqueValues
newUVI.symbol = newSym;
//console.log("\n\nNEW SYMBOL: " + JSON.stringify(newSym.json));
newRenderer.addValue(newUVI);
}
featLyr.renderer = newRenderer;
console.log("\n\nNEW RENDERER: " + JSON.stringify(newRenderer.json));
}
}
}
}
Geodatabase {
id: damageGdb
onValidChanged: {
if (valid) {
// Add feature layer to map
var gdbFeatTab = geodatabaseFeatureTable("Work Assignment");
var operLayer = ArcGISRuntime.createObject("FeatureLayer");
operLayer.featureTable = gdbFeatTab;
appMap.addLayer(operLayer);
}
}
}
GeodatabaseFeatureTable {
id: featTab
geodatabase: damageGdb.valid ? damageGdb : null
featureServiceLayerName: "Work Assignment"
onGeodatabaseFeatureTableValidChanged: {
if (geodatabaseFeatureTableValid) {
console.log("Work Assignment feature table is initialized ...")
}
}
}
}
Solved! Go to Solution.
Hey Andy,
Yes, that should work as well. I think the main issue with your code is that you aren't setting the attributeNames on the feature layer's new renderer. Check out the example below and see if you can get that working in your app.
-Luke
import QtQuick 2.3 import QtQuick.Controls 1.2 import ArcGIS.Runtime 10.25 import ArcGIS.Extras 1.0 ApplicationWindow { id: appWindow width: 800 height: 600 title: "SmallSymbolFix" Map { id: appMap anchors.fill: parent ArcGISTiledMapServiceLayer { url: "http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer" } FeatureLayer { id: featLyr featureTable: featureServiceTable } } Button { anchors { left: parent.left top: parent.top margins: 15 } text: "change renderer" onClicked: { var orig_info_List = featLyr.renderer.uniqueValues; var new_renderer = ArcGISRuntime.createObject("UniqueValueRenderer", {attributeNames: featLyr.renderer.attributeNames}); for (var i = 0; i < orig_info_List.length; ++i) { //create the new symbol var symbol = orig_info_List.symbol; symbol.width = 40; symbol.height = 40; //create the new UniqueValueInfo var newInfo = ArcGISRuntime.createObject("UniqueValueInfo"); newInfo = orig_info_List; newInfo.symbol = symbol; new_renderer.addValue(newInfo); } featLyr.renderer = new_renderer; } } GeodatabaseFeatureServiceTable { id: featureServiceTable url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0" } }
Hey Andy-
In general, it can be done. Here is a simplified version of your code that uses the DamageInpsection geodatabase that comes with the sdk. I can switch it over to use a simple marker symbol.
import QtQuick 2.3 import QtQuick.Controls 1.2 import ArcGIS.Runtime 10.25 import ArcGIS.Extras 1.0 ApplicationWindow { id: appWindow width: 800 height: 600 title: "SmallSymbolFix" Map { id: appMap anchors.fill: parent wrapAroundEnabled: true ArcGISTiledMapServiceLayer { url: "http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer" } FeatureLayer { id: featLyr featureTable: featTab } } Button { anchors { left: parent.left top: parent.top margins: 15 } text: "change renderer" onClicked: { var newRenderer = ArcGISRuntime.createObject("SimpleRenderer"); newRenderer.symbol = ArcGISRuntime.createObject("SimpleMarkerSymbol", {color: "blue", size: 25}); featLyr.renderer = newRenderer; } } Geodatabase { id: damageGdb path: "C:/temp/DamageInspection6.geodatabase" } GeodatabaseFeatureTable { id: featTab geodatabase: damageGdb featureServiceLayerId: 0 } }
HI Lucas,
Thanks for the reply. When you say in general does that mean it can only be done for simple renderers? Can I do this with unique value renderers? Can I modify the layer's existing renderer or does it just work when you create something from scratch?
I feel like I'm very close as I can see my symbol modifications in the json for the new renderer, I just can't figure out how to apply that new renderer to the feature layer.
Hey Andy,
Yes, that should work as well. I think the main issue with your code is that you aren't setting the attributeNames on the feature layer's new renderer. Check out the example below and see if you can get that working in your app.
-Luke
import QtQuick 2.3 import QtQuick.Controls 1.2 import ArcGIS.Runtime 10.25 import ArcGIS.Extras 1.0 ApplicationWindow { id: appWindow width: 800 height: 600 title: "SmallSymbolFix" Map { id: appMap anchors.fill: parent ArcGISTiledMapServiceLayer { url: "http://services.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer" } FeatureLayer { id: featLyr featureTable: featureServiceTable } } Button { anchors { left: parent.left top: parent.top margins: 15 } text: "change renderer" onClicked: { var orig_info_List = featLyr.renderer.uniqueValues; var new_renderer = ArcGISRuntime.createObject("UniqueValueRenderer", {attributeNames: featLyr.renderer.attributeNames}); for (var i = 0; i < orig_info_List.length; ++i) { //create the new symbol var symbol = orig_info_List.symbol; symbol.width = 40; symbol.height = 40; //create the new UniqueValueInfo var newInfo = ArcGISRuntime.createObject("UniqueValueInfo"); newInfo = orig_info_List; newInfo.symbol = symbol; new_renderer.addValue(newInfo); } featLyr.renderer = new_renderer; } } GeodatabaseFeatureServiceTable { id: featureServiceTable url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0" } }
The attributeNames property was the missing piece. Thanks for your help Lucas!
i am using the same example but instead of a simple mark symbol i wanna add a picture one but doesnt refrect on the layer it just shows a red circle marker not the image :
var newRenderer = ArcGISRuntime.createObject("SimpleRenderer");
newRenderer.symbol = ArcGISRuntime.createObject("PictureMarkerSymbol", {url: "RedShinyPin.png"});
layer.renderer = newRenderer; what might be the problem?
The code looks fine and should work no problem. Maybe it can't find the PNG? Try giving it an online URL like this just to make sure that isn't the problem - http://static.arcgis.com/images/Symbols/AtoZ/redB.png