/* * 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 java.util.List; import eu.geopaparazzi.spatialite.database.spatial.core.SpatialVectorTable; import it.geosolutions.android.map.activities.GetFeatureInfoLayerListActivity; import it.geosolutions.android.map.common.Constants; import it.geosolutions.android.map.common.Constants.Modes; import it.geosolutions.android.map.database.SpatialDataSourceManager; import it.geosolutions.android.map.model.Layer; import it.geosolutions.android.map.model.query.PolygonQuery; import it.geosolutions.android.map.overlay.managers.MultiSourceOverlayManager; import it.geosolutions.android.map.style.AdvancedStyle; import it.geosolutions.android.map.style.StyleManager; import it.geosolutions.android.map.utils.ConversionUtilities; import it.geosolutions.android.map.utils.StyleUtils; import it.geosolutions.android.map.utils.Coordinates.Coordinates; import it.geosolutions.android.map.utils.Coordinates.Coordinates_Query; import it.geosolutions.android.map.view.AdvancedMapView; import android.app.Activity; import android.content.Intent; import android.util.Log; import android.view.GestureDetector; import android.view.GestureDetector.OnDoubleTapListener; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; /** * Listener to implements double tap event on map. * @author Jacopo Pianigiani (jacopo.pianigiani85@gmail.com). */ public class PolygonTapListener implements OnGestureListener, OnDoubleTapListener, OnTouchListener{ private int mode = Modes.MODE_EDIT; private AdvancedMapView view; private Activity activity; private GestureDetector gd; private ArrayList<Coordinates> points; //Store coordinates of points touched on map. private boolean pointsAcquired, acquisitionStarted; private Coordinates new_point; private float startX, startY; /** * Constructor for class PolygonTapListener * @param view * @param activity */ public PolygonTapListener(AdvancedMapView view, Activity activity){ this.view = view; this.activity = activity; pointsAcquired = false; acquisitionStarted = true; points = new ArrayList<Coordinates>(); gd = new GestureDetector(view.getContext(),this); } /** * Create a new ArrayList with points captured converted from pixel to latitude/longitude, ready for query */ public void preparePoints(){ Coordinates point; Coordinates_Query to_add; //It will contain long/lat of the points that will be used to query on spatialite database ArrayList<Coordinates_Query> polygon_points = new ArrayList<Coordinates_Query>(); for(int i = 0; i<points.size()-1; i++){ //Exclude last point because with double tap it will be captured twice point = points.get(i); to_add = new Coordinates_Query(point.getX(),point.getY()); polygon_points.add(to_add); } infoDialogPolygon(polygon_points,view.getMapViewPosition().getZoomLevel()); } /** * Create a Feature Query for polygonal selection and passes to an GetFeatureInfoLayerListActivity via intent. * @param polygon_points * @param zoomLevel */ private void infoDialogPolygon(final ArrayList<Coordinates_Query> polygon_points,byte zoomLevel){ try { ArrayList<Layer> layers = getLayers(); Intent i = new Intent(view.getContext(), GetFeatureInfoLayerListActivity.class); i.putExtra(Constants.ParamKeys.LAYERS, layers); PolygonQuery query = new PolygonQuery(); query.setPolygonPoints(polygon_points); query.setSrid("4326"); query.setZoomLevel(zoomLevel); i.putExtra("query", query); if (mode == Modes.MODE_EDIT) { i.setAction(Intent.ACTION_PICK); } else { i.setAction(Intent.ACTION_VIEW); } activity.startActivityForResult(i, GetFeatureInfoLayerListActivity.POLYGON_REQUEST); } catch (Exception ex) { Log.e("Exception launched", ex.getMessage()); } reset(); } /** * 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; } /** * Return mode value * @return */ public int getMode() { return mode; } /** * Set mode * @param mode */ public void setMode(int mode) { this.mode = mode; } /** * Return true if a double tap event has been captured and all points of a polygonal selection * are available. * @return */ public boolean isPointsAcquired(){ return pointsAcquired; } /** * Return true if acquisition of points is started, otherwise return false. * @return */ public boolean isAcquisitionStarted(){ return acquisitionStarted; } @Override public boolean onDoubleTap(MotionEvent arg0) { pointsAcquired = true; preparePoints(); return false; } @Override public boolean onDoubleTapEvent(MotionEvent e) { return false; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { return false; } @Override public boolean onDown(MotionEvent event) { //Use this to capture points for polygonal selection startX = event.getX(); startY = event.getY(); //Convert coordinates of point in longitude/latitude. new_point = new Coordinates(ConversionUtilities.convertFromPixelsToLongitude(view, startX), ConversionUtilities.convertFromPixelsToLatitude(view, startY)); return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } @Override public void onLongPress(MotionEvent e){} @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } @Override public void onShowPress(MotionEvent e){} @Override public boolean onSingleTapUp(MotionEvent e) { points.add(new_point); acquisitionStarted = true; view.redraw(false); return true; } @Override public boolean onTouch(View v, MotionEvent event){ return gd.onTouchEvent(event); } /** * Return number of points that are currently acquired * @return */ public int getNumberOfPoints(){ return points.size(); } /** * Return x coordinate(longitude) for a point of selection. * @param index * @return */ public double getXPoint(int index){ return points.get(index).getX(); } /** * Return y coordinate(latitude) for a point of selection. * @param index * @return */ public double getYPoint(int index){ return points.get(index).getY(); } /** * Clear collection of point and restore initial configuration by selection */ public void reset(){ points.clear(); pointsAcquired = false; acquisitionStarted = false; view.redraw(false); } }