package modestMapsMT;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.io.File;
import java.io.FileInputStream;
import java.nio.DoubleBuffer;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import javax.media.opengl.GL;
import org.mt4j.MTApplication;
import org.mt4j.components.MTComponent;
import org.mt4j.components.TransformSpace;
import org.mt4j.components.interfaces.IMTComponent3D;
import org.mt4j.components.visibleComponents.shapes.MTEllipse;
import org.mt4j.components.visibleComponents.widgets.MTImage;
import org.mt4j.components.visibleComponents.widgets.buttons.MTImageButton;
import org.mt4j.components.visibleComponents.widgets.progressBar.AbstractProgressThread;
import org.mt4j.components.visibleComponents.widgets.progressBar.MTProgressBar;
import org.mt4j.input.IMTEventListener;
import org.mt4j.input.IMTInputEventListener;
import org.mt4j.input.MTEvent;
import org.mt4j.input.inputData.InputMotion;
import org.mt4j.input.inputData.MTInputEvent;
import org.mt4j.input.inputProcessors.IGestureEventListener;
import org.mt4j.input.inputProcessors.MTGestureEvent;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragEvent;
import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.rotateProcessor.RotateProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.scaleProcessor.ScaleEvent;
import org.mt4j.input.inputProcessors.componentProcessors.scaleProcessor.ScaleProcessor;
import org.mt4j.input.inputProcessors.componentProcessors.tapProcessor.TapEvent;
import org.mt4j.input.inputProcessors.componentProcessors.tapProcessor.TapProcessor;
import org.mt4j.input.inputProcessors.globalProcessors.rawFingerProcessor.RawFingerEvent;
import org.mt4j.input.inputProcessors.globalProcessors.rawFingerProcessor.RawFingerProcessor;
import org.mt4j.sceneManagement.AbstractScene;
import org.mt4j.sceneManagement.IPreDrawAction;
import org.mt4j.util.ConstantsAndSettings;
import org.mt4j.util.camera.MTCamera;
import org.mt4j.util.math.Matrix;
import org.mt4j.util.math.Vector3D;
import processing.core.PImage;
import processing.opengl.PGraphicsOpenGL;
import com.aetrion.flickr.Flickr;
import com.aetrion.flickr.photos.GeoData;
import com.aetrion.flickr.photos.Photo;
import com.aetrion.flickr.photos.SearchParameters;
import com.modestmaps.TestInteractiveMap;
import com.modestmaps.core.Point2f;
import com.modestmaps.geo.Location;
import com.modestmaps.providers.AbstractMapProvider;
import com.modestmaps.providers.BlueMarble;
import com.modestmaps.providers.CloudMade;
import com.modestmaps.providers.DailyPlanet;
import com.modestmaps.providers.Microsoft;
import com.modestmaps.providers.OpenAerialMap;
import com.modestmaps.providers.OpenStreetMaps;
import flickrMT.FlickrLoader;
public class MapsScene extends AbstractScene implements MouseWheelListener, MouseListener, IMTInputEventListener {
private TestInteractiveMap map;
private MTApplication p;
private MTComponent fingerCircleContainer;
private MTComponent fotoTagContainer;
private MTComponent fotoContainer;
private MTComponent buttonContainer;
private HashMap<InputMotion, MTEllipse> motionIDToFingerPoint;
private MTCamera defaultCenterCam;
private MTProgressBar progressBar;
private Map<MTEllipse, Photo> tagToPhoto;
public MapsScene(MTApplication mtApplication, String name) {
super(mtApplication, name);
this.p = mtApplication;
defaultCenterCam = new MTCamera(p);
//Container for the foto tags on the map
fotoTagContainer = new MTComponent(p);
//Container for the touch points
fingerCircleContainer = new MTComponent(p);
fingerCircleContainer.attachCamera(defaultCenterCam);
fingerCircleContainer.setDepthBufferDisabled(true);
//Container for the Fotos
fotoContainer = new MTComponent(p);
fotoContainer.attachCamera(defaultCenterCam);
//Container for the buttons
buttonContainer = new MTComponent(p);
buttonContainer.attachCamera(defaultCenterCam);
//Map to match the finger to the visible touch point circle
motionIDToFingerPoint = new HashMap<InputMotion, MTEllipse>();
RawFingerProcessor allInputAnalyzer = new RawFingerProcessor();
this.registerGlobalInputProcessor( allInputAnalyzer);
allInputAnalyzer.addProcessorListener(this);
//Create map
AbstractMapProvider mapProvider = new Microsoft.HybridProvider();
map = new TestInteractiveMap(mtApplication, mapProvider);
map.setName("map");
map.MAX_IMAGES_TO_KEEP = 256;
//TODO ENABLE
// map.zoomIn();
map.registerInputProcessor(new DragProcessor(mtApplication));
map.setGestureAllowance(DragProcessor.class, true);
map.addGestureListener(DragProcessor.class, new MapDrag());
map.registerInputProcessor(new ScaleProcessor(mtApplication));
map.setGestureAllowance(ScaleProcessor.class, true);
map.addGestureListener(ScaleProcessor.class, new MapScale());
map.setGestureAllowance(DragProcessor.class, true);
map.setGestureAllowance(RotateProcessor.class, false);
map.setGestureAllowance(ScaleProcessor.class, true);
map.setGestureAllowance(TapProcessor.class, false);
this.getCanvas().addChild(map);
//Set up the progressbar
progressBar = new MTProgressBar(p, p.loadFont(System.getProperty("user.dir") + File.separator + "data" + File.separator+ "Ziggurat.vlw"));
progressBar.attachCamera(defaultCenterCam);
progressBar.setDepthBufferDisabled(true);
progressBar.setVisible(false);
progressBar.setPickable(false);
this.getCanvas().addChild(progressBar);
this.getCanvas().addChild(fotoTagContainer);
this.getCanvas().addChild(fotoContainer);
this.getCanvas().addChild(buttonContainer);
this.getCanvas().addChild(fingerCircleContainer);
map.sc = 4;
this.updateTagContainerScale();
//Button for foto search
final MTImageButton fotoButton;
PImage fotoButtonImg = p.loadImage(System.getProperty("user.dir")+File.separator + "examples"+ File.separator +"modestMapsMT"+ File.separator + File.separator + "data"+ File.separator + "foto3.png");
fotoButton = new MTImageButton(fotoButtonImg, p);
fotoButton.setName("fotoButton");
fotoButton.setUseDirectGL(false);
fotoButton.setNoStroke(true);
fotoButton.setDepthBufferDisabled(true);
fotoButton.translate(new Vector3D(5, ConstantsAndSettings.getInstance().getScreenHeight()- fotoButton.getHeightXY(TransformSpace.RELATIVE_TO_PARENT) -5, 0));
fotoButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
switch (ae.getID()) {
case TapEvent.BUTTON_CLICKED:
Point[] p = getScreenPoints();
for (int i = 0; i < p.length; i++) {
Point point = p[i];
Location loc = map.pointLocation(point.x ,point.y);
getPictures(loc, getAccuracyForZoom(map), true);
}
getPictures(map.getCenter(), getAccuracyForZoom(map), false);
break;
default:
break;
}
}
});
fotoButton.setTextureEnabled(true);
fotoButton.setUseDirectGL(true);
this.buttonContainer.addChild(fotoButton);
p.addMouseWheelListener(this);
tagToPhoto = new HashMap<MTEllipse, Photo>();
}
private class MapDrag implements IGestureEventListener{
public boolean processGestureEvent(MTGestureEvent g) {
if (g instanceof DragEvent){
DragEvent dragEvent = (DragEvent)g;
Vector3D tVect = dragEvent.getTranslationVect();
map.move(tVect.x, tVect.y);
/*
transVect.setXYZ(tVect.x, tVect.y, 0);
fotoTagContainer.translate(transVect);
*/
// /*
updateTagContainerScale();
// */
}
return true;
}
}
private class MapScale implements IGestureEventListener{
private Vector3D scaleP = new Vector3D(p.width/2, p.height/2, 0);
// scaleP.setXYZ(p.width/2, p.height/2, 0);
public boolean processGestureEvent(MTGestureEvent g) {
if (g instanceof ScaleEvent){
ScaleEvent se = (ScaleEvent)g;
float x = se.getScaleFactorX();
float y = se.getScaleFactorY();
//System.out.println("X:" + x + " Y:" +y);
if (x != 1 && y != 1){
map.sc *= x;
updateTagContainerScale();
MTComponent[] tags = fotoTagContainer.getChildren(); //TODO ohne toArray machen
for (int i = 0; i < tags.length; i++) {
MTComponent baseComponent = tags[i];
if (baseComponent instanceof MTEllipse) {
MTEllipse ell = (MTEllipse) baseComponent;
float scX = 1f/x;
float scY = 1f/y;
// System.out.println("Scaling: " + scX + " " + scY);
// ell.scale(scX, scY, 1, ell.getCenterPointGlobal(), TransformSpace.RELATIVE_TO_WORLD);
ell.scale(scX, scY, 1, ell.getCenterPointRelativeToParent(), TransformSpace.RELATIVE_TO_PARENT);
}
}
//TODO fotos tags mitscalen, damit sie nicht zu gross oder klein sind
// Matrix m = Matrix.getScalingMatrix(scaleP, (float)map.sc, (float)map.sc, 1);
// fotoTagContainer.scale(x, y, 1, scaleP, TransformSpace.RELATIVE_TO_PARENT);
// System.out.println("Map scale: " + map.sc + " Map tx,ty:" + map.tx + "," + map.ty + " TagContainer scale: " + fotoTagContainer.getAbsoluteLocalToWorldMatrix());
// fotoTagContainer.translate( new Vector3D(400,400,0));
// fotoTagContainer.scale(x, y, 1, new Vector3D(0,0,0), TransformSpace.RELATIVE_TO_SELF);
// fotoTagContainer.translate( new Vector3D((float)map.tx, (float)map.ty, 0));
}
}
return true;
}
}
@Override
public void init() {
p.registerKeyEvent(this);
p.addMouseWheelListener(this);
p.addMouseListener(this);
}
@Override
public void shutDown() {
p.unregisterKeyEvent(this);
p.removeMouseWheelListener(this);
p.removeMouseListener(this);
}
/**
* Returns some more or less random points
* on the screen to search for nearby flickr fotos.
*
* @return the screen points
*/
private Point[] getScreenPoints(){
Point[] p = new Point[5];
int sw = ConstantsAndSettings.getInstance().getScreenWidth();
int sh = ConstantsAndSettings.getInstance().getScreenHeight();
float wThird = sw/3f;
float wThirdHalf = wThird/2f;
float hHalf = sh/2f;
p[0] = new Point( Math.round(wThirdHalf), Math.round(hHalf/2f) );
p[1] = new Point( Math.round(wThirdHalf), sh - Math.round(hHalf/2f) );
p[2] = new Point( Math.round(sw/2f), Math.round(sh/2f) );
p[3] = new Point( sw - Math.round(wThirdHalf), Math.round(hHalf/2f) );
p[4] = new Point( sw - Math.round(wThirdHalf), sh - Math.round(hHalf/2f) );
return p;
}
private void getPictures(Location c, int theAccuracy, boolean usePlacesForGeoSearch) {
//TODO zwei verschiednen accuracies suchen? zb, citty und street? von jedem die hälfte zeigen
//TODO wenn keine im screen neu suchen -> erst punkte zeigen, erst foto zeigen laden bei click drauf
SearchParameters sp = new SearchParameters();
int radius = 3;
// /*
sp.setLatitude(new Float(c.lat).toString());
sp.setLongitude(new Float(c.lon).toString());
sp.setRadius(radius);
sp.setRadiusUnits("km");
sp.setHasGeo(true);
sp.setAccuracy(theAccuracy);
sp.setSort(SearchParameters.INTERESTINGNESS_DESC);
// sp.setSort(SearchParameters.INTERESTINGNESS_ASC);
// sp.setSort(SearchParameters.RELEVANCE);
// sp.setSort(SearchParameters.DATE_POSTED_DESC);
// */
/*
Location lowerLeft = map.pointLocation(0, p.height - 0);
System.out.println("Lower Left: " + lowerLeft);
Location upperLeft = map.pointLocation(0,0);
System.out.println("upperleft: " + upperLeft);
Location lowerRight = map.pointLocation(p.height, p.height); //taken height to form box
System.out.println("LowerRight: " + lowerRight);
float extent = (lowerRight.lat-upperLeft.lat );
// extent = 0.05f;
System.out.println("Box Extent: " + extent);
// sp.setBBox(new Float(upperLeft.lat).toString(), new Float(upperLeft.lon).toString(), new Float(lowerRight.lat).toString(), new Float(lowerRight.lon).toString());
sp.setBBox(new Float(upperLeft.lat).toString(), new Float(upperLeft.lon).toString(), new Float(upperLeft.lat + extent).toString(), new Float(upperLeft.lon + extent).toString());
if (extent <= 0){
System.out.println("Extent < 0 - calcing new");
extent = (upperLeft.lat - lowerRight.lat);
sp.setBBox(new Float(lowerRight.lat).toString(), new Float(lowerRight.lon).toString(), new Float(lowerRight.lat + extent).toString(), new Float(lowerRight.lon + extent).toString());
System.out.println("New Box Extent: " + extent);
}
float[] box = new float[]{new Float(sp.getBBox()[0]),new Float(sp.getBBox()[1]),new Float(sp.getBBox()[2]),new Float(sp.getBBox()[3]) };
for (int i = 0; i < box.length; i++) {
float f = box[i];
System.out.println(f);
}
System.out.println("Box width: " + (box[2]-box[0]));
System.out.println("Box height: " + (box[3]- box[1]));
boolean isBox = (box[2]-box[0]) == (box[3]- box[1]);
System.out.println("Is Box: " + isBox);
//Lisboa bbox: 38,704, -9,215 | (38,688, -9,171)
sp.setAccuracy(13);
*/
//TODO radius so anpassen, dass ungefähr der momentane
//map ausschnitt (scale beachten) gesucht wird
System.out.println("Searching for fotos at map center location: " + c + " with radius: " + radius);
String flickrApiKey = "";
String flickrSecret = "";
Properties properties = new Properties();
try {
properties.load(new FileInputStream(System.getProperty("user.dir")+File.separator+"examples"+File.separator+"flickrMT"+File.separator+"data" + File.separator + "FlickrApiKey.txt"));
flickrApiKey = properties.getProperty("FlickrApiKey", " ");
flickrSecret = properties.getProperty("FlickrSecret", " ");
} catch (Exception e) {
System.err.println("Error while loading Settings.txt file. Using defaults.");
}
final FlickrLoader flickrLoader = new FlickrLoader(p, flickrApiKey, flickrSecret, sp, 100);
flickrLoader.setFotoLoadCount(3);
flickrLoader.setUsePlacesForGeoSearch(usePlacesForGeoSearch);
flickrLoader.addProgressFinishedListener(new IMTEventListener(){
public void processMTEvent(MTEvent mtEvent) {
System.out.println("Loading finished!");
p.getCurrentScene().registerPreDrawAction(new IPreDrawAction(){
public boolean isLoop() {
return false;
}
public void processAction() {
progressBar.setVisible(false);
Photo[] photos = flickrLoader.getPhotos();
for (int i = 0; i < photos.length; i++) {
Photo foto = photos[i];
String id = foto.getId();
//System.out.println("Foto ID:" + id);
boolean alreadyContained = false;
Collection<Photo> vlaues = tagToPhoto.values();
for (Iterator<Photo> iterator = vlaues.iterator(); iterator.hasNext();) {
Photo photo = (Photo) iterator.next();
if (photo.getId().equalsIgnoreCase(foto.getId())){
alreadyContained = true;
}
}
if (!alreadyContained/*!tagToPhoto.containsValue(foto)*/){
String fotoName = foto.getTitle();
if (foto.hasGeoData()){
GeoData geo = foto.getGeoData();
float lat = geo.getLatitude();
float lon = geo.getLongitude();
System.out.println("\"" + fotoName + "\"" + " Has GeoData! -> Lat:" + lat + " Lon:" + lon + " PlaceID: " + foto.getPlaceId());
Point2f pointOnScreen = map.locationPoint(new Location(lat, lon));
// System.out.println(" -> Point on Screen: " + pointOnScreen);
Vector3D vecOnScreen = new Vector3D(0,0,0f);
// Vector3D vecOnScreen = new Vector3D(pointOnScreen.x , pointOnScreen.y , 0.01f);
// Vector3D vecOnScreen = new Vector3D(pointOnScreen.x -p.width/2 +128, pointOnScreen.y -p.height/2 +128, 0.01f);
//System.out.println("-> Creating tag at: " + vecOnScreen);
if ( pointOnScreen.x >= 0 && pointOnScreen.x <= p.width
&& pointOnScreen.y >= 0 && pointOnScreen.y <= p.height
){
final MTEllipse tagCircle = new MTEllipse(p, vecOnScreen, 15, 15, 30);
tagCircle.setPickable(true);
tagCircle.setFillColor(90, 205, 230, 200);
tagCircle.setDrawSmooth(true);
tagCircle.setStrokeWeight(2);
tagCircle.setStrokeColor(40, 130, 220, 255);
tagCircle.setGestureAllowance(DragProcessor.class, false);
tagCircle.setGestureAllowance(RotateProcessor.class, false);
tagCircle.setGestureAllowance(ScaleProcessor.class, false);
tagCircle.setGestureAllowance(TapProcessor.class, true);
tagCircle.registerInputProcessor(new TapProcessor(p));
tagCircle.translate(new Vector3D(pointOnScreen.x, pointOnScreen.y , 0.0f));
tagCircle.transform(
fotoTagContainer.getGlobalInverseMatrix()
);
tagCircle.setName(id);
tagToPhoto.put(tagCircle, foto);
fotoTagContainer.addChild(tagCircle);
tagCircle.addGestureListener(TapProcessor.class, new IGestureEventListener(){
@Override
public boolean processGestureEvent(MTGestureEvent g) {
if (g instanceof TapEvent) {
TapEvent ce = (TapEvent) g;
switch (ce.getId()) {
case TapEvent.BUTTON_DOWN:
IMTComponent3D e = ce.getTargetComponent();
Photo foto = tagToPhoto.get(e);
if (foto != null){
SinglePhotoLoader fotoLoader = new SinglePhotoLoader(foto, 50);
fotoLoader.start();
//Disable and remove the fototag
tagCircle.setGestureAllowance(TapProcessor.class, false);
p.getCurrentScene().registerPreDrawAction(new IPreDrawAction(){
public boolean isLoop() {
return false;
}
public void processAction() {
// fotoTagContainer.removeChild(tagCircle);
tagToPhoto.remove(tagCircle);
tagCircle.destroy();
}
});
}
break;
default:
break;
}
}
return true;
}
});
}//if point is on screen
else{
System.out.println("Foto not on screen: position:" + pointOnScreen + " Title: "+ foto.getTitle() + " id:" + id);
}
}else{
System.out.println("Foto already loaded: "+ foto.getTitle() + " id:" + id);
}
/*
ImageCard[] images = flickrLoader.getMtFotos();
ImageCard image = images[i];
if (image != null){
if (pointOnScreen.x >= 0 && pointOnScreen.x <= p.width
&& pointOnScreen.y >= 0 && pointOnScreen.y <= p.height){
image.setUseDirectGL(true);
image.setDisplayCloseButton(true);
// image.translate(new Vector3D((float)(-image.getWidthLocal()/2f) , (float)(-image.getHeightLocal()/2f) , 0.0f));
image.translate(new Vector3D(pointOnScreen.x, pointOnScreen.y , 0.1f));
image.transform(
fotoTagContainer.getAbsoluteWorldToLocalMatrix()
);
// image.scale((float)(1f/map.sc), (float)(1f/map.sc), 1, image.getCenterPointGlobal(), TransformSpace.RELATIVE_TO_WORLD);
fotoContainer.addChild(image);
// Vector3D centerPoint = image.getCenterPointGlobal(); //TODO rename ..Local to ParentRelative
// float width = 15;
// image.scaleGlobal(1/image.getWidthGlobal(), 1/image.getWidthGlobal(), 1, centerPoint);
// image.scaleGlobal(width, width, 1, centerPoint);
// Vector3D centerPoint = image.getCenterPointLocal(); //TODO rename ..Local to ParentRelative
// float width = 15;
// image.scale(1/image.getWidthLocal(), 1/image.getWidthLocal(), 1, centerPoint, TransformSpace.RELATIVE_TO_PARENT);
// image.scale(width, width, 1, centerPoint, TransformSpace.RELATIVE_TO_PARENT);
// image.translate(new Vector3D(pointOnScreen.x , pointOnScreen.y , 0.01f));
// image.setPositionGlobal(new Vector3D(pointOnScreen.x , pointOnScreen.y , 0.01f));
}else{
System.out.println("Image '" + image.getName() + "' out of screen -> remove.");
image.destroy();
}
}
*/
}//if has geo
}//for fotos
}//prcessPreDrawAction()
});//registerPreAction()
}//ProcessMTEvent()
});//addThreadFinishedListener()
progressBar.setProgressInfoProvider(flickrLoader);
progressBar.setVisible(true);
//Run the thread
flickrLoader.start();
}
/**
* Thread for loading a single flickr foto
*/
private class SinglePhotoLoader extends AbstractProgressThread{
private Photo foto;
private MTImage image;
public SinglePhotoLoader(Photo foto, long sleepTime) {
super(sleepTime);
this.foto = foto;
this.setTarget(1); //1 action to do in the thread
}
@Override
public void run() {
try {
Thread.sleep(this.getSleepTime());
} catch (InterruptedException e) {
e.printStackTrace();
}
// String fotoUrl = foto.getSmallUrl();
String fotoUrl = foto.getMediumUrl(); //Get the bigger photo
image = new MTImage(p.loadImage(fotoUrl), p);
this.addProgressFinishedListener(new IMTEventListener(){
public void processMTEvent(MTEvent mtEvent) {
p.getCurrentScene().registerPreDrawAction(new IPreDrawAction(){
public boolean isLoop() {
return false;
}
public void processAction() {
//User direct gl..
image.setDisplayCloseButton(true);
image.scale(0.5f, 0.5f, 1, new Vector3D(0,0,0), TransformSpace.LOCAL);
image.translate(new Vector3D(ConstantsAndSettings.getInstance().getScreenWidth(), 0, 0));
image.tweenTranslate(new Vector3D(-ConstantsAndSettings.getInstance().getScreenWidth(), 0, 0), 600, 0.1f, 0.6f);
fotoContainer.addChild(image);
}
});
}
});
this.setCurrentAction("Loading: " + foto.getTitle());
this.setCurrent(1); //Did 1/1 actions of the thread -> finished
}
}
/**
* Tries to get the best suitable flickr zoom factor for map zoom factor.
* @param map2
* @return the zoom level
*/
private int getAccuracyForZoom(TestInteractiveMap map2) {
//1-4 zoom = world
//5-7 zoom = country
//8-11 zoom = region
//12-15 zoom = city
//16-20 zoom = street
int zoom = map.getZoom();
if (zoom < 1){
System.out.println("zoom < 1 -> Using accuracy: 'ACCURACY_WORLD'");
return Flickr.ACCURACY_WORLD;
}else if (zoom >= 1 && zoom <= 3 ){
System.out.println("Using accuracy: 'ACCURACY_WORLD'");
return Flickr.ACCURACY_WORLD;
}else if (zoom >= 4 && zoom <= 7 ){
System.out.println("Using accuracy: 'ACCURACY_COUNTRY'");
return Flickr.ACCURACY_COUNTRY;
}else if (zoom >= 8 && zoom <= 11 ){
System.out.println("Using accuracy: 'ACCURACY_REGION'");
return Flickr.ACCURACY_REGION;
}else if (zoom >= 12 && zoom <= 14 ){
System.out.println("Using accuracy: 'ACCURACY_CITY'");
return Flickr.ACCURACY_CITY;
}else if (zoom >= 15){
System.out.println("Using accuracy: 'ACCURACY_STREET'");
return Flickr.ACCURACY_STREET;
}else{
System.out.println("Couldnt determine right accuracy -> Using accuracy: 'ACCURACY_REGION'");
return Flickr.ACCURACY_REGION;
}
}
//TODO CLEANUP
private DoubleBuffer model = DoubleBuffer.allocate(16);
private Matrix mgl = new Matrix();
/**
* Kind of a hack to fit the scale of the foto tags to the map scale.
* Has to be called each time the map scale changes.
*/
private void updateTagContainerScale(){
//TODO openGL commands benutzen? und dann modelview auslesen?
model.clear();
PGraphicsOpenGL pgl = ((PGraphicsOpenGL)p.g);
// GL gl = pgl.beginGL();
GL gl = pgl.gl;
gl.glPushMatrix();
gl.glScalef(1, -1, 1);
gl.glTranslatef(p.width/2, p.height/2, 0);
gl.glScalef((float)map.sc, (float)map.sc, 1);
gl.glTranslatef((float)map.tx, (float)map.ty, 0);
gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, model);
gl.glPopMatrix();
// pgl.endGL();
try {
mgl.set(new float[]{(float)model.get(0), (float)model.get(4), (float)model.get(8), (float)model.get(12),
(float)model.get(1), (float)model.get(5), (float)model.get(9), (float)model.get(13),
(float)model.get(2), (float)model.get(6), (float)model.get(10), (float)model.get(14),
(float)model.get(3), (float)model.get(7), (float)model.get(11), (float)model.get(15)});
} catch (Exception e) {
e.printStackTrace();
}
// Matrix mgl = new Matrix(
// (float)model.get(0), (float)model.get(4), (float)model.get(8), (float)model.get(12),
// (float)model.get(1), (float)model.get(5), (float)model.get(9), (float)model.get(13),
// (float)model.get(2), (float)model.get(6), (float)model.get(10), (float)model.get(14),
// (float)model.get(3), (float)model.get(7), (float)model.get(11), (float)model.get(15)
// );
fotoTagContainer.setLocalMatrix(mgl);
// System.out.println(mgl);
/*
Matrix m = Matrix.getTranslationMatrix((float)p.width/2, (float)p.height/2, 0);
Matrix s = Matrix.getScalingMatrix((float)map.sc, (float)map.sc, 1);
Matrix t = Matrix.getTranslationMatrix((float)map.tx, (float)map.ty, 0);
m.multLocal(s);
m.multLocal(t);
// m.translate((float)p.width/2, (float)p.height/2, 0);
// m.scale((float)map.sc);
// m.translate((float)map.tx, (float)map.ty);
System.out.println("2:" + m);
// fotoTagContainer.setLocalBasisMatrix(m);
*/
}
public TestInteractiveMap getMap() {
return map;
}
public void setMap(TestInteractiveMap map) {
this.map = map;
}
@Override
public boolean processInputEvent(MTInputEvent inEvt) {
if (inEvt instanceof RawFingerEvent){
/* draw blobs where fingers touch */
RawFingerEvent ie = (RawFingerEvent)inEvt;
switch (ie.getId()) {
case MTGestureEvent.GESTURE_DETECTED:
MTEllipse fingerCircle = new MTEllipse(p, ie.getInputPosition(), 6, 6, 10);
fingerCircle.setPickable(false);
fingerCircle.setNoFill(true);
fingerCircle.setDrawSmooth(true);
fingerCircle.setStrokeWeight(2);
fingerCircle.setStrokeColor(40, 130, 220, 255);
motionIDToFingerPoint.put(ie.getInputMotion(), fingerCircle);
fingerCircleContainer.addChild(fingerCircle);
break;
case MTGestureEvent.GESTURE_UPDATED:
MTEllipse circle = motionIDToFingerPoint.get(ie.getInputMotion());
circle.setPositionGlobal(ie.getInputPosition());
break;
case MTGestureEvent.GESTURE_ENDED:
MTEllipse e = motionIDToFingerPoint.get(ie.getInputMotion());
fingerCircleContainer.removeChild(e);
e = null;
break;
default:
break;
}
}
return true;
}
public void mouseWheelMoved(MouseWheelEvent e) {
int notches = e.getWheelRotation();
System.out.println(notches);
if (notches < 0) {
// map.zoomIn();
// map.zoom(0.5f);
map.sc *= 1.1f;
p.getCurrentScene().registerPreDrawAction(new IPreDrawAction(){
public boolean isLoop() {
return false;
}
public void processAction() {
updateTagContainerScale();
}
});
} else {
// map.zoomOut();
map.sc *= 0.9f;
p.getCurrentScene().registerPreDrawAction(new IPreDrawAction(){
public boolean isLoop() {
return false;
}
public void processAction() {
updateTagContainerScale();
}
});
}
}
@Override
public void mouseClicked(MouseEvent arg0) {
int b = arg0.getButton();
switch (b) {
case MouseEvent.BUTTON2:
map.setZoom(map.bestZoomForScale((float) map.sc));
p.getCurrentScene().registerPreDrawAction(new IPreDrawAction(){
public boolean isLoop() {
return false;
}
public void processAction() {
updateTagContainerScale();
}
});
break;
case MouseEvent.BUTTON3:
this.getPictures(map.pointLocation(p.mouseX, p.mouseY), this.getAccuracyForZoom(map), true);
break;
default:
break;
}
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
/**
*
* @param e
*/
public void keyEvent(KeyEvent e){
int evtID = e.getID();
if (evtID != KeyEvent.KEY_PRESSED)
return;
switch (e.getKeyCode()){
case KeyEvent.VK_G:
fotoTagContainer.scale(0.75f,0.75f,1, new Vector3D(0,0,0));
fotoTagContainer.scale(1f/0.75f,1f/0.75f,1, new Vector3D(0,0,0));
break;
case KeyEvent.VK_PLUS:
map.zoomIn();
this.updateTagContainerScale();
break;
case KeyEvent.VK_MINUS:
map.zoomOut();
this.updateTagContainerScale();
break;
case KeyEvent.VK_F12:
p.saveFrame();
break;
case KeyEvent.VK_A:
map.setMapProvider( new Microsoft.AerialProvider());
break;
case KeyEvent.VK_R:
map.setMapProvider( new Microsoft.RoadProvider());
break;
case KeyEvent.VK_H:
map.setMapProvider( new Microsoft.HybridProvider());
break;
case KeyEvent.VK_O:
map.setMapProvider( new OpenAerialMap());
break;
case KeyEvent.VK_B:
map.setMapProvider( new BlueMarble());
break;
case KeyEvent.VK_S:
map.setMapProvider( new OpenStreetMaps());
break;
case KeyEvent.VK_C:
map.setMapProvider( new CloudMade.Tourist());
break;
case KeyEvent.VK_D:
map.setMapProvider( new DailyPlanet());
break;
case KeyEvent.VK_BACK_SPACE:
p.popScene();
break;
case KeyEvent.VK_F1:
Location stuttgartLoc = new Location( 48.7771056f, 9.1807688f);
map.setCenterZoom(stuttgartLoc, 15);
System.out.println("Center set to location: " + stuttgartLoc);
break;
case KeyEvent.VK_F2:
Location c = map.getCenter();
this.getPictures(c, this.getAccuracyForZoom(map), true);
break;
case KeyEvent.VK_F3:
Point[] p = this.getScreenPoints();
for (int i = 0; i < p.length; i++) {
Point point = p[i];
Location loc = map.pointLocation(point.x ,point.y);
this.getPictures(loc, this.getAccuracyForZoom(map), true);
}
this.getPictures(map.getCenter(), this.getAccuracyForZoom(map), false);
break;
case KeyEvent.VK_F9:
Location lisbon = new Location(38.693f, -9.198f);
map.setCenterZoom(lisbon, 15);
System.out.println("Center set to location: " + lisbon);
this.updateTagContainerScale();
break;
case KeyEvent.VK_T:
System.out.println("Map zoom: " + map.getZoom()
+ " Map scale: " + map.sc);
break;
default:
break;
}
}
}