Skip to content
Snippets Groups Projects
Commit 2fb56bed authored by Eirik Steira's avatar Eirik Steira
Browse files

Add GMapFX - Google Map API depencendy

Registered Google Maps API key in order to view the map

Fix find or create tag to search by name instead of id since non-existing tags wont have id

Fix recursion in Image, Album and Tag toString

Auto stash before checking out "HEAD"
Fix checkout commit issues
parent 1f8ac880
No related branches found
No related tags found
1 merge request!165Weekly merge to Master
......@@ -128,6 +128,20 @@
<version>1.56</version>
</dependency>
<!-- Google Maps API -->
<dependency>
<groupId>com.lynden</groupId>
<artifactId>GMapsFX</artifactId>
<version>2.12.0</version>
<exclusions>
<!-- Exclude svf4j found in logback-->
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
......
......@@ -111,8 +111,7 @@ public class ExploreAlbums implements Initializable {
try {
return albumService.getAllAlbums();
} catch (Exception e) {
logger.error("[x] Failed to fetch albums");
e.printStackTrace();
logger.error("[x] Failed to fetch albums", e);
}
return new ArrayList<>();
}
......@@ -165,8 +164,7 @@ public class ExploreAlbums implements Initializable {
try {
return album.getImages();
} catch (Exception e) {
logger.error("[x] Failed to fetch images for album {}", album);
e.printStackTrace();
logger.error("[x] Failed to fetch images for album {}", album, e);
}
return new ArrayList<>();
}
......@@ -229,8 +227,7 @@ public class ExploreAlbums implements Initializable {
try{
switchToViewAlbum(mouseEvent);
} catch (IOException ex) {
logger.error("[x] Failed to switch to Album View");
ex.printStackTrace();
logger.error("[x] Failed to switch to Album View", ex);
}
});
......@@ -291,8 +288,7 @@ public class ExploreAlbums implements Initializable {
try{
switchToViewAlbum(mouseEvent);
} catch (IOException ex) {
logger.error("[x] Failed to switch to Album View");
ex.printStackTrace();
logger.error("[x] Failed to switch to Album View", ex);
}
});
......
package NTNU.IDATT1002.controllers;
import NTNU.IDATT1002.models.Image;
import com.lynden.gmapsfx.GoogleMapView;
import com.lynden.gmapsfx.javascript.object.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.stream.Collectors;
/**
* Class ImageMapFactory. Factory for map creation with markers for given images and default options.
* Default center location is Berlin in order to center the full scale map onto a page.
*
* @author Eirik Steira
*/
public class ImageMapFactory {
private static Logger logger = LoggerFactory.getLogger(ImageMapFactory.class);
private ImageMapFactory() {}
/**
* Create a map from given {@link GoogleMapView} with default options and markers for images in given list.
*
* @param googleMapView the map view to add the map to
* @param images the list of images to place on the map
* @return the {@link GoogleMap} created to enable further customization
*/
public static GoogleMap createMap(GoogleMapView googleMapView, List<Image> images) {
List<LatLong> locations = getLatLongs(images);
MapOptions mapOptions = getMapOptions();
GoogleMap googleMap = googleMapView.createMap(mapOptions);
logger.info("[x] Google map created with {} locations", locations.size());
List<Marker> markers = getMarkers(locations);
googleMap.addMarkers(markers);
logger.info("[x] {} markers added", markers.size());
return googleMap;
}
/**
* Get latitude and longitude ({@link LatLong}) values for given images.
*
* @param images the list of images
* @return a list of {@link LatLong}
*/
private static List<LatLong> getLatLongs(List<Image> images) {
return images.stream()
.map(Image::getGeoLocation)
.map(geoLocation -> {
double latitude = Double.parseDouble(geoLocation.getLatitude());
double longitude = Double.parseDouble(geoLocation.getLongitude());
return new LatLong(latitude, longitude);
})
.collect(Collectors.toList());
}
/**
* Create default {@link MapOptions} to be applied to a map. Extend this for further marker customizations.
* The default center location is Berlin to get a look of the entire map when the zoom is set to fit the window.
*
* @return the default map options
*/
private static MapOptions getMapOptions() {
LatLong berlin = new LatLong(52.520008, 13.404954);
return new MapOptions()
.center(berlin)
.mapType(MapTypeIdEnum.ROADMAP)
.overviewMapControl(false)
.panControl(false)
.rotateControl(false)
.scaleControl(false)
.streetViewControl(false)
.zoomControl(false)
.zoom(3);
}
/**
* Create {@link Marker}s for each location in given list of locations.
*
* @param locations the list containing the locations
* @return the list of markers created
*/
private static List<Marker> getMarkers(List<LatLong> locations) {
return locations.stream()
.map(location -> {
MarkerOptions markerOptions = new MarkerOptions()
.position(location);
logger.info("[x] Marker created for location: {}", location);
return new Marker(markerOptions);
})
.collect(Collectors.toList());
}
}
package NTNU.IDATT1002.controllers;
import NTNU.IDATT1002.App;
import NTNU.IDATT1002.models.Image;
import NTNU.IDATT1002.service.ImageService;
import com.lynden.gmapsfx.GoogleMapView;
import com.lynden.gmapsfx.MapComponentInitializedListener;
import com.lynden.gmapsfx.javascript.object.GoogleMap;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.EntityManager;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Controls the buttons and changeable elements on map.fxml,
* a page where you can find images by location
* @version 1.0 22.03.2020
*/
public class Map {
public class Map implements Initializable, MapComponentInitializedListener {
public ImageView tbar_logo;
public TextField tbar_search;
public Button tbar_searchBtn;
......@@ -26,8 +43,64 @@ public class Map {
public Button searchBtn;
public Button tbar_albums;
@FXML
private GoogleMapView mapView;
private GoogleMap map;
private ImageService imageService;
private ExecutorService executorService = Executors.newCachedThreadPool();
private static Logger logger = LoggerFactory.getLogger(Map.class);
public Map() {
EntityManager entityManager = App.ex.getEntityManager();
imageService = new ImageService(entityManager);
}
/**
* Register the api key for Google Maps API and listen for map initialization
* in order to update the view once it has been initialized.
*
* @param url
* @param rb
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
mapView.setKey("AIzaSyB_ox5XC8zYBS__aezKumB-KSgKGUjcRx4");
mapView.addMapInializedListener(this);
}
/**
* Fetch all images in a background task and create and display the map on success.
*/
@Override
public void mapInitialized() {
executorService.submit(fetchImages);
fetchImages.setOnSucceeded(workerStateEvent -> {
List<Image> images = fetchImages.getValue();
ImageMapFactory.createMap(mapView, images);
});
}
/**
* Background task for fetching all images.
*/
private Task<List<Image>> fetchImages = new Task<>() {
@Override
protected List<Image> call() {
try {
return imageService.getAllImages();
} catch (Exception e) {
logger.error("[x] Failed to fetch images", e);
}
return new ArrayList<>();
}
};
/**
* Method that changes scene to Main page
* Change scene to Main page
* @param mouseEvent
* @throws IOException
*/
......@@ -36,7 +109,7 @@ public class Map {
}
/**
* Method that changes scene to Search page. It reads the value of the search
* Change scene to Search page. It reads the value of the search
* field and if not empty it is passed to dataexchange
* @param actionEvent
* @throws IOException
......@@ -49,7 +122,7 @@ public class Map {
}
/**
* Method that changes scene to Explore page
* Change scene to Explore page
* @param actionEvent
* @throws IOException
*/
......@@ -58,7 +131,7 @@ public class Map {
}
/**
* Method that changes scene to Albums page
* Change scene to Albums page
* @param actionEvent
* @throws IOException
*/
......@@ -67,7 +140,8 @@ public class Map {
}
/**
* Method that changes scene to Map page
* Change scene to Map page.
*
* @param actionEvent
* @throws IOException
*/
......@@ -76,7 +150,8 @@ public class Map {
}
/**
* Method that changes scene to Upload page
* Change scene to Upload page.
*
* @param actionEvent the mouse has done something
* @throws IOException this page does not exist
*/
......@@ -85,7 +160,8 @@ public class Map {
}
/**
* Method that searches for images on a specific place
* Search for images on a specific place.
*
* @param actionEvent
*/
public void MapSearch(ActionEvent actionEvent) {
......
......@@ -135,6 +135,18 @@ public class Image {
albums.remove(album);
}
/**
* Get Geo Location related to this image.
*
* @return the location the image was taken
*/
public GeoLocation getGeoLocation() {
if (metadata == null)
return new GeoLocation("0","0");
return metadata.getGeoLocation();
}
@Override
public boolean equals(Object o) {
if (this == o) {
......
package NTNU.IDATT1002.service;
import NTNU.IDATT1002.filters.ImageFilter;
import NTNU.IDATT1002.models.*;
import NTNU.IDATT1002.repository.*;
import NTNU.IDATT1002.repository.ImageRepository;
import NTNU.IDATT1002.utils.ImageUtil;
import NTNU.IDATT1002.utils.MetaDataExtractor;
import java.util.Arrays;
import javafx.scene.control.TextField;
import javax.persistence.EntityManager;
import java.io.File;
import java.util.ArrayList;
......@@ -99,6 +98,4 @@ public class ImageService {
.collect(Collectors.toList());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextField?>
<?import com.lynden.gmapsfx.GoogleMapView?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<?import javafx.scene.web.WebView?>
<AnchorPane prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="NTNU.IDATT1002.controllers.Map">
<children>
<VBox prefHeight="1080.0" prefWidth="1920.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
......@@ -58,12 +53,9 @@
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="797.0" prefWidth="1920.0" style="-fx-background-color: #888888;" VBox.vgrow="ALWAYS">
<children>
<WebView prefHeight="717.0" prefWidth="1920.0" AnchorPane.bottomAnchor="80.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<Text layoutX="598.0" layoutY="378.0" strokeType="OUTSIDE" strokeWidth="0.0" text="MAP WILL BE INTEGRATED LATER." textAlignment="CENTER" AnchorPane.bottomAnchor="406.953125" AnchorPane.topAnchor="326.046875">
<font>
<Font size="48.0" />
</font>
</Text>
<GoogleMapView fx:id="mapView" prefHeight="750.0" prefWidth="761.0" AnchorPane.bottomAnchor="-185.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="-441.0" AnchorPane.topAnchor="0.0"/>
</children>
</AnchorPane>
</children>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment