Skip to content

Commit efc0e1a

Browse files
Transferred project from private repository
1 parent 592c2fb commit efc0e1a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+16968
-0
lines changed

Documentation-de.docx

294 KB
Binary file not shown.

README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Geo Image Viewer
2+
A project that visualizes the locations where pictures were taken.
3+
4+
## Usage
5+
Drag and drop pictures with GPS-Information from your local explorer onto the map, the program will show you where they were taken.
6+
7+
### Command line arguments
8+
| shortcut | option | argument 1 | description |
9+
|----------|-------------------|--------------------|-----------------------------------------------|
10+
| -h | --help | | prints help message and exits |
11+
| -l | --log-file | /path/to/file | enables logging and sets log file accordingly |
12+
| -d | --image-directory | /path/to/directory | sets image directory accordingly |
13+
14+
## Dependencies
15+
16+
### [metadata-extractor](https://github.com/drewnoakes/metadata-extractor)
17+
We use this library, so we can support many file types at once with little effort.
18+
19+
### [jxmapviewer2](https://github.com/msteiger/jxmapviewer2)
20+
This library helps us to draw the maps from OpenStreetMap.
21+
22+
### [commons-cli](https://commons.apache.org/proper/commons-cli/)
23+
In order to parse command line arguments, we use this library.
24+
25+
### [commons-csv](https://commons.apache.org/proper/commons-csv/)
26+
We are using this library to easily read and write CSV files.
27+
28+
## Requirements
29+
This project uses [Maven](https://maven.apache.org/) to manage its dependencies.
30+
The next instructions can only be followed if Maven has been successfully installed onto your system.
31+
32+
## Building the app
33+
The following commands should provide you a running build.
34+
35+
### 1. Build script:
36+
Works on most GNU+Linux based operating systems (Build + Execute):
37+
`/path/to/geoimageviewer/build.sh`
38+
39+
### 2. Manual procedure:
40+
```bash
41+
cd /path/to/geoimageviewer
42+
mvn clean package
43+
java -jar target/geoimageviewer-1.0-SNAPSHOT.jar
44+
```
45+
46+
## Documentation
47+
### UML diagrams
48+
Latest UML diagram:
49+
50+
![Image failed to load](https://github.com/madcomputerscientists/geoimageviewer/blob/main/plans/UML/MainDiagram-latest.png?raw=true)
51+
52+
The UML diagrams for this project are stored [here](https://github.com/madcomputerscientists/geoimageviewer/tree/main/plans/UML).
53+
54+
## Feel free to create [Issues](https://github.com/madcomputerscientists/geoimageviewer/issues) and [Pull Requests](https://github.com/madcomputerscientists/geoimageviewer/pulls)!

build.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
3+
SCRIPT_PATH=`readlink -f "$0"`
4+
SCRIPT_DIR=`dirname "$SCRIPT_PATH"`
5+
6+
cd "$SCRIPT_DIR"
7+
mvn clean package
8+
java -jar target/geoimageviewer-1.0-SNAPSHOT.jar -d images

plans/GUI/MainScreen.pdn

Lines changed: 5810 additions & 0 deletions
Large diffs are not rendered by default.

plans/GUI/MainScreen.png

1.77 MB
Loading

plans/GUI/Marker Clicked.pdn

Lines changed: 7844 additions & 0 deletions
Large diffs are not rendered by default.

plans/GUI/Marker Clicked.png

1.88 MB
Loading

plans/GUI/Upload Image.pdn

2.69 MB
Binary file not shown.

plans/GUI/Upload Image.png

1.43 MB
Loading

plans/UML/MainDiagram v0.1.png

7.5 KB
Loading

plans/UML/MainDiagram v0.2.png

21.6 KB
Loading

plans/UML/MainDiagram v0.3.png

46.6 KB
Loading

plans/UML/MainDiagram v0.4.png

89.5 KB
Loading

plans/UML/MainDiagram v0.5.png

273 KB
Loading

plans/UML/MainDiagram-latest.png

273 KB
Loading

plans/UML/MainDiagram.dia

10.7 KB
Binary file not shown.

plans/resources

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
https://github.com/msteiger/jxmapviewer2
2+
https://github.com/drewnoakes/metadata-extractor/
3+
https://web.archive.org/web/20100309081606/http://today.java.net/pub/a/today/2007/10/30/building-maps-into-swing-app-with-jxmapviewer.html

pom.xml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>org.madcomputerscientists</groupId>
8+
<artifactId>geoimageviewer</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<maven.compiler.source>17</maven.compiler.source>
13+
<maven.compiler.target>17</maven.compiler.target>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
<exec.mainClass>org.madcomputerscientists.Main</exec.mainClass>
16+
</properties>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>org.jxmapviewer</groupId>
21+
<artifactId>jxmapviewer2</artifactId>
22+
<version>2.6</version>
23+
</dependency>
24+
<dependency>
25+
<groupId>com.drewnoakes</groupId>
26+
<artifactId>metadata-extractor</artifactId>
27+
<version>2.18.0</version>
28+
</dependency>
29+
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
30+
<dependency>
31+
<groupId>commons-cli</groupId>
32+
<artifactId>commons-cli</artifactId>
33+
<version>1.5.0</version>
34+
</dependency>
35+
<dependency>
36+
<groupId>org.apache.commons</groupId>
37+
<artifactId>commons-csv</artifactId>
38+
<version>1.9.0</version>
39+
</dependency>
40+
</dependencies>
41+
42+
<build>
43+
<plugins>
44+
<plugin>
45+
<groupId>org.apache.maven.plugins</groupId>
46+
<artifactId>maven-dependency-plugin</artifactId>
47+
<executions>
48+
<execution>
49+
<id>copy-dependencies</id>
50+
<phase>prepare-package</phase>
51+
<goals>
52+
<goal>copy-dependencies</goal>
53+
</goals>
54+
<configuration>
55+
<outputDirectory>${project.build.directory}/${project.build.finalName}.lib</outputDirectory>
56+
</configuration>
57+
</execution>
58+
</executions>
59+
</plugin>
60+
<plugin>
61+
<!-- Build an executable JAR -->
62+
<groupId>org.apache.maven.plugins</groupId>
63+
<artifactId>maven-jar-plugin</artifactId>
64+
<version>3.3.0</version>
65+
<configuration>
66+
<archive>
67+
<manifest>
68+
<addClasspath>true</addClasspath>
69+
<classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
70+
<mainClass>org.madcomputerscientists.Main</mainClass>
71+
</manifest>
72+
</archive>
73+
</configuration>
74+
</plugin>
75+
</plugins>
76+
</build>
77+
</project>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.madcomputerscientists;
2+
3+
import org.jxmapviewer.viewer.DefaultWaypoint;
4+
import org.jxmapviewer.viewer.GeoPosition;
5+
6+
import javax.swing.JButton;
7+
import javax.swing.Icon;
8+
9+
import java.awt.Dimension;
10+
11+
public class ClickableWaypoint extends DefaultWaypoint {
12+
private ResourceFetcher resourceFetcher = new ResourceFetcher();
13+
private Icon defaultIcon = resourceFetcher.getIconByName("imageRecordLocation.png");
14+
private JButton button = new JButton();
15+
16+
public ClickableWaypoint(GeoPosition geoPosition, int width, int height) {
17+
super(geoPosition);
18+
button.setContentAreaFilled(false);
19+
button.setIcon(defaultIcon);
20+
button.setBorderPainted(false);
21+
button.setFocusPainted(false);
22+
button.setSize(new Dimension(width, height));
23+
button.setBorder(null);
24+
}
25+
26+
public JButton getButton() {
27+
return button;
28+
}
29+
30+
public boolean equals(ClickableWaypoint waypoint){
31+
return this.getPosition().equals(waypoint.getPosition());
32+
}
33+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package org.madcomputerscientists;
2+
3+
import org.jxmapviewer.JXMapViewer;
4+
import org.jxmapviewer.viewer.WaypointPainter;
5+
6+
import javax.swing.JButton;
7+
8+
import java.awt.Graphics2D;
9+
import java.awt.Rectangle;
10+
import java.awt.geom.Point2D;
11+
12+
public class ClickableWaypointRenderer extends WaypointPainter<ClickableWaypoint> {
13+
@Override
14+
protected void doPaint(Graphics2D g, JXMapViewer map, int width, int height) {
15+
for (ClickableWaypoint waypoint : this.getWaypoints()) {
16+
Point2D point = map.getTileFactory().geoToPixel(waypoint.getPosition(), map.getZoom());
17+
18+
Rectangle viewportBounds = map.getViewportBounds();
19+
int x = (int) (point.getX() - viewportBounds.getX());
20+
int y = (int) (point.getY() - viewportBounds.getY());
21+
22+
JButton button = waypoint.getButton();
23+
button.setLocation(x - button.getWidth() / 2, y - button.getHeight());
24+
}
25+
}
26+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package org.madcomputerscientists;
2+
3+
import java.text.DecimalFormat;
4+
import java.text.DecimalFormatSymbols;
5+
import java.util.Locale;
6+
7+
public class Coordinate {
8+
private double latitude_dec;
9+
private double longitude_dec;
10+
11+
private String latitude_str;
12+
private String longitude_str;
13+
14+
15+
public Coordinate(double latitude, double longitude) {
16+
this.latitude_dec = latitude;
17+
this.longitude_dec = longitude;
18+
19+
this.latitude_str = decToStr(latitude);
20+
this.longitude_str = decToStr(longitude);
21+
}
22+
23+
/**
24+
* uses the <a href="https://en.wikipedia.org/wiki/Haversine_formula">Haversine</a>
25+
* formula to calculate the distance between two coordinates on earth
26+
* @param coordinate coordinate to which the distance should be calculated
27+
* @return distance from the coordinate that the method was called on to the given coordinate
28+
*/
29+
public double distanceTo(Coordinate coordinate) {
30+
final int EARTH_RADIUS_KM = 6371;
31+
32+
double lat1 = this.latitude_dec;
33+
double long1 = this.longitude_dec;
34+
double lat2 = coordinate.latitude_dec;
35+
double long2 = coordinate.longitude_dec;
36+
37+
double latDistance = Math.toRadians(lat2-lat1);
38+
double longDistance = Math.toRadians(long2-long1);
39+
double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) +
40+
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
41+
Math.sin(longDistance / 2) * Math.sin(longDistance / 2);
42+
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
43+
44+
return EARTH_RADIUS_KM * c * 1000; //convert distance from kilometers in meters
45+
}
46+
47+
/**
48+
*
49+
* @param coordinate the coordinate the range should be compared to
50+
* @param range range in meter
51+
* @return true/false if coordinate is in range
52+
*/
53+
public boolean isInRange(Coordinate coordinate, double range) {
54+
return distanceTo(coordinate) <= range;
55+
}
56+
57+
public static double toDecimal(String value) {
58+
value = value.replaceAll(" ", "").replaceAll(",", ".");
59+
60+
int degreeIndex = value.indexOf('°');
61+
int minuteIndex = value.indexOf('\'');
62+
int secondsIndex = value.indexOf("\"");
63+
64+
int degrees = Integer.parseInt(value.substring(0, degreeIndex));
65+
66+
if (degrees < 0) {
67+
degrees *= -1;
68+
}
69+
70+
int minutes = Integer.parseInt(value.substring(degreeIndex + 1, minuteIndex));
71+
double seconds = Double.parseDouble(value.substring(minuteIndex + 1, secondsIndex));
72+
73+
double result = degrees + (minutes * 60.0 + seconds) / 3600.0;
74+
75+
if (value.contains("-")) {
76+
result *= -1;
77+
}
78+
79+
return result;
80+
}
81+
82+
public static String decToStr(double value) {
83+
DecimalFormat df = new DecimalFormat("0.00", DecimalFormatSymbols.getInstance(Locale.US));
84+
85+
String pre = "";
86+
if (value < 0) {
87+
pre = "-";
88+
value *= -1;
89+
}
90+
91+
int degrees = (int) value;
92+
double a = (value - degrees) * 60;
93+
int minutes = (int) a;
94+
double seconds = (a - minutes) * 60;
95+
96+
return pre + degrees + "° " + minutes + "' " + df.format(seconds) + "\"";
97+
}
98+
99+
public String toString() {
100+
return "Lat: " + latitude_str + " Long: " + longitude_str;
101+
}
102+
103+
public double getLatitude_dec() {
104+
return this.latitude_dec;
105+
}
106+
public double getLongitude_dec() {
107+
return longitude_dec;
108+
}
109+
110+
public String getLatitude_str() {
111+
return this.latitude_str;
112+
}
113+
114+
public String getLongitude_str() {
115+
return this.longitude_str;
116+
}
117+
118+
public void setCoordinate(double latitude, double longitude){
119+
this.latitude_dec = latitude;
120+
this.longitude_dec = longitude;
121+
122+
this.latitude_str = decToStr(latitude);
123+
this.longitude_str = decToStr(longitude);
124+
}
125+
126+
public String getLatitude_dec_Formatted(){
127+
DecimalFormat df = new DecimalFormat("0.000000", DecimalFormatSymbols.getInstance(Locale.US));
128+
return df.format(latitude_dec);
129+
}
130+
131+
public String getLongitude_dec_Formatted(){
132+
DecimalFormat df = new DecimalFormat("0.000000", DecimalFormatSymbols.getInstance(Locale.US));
133+
return df.format(longitude_dec);
134+
}
135+
}

0 commit comments

Comments
 (0)