I would like to perform a definiton query against a FeatureLayer that I've loaded into my map from a local geodatabase. Reading through the help, it seems that definition queries are only supported against FeatureServiceLayers. The FeatureLayerInfo object has the definitionExpression property, but takes a url to set the feature layer's endpoint. So I don't see any way to get at the FeatureLayerInfo property for a FeatureLayer from a local geodatabase.
What I do see on a FeatureLayer is the setFeatureVisible property, which looks like it does the same sort of thing that a definition query would. The problem here is I would have to do this one feature at a time. That doesn't seem very efficient.
Hopefully I'm way off base here. Does anyone have an example they could post showing how to do a definition query against a local gdb feature layer?
Solved! Go to Solution.
Yeh no problem. This is a quick and dirty test harness, but it shows at a basic level how to implement this type of thing.
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: "DefQueryTest"
property string m_LocalDataPath: System.userHomeFolder.path + "/Documents"
property string globalId: '{AA225F49-C337-4163-A1D6-92CE6B64052D}'
Map {
anchors.fill: parent
focus: true
ArcGISTiledMapServiceLayer {
url: "http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"
}
onStatusChanged: {
if (status === Enums.MapStatusReady)
assignmentGdb.path = m_LocalDataPath + "/EpochField/Data/DamageAssessment/Assignment5763-E0927.geodatabase"
}
FeatureLayer {
id: zbFeatLyr
featureTable: zbFeatTab
}
}
Geodatabase {
id: assignmentGdb
}
GeodatabaseFeatureTable {
id: zbFeatTab
geodatabase: assignmentGdb.valid ? assignmentGdb : null
featureServiceLayerName: "Zone Buffer"
property string defQueryType
onGeodatabaseFeatureTableValidChanged: {
if (geodatabaseFeatureTableValid) {
console.log("Zone Buffer feature table is initialized ...")
}
}
onQueryFeaturesStatusChanged: {
if (queryFeaturesStatus === Enums.QueryFeaturesStatusCompleted) {
console.log("QUERY RETURNED WITH " + queryFeaturesResult.featureCount + " FEATURES!!!");
var iterator = queryFeaturesResult.iterator;
while (iterator.hasNext()) {
// Get feature
var currentFeat = iterator.next();
var waGlobalId = currentFeat.attributeValue("WORK_ASSIGNMENT_GLOBALID");
if (defQueryType === "QUERY") {
if (waGlobalId === globalId) {
console.log("WE HAVE A MATCH!!!");
zbFeatLyr.setFeatureVisible(currentFeat.uniqueId, true);
}
else {
zbFeatLyr.setFeatureVisible(currentFeat.uniqueId, false);
}
}
else if (defQueryType === "RESET") {
zbFeatLyr.setFeatureVisible(currentFeat.uniqueId, true);
}
}
console.log("DONE");
}
}
}
Query {
id: layerQuery
returnGeometry: false
outFields: ["OBJECTID", "WORK_ASSIGNMENT_GLOBALID"]
}
Button {
text: "Query"
anchors {
top: parent.top
right: parent.right
margins: 10
}
onClicked: {
zbFeatTab.defQueryType = "QUERY";
layerQuery.where = "1=1";
zbFeatTab.queryFeatures(layerQuery);
}
}
Button {
text: "Reset"
anchors {
top: parent.top
left: parent.left
margins: 10
}
onClicked: {
zbFeatTab.defQueryType = "RESET";
layerQuery.where = "1=1";
zbFeatTab.queryFeatures(layerQuery);
}
}
}
Andy-
It looks like the issue is that we need a definitionExpression property on the FeatureLayer, but do not have it in C++ or QML. The definitionExpression on the GeodatabaseFeatureServiceTable is meant to work with that class only, and isn't supported with the GeodatabaseFeatureTable. I have logged an issue internally to get this added to the FeatureLayer. If you are creating your geodatabase from a service, then you could provide a query when generating the geodatabase. Otherwise, if you are generating the geodatabase through ArcMap, then I unfortunately cannot think of an easy workaround. What you suggested could work, but will likely be very time consuming.
-Luke
We are creating the geodatabase from a service, but we can't blanketly set one def query and be done. The def query needs to change based on what assignments the user is currently working. Even being able to pass a list of ids into the setFeatureVisible would be better. I am going to try to do the loop thing and see how it performs, but this enhancement would be a big win for the next release.
Thanks for your feedback Lucas ...
Lucas,
I just implemented the setFeatureVisible stuff and it actually doesn't perform half bad. Looks like it will be a decent workaround until you get the def query stuff implemented.
Thanks for the update, Andy. If you have a simple example of what you did and don't mind posting, it may be helpful for others if you copy a little snippet up here. If it's too much work and very specific to your app, then no worries though!
Yeh no problem. This is a quick and dirty test harness, but it shows at a basic level how to implement this type of thing.
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: "DefQueryTest"
property string m_LocalDataPath: System.userHomeFolder.path + "/Documents"
property string globalId: '{AA225F49-C337-4163-A1D6-92CE6B64052D}'
Map {
anchors.fill: parent
focus: true
ArcGISTiledMapServiceLayer {
url: "http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"
}
onStatusChanged: {
if (status === Enums.MapStatusReady)
assignmentGdb.path = m_LocalDataPath + "/EpochField/Data/DamageAssessment/Assignment5763-E0927.geodatabase"
}
FeatureLayer {
id: zbFeatLyr
featureTable: zbFeatTab
}
}
Geodatabase {
id: assignmentGdb
}
GeodatabaseFeatureTable {
id: zbFeatTab
geodatabase: assignmentGdb.valid ? assignmentGdb : null
featureServiceLayerName: "Zone Buffer"
property string defQueryType
onGeodatabaseFeatureTableValidChanged: {
if (geodatabaseFeatureTableValid) {
console.log("Zone Buffer feature table is initialized ...")
}
}
onQueryFeaturesStatusChanged: {
if (queryFeaturesStatus === Enums.QueryFeaturesStatusCompleted) {
console.log("QUERY RETURNED WITH " + queryFeaturesResult.featureCount + " FEATURES!!!");
var iterator = queryFeaturesResult.iterator;
while (iterator.hasNext()) {
// Get feature
var currentFeat = iterator.next();
var waGlobalId = currentFeat.attributeValue("WORK_ASSIGNMENT_GLOBALID");
if (defQueryType === "QUERY") {
if (waGlobalId === globalId) {
console.log("WE HAVE A MATCH!!!");
zbFeatLyr.setFeatureVisible(currentFeat.uniqueId, true);
}
else {
zbFeatLyr.setFeatureVisible(currentFeat.uniqueId, false);
}
}
else if (defQueryType === "RESET") {
zbFeatLyr.setFeatureVisible(currentFeat.uniqueId, true);
}
}
console.log("DONE");
}
}
}
Query {
id: layerQuery
returnGeometry: false
outFields: ["OBJECTID", "WORK_ASSIGNMENT_GLOBALID"]
}
Button {
text: "Query"
anchors {
top: parent.top
right: parent.right
margins: 10
}
onClicked: {
zbFeatTab.defQueryType = "QUERY";
layerQuery.where = "1=1";
zbFeatTab.queryFeatures(layerQuery);
}
}
Button {
text: "Reset"
anchors {
top: parent.top
left: parent.left
margins: 10
}
onClicked: {
zbFeatTab.defQueryType = "RESET";
layerQuery.where = "1=1";
zbFeatTab.queryFeatures(layerQuery);
}
}
}