pro.dbro.iburn_2012.OpenStreetMapFragment.java Source code

Java tutorial

Introduction

Here is the source code for pro.dbro.iburn_2012.OpenStreetMapFragment.java

Source

package pro.dbro.iburn_2012;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import org.osmdroid.ResourceProxy;
import org.osmdroid.bonuspack.overlays.ItemizedOverlayWithBubble;
import org.osmdroid.events.MapListener;
import org.osmdroid.events.ScrollEvent;
import org.osmdroid.events.ZoomEvent;
import org.osmdroid.tileprovider.MapTileProviderArray;
import org.osmdroid.tileprovider.MapTileProviderBasic;
import org.osmdroid.tileprovider.modules.MapTileAssetProvider;
import org.osmdroid.tileprovider.modules.MapTileModuleProviderBase;
import org.osmdroid.tileprovider.tilesource.BitmapAssetTileSource;
import org.osmdroid.util.BoundingBoxE6;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.BoundedMapView;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedIconOverlay;
import org.osmdroid.views.overlay.ItemizedOverlayWithFocus;
import org.osmdroid.views.overlay.MyLocationOverlay;
import org.osmdroid.views.overlay.OverlayItem;
import org.osmdroid.views.overlay.TilesOverlay;

import pro.dbro.iburn_2012.DeviceLocation.LocationResult;
import pro.dbro.iburn_2012.data.CampTable;
import pro.dbro.iburn_2012.data.DataUtils;
import pro.dbro.iburn_2012.data.JSONDeserializers;
import pro.dbro.iburn_2012.data.PlayaContentProvider;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.SearchViewCompat;
import android.support.v4.widget.SearchViewCompat.OnQueryTextListenerCompat;
import android.text.InputType;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

/**
* Based on osmdroid default map view activity.
*
* 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
* 
* Default map view activity.
* @author Manuel Stahl
*
*/

public class OpenStreetMapFragment extends Fragment {
    /** Called when the activity is first created. */
    public static MapController mapController;
    static BoundedMapView mapView;

    public static View container;
    //public static View mapView;
    //private MapView mapView;

    // prevent more than one poi touch event being dispatched at once
    public static boolean mapOverlayShowing = false;

    // keep track of activePoi index 
    public static int activePoi = -1;

    // screen-bottom popup
    public static PopupWindow pw;

    private MyLocationOverlay mLocationOverlay;
    private ResourceProxy mResourceProxy;

    static ItemizedOverlayWithFocus poiOverlay;

    public DeviceLocation deviceLocation;

    // Location 
    Location currentLocation;
    double currentLat;
    double currentLon;
    double distance; // from man
    boolean hasLocation = false;

    //static ItemizedOverlayWithBubble poiOverlay;

    // Map bounds
    private final GeoPoint northEast = new GeoPoint(40802822, -119172673);
    private final GeoPoint southWest = new GeoPoint(40759210, -119234540);

    // Zoom Constants
    final static int PINS_AT_ZOOM = 17;

    Resources res;

    private SharedPreferences prefs;
    private SharedPreferences.Editor editor;

    private Fragment fragment;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        fragment = this;

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        Resources res = getResources();
        prefs = getActivity().getSharedPreferences("PREFS", 0);
        editor = prefs.edit();

        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            new AlertDialog.Builder(getActivity()).setTitle("Sorry, Friend").setMessage(
                    "iBurn requires your sd card is properly inserted. Perhaps you have been chosen to experience Burning Man without the hassle of technology.")
                    .setPositiveButton("Bummer", new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            fragment.getActivity().finish();

                        }

                    }).show();

        } else if (prefs.getBoolean("first_timer", true)) {
            editor.putBoolean("first_timer", false);
            editor.commit();

            new AlertDialog.Builder(getActivity()).setTitle("Welcome to iBurn!").setMessage(
                    "iBurn will activate as you get closer to the Playa. Art, Camp, and Event data is currently loading.")
                    .setPositiveButton("Let's burn", null).show();
        }

        // http://iburn.s3.amazonaws.com/2012
        final MapTileProviderBasic tileProvider = new MapTileProviderBasic(FragmentTabsPager.app);
        //final XYTileSource tileSource = new XYTileSource("burn", null, 5, 18, 256, ".png",
        //                    "http://iburn.s3.amazonaws.com/2012/");
        final BitmapAssetTileSource tileSource = new BitmapAssetTileSource("burn", null, 5, 18, 256, "");
        tileSource.isSourceTMS = false;
        AssetManager assets = FragmentTabsPager.app.getAssets();
        //MapTileModuleProviderBase[] tileProviderArray = {new MapTileAssetProvider(assets, tileSource, 0)};
        //MapAssetTileProviderArray providerArray = new MapAssetTileProviderArray(tileSource, null, tileProviderArray);

        MapTileModuleProviderBase[] myProviders = new MapTileModuleProviderBase[1];

        //myProviders[0] = new MapTileFileArchiveProvider(new SimpleRegisterReceiver(getApplicationContext()), myTiles, myArchives);

        myProviders[0] = new MapTileAssetProvider(assets, tileSource, 0);

        //myProviders[0] =  new MapTileDownloader(TileSourceFactory.MAPNIK);

        MapTileProviderArray MyTileProvider = new MapTileProviderArray(tileSource, null, myProviders);

        TilesOverlay MyTilesOverlay = new TilesOverlay(MyTileProvider, FragmentTabsPager.app);
        // MapView Bounds:
        // .northeast = {.latitude = 40.802822, .longitude = -119.172673}, 
        //.southwest = {.latitude = 40.759210, .longitude = -119.23454}})
        // Bounds offset Lat .006720

        //MapTileAssetProvider mtap = new MapTileAssetProvider(assets, tileSource, 0);
        View view = inflater.inflate(R.layout.map, null);
        this.container = (View) view.findViewById(R.id.container);
        mapView = (BoundedMapView) view.findViewById(R.id.mapview);
        mapView.setMapListener(new MapListener() {

            @Override
            public boolean onScroll(ScrollEvent arg0) {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public boolean onZoom(ZoomEvent arg0) {
                Log.d("Zoom:",
                        String.valueOf(arg0.getZoomLevel()) + " dbReady: + "
                                + String.valueOf(FragmentTabsPager.app.dbReady) + " embargoed: "
                                + String.valueOf(FragmentTabsPager.app.embargoClear));
                // if EmbargoClear, allow poi points
                if (FragmentTabsPager.app.dbReady && FragmentTabsPager.app.embargoClear) {
                    if (poiOverlay == null)
                        setPoiLayer();
                    if (arg0.getZoomLevel() > OpenStreetMapFragment.PINS_AT_ZOOM) {
                        if (!mapView.getOverlays().contains(poiOverlay))
                            mapView.getOverlays().add(poiOverlay);
                    } else {
                        if (mapView.getOverlays().contains(poiOverlay))
                            mapView.getOverlays().remove(poiOverlay);
                    }

                    return false;
                }

                return false;
            }

        });
        mResourceProxy = new ResourceProxyImpl(FragmentTabsPager.app);
        mLocationOverlay = new MyLocationOverlay(FragmentTabsPager.app, mapView, mResourceProxy);
        if (Build.VERSION.SDK_INT < 11) {
            // There seems to be an OPENGL issue with the compass rendering 
            // non-hardware accelerated views seem fine
            mLocationOverlay.enableCompass();
        }
        //mapView.setMultiTouchControls(true);

        //ItemizedIconOverlay<OverlayItem> itemOverlay = new ItemizedIconOverlay<OverlayItem>(generateOverlayItems(),
        //poiOverlay = new ItemizedOverlayWithBubble<OverlayItem>(getActivity(), generateOverlayItems(), mapView);

        //mapView = (MapView) view.findViewById(R.id.mapview);
        BoundingBoxE6 bounds = new BoundingBoxE6(northEast, southWest);
        mapView.setScrollableAreaLimit(bounds);
        mapView.getOverlays().add(MyTilesOverlay);
        mapView.getOverlays().add(this.mLocationOverlay);
        //mapView.setTileSource(tileSource);
        mapView.setBuiltInZoomControls(true);
        mapView.setUseDataConnection(false);
        mapController = mapView.getController();
        mapController.setZoom(15);
        GeoPoint point2 = new GeoPoint(40.782818, -119.209042);
        mapController.setCenter(point2);

        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(dbReadyReceiver,
                new IntentFilter("dbReady"));
        if (!FragmentTabsPager.app.embargoClear) {
            Log.d("Embargo", "NOT CLEAR");
            //Embargo NOT clear
            getDeviceLocation();
            getActivity().findViewById(R.id.map_placeholder).setVisibility(View.VISIBLE);
            if (distance != 0) {
                double rounded_distance = ((int) ((distance * 10) + 0.5)) / 10;
                ((TextView) getActivity().findViewById(R.id.map_placeholder_text))
                        .setText("You are " + String.valueOf(rounded_distance) + " miles from the man.");
            }
            mapView.setVisibility(View.GONE);
        } else {
            //Embargo clear
            Log.d("Embargo", "CLEAR");
            mLocationOverlay.enableMyLocation();
            getActivity().findViewById(R.id.map_placeholder).setVisibility(View.GONE);
            mapView.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(dbReadyReceiver);
        if (FragmentTabsPager.app.embargoClear)
            mLocationOverlay.disableMyLocation();

        if (deviceLocation != null)
            deviceLocation.stopListening();
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        if (!FragmentTabsPager.app.embargoClear) {
            MenuItem unlockItem = menu.add(Menu.NONE, R.id.menu_unlock, Menu.NONE, "Unlock");
            MenuItemCompat.setShowAsAction(unlockItem, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
            unlockItem.setIcon(R.drawable.unlock);
            unlockItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {

                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    if (!FragmentTabsPager.app.embargoClear) {
                        AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());

                        alert.setTitle("Enter Unlock Password");

                        // Set an EditText view to get user input 
                        final EditText input = new EditText(getActivity());
                        input.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
                        alert.setView(input);
                        alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {
                                String value = input.getText().toString();
                                if (value.compareTo(FragmentTabsPager.app.unlockPassword) == 0) {
                                    FragmentTabsPager.app.setEmbargoClear(true);
                                    mLocationOverlay.enableMyLocation();
                                    getActivity().findViewById(R.id.map_placeholder).setVisibility(View.GONE);
                                    mapView.setVisibility(View.VISIBLE);

                                } else {
                                    dialog.cancel();
                                    AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
                                    alert.setTitle("Invalid Password");
                                    alert.show();
                                }
                            }
                        });

                        alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {
                            }
                        });

                        alert.show();
                        //FragmentTabsPager.app.embargoClear = true;
                    }
                    return false;
                }

            });
        }

    } // end OnCreateOptionsMenu

    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }

    public static ArrayList<OverlayItem> generateOverlayItems() {

        final ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
        String[] projection = new String[] { CampTable.COLUMN_NAME, CampTable.COLUMN_LATITUDE,
                CampTable.COLUMN_LONGITUDE, CampTable.COLUMN_ID };
        Cursor camps = FragmentTabsPager.app.getContentResolver().query(PlayaContentProvider.CAMP_URI, projection,
                null, null, CampTable.COLUMN_LATITUDE + " ASC");
        if (camps.moveToFirst()) {
            Drawable base_pin = FragmentTabsPager.app.getResources().getDrawable(R.drawable.red_pin);
            OverlayItem item;
            do {
                if (!camps.isNull(camps.getColumnIndex(CampTable.COLUMN_LATITUDE))) {
                    item = new OverlayItem(camps.getString(camps.getColumnIndex(CampTable.COLUMN_NAME)),
                            camps.getString(camps.getColumnIndex(CampTable.COLUMN_ID)),
                            new GeoPoint(camps.getDouble(camps.getColumnIndex(CampTable.COLUMN_LATITUDE)),
                                    camps.getDouble(camps.getColumnIndex(CampTable.COLUMN_LONGITUDE))));
                    item.setMarker(base_pin);
                    items.add(item);
                    //Log.d("Camp Location added", String.valueOf(camps.getDouble(camps.getColumnIndex(CampTable.COLUMN_LATITUDE))) + " : " + camps.getDouble(camps.getColumnIndex(CampTable.COLUMN_LONGITUDE)));
                }

            } while (camps.moveToNext());
        }
        camps.close();
        return items;
    }

    public static class loadOverlayItems extends AsyncTask<Void, Void, ArrayList<OverlayItem>> {
        // This method is executed in a separate thread
        @Override
        protected ArrayList<OverlayItem> doInBackground(Void... input) {
            return generateOverlayItems();
        }

        @Override
        protected void onPostExecute(ArrayList<OverlayItem> result) {

            super.onPostExecute(result);

        }

    }

    private BroadcastReceiver dbReadyReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // 1 -- success, 0 -- error, -1 no data
            int status = intent.getIntExtra("status", -1);
            if (status == 1) {
                setPoiLayer();
            }
        }
    };

    @Override
    public void onDestroy() {
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(dbReadyReceiver);
        super.onDestroy();
    }

    public void setPoiLayer() {
        poiOverlay = new ItemizedOverlayWithFocus<OverlayItem>(generateOverlayItems(),
                new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
                    @Override
                    public boolean onItemSingleTapUp(final int index, final OverlayItem item) {

                        if (mapOverlayShowing == false) {
                            activePoi = index;
                            LayoutInflater layoutInflater = (LayoutInflater) getActivity()
                                    .getSystemService(getActivity().LAYOUT_INFLATER_SERVICE);
                            View popup = layoutInflater.inflate(R.layout.map_item_popup, null);
                            Log.d("itemClick", item.getTitle() + " " + item.mDescription);
                            ((TextView) popup.findViewById(R.id.popup_title)).setText(item.getTitle());
                            popup.setTag(R.id.list_item_related_model, item.mDescription);
                            popup.setOnClickListener(new OnClickListener() {

                                @Override
                                public void onClick(View v) {
                                    pw.dismiss();
                                    //FragmentTabsPager.mViewPager.setCurrentItem(2);
                                    String camp_id = v.getTag(R.id.list_item_related_model).toString();
                                    CampFragment.CursorLoaderListFragment
                                            .showCampPopup(OpenStreetMapFragment.mapView, camp_id);

                                }

                            });

                            pw = new PopupWindow(popup, LayoutParams.MATCH_PARENT, 100, true);
                            pw.setOnDismissListener(new OnDismissListener() {
                                @Override
                                public void onDismiss() {
                                    mapOverlayShowing = false;
                                    poiOverlay.getItem(activePoi)
                                            .setMarker(getResources().getDrawable(R.drawable.red_pin));

                                }
                            });

                            item.setMarker(getResources().getDrawable(R.drawable.blue_pin));
                            pw.setFocusable(true);
                            //pw.setOutsideTouchable(true);
                            pw.setBackgroundDrawable(new BitmapDrawable());
                            //pw.
                            //pw.showAsDropDown(OpenStreetMapFragment.container);
                            pw.showAtLocation(OpenStreetMapFragment.mapView, Gravity.BOTTOM, 0, 0);
                            mapOverlayShowing = true;
                        }
                        return false; // We 'handled' this event.
                    }

                    @Override
                    public boolean onItemLongPress(final int index, final OverlayItem item) {
                        return false;
                    }
                }, mResourceProxy);
    }

    // Registers with LocationService to update appropriate class variables
    // with LocationResult when it's available
    private void getDeviceLocation() {
        deviceLocation = new DeviceLocation();
        LocationResult locationResult = new LocationResult() {
            @Override
            public void gotLocation(final Location location) {
                //Got the location!

                currentLocation = location;
                if (location != null) {
                    currentLat = location.getLatitude();
                    currentLon = location.getLongitude();
                    distance = DataUtils.distanceFromTheMan(currentLat, currentLon);
                    Log.d("RefreshLocation", String.valueOf(currentLat) + " , " + String.valueOf(currentLon)
                            + ": Distance fom man: " + String.valueOf(distance));
                    if (distance < DataUtils.MAN_DISTANCE_THRESHOLD) {
                        sendEmbargoClearMessage(1); // success
                        deviceLocation.stopListening();
                        mLocationOverlay.enableMyLocation();
                        getActivity().findViewById(R.id.map_placeholder).setVisibility(View.GONE);
                        mapView.setVisibility(View.VISIBLE);

                    } else {
                        if (distance != 0) {
                            double rounded_distance = ((int) ((distance * 10) + 0.5)) / 10;
                            //((TextView)container.findViewById(R.id.map_placeholder_text)).setText("You are " + String.valueOf(rounded_distance) + " miles from the man.");
                        }
                    }

                }
                hasLocation = true;
            };
        };
        deviceLocation.getLocation(getActivity(), locationResult);
    }

    private void sendEmbargoClearMessage(int status) {
        Intent intent = new Intent("embargoClear");
        intent.putExtra("status", status);
        LocalBroadcastManager.getInstance(FragmentTabsPager.app).sendBroadcast(intent);
    }

    public static void centerMap(GeoPoint point) {
        //mapController.animateTo(point);
        mapController.setCenter(point);
        mapController.setZoom(18);

    }

}