it.geosolutions.android.map.loaders.FeatureCircleLoader.java Source code

Java tutorial

Introduction

Here is the source code for it.geosolutions.android.map.loaders.FeatureCircleLoader.java

Source

/*
 * GeoSolutions map - Digital field mapping on Android based devices
 * Copyright (C) 2013  GeoSolutions (www.geo-solutions.it)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package it.geosolutions.android.map.loaders;

import it.geosolutions.android.map.database.SpatialDataSourceHandler;
import it.geosolutions.android.map.model.Feature;
import it.geosolutions.android.map.model.FeatureCircleQueryResult;
import it.geosolutions.android.map.model.FeatureCircleTaskQuery;
import java.util.ArrayList;
import java.util.List;
import jsqlite.Exception;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
import android.util.Log;
import eu.geopaparazzi.spatialite.database.spatial.core.SpatialVectorTable;

/**
 * Async query task to query layers. Updates an adapter with the results from a
 * query A query to the task is a "List of Lists of Maps", implemented with a
 * bundle of bundles The main bundle contains is name->list of features feature
 * contains name->value bundles
 * 
 * @author Lorenzo Natali (www.geo-solutions.it)
 */
public class FeatureCircleLoader extends AsyncTaskLoader<List<FeatureCircleQueryResult>> {

    int features_loaded = 0;

    private List<FeatureCircleQueryResult> mData;

    private FeatureCircleTaskQuery[] queryQueue;

    // private FeatureCircleObserver mObserver;
    private static int MAX_FEATURES = 10;

    public FeatureCircleLoader(Context ctx, FeatureCircleTaskQuery[] queryQueue) {
        // Loaders may be used across multiple Activities (assuming they aren't
        // bound to the LoaderManager), so NEVER hold a reference to the context
        // directly. Doing so will cause you to leak an entire Activity's context.
        // The superclass constructor will store a reference to the Application
        // Context instead, and can be retrieved with a call to getContext().
        super(ctx);
        this.queryQueue = queryQueue;

    }

    protected void doInBackground(FeatureCircleTaskQuery[] queryQueue, List<FeatureCircleQueryResult> data) {
        Log.d("FEATURE_Circle_TASK", "Circle Task Launched");
        //process all queries
        for (FeatureCircleTaskQuery query : queryQueue) {
            if (!processQuery(query, data)) {
                return;
            }
        }
        return;

    }

    /**
     * Process a single <FeatureCircleQuery>
     * @param query
     * @param data the result will be added to this array
     */
    private boolean processQuery(FeatureCircleTaskQuery query, List<FeatureCircleQueryResult> data) {
        SpatialDataSourceHandler handler = query.getHandler();
        SpatialVectorTable table = query.getTable();
        String tableName = query.getTable().getName();
        // check visibility before adding the table
        // AdvancedStyle s = sm.getStyle(tableName);
        // if ( !StyleUtils.isVisible(s, zoomLevel) ) {
        // onProgressUpdate(0);
        // continue;
        // }

        double x = query.getX();
        double y = query.getY();
        double radius = query.getRadius();

        Integer start = query.getStart();
        Integer limit = query.getLimit();
        if (Log.isLoggable("FEATURE_Circle_TASK", Log.DEBUG)) { // Log check to avoid
                                                                // string creation
            Log.d("FEATURE_Circle_TASK", "starting query for table " + tableName);
        }
        // this is empty to skip geometries that returns errors
        ArrayList<Feature> features = new ArrayList<Feature>();
        try {
            features = handler.intersectionToCircle("4326", table, x, y, radius, start, limit);
        } catch (Exception e) {
            Log.e("FEATURE_Circle_TASK",
                    "unable to retrive data for table'" + tableName + "\'.Error:" + e.getLocalizedMessage());
            // TODO now simply skip, do better work
        }
        // add features
        FeatureCircleQueryResult result = new FeatureCircleQueryResult();
        result.setLayerName(tableName);
        result.setFeatures(features);
        Log.v("FEATURE_Circle_TASK", features.size() + " items found for table " + tableName);
        features_loaded += features.size();
        // publishProgress(result);
        data.add(result);

        return true;

    }

    /*
     * (non-Javadoc)
     * @see android.support.v4.content.AsyncTaskLoader#loadInBackground()
     */
    @Override
    public List<FeatureCircleQueryResult> loadInBackground() {
        List<FeatureCircleQueryResult> data = new ArrayList<FeatureCircleQueryResult>();

        // TODO: Perform the query here and add the results to 'data'.
        doInBackground(queryQueue, data);

        return data;
    }

    // ********************************************************/
    // ** Deliver the results to the registered listener **/
    // ********************************************************/
    @Override
    public void deliverResult(List<FeatureCircleQueryResult> data) {
        if (isReset()) {
            // The Loader has been reset; ignore the result and invalidate the data.
            releaseResources(data);
            return;
        }

        // Hold a reference to the old data so it doesn't get garbage collected.
        // We must protect it until the new data has been delivered.
        List<FeatureCircleQueryResult> oldData = mData;
        mData = data;
        if (isStarted()) {
            // If the Loader is in a started state, deliver the results to the
            // client. The superclass method does this for us.
            super.deliverResult(data);
        }

        // Invalidate the old data as we don't need it any more.
        if (oldData != null && oldData != data) {
            releaseResources(oldData);
        }
    }

    // ********************************************************/
    // ** Implement the Loaders state-dependent behavior **/
    // ********************************************************/
    @Override
    protected void onStartLoading() {
        if (mData != null) {
            // Deliver any previously loaded data immediately.
            deliverResult(mData);
        }

        // Begin monitoring the underlying data source.
        // if (mObserver == null) {
        // mObserver = new SampleObserver();
        // // TODO: register the observer
        // }

        if (takeContentChanged() || mData == null) {
            // When the observer detects a change, it should call onContentChanged()
            // on the Loader, which will cause the next call to takeContentChanged()
            // to return true. If this is ever the case (or if the current data is
            // null), we force a new load.
            forceLoad();
        }
    }

    /*
     * (non-Javadoc)
     * @see android.support.v4.content.Loader#onStopLoading()
     */
    @Override
    protected void onStopLoading() {
        cancelLoad();
    }

    /*
     * (non-Javadoc)
     * @see android.support.v4.content.Loader#onReset()
     */
    @Override
    protected void onReset() {

        onStopLoading();
        if (mData != null) {
            releaseResources(mData);
            mData = null;
        }

        // if(mObserver !=null){
        // //TODO unregister the observer
        // moObserver=null;
        //
        // }
    }

    /*
     * (non-Javadoc)
     * @see android.support.v4.content.AsyncTaskLoader#onCanceled(java.lang.Object)
     */
    @Override
    public void onCanceled(List<FeatureCircleQueryResult> data) {
        // TODO Auto-generated method stub
        super.onCanceled(data);
        releaseResources(data);
    }

    /**
     * @param data
     */
    private void releaseResources(List<FeatureCircleQueryResult> data) {
        // release resource if needed

    }
}