/*
* GeoSolutions Android Map Library - 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.listeners;
import java.util.ArrayList;
import it.geosolutions.android.map.utils.ConversionUtilities;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import it.geosolutions.android.map.activities.GetFeatureInfoLayerListActivity;
import it.geosolutions.android.map.common.Constants;
import it.geosolutions.android.map.model.Layer;
import it.geosolutions.android.map.model.query.CircleQuery;
import it.geosolutions.android.map.overlay.managers.MultiSourceOverlayManager;
import it.geosolutions.android.map.view.AdvancedMapView;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
/**
* Listener with a gesture detector for one point selection on map.
* @author Jacopo Pianigiani (jacopo.pianigiani85@gmail.com).
*/
public class OneTapListener implements OnTouchListener, OnGestureListener {
// MODES
private int mode = Constants.Modes.MODE_EDIT;
private AdvancedMapView view;
private Activity activity;
private boolean pointsAcquired;
private SharedPreferences pref;
private float startX, startY, radius_pixel;
private GestureDetector gd;
/**
* Constructor for class OneTapListener.
* @param view
* @param activity
*/
public OneTapListener(AdvancedMapView view, Activity activity){
this.view = view;
this.activity = activity;
pointsAcquired = false;
pref = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
gd = new GestureDetector(view.getContext(),this);
}
/**
* Return x coordinate on map to drawing.
* @return
*/
public float getStartX(){
return startX;
}
/**
* Return y coordinate on map to drawing.
* @return
*/
public float getStartY(){
return startY;
}
/**
* Return radius of selection to draw a circle on map.
* @return
*/
public float getRadius(){
return radius_pixel;
}
/**
* Calculate radius of one point selection and convert coordinates from pixel to long/lat.
*/
public void query_layer(){
if(!pointsAcquired) return;
double x,y, radius;
x = ConversionUtilities.convertFromPixelsToLongitude(view, startX);
y = ConversionUtilities.convertFromPixelsToLatitude(view, startY);
//Calculate radius of one point selection
float radius_pixel = (float)pref.getInt("OnePointSelectionRadius", 10);
double fin_x = ConversionUtilities.convertFromPixelsToLongitude(view, startX+radius_pixel);
radius = Math.abs(fin_x - x);
Log.v("MAPINFOTOOL", "circle: center (" + x + "," + y + ") radius " + radius);
infoDialogCircle(x,y,radius,view.getMapViewPosition().getZoomLevel());
}
/**
* Create a Feature Query for one point selection and pass it to an activity via intent.
* @param x
* @param y
* @param radius
* @param zooomLevel
*/
private void infoDialogCircle(final double x, final double y, final double radius, byte zoomLevel){
try{
ArrayList<Layer> layerNames = getLayers();
Intent i = new Intent(view.getContext(),
GetFeatureInfoLayerListActivity.class);
i.putExtra(Constants.ParamKeys.LAYERS, layerNames);
CircleQuery query = new CircleQuery();
query.setX(x);
query.setY(y);
query.setRadius(radius);
query.setSrid("4326");
query.setZoomLevel(zoomLevel);
i.putExtra("query", query);
if (mode == Constants.Modes.MODE_EDIT) {
i.setAction(Intent.ACTION_PICK);
} else {
i.setAction(Intent.ACTION_VIEW);
}
activity.startActivityForResult(i,
GetFeatureInfoLayerListActivity.CIRCLE_REQUEST);
}catch(Exception ex){
Log.e("Exception launched ", ex.getMessage());
}
}
/**
* Get layers from the mapView
* @return an arrayList of layers
*/
private ArrayList<Layer> getLayers() {
MultiSourceOverlayManager manager = view.getLayerManager();
ArrayList<Layer> layers = manager.getLayers();
ArrayList<Layer> result =new ArrayList<Layer>();
for(Layer layer:layers){
if(layer.isVisibility()){
result.add(layer);
}
}
return result;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
radius_pixel = (float)pref.getInt("OnePointSelectionRadius", 10);
return gd.onTouchEvent(event);
}
/**
* Return mode.
* @return
*/
public int getMode() {
return mode;
}
/**
* Set mode.
* @param mode
*/
public void setMode(int mode) {
this.mode = mode;
}
/**
* Return true if points have been acquired, false otherwise
* @return
*/
public boolean pointsAcquired(){
return pointsAcquired;
}
@Override
public boolean onDown(MotionEvent e) {
startX = e.getX();
startY = e.getY();
view.redraw(false);
pointsAcquired = true;
return false;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
query_layer();
pointsAcquired = false;
view.redraw(false);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
pointsAcquired = false;
return false;
}
@Override
public void onShowPress(MotionEvent e) {}
@Override
public boolean onSingleTapUp(MotionEvent e) {
query_layer();
pointsAcquired = false;
view.redraw(false);
return true;
}
}