/*********************************************************************** * mt4j Copyright (c) 2008 - 2010 Christopher Ruff, Fraunhofer-Gesellschaft All rights reserved. * * 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 advanced.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.font.FontManager; import org.mt4j.components.visibleComponents.font.IFont; import org.mt4j.components.visibleComponents.shapes.AbstractShape; import org.mt4j.components.visibleComponents.shapes.MTEllipse; import org.mt4j.components.visibleComponents.shapes.MTRoundRectangle; import org.mt4j.components.visibleComponents.shapes.MTRectangle.PositionAnchor; import org.mt4j.components.visibleComponents.widgets.MTImage; import org.mt4j.components.visibleComponents.widgets.MTList; import org.mt4j.components.visibleComponents.widgets.MTListCell; import org.mt4j.components.visibleComponents.widgets.MTTextArea; 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.MTEvent; 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.CursorTracer; import org.mt4j.sceneManagement.AbstractScene; import org.mt4j.sceneManagement.IPreDrawAction; import org.mt4j.util.MT4jSettings; import org.mt4j.util.MTColor; import org.mt4j.util.animation.Animation; import org.mt4j.util.animation.AnimationEvent; import org.mt4j.util.animation.IAnimationListener; import org.mt4j.util.animation.MultiPurposeInterpolator; 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 advanced.flickrMT.FlickrLoader; 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.OpenStreetMaps; /** * The Class MapsScene. * * @author Christopher Ruff */ public class MapsScene extends AbstractScene implements MouseWheelListener, MouseListener { /** The map. */ private TestInteractiveMap map; /** The p. */ private MTApplication p; /** The tag container. */ private MTComponent tagContainer; /** The foto container. */ private MTComponent fotoContainer; /** The button container. */ private MTComponent buttonContainer; /** The default center cam. */ private MTCamera defaultCenterCam; /** The progress bar. */ private MTProgressBar progressBar; /** The tag to photo. */ private Map<MTEllipse, Photo> tagToPhoto; //TODO button/gesture for optimal zoom level - map.setZoom(map.bestZoomForScale((float) map.sc)); ? /** * Instantiates a new maps scene. * * @param mtApplication the mt application * @param name the name */ public MapsScene(MTApplication mtApplication, String name) { super(mtApplication, name); this.p = mtApplication; if (!MT4jSettings.getInstance().isOpenGlMode()){ System.err.println("Scene only usable when using the OpenGL renderer! - See settings.txt"); return; } //Show our touches this.registerGlobalInputProcessor(new CursorTracer(mtApplication, this)); defaultCenterCam = new MTCamera(p); //Container for the foto tags on the map tagContainer = new MTComponent(p); //Container for the Fotos fotoContainer = new MTComponent(p); fotoContainer.attachCamera(defaultCenterCam); //Container for the buttons buttonContainer = new MTComponent(p); buttonContainer.attachCamera(defaultCenterCam); //Create map AbstractMapProvider mapProvider = new Microsoft.HybridProvider(); map = new TestInteractiveMap(mtApplication, mapProvider); map.setName("map"); map.MAX_IMAGES_TO_KEEP = 256; map.sc = 4; //Initial map scale //Map gestures map.registerInputProcessor(new DragProcessor(mtApplication)); map.addGestureListener(DragProcessor.class, new MapDrag()); map.registerInputProcessor(new ScaleProcessor(mtApplication)); map.addGestureListener(ScaleProcessor.class, new MapScale()); map.setGestureAllowance(RotateProcessor.class, false); this.getCanvas().addChild(map); //Set up the progressbar // progressBar = new MTProgressBar(p, p.loadFont(MT4jSettings.getInstance().getDefaultFontPath() + "Ziggurat.vlw")); // progressBar = new MTProgressBar(p, p.loadFont("arial")); progressBar = new MTProgressBar(p, p.createFont("arial", 18)); progressBar.attachCamera(defaultCenterCam); progressBar.setDepthBufferDisabled(true); progressBar.setVisible(false); progressBar.setPickable(false); this.getCanvas().addChild(progressBar); this.getCanvas().addChild(tagContainer); this.getCanvas().addChild(fotoContainer); this.getCanvas().addChild(buttonContainer); //Button for foto search final MTImageButton fotoButton; // PImage fotoButtonImg = p.loadImage(System.getProperty("user.dir")+File.separator + "examples"+ File.separator +"advanced"+ File.separator+ File.separator +"modestMapsMT"+ File.separator + File.separator + "data"+ File.separator + // "foto6.png"); //Load image from classpath PImage fotoButtonImg = p.loadImage( "advanced" + MTApplication.separator + "modestMapsMT" + MTApplication.separator + "data" + MTApplication.separator + "foto6.png"); fotoButtonImg.resize((int)(fotoButtonImg.width/1.5f), (int)(fotoButtonImg.height/1.5f)); fotoButton = new MTImageButton(fotoButtonImg, p); fotoButton.setName("fotoButton"); fotoButton.setNoStroke(true); fotoButton.setDepthBufferDisabled(true); //Draw on top of everything // fotoButton.translate(new Vector3D(MT4jSettings.getInstance().getScreenWidth() - fotoButton.getWidthXY(TransformSpace.RELATIVE_TO_PARENT) -5, MT4jSettings.getInstance().getScreenHeight()- fotoButton.getHeightXY(TransformSpace.RELATIVE_TO_PARENT) -5, 0)); fotoButton.translate(new Vector3D(0, MT4jSettings.getInstance().getWindowHeight()- fotoButton.getHeightXY(TransformSpace.RELATIVE_TO_PARENT) , 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); } } }); fotoButton.setTextureEnabled(true); fotoButton.setUseDirectGL(true); this.buttonContainer.addChild(fotoButton); tagToPhoto = new HashMap<MTEllipse, Photo>(); /// Create map provider menu \\\ IFont font = FontManager.getInstance().createFont(p, "SansSerif.Bold", 15, MTColor.WHITE, MTColor.WHITE); MTRoundRectangle mapMenu = new MTRoundRectangle(0,0,0, 220,335, 20,20, p); // mapMenu.setFillColor(new MTColor(110,110,110,180)); // mapMenu.setStrokeColor(new MTColor(110,110,110,180)); mapMenu.setFillColor(new MTColor(35,35,35,180)); mapMenu.setStrokeColor(new MTColor(35,35,35,180)); mapMenu.setPositionGlobal(new Vector3D(p.width/2f, p.height/2f)); mapMenu.translateGlobal(new Vector3D(-p.width/2f - 80,0)); getCanvas().addChild(mapMenu); float cellWidth = 155; float cellHeight = 40; MTColor cellFillColor = new MTColor(new MTColor(0,0,0,210)); MTColor cellPressedFillColor = new MTColor(new MTColor(20,20,20,220)); MTList list = new MTList(0,0, 152, 7* cellHeight + 7*3, p); list.setChildClip(null); //FIXME TEST -> do no clipping for performance list.setNoFill(true); list.setNoStroke(true); list.unregisterAllInputProcessors(); list.setAnchor(PositionAnchor.CENTER); list.setPositionRelativeToParent(mapMenu.getCenterPointLocal()); mapMenu.addChild(list); list.addListElement(this.createListCell("Microsoft Aerial", font, new Microsoft.AerialProvider(), cellWidth, cellHeight, cellFillColor, cellPressedFillColor)); list.addListElement(this.createListCell("Microsoft Road", font, new Microsoft.RoadProvider(), cellWidth, cellHeight, cellFillColor, cellPressedFillColor)); list.addListElement(this.createListCell("Microsoft Hybrid", font, new Microsoft.HybridProvider(), cellWidth, cellHeight, cellFillColor, cellPressedFillColor)); list.addListElement(this.createListCell("Open Street Maps", font, new OpenStreetMaps(), cellWidth, cellHeight, cellFillColor, cellPressedFillColor)); list.addListElement(this.createListCell("Cloudmade Tourist", font, new CloudMade.Tourist(), cellWidth, cellHeight, cellFillColor, cellPressedFillColor)); list.addListElement(this.createListCell("Blue Marble", font, new BlueMarble(), cellWidth, cellHeight, cellFillColor, cellPressedFillColor)); list.addListElement(this.createListCell("Daily Planet", font, new DailyPlanet(), cellWidth, cellHeight, cellFillColor, cellPressedFillColor)); MultiPurposeInterpolator in = new MultiPurposeInterpolator(0,170, 700, 0.1f, 0.7f, 1); final Animation slideOut = new Animation("slide out animation", in, mapMenu); slideOut.addAnimationListener(new IAnimationListener() { public void processAnimationEvent(AnimationEvent ae) { float delta = ae.getCurrentStepDelta(); ((IMTComponent3D)ae.getTargetObject()).translateGlobal(new Vector3D(delta,0,0)); switch (ae.getId()) { case AnimationEvent.ANIMATION_ENDED: doSlideIn = true; animationRunning = false; break; } } }); final Animation slideIn = new Animation("slide out animation", in, mapMenu); slideIn.addAnimationListener(new IAnimationListener() { public void processAnimationEvent(AnimationEvent ae) { float delta = -ae.getCurrentStepDelta(); ((IMTComponent3D)ae.getTargetObject()).translateGlobal(new Vector3D(delta,0,0)); switch (ae.getId()) { case AnimationEvent.ANIMATION_ENDED: doSlideIn = false; animationRunning = false; break; } } }); mapMenu.unregisterAllInputProcessors(); mapMenu.registerInputProcessor(new TapProcessor(mtApplication, 50)); mapMenu.addGestureListener(TapProcessor.class, new IGestureEventListener() { public boolean processGestureEvent(MTGestureEvent ge) { if (((TapEvent)ge).getTapID() == TapEvent.BUTTON_CLICKED){ if (!animationRunning){ animationRunning = true; if (doSlideIn){ slideIn.start(); }else{ slideOut.start(); } } } return false; } }); } private boolean animationRunning = false; private boolean doSlideIn = false; private MTListCell createListCell(final String label, IFont font, final AbstractMapProvider mapProvider, float cellWidth, float cellHeight, final MTColor cellFillColor, final MTColor cellPressedFillColor){ final MTListCell cell = new MTListCell(cellWidth, cellHeight, p); cell.setChildClip(null); //FIXME TEST, no clipping for performance! cell.setFillColor(cellFillColor); MTTextArea listLabel = new MTTextArea(p, font); listLabel.setNoFill(true); listLabel.setNoStroke(true); listLabel.setText(label); cell.addChild(listLabel); listLabel.setPositionRelativeToParent(cell.getCenterPointLocal()); cell.unregisterAllInputProcessors(); cell.registerInputProcessor(new TapProcessor(p, 15)); cell.addGestureListener(TapProcessor.class, new IGestureEventListener() { public boolean processGestureEvent(MTGestureEvent ge) { TapEvent te = (TapEvent)ge; switch (te.getTapID()) { case TapEvent.BUTTON_DOWN: cell.setFillColor(cellPressedFillColor); break; case TapEvent.BUTTON_UP: cell.setFillColor(cellFillColor); break; case TapEvent.BUTTON_CLICKED: // System.out.println("Button clicked: " + label); cell.setFillColor(cellFillColor); map.setMapProvider(mapProvider); break; } return false; } }); return cell; } /** * The Class MapDrag. * @author C.Ruff */ 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 false; } } /** * The Class MapScale. * * @author C.Ruff */ 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 scaleX = se.getScaleFactorX(); //System.out.println("X:" + x + " Y:" +y); //Scale the map and the tags scaleMap(scaleX); } return false; } } /** * Scale the map and also the tags. * * @param scaleFactor the scale factor */ private void scaleMap(float scaleFactor){ if (scaleFactor != 1){ map.sc *= scaleFactor; updateTagContainerScale(); updateTagShapeScale(scaleFactor); } } //TODO CLEANUP /** The model. */ private DoubleBuffer model = DoubleBuffer.allocate(16); /** The mgl. */ 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(){ 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(); } tagContainer.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); */ } /** * Inversely scales the tagcontainers child shapes so they * appear to be the same size, independent of the map's scale. * * @param scale the scale */ private void updateTagShapeScale(float scale){ MTComponent[] tags = tagContainer.getChildren(); float scX = 1f/scale; for (int i = 0; i < tags.length; i++) { MTComponent baseComponent = tags[i]; if (baseComponent instanceof AbstractShape) { AbstractShape shape = (AbstractShape) baseComponent; // System.out.println("Scaling: " + scX + " " + scY); // shape.scale(scX, scY, 1, shape.getCenterPointGlobal(), TransformSpace.GLOBAL); shape.scale(scX, scX, 1, shape.getCenterPointRelativeToParent(), TransformSpace.RELATIVE_TO_PARENT); } } } public void init() { p.registerKeyEvent(this); p.addMouseWheelListener(this); p.addMouseListener(this); } 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 = MT4jSettings.getInstance().getWindowWidth(); int sh = MT4jSettings.getInstance().getWindowHeight(); 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; } /** * Gets the pictures. * * @param c the c * @param theAccuracy the the accuracy * @param usePlacesForGeoSearch the use places for geo search * * @return the pictures */ 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 +"advanced"+ File.separator+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 FlickrApiKey.txt file."); } 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(new MTColor(90, 205, 230, 200)); tagCircle.setDrawSmooth(true); tagCircle.setStrokeWeight(2); tagCircle.setStrokeColor(new MTColor(40, 130, 220, 255)); tagCircle.translate(new Vector3D(pointOnScreen.x, pointOnScreen.y , 0.0f)); tagCircle.transform(tagContainer.getGlobalInverseMatrix()); tagCircle.setName(id); tagToPhoto.put(tagCircle, foto); tagContainer.addChild(tagCircle); tagCircle.unregisterAllInputProcessors(); tagCircle.registerInputProcessor(new TapProcessor(p)); tagCircle.addGestureListener(TapProcessor.class, new IGestureEventListener(){ //@Override public boolean processGestureEvent(MTGestureEvent g) { if (g instanceof TapEvent) { TapEvent ce = (TapEvent) g; switch (ce.getTapID()) { 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{ /** The foto. */ private Photo foto; /** The image. */ private MTImage image; /** * Instantiates a new single photo loader. * * @param foto the foto * @param sleepTime the sleep time */ public SinglePhotoLoader(Photo foto, long sleepTime) { super(sleepTime); this.foto = foto; this.setTarget(1); //1 action to do in the thread } //@Override /* (non-Javadoc) * @see org.mt4j.components.visibleComponents.widgets.progressBar.AbstractProgressThread#run() */ 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(MT4jSettings.getInstance().getWindowWidth(), 0, 0)); image.tweenTranslate(new Vector3D(-MT4jSettings.getInstance().getWindowWidth(), 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 the 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; } } /** * Gets the map. * * @return the map */ public TestInteractiveMap getMap() { return map; } /** * Sets the map. * * @param map the new map */ public void setMap(TestInteractiveMap map) { this.map = map; } public void mouseWheelMoved(MouseWheelEvent e) { int notches = e.getWheelRotation(); System.out.println(notches); if (notches < 0) { p.getCurrentScene().registerPreDrawAction(new IPreDrawAction(){ public boolean isLoop() { return false; } public void processAction() { scaleMap(1.1f); } }); } else { p.getCurrentScene().registerPreDrawAction(new IPreDrawAction(){ public boolean isLoop() { return false; } public void processAction() { scaleMap(0.9f); } }); } } 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; } } public void mouseEntered(MouseEvent arg0) { } public void mouseExited(MouseEvent arg0) { } public void mousePressed(MouseEvent arg0) { } public void mouseReleased(MouseEvent arg0) { } /** * Key event. * * @param e the e */ public void keyEvent(KeyEvent e){ int evtID = e.getID(); if (evtID != KeyEvent.KEY_PRESSED) return; switch (e.getKeyCode()){ case KeyEvent.VK_G: tagContainer.scale(0.75f,0.75f,1, new Vector3D(0,0,0)); tagContainer.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()); //FIXME NOT WORKING ANYMORE // 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; } } }