Using ArcGISFeatureLayer offline

4833
10
12-19-2012 05:14 AM
KevinGebhardt
New Contributor III
Hello,
I'm trying to use an ArcGISFeatureLayer offline.
Here is my code:

Graphic[] graphics = new Graphic[baumLayerFields.length];
ArrayList<Field> fields = new ArrayList<Field>();
FeatureSet featureSet = new FeatureSet();
for (int i = 0; i < baumLayerFields.length; i++)
{
Field f = new Field(baumLayerFields,baumLayerFields,"esriFieldTypeString");
fields.add(f);
}
featureSet.setFields(fields);

for (all features in my local storage)
{
Hashtable<String,Object> map = new Hashtable<String,Object>();
map.put("OBJECTID", String.valueOf(i));
map.put("VNK", baeume.get(i).getVNK());
map.put("NNK", baeume.get(i).getNNK());
map.put("VST", baeume.get(i).getVST());
PictureMarkerSymbol pms = new PictureMarkerSymbol(drawable);
InfoTemplate infoTemplate = new InfoTemplate();
Point p = new Point();
p.setX(baeume.get(i).getX());
p.setY(baeume.get(i).getY());
SimpleMarkerSymbol sms = new SimpleMarkerSymbol(Color.RED, 50, SimpleMarkerSymbol.STYLE.CIRCLE);
Graphic g = new Graphic(p,sms,map,infoTemplate);
graphics = g;
}
featureSet.setGraphics(graphics);
featureSet.setSpatialReference(new SpatialReference("\"wkid\":31468"));
fLayer = new ArcGISFeatureLayer(null,featureSet, o);

My Problem is, that i have an extent, but cant see any features. I also dont understand how the LayerDefinition for the ArcGISFeatureLayer should look like. I have tried some, but nothing seems to work.

Has anyone an idea, or is there a better approach?

Kind regards,
Kevin
0 Kudos
10 Replies
deleted-user-ATjHIWsdQYmT
Occasional Contributor III
Offline support is not currently supported, but it is slated for the next release.  See this thread: http://forums.arcgis.com/threads/73749-Offline-Use-March-2012
0 Kudos
KevinGebhardt
New Contributor III
But when I'm looking at the API-Documentation of ArcGISFeatureLayer there is the following constructor:

public ArcGISFeatureLayer(String layerDefinition,
                          FeatureSet featureCollection,
                          ArcGISFeatureLayer.Options layerOption)

    The constructor is used if you are instantiating the ArcGISFeatureLayer using a feature collection.

    The feature layer, when initialized with a feature collection object has the following behavior:
    Edits are applied on the client not posted to the server.
    The feature layer generates a unique ObjectId for new features.
    All queries are done on the client side.
    Does not support operations that need to be performed on the server, e.g. attachment, appyEdit.

So i can create a FeatureSet from given coords from a local source (file system, database) and give it to the FeatureLayer.
0 Kudos
DanO_Neill
Occasional Contributor III
The ArcGISFeatureLayer(String layerDefinition, FeatureSet featureCollection, ArcGISFeatureLayer.Options layerOption) cannot have a null layer definition.  You need to create a string resource and populate it with your layer definition.  You can look at ArcGIS Services directory to see what a layer definition looks like, e.g. ESRI USA Census States layer definition.  Your code needs the layer definition defined by baumLayerFields presumably.  Below I offer a working example from one of the SDK samples. 

Take a look at the CreateLocalJsonFeatures sample for an example of creating an offline ArcGISFeatureLayer from an existing FeatureLayer online

In the sample an ArcGISFeatureLayer is created from ArcGIS Online.  The sample allows users to sketch a polygon to query the ArcGISFeatureLayer and submit the query results to create an offline subset of the ArcGISFeatureLayer. 

Query the online ArcGISFeatureLayer
    
    Query query = new Query();
    // set spatial reference 
    SpatialReference sr = SpatialReference.create(102100);
    // set the geometry to the sketch polygon
    query.setGeometry(selection);
    // query features that are completely contained by selection
    query.setSpatialRelationship(SpatialRelationship.CONTAINS);
    // set query in/out spatial ref
    query.setInSpatialReference(sr);
    query.setOutSpatialReference(sr);
    // return all features
    query.setOutFields(new String[]{"*"});
    // include geometry in result set
    query.setReturnGeometry(true);
    // run query on FeatureLayer off UI thread
    windTurbine.queryFeatures(query, new CallbackListener<FeatureSet>() {


The result of the query is a FeatureSet result.  FeatureSet has to/fromJson methods that allow you to persist the features to json and locally on device. 

            // create feature set as json string
            String fsstring = FeatureSet.toJson(result);
            // create fully qualified path for json file
            path = createJsonFile();
            // create a File from json fully qualified path
            File outfile = new File(path);
            // create output stream to write to json file
            outstream = new FileOutputStream(outfile);
            outstream.write(fsstring.getBytes());
            // close output stream
            outstream.close();


The json local file path can be used to create an offline FeatureSet

  
public FeatureSet createWindTurbinesFeatureSet(String path) {
    FeatureSet fs = null;
    
    try {
      JsonFactory factory = new JsonFactory();
      JsonParser parser = factory.createJsonParser(new FileInputStream(path));
      parser.nextToken();
      fs = FeatureSet.fromJson(parser);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return fs;
  } 


With a Layer Definition defined and a populated offline FeatureSet from json you can create your offline ArcGISFeatureLayer.

    // Create wind turbine featurelayer from json
    windTurbineFeatureSet = createWindTurbinesFeatureSet(jsonPath);
    windTurbineLayerDefinition = this.getResources().getString(R.string.config_windturbine_layer_definition);
    ArcGISFeatureLayer.Options layerOptions = new ArcGISFeatureLayer.Options();
    layerOptions.mode = ArcGISFeatureLayer.MODE.SNAPSHOT;

    // create the offline feature layer
    windTurbinesFeatureLayer = new ArcGISFeatureLayer(windTurbineLayerDefinition, windTurbineFeatureSet, layerOptions);


Hope this helps
0 Kudos
AxelBronder1
New Contributor
Hi all,

about the layer definition... how do I create a string resource and populate it with my layer definition?

Is it only possible through ArcGIS Server/ ArcGIS online, or do I have other options?

Thanks!
0 Kudos
KonstantinKurtukov
New Contributor
Hi all.
I'll try to load feature layer offline. I used code such as in example Wind Turbines.
I send query to layer, save json to file, get definition from server.
But there are not features on map. Why is this happening?
0 Kudos
KonstantinKurtukov
New Contributor
Hi all.
I'll try to load feature layer offline. I used code such as in example Wind Turbines.
I send query to layer, save json to file, get definition from server.
But there are not features on map. Why is this happening?


I resolved my problem. This happenes when i try load few layers simultaneously. Need to wait while first load, save it to json and then load another.
0 Kudos
VansiKrishna
New Contributor II
Hi all.
I'll try to load feature layer offline. I used code such as in example Wind Turbines.
I send query to layer, save json to file, get definition from server.
But there are not features on map. Why is this happening?


Hello,

Can you please tell me how did you manage to get the layer definition dynamically through code. I can see that in the "CreateJSONLocalMaps" project, the layer definition is hardcoded in the "strings.xml". I have nearly 90 layers for which i want to dynamically fetch the layer definition.
0 Kudos
KonstantinKurtukov
New Contributor
Hello,

Can you please tell me how did you manage to get the layer definition dynamically through code. I can see that in the "CreateJSONLocalMaps" project, the layer definition is hardcoded in the "strings.xml". I have nearly 90 layers for which i want to dynamically fetch the layer definition.


I send request to my ArcGis Service using layer url + "?f=pjson". Get this json and save it to the file. And then using layer definition from this file.
0 Kudos
VansiKrishna
New Contributor II
I send request to my ArcGis Service using layer url + "?f=pjson". Get this json and save it to the file. And then using layer definition from this file.


Hello kosmich,

Yes i know that format. I used to do the same for all of my layers until the ArcGIS service url was open and executable through query string. But now, the service url is authenticated. It needs a security token for free access. Now i cannot use the above process since it always returns me the following result.

{
 "error": {
  "code": 499,
  "message": "Token Required",
  "details": []
 }
}


Not to show my layer data in offline mode, firstly i am getting the instance of ArcGISFeatureLayer and then Query the data for a selected boundary. I now use the following approach to get the instance of ArcGISFeatureLayer :

UserCredentials creds = new UserCredentials();
creds.setUserAccount("username", "password");
creds.setUserToken("token", "AkwekUYsasaYU");    
ArcGISDynamicMapServiceLayer layer = new ArcGISDynamicMapServiceLayer(
  "http://servicesbeta.esri.com/ArcGIS/rest/services/SanJuan/TrailConditions/MapServer", null,creds);


I am also able to get the data too. But to show them on an offline layer i would need the layer definition as string. What to do now?
0 Kudos