Issue with GitHub Offline geodatabase Example

826
8
11-27-2017 12:56 PM
RayfieldNeel
New Contributor II

I found the following sample code on the Esri GitHub AppStudio wiki:

Working with Offline content · Esri/arcgis-appstudio-samples Wiki · GitHub 

I'm specifically interested in the 2nd section, "Adding offline geodatabase to your app". This is critical to my application; I need to get a queryable featureTable in there, so that I can do a simple geofence, the user's current location against offline-stored polygons. 

I started out using the existing Feature Layer sample code, then placed the code from above in the FeatureLayerQuery.qml code, within the Map section, (replacing the existing FeatureLayer and ServiceFeatureTable sections). When I go to run the query in the app, it stops with 'Cannot assign to non-existent property "onStatusChanged"'. In the editor, I'm getting invalid property name flags for featureServiceLayerId, enableLabels, onStatusChanged. (graphic included of what I see).

I'm guessing that this code sample has worked for others, since it's been on GitHub for over a year, so I must have something missing or wrong. Barring an explanation of this, does anyone have a link to actual working code, of an offline geodatabase, being queried via GeometryEngine? Nothing I've tried where I simply replace online code with a gdb has worked, to date. 

Thanks for any assistance!

--Ray

0 Kudos
8 Replies
nakulmanocha
Esri Regular Contributor

This sample code is based on old runtime 10.2.6 (which will soon be deprecated). Are you using 10.2.6 or 100.1 (new) runtime? If using 100.1 you need to look at the sample below. This is also available to with the AppStudio desktop (search for Feature Layer (Geodatabase))

arcgis-appstudio-samples/Feature Layer (Geodatabase) at v2.1 · Esri/arcgis-appstudio-samples · GitHu... 

0 Kudos
RayfieldNeel
New Contributor II

Thanks, yes, I've worked with the Feature Layer (Geodatabase) code, as well. I can load a geodatabase to the displayed map...but I've yet to get it to successfully query against it. One clue is that even the barebones Feature Layer (Geodatabase) example is getting an error in my console?:

MyApp.qml:100:39: Unable to assign [undefined] to QmlFeatureTable*

I've worked with this code, as well as the "Generate Geodatabase" sample; I can make features show on the map, but that's not the end game for me. I need to be able to use GeometryEngine against it (within), and can't seem to get to that extra step. Thank you for pointing out that I'm using sample code for the older runtime, that's a start!

0 Kudos
nakulmanocha
Esri Regular Contributor

What exactly is the issue with GeometryEngine? I believe you posted this earlier here

https://community.esri.com/message/726386-re-geometryengine-simple-geofence-problem?commentID=726386... 

I would highly recommend you to log a support ticket if you continue to have issues with the GeometryEngine. They will be able to pinpoint the issue.

0 Kudos
RayfieldNeel
New Contributor II

Yes, that was when I was simply trying to get GeometryEngine working with online layers. No problem doing that, but I run into difficulty when I try to get my offline data (runtime content) to the same place, where I can run GeometryEngine.within against individual features. (Polygons)

The error that I referenced in my last post was really throwing me, but it sounds like it may be a known bug, and ignorable. (?) 

Beyond that, I've tinkered for a while and have the following code loading the geodatabase polygon on my map, no problem. 

However, when querying, I never get queryFeaturesStatus to be "Complete". I get a value of 1 from my console. 

Loading to the map implies that the data is present, just not sure how to drill down to features, so that I can do my "within" call, like what worked for me, with online resources. 

Perhaps there's a better way! Any thoughts? 🙂

FeatureLayer {
    id: gdbFeatureLayer
    // obtain the feature table from the geodatabase by name
    featureTable: gdb.geodatabaseFeatureTablesByTableName["fake_brushview_polygons"]
    onLoadStatusChanged: {
        map.operationalLayers.append( gdbFeatureLayer );
        onQueryFeaturesStatusChanged: {
            console.log( "queryFeaturesStatus: ",gdbFeatureLayer.featureTable.queryFeaturesStatus );
            if( gdbFeatureLayer.featureTable.queryFeaturesStatus === Enums.TaskStatusCompleted ) {
                console.log( "Query Complete!" );
            }
        }
    }
    // create the geodatabase
    Geodatabase {
        id: gdb
        path: AppFramework.resolvedPathUrl( outputGeofencing )
    }
}
0 Kudos
nakulmanocha
Esri Regular Contributor

Once you get at the Geometry level, it doesn't matter if you are using an online resource or offline. It works the same way.

You query features get the ids. Every id will represent a feature. Every feature has a geometry. You pass that geometry to GeometryEngine for further analytics/ relationships such as within.

To get to feature(s) you use FeatureQueryResult.iterator . Then you can either get all the features by using features property or use next() method to get to first feature.

FeatureIterator QML Type | ArcGIS for Developers 

0 Kudos
RayfieldNeel
New Contributor II

Right, but I'm not getting to the geometry level. I used exactly what you're describing, successfully, with the iterator, with online resources. But I can't get a successful return to my query to the Geodatabase. 

In other words, I never get "Query Complete!" in my console, in my above code, even though I'm getting the layer showing up on my map. 

0 Kudos
nakulmanocha
Esri Regular Contributor

Not sure why it doesn't work for you. This requires more investigation. Please log a support issue to further troubleshoot this issue.

0 Kudos
RayfieldNeel
New Contributor II

Using some input from a fellow GeoNet'er, and getting some more learning under my belt, I was able to get this working, today. (A nice way to start a weekend!)

Here's the code I used, for the benefit of others:

Geodatabase {
   id: gdb_geofence
   path: AppFramework.resolvedPathUrl( outputGeofencing )

   onLoadStatusChanged: {
      if(Enums.LoadStatusLoaded === gdb_geofence.loadStatus) {
         var layer = ArcGISRuntimeEnvironment.createObject("FeatureLayer")
         layer.featureTable = gdb_geofence.geodatabaseFeatureTablesByTableName["fake_brushview_polygons"]

         gdbLayers.push( layer );
         map.operationalLayers.append(layer);

         layer.featureTable.queryFeaturesStatusChanged.connect( function() {
            if (layer.featureTable.queryFeaturesStatus === Enums.TaskStatusCompleted) {
               //Create array for features and collect them
               var features = []
               while (layer.featureTable.queryFeaturesResult.iterator.hasNext) {
                  features.push( layer.featureTable.queryFeaturesResult.iterator.next() );
               }
               console.log( "number of features in array: ", features.length );

               //Get the current map point
               var newPoint = mapView.locationDisplay.location.position

               //set default value for not being in a zone, before checking:
               var inAZone = false;

               for( var i = 0; i < features.length; i++ ) {
                  var zoneGeometry = features.geometry
                  var withinZone = GeometryEngine.within( newPoint, zoneGeometry );

                  if( withinZone ) {
                     inAZone = true
                  debugMessage.text = features.attributes.attributesJson.name
                  }

                  if( !inAZone ) {
                     debugMessage.text = "Not currently in a Zone"
                  }
                  console.log( i, features.attributes.attributesJson.name, " withinZone is set to ", withinZone );
               }
            }
         });
         layer.featureTable.queryFeatures( queryParameters );
      }
   }
}

0 Kudos