Loop and apply edit

214
4
07-08-2021 11:02 AM
NicolasElgueta
New Contributor II

Hello everyone, I have the following problem, I read from a data array and what I want to do is go through the at create the geometry and send it through a feature service.
Everything works for me ok, except that my shipments are duplicated.

I am attaching my code to see if someone can help me.

 

 

 

 private void sendData(){
        ServiceFeatureTable featureTable;
        featureTable = mServiceFeatureTable;

                for (RepartoClass rep : arrayData){
                    Integer myId = rep.getId();

                    Map<String, Object> attributes = new HashMap<>();
                    attributes.put( "nis", rep.getNis() );
                    attributes.put( "valor_captura", rep.getCodigo() );
                    attributes.put( "empresa", empresa );
                    attributes.put( "modulo", rep.getTipo() );
                    attributes.put( "fecha", rep.getFecha() );

                    String oTipo;
                    oTipo = rep.getTipo();

                    Point oUbicacion = new Point( rep.getX(), rep.getY(), SpatialReference.create( 32719 ) );

                   
                            featureTable.addDoneLoadingListener( () -> {
                                Feature feature = featureTable.createFeature( attributes, oUbicacion );
                                if (featureTable.canAdd()) {
                                    myDeletes.add( myId );
                                    //featureTable.addFeatureAsync( feature ).addDoneListener( () -> applyEdits( featureTable ) );
                                    featureTable.addFeatureAsync( feature );
                                }
                            } );
                }

        featureTable.loadAsync();
        final ListenableFuture<List<FeatureEditResult>> editResult = featureTable.applyEditsAsync();
        editResult.addDoneListener( () -> {
            try {
                List<FeatureEditResult> editResults = editResult.get();
                //Check if the server edit succeful
                if (editResults != null && !editResults.isEmpty()) {
                    if (!editResults.get( 0 ).hasCompletedWithErrors()) {                       
                    } else {
                        throw editResults.get( 0 ).getError();
                    }
                }
            } catch (InterruptedException | ExecutionException e) {
                runOnUiThread( () -> logToUser( true, "ErrorApply:" + e.getCause().getMessage() ) );
            }
        } );       
    }

 

 

 

0 Kudos
4 Replies
RamaChintapalli
Esri Contributor

Hi,

Could you try & move your for loop within the featuretable done listener. You only need to load the feature table once. And make sure addFeatures only add's the required number of features and applyEdits is only called once after all the features you need are added to the feature table.

 

Thanks

Rama

0 Kudos
NicolasElgueta
New Contributor II

I have done the indicated but not all the features get out of the loop to the server.
apparently it is a bug since within the loop they all reach the server but are duplicated, in version 10.X this problem did not occur.

0 Kudos
RamaChintapalli
Esri Contributor

Hi,

I tried below code with a sample service and it seem's to work fine as expected (i.e add all features in loop and apply them to server only once).

Sample Service: https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0

 

 

private void addFeaturesInALoop() {

    mServiceFeatureTable.addDoneLoadingListener( () -> {
      int i = 0;

      for (i=0;i<3;i++){
        FeatureType featureType = mServiceFeatureTable.getFeatureTypes().get(0);

        Feature feature = mServiceFeatureTable.createFeature(featureType);
        if (mServiceFeatureTable.canAdd()) {
          try {
            mServiceFeatureTable.addFeatureAsync(feature).get();
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
      applyEditsToServer();
    } );
    mServiceFeatureTable.loadAsync();

  }

  /**
   * Applies edits to the FeatureService
   */
  private void applyEditsToServer() {
    final ListenableFuture<List<FeatureEditResult>> applyEditsFuture = ((ServiceFeatureTable) mFeatureLayer
        .getFeatureTable()).applyEditsAsync();
    applyEditsFuture.addDoneListener(() -> {
      try {
        // get results of edit
        List<FeatureEditResult> featureEditResultsList = applyEditsFuture.get();
        if (!featureEditResultsList.get(0).hasCompletedWithErrors()) {
          Toast.makeText(this,
              "Applied Edits to Server. ObjectID: " + featureEditResultsList.get(0).getObjectId(),
              Toast.LENGTH_SHORT).show();
        }
      } catch (InterruptedException | ExecutionException e) {
        Log.e(TAG, "Update feature failed: " + e.getMessage());
      }
    });
  }

 


Thanks
Rama

0 Kudos
NicolasElgueta
New Contributor II

Hi Rama, can see that you are looping an existing featuretable, I try to loop a sqlLite database and create a feature from the existing array data in the database, then send.

When doing this reading of data from bd sqllite with the following code, I get the following error indicating that it cannot find a record.

 

 private void enviarDatos() {

        mServiceFeatureTable.addDoneLoadingListener( () -> {
           
        for (RepartoClass rep : arrayDatos) {
            Map<String, Object> attributes = new HashMap<>();
            attributes.put( "nis", rep.getNis() );
            attributes.put( "valor_captura", rep.getCodigo() );
            attributes.put( "empresa", empresa );
            attributes.put( "modulo", rep.getTipo() );
            attributes.put( "fecha", rep.getFecha() );

            String oTipo;
            oTipo = rep.getTipo();

            Point oUbicacion = new Point( rep.getX(), rep.getY(), SpatialReference.create( 32719 ) );
            switch (oTipo) {
                case "BOL":
                    Feature featureBoleta = mServiceFeatureTable.createFeature(attributes,oUbicacion);
                    if(mServiceFeatureTable.canAdd()){
                        try {
                            mServiceFeatureTable.addFeatureAsync( featureBoleta ).get();
                        } catch (Exception w) {
                            w.printStackTrace();
                        }
                    }
                case "MDV":
                    Feature featureCarta = mServiceFeatureTableCarta.createFeature(attributes,oUbicacion);
                    if(mServiceFeatureTableCarta.canAdd()){
                        try{
                            mServiceFeatureTableCarta.addFeatureAsync( featureCarta ).get();
                        }catch (Exception w){
                            w.printStackTrace();
                        }

                    }
            }
        }            
        } );
        applyEditsToServer3();
    }

    private void applyEditsToServer3() {
        final ListenableFuture<List<FeatureEditResult>> applyEditsFuture =((ServiceFeatureTable) featureLayerBoleta.getFeatureTable()).applyEditsAsync();
        applyEditsFuture.addDoneListener( () -> {
            try {
                List<FeatureEditResult> featureEditResultList = applyEditsFuture.get();
                if(!featureEditResultList.get( 0 ).hasCompletedWithErrors()){
                    Toast.makeText( this,"Applied Edits to server ObjectID: " + featureEditResultList.get( 0 ).getObjectId() ,Toast.LENGTH_SHORT).show();
                }
            }catch (InterruptedException| ExecutionException e){
                Log.e(TAG,"Update feature failed: " + e.getMessage());
            }
        } );
    }

 

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.giscen.gisred, PID: 20646
    java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.esri.arcgisruntime.a.q.i0.get(SourceFile:1)
        at com.giscen.gisred.RepartoActivity.lambda$applyEditsToServer3$3$RepartoActivity(RepartoActivity.java:470)
        at com.giscen.gisred.-$$Lambda$RepartoActivity$8PkwM4RtkThdsT-H59pLFI8r0xM.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7073)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)

 

I can't get to success

 

Regards

Nicolas

0 Kudos