@ -15,6 +15,7 @@ include ':vtm-json'
|
|||||||
include ':vtm-jts'
|
include ':vtm-jts'
|
||||||
include ':vtm-playground'
|
include ':vtm-playground'
|
||||||
include ':vtm-tests'
|
include ':vtm-tests'
|
||||||
|
include ':vtm-theme-comparator'
|
||||||
include ':vtm-themes'
|
include ':vtm-themes'
|
||||||
include ':vtm-web'
|
include ':vtm-web'
|
||||||
include ':vtm-web-app'
|
include ':vtm-web-app'
|
||||||
|
34
vtm-theme-comparator/build.gradle
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
apply plugin: 'java'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile project(':vtm-desktop')
|
||||||
|
compile project(':vtm-extras')
|
||||||
|
compile project(':vtm-http')
|
||||||
|
compile project(':vtm-json')
|
||||||
|
compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
|
||||||
|
|
||||||
|
|
||||||
|
compile group: 'com.jtattoo', name: 'JTattoo', version: '1.6.11'
|
||||||
|
compile group: 'com.fifesoft', name: 'rsyntaxtextarea', version: '2.6.1'
|
||||||
|
|
||||||
|
|
||||||
|
compile 'org.mapsforge:mapsforge-core:0.8.0'
|
||||||
|
compile 'org.mapsforge:mapsforge-themes:0.8.0'
|
||||||
|
compile 'org.mapsforge:mapsforge-map:0.8.0'
|
||||||
|
compile 'org.mapsforge:mapsforge-map-reader:0.8.0'
|
||||||
|
compile("org.mapsforge:mapsforge-map-awt:0.8.0")
|
||||||
|
compile 'com.kitfox.svg:svg-salamander:1.0'
|
||||||
|
compile 'net.sf.kxml:kxml2:2.3.0'
|
||||||
|
|
||||||
|
//include libs
|
||||||
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java.srcDirs = ['src']
|
||||||
|
resources.srcDirs = ['resources']
|
||||||
|
}
|
||||||
|
}
|
BIN
vtm-theme-comparator/resources/debug_dark.png
Normal file
After Width: | Height: | Size: 454 B |
BIN
vtm-theme-comparator/resources/editSource_dark.png
Normal file
After Width: | Height: | Size: 340 B |
BIN
vtm-theme-comparator/resources/exit_dark.png
Normal file
After Width: | Height: | Size: 361 B |
BIN
vtm-theme-comparator/resources/gc_dark.png
Normal file
After Width: | Height: | Size: 386 B |
BIN
vtm-theme-comparator/resources/locate_dark.png
Normal file
After Width: | Height: | Size: 225 B |
BIN
vtm-theme-comparator/resources/menu-open.png
Normal file
After Width: | Height: | Size: 131 B |
BIN
vtm-theme-comparator/resources/menu-saveall.png
Normal file
After Width: | Height: | Size: 143 B |
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
|
||||||
|
import org.mapsforge.core.model.MapPosition;
|
||||||
|
import org.oscim.theme.comparator.location.LocationData;
|
||||||
|
import org.oscim.theme.comparator.location.LocationDataListener;
|
||||||
|
import org.oscim.theme.comparator.mapsforge.MapsforgeMapPanel;
|
||||||
|
import org.oscim.theme.comparator.vtm.VtmPanel;
|
||||||
|
|
||||||
|
import java.util.prefs.BackingStoreException;
|
||||||
|
|
||||||
|
public class BothMapPositionHandler implements LocationDataListener {
|
||||||
|
|
||||||
|
private final MapsforgeMapPanel mapsforgeMapPanel;
|
||||||
|
private final VtmPanel vtmPanel;
|
||||||
|
private MainMenu menu;
|
||||||
|
|
||||||
|
public BothMapPositionHandler(MapsforgeMapPanel mapsforgeMapPanel, VtmPanel vtmPanel) {
|
||||||
|
this.mapsforgeMapPanel = mapsforgeMapPanel;
|
||||||
|
this.vtmPanel = vtmPanel;
|
||||||
|
LocationData.addChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCoordinate(final double latitude, final double longitude, final byte zoomLevel) {
|
||||||
|
Gdx.app.postRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mapsforgeMapPanel.setCoordinate(latitude, longitude, zoomLevel);
|
||||||
|
vtmPanel.setCoordinate(latitude, longitude, (byte) (zoomLevel - 1));
|
||||||
|
storePositionOnPrefs(latitude, longitude, zoomLevel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mapPositionChangedFromMapPanel(final MapPosition mapPosition) {
|
||||||
|
Gdx.app.postRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
vtmPanel.setCoordinate(mapPosition.latLong.latitude, mapPosition.latLong.longitude, (byte) (mapPosition.zoomLevel - 1));
|
||||||
|
//TODO wy is zoom level on vtm x-1?
|
||||||
|
storePositionOnPrefs(mapPosition.latLong.latitude, mapPosition.latLong.longitude, mapPosition.zoomLevel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mapPositionChangedFromVtmMap(org.oscim.core.MapPosition mapPosition) {
|
||||||
|
mapsforgeMapPanel.setCoordinate(mapPosition.getLatitude(), mapPosition.getLongitude(), (byte) (mapPosition.zoomLevel + 1));
|
||||||
|
storePositionOnPrefs(mapPosition.getLatitude(), mapPosition.getLongitude(), (byte) (mapPosition.zoomLevel));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void storePositionOnPrefs(double latitude, double longitude, byte zoomLevel) {
|
||||||
|
Main.prefs.putDouble("latitude", latitude);
|
||||||
|
Main.prefs.putDouble("longitude", longitude);
|
||||||
|
Main.prefs.putInt("zoomLevel", zoomLevel);
|
||||||
|
try {
|
||||||
|
Main.prefs.flush();
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// change position label on MenuBar
|
||||||
|
if (this.menu != null) this.menu.setPos(latitude, longitude, zoomLevel);
|
||||||
|
|
||||||
|
// change values on Location panel
|
||||||
|
LocationData.set(latitude, longitude, zoomLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadPrefsPosition() {
|
||||||
|
double latitude = Main.prefs.getDouble("latitude", 300);
|
||||||
|
double longitude = Main.prefs.getDouble("longitude", 300);
|
||||||
|
byte zoomLevel = (byte) Main.prefs.getInt("zoomLevel", -1);
|
||||||
|
|
||||||
|
if (latitude < 300) {
|
||||||
|
setCoordinate(latitude, longitude, zoomLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCallBack(MainMenu menu) {
|
||||||
|
this.menu = menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChanged() {
|
||||||
|
|
||||||
|
double latitude = LocationData.getLatitude();
|
||||||
|
double longitude = LocationData.getLongitude();
|
||||||
|
int zoomLevel = LocationData.getZoom();
|
||||||
|
|
||||||
|
if (LocationData.getNS() == LocationData.Orientation.SOUTH) {
|
||||||
|
latitude *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LocationData.getEW() == LocationData.Orientation.WEST) {
|
||||||
|
longitude *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCoordinate(latitude, longitude, (byte) zoomLevel);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator;
|
||||||
|
|
||||||
|
import org.oscim.theme.comparator.editor.EditorPane;
|
||||||
|
import org.oscim.theme.comparator.location.LocationPane;
|
||||||
|
import org.oscim.theme.comparator.logging.AllLoggingPane;
|
||||||
|
import org.oscim.theme.comparator.logging.MapsforgeLoggingPane;
|
||||||
|
import org.oscim.theme.comparator.logging.VtmLoggingPane;
|
||||||
|
import org.oscim.theme.comparator.mapsforge.MapsforgeMapPanel;
|
||||||
|
import org.oscim.theme.comparator.vtm.VtmPanel;
|
||||||
|
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JTabbedPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
class InfoPanel extends JPanel {
|
||||||
|
|
||||||
|
InfoPanel(final VtmPanel vtmPanel, final MapsforgeMapPanel mapsforgeMapPanel,
|
||||||
|
final MainMenu mainMenu) {
|
||||||
|
super(new GridLayout(1, 1));
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
JTabbedPane tabbedPane = new JTabbedPane();
|
||||||
|
tabbedPane.addTab("Theme Editor", Main.ICON_EDIT, new EditorPane(vtmPanel, mapsforgeMapPanel, mainMenu), "");
|
||||||
|
tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
|
||||||
|
|
||||||
|
tabbedPane.addTab("Log's ALL", Main.ICON_DEBUG, new AllLoggingPane(), "");
|
||||||
|
tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
|
||||||
|
|
||||||
|
tabbedPane.addTab("Log's VTM", Main.ICON_DEBUG, new VtmLoggingPane(), "");
|
||||||
|
tabbedPane.setMnemonicAt(1, KeyEvent.VK_3);
|
||||||
|
|
||||||
|
tabbedPane.addTab("Log's MAPSFORGE", Main.ICON_DEBUG, new MapsforgeLoggingPane(), "");
|
||||||
|
tabbedPane.setMnemonicAt(1, KeyEvent.VK_4);
|
||||||
|
|
||||||
|
tabbedPane.addTab("Set Map position", Main.ICON_LOCATE, new LocationPane(), "");
|
||||||
|
tabbedPane.setMnemonicAt(1, KeyEvent.VK_4);
|
||||||
|
|
||||||
|
tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
|
||||||
|
add(tabbedPane);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
153
vtm-theme-comparator/src/org/oscim/theme/comparator/Main.java
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.SharedLibraryLoader;
|
||||||
|
import com.jtattoo.plaf.DecorationHelper;
|
||||||
|
import com.jtattoo.plaf.hifi.HiFiLookAndFeel;
|
||||||
|
|
||||||
|
import org.oscim.awt.AwtGraphics;
|
||||||
|
import org.oscim.backend.GLAdapter;
|
||||||
|
import org.oscim.gdx.GdxAssets;
|
||||||
|
import org.oscim.gdx.LwjglGL20;
|
||||||
|
import org.oscim.theme.comparator.logging.AllAppender;
|
||||||
|
import org.oscim.theme.comparator.logging.BaseAppender;
|
||||||
|
import org.oscim.theme.comparator.logging.MapsforgeAppender;
|
||||||
|
import org.oscim.theme.comparator.logging.VtmAppender;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.prefs.BackingStoreException;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JRootPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.LoggerContext;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
public static Preferences prefs = Preferences.userNodeForPackage(Main.class);
|
||||||
|
public static boolean useDarkTheme = true; // set black look and feel as default for unimpaired color impression
|
||||||
|
public final static BaseAppender ALL_APPENDER = new AllAppender();
|
||||||
|
public final static BaseAppender VTM_APPENDER = new VtmAppender();
|
||||||
|
public final static BaseAppender MAPSFORGE_APPENDER = new MapsforgeAppender();
|
||||||
|
|
||||||
|
public final static int MAX_ZOOM_LEVEL = 21;
|
||||||
|
public final static int MIN_ZOOM_LEVEL = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public final static ImageIcon ICON_OPEN = new ImageIcon(Main.class.getClassLoader().getResource("menu-open.png"));
|
||||||
|
public final static ImageIcon ICON_SAVE = new ImageIcon(Main.class.getClassLoader().getResource("menu-saveall.png"));
|
||||||
|
public static final ImageIcon ICON_EDIT = new ImageIcon(Main.class.getClassLoader().getResource("editSource_dark.png"));
|
||||||
|
public static final ImageIcon ICON_DEBUG = new ImageIcon(Main.class.getClassLoader().getResource("debug_dark.png"));
|
||||||
|
public static final ImageIcon ICON_EXIT = new ImageIcon(Main.class.getClassLoader().getResource("exit_dark.png"));
|
||||||
|
public static final ImageIcon ICON_LOCATE = new ImageIcon(Main.class.getClassLoader().getResource("locate_dark.png"));
|
||||||
|
|
||||||
|
private static JFrame window;
|
||||||
|
|
||||||
|
// add TextArea logging appender
|
||||||
|
static {
|
||||||
|
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
|
||||||
|
ch.qos.logback.classic.Logger rootLogger = lc.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||||
|
rootLogger.addAppender(ALL_APPENDER);
|
||||||
|
ALL_APPENDER.start();
|
||||||
|
rootLogger.addAppender(VTM_APPENDER);
|
||||||
|
VTM_APPENDER.start();
|
||||||
|
rootLogger.addAppender(MAPSFORGE_APPENDER);
|
||||||
|
MAPSFORGE_APPENDER.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
useDarkTheme = prefs.getBoolean("DARK", true);
|
||||||
|
|
||||||
|
setTheme();
|
||||||
|
|
||||||
|
System.setProperty("org.lwjgl.opengl.Display.allowSoftwareOpenGL", "true");
|
||||||
|
|
||||||
|
new SharedLibraryLoader().load("vtm-jni");
|
||||||
|
AwtGraphics.init();
|
||||||
|
GdxAssets.init("");
|
||||||
|
GLAdapter.init(new LwjglGL20());
|
||||||
|
GLAdapter.GDX_DESKTOP_QUIRKS = true;
|
||||||
|
window = new MainWindow();
|
||||||
|
window.setSize(800, 600);
|
||||||
|
window.setLocationRelativeTo(null);
|
||||||
|
window.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setTheme() {
|
||||||
|
if (useDarkTheme) {
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel("com.jtattoo.plaf.hifi.HiFiLookAndFeel");
|
||||||
|
Properties properties = HiFiLookAndFeel.getThemeProperties("Default");
|
||||||
|
properties.setProperty("textAntiAliasing", "on");
|
||||||
|
properties.setProperty("backgroundPattern", "off");
|
||||||
|
properties.put("logoString", "");
|
||||||
|
HiFiLookAndFeel.setTheme(properties);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void switchTheme() {
|
||||||
|
|
||||||
|
useDarkTheme = !useDarkTheme;
|
||||||
|
|
||||||
|
prefs.putBoolean("DARK", useDarkTheme);
|
||||||
|
try {
|
||||||
|
prefs.flush();
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme();
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
SwingUtilities.updateComponentTreeUI(window);
|
||||||
|
if (!useDarkTheme) {
|
||||||
|
DecorationHelper.decorateWindows(false);
|
||||||
|
window.dispose();
|
||||||
|
window.setUndecorated(false);
|
||||||
|
window.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
|
||||||
|
window.setVisible(true);
|
||||||
|
} else {
|
||||||
|
DecorationHelper.decorateWindows(true);
|
||||||
|
window.dispose();
|
||||||
|
window.setUndecorated(true);
|
||||||
|
window.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
|
||||||
|
window.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.StringBuilder;
|
||||||
|
|
||||||
|
import org.mapsforge.core.util.MercatorProjection;
|
||||||
|
import org.oscim.theme.comparator.editor.ThemeLoader;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.prefs.BackingStoreException;
|
||||||
|
|
||||||
|
import javax.swing.Box;
|
||||||
|
import javax.swing.JCheckBoxMenuItem;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JMenuBar;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
|
||||||
|
public class MainMenu extends JMenuBar {
|
||||||
|
|
||||||
|
private final MapLoader mapLoader;
|
||||||
|
private final JMenu fileMenu = new JMenu("File");
|
||||||
|
private final JMenu viewMenu = new JMenu("View");
|
||||||
|
private final JMenu posMenu = new JMenu("Pos");
|
||||||
|
private ThemeLoader themeLoader;
|
||||||
|
|
||||||
|
MainMenu(MapLoader mapLoader, BothMapPositionHandler mapPosition) {
|
||||||
|
this.mapLoader = mapLoader;
|
||||||
|
mapPosition.setCallBack(this);
|
||||||
|
addFileEntrys();
|
||||||
|
addViewEntrys();
|
||||||
|
addPosEntrys();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFileEntrys() {
|
||||||
|
fileMenu.getPopupMenu().setLightWeightPopupEnabled(false);
|
||||||
|
fileMenu.setMnemonic(KeyEvent.VK_F);
|
||||||
|
fileMenu.add(itemLoadMap());
|
||||||
|
fileMenu.add(itemLoadTheme());
|
||||||
|
fileMenu.addSeparator();
|
||||||
|
fileMenu.add(itemExit());
|
||||||
|
this.add(fileMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addViewEntrys() {
|
||||||
|
JCheckBoxMenuItem checkBoxItem = new JCheckBoxMenuItem("Dark Theme");
|
||||||
|
checkBoxItem.setState(Main.useDarkTheme);
|
||||||
|
checkBoxItem.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
Main.switchTheme();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
viewMenu.getPopupMenu().setLightWeightPopupEnabled(false);
|
||||||
|
viewMenu.add(checkBoxItem);
|
||||||
|
this.add(viewMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPosEntrys() {
|
||||||
|
this.add(Box.createHorizontalGlue());
|
||||||
|
posMenu.getPopupMenu().setLightWeightPopupEnabled(false);
|
||||||
|
this.add(posMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JMenuItem itemExit() {
|
||||||
|
JMenuItem item = new JMenuItem("Exit", Main.ICON_EXIT);
|
||||||
|
item.setMnemonic(KeyEvent.VK_E);
|
||||||
|
item.setToolTipText("Exit application");
|
||||||
|
item.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JMenuItem itemLoadMap() {
|
||||||
|
JMenuItem item = new JMenuItem("Load Map file", Main.ICON_OPEN);
|
||||||
|
item.setMnemonic(KeyEvent.VK_M);
|
||||||
|
item.setToolTipText("Load Mapsforge map file (*.map)");
|
||||||
|
item.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
// load Map
|
||||||
|
String mapPath = Utils.getFile(Main.prefs.get("lastMapDir", ""), "map", "Load Map");
|
||||||
|
if (mapPath != null) {
|
||||||
|
|
||||||
|
//store last selected folder
|
||||||
|
File file = new File(mapPath);
|
||||||
|
if (!file.exists() || !file.canRead()) return;
|
||||||
|
File dir = file.getParentFile();
|
||||||
|
Main.prefs.put("lastMapDir", dir.getAbsolutePath());
|
||||||
|
try {
|
||||||
|
Main.prefs.flush();
|
||||||
|
} catch (BackingStoreException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
mapLoader.loadMap(new File(mapPath), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JMenuItem itemLoadTheme() {
|
||||||
|
JMenuItem item = new JMenuItem("Load Theme file", Main.ICON_OPEN);
|
||||||
|
item.setMnemonic(KeyEvent.VK_M);
|
||||||
|
item.setToolTipText("Load Theme file (*.xml)");
|
||||||
|
item.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
try {
|
||||||
|
MainMenu.this.themeLoader.selectThemeFile();
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setPos(double latitude, double longitude, byte zoomLevel) {
|
||||||
|
|
||||||
|
//clear string builder
|
||||||
|
stringBuilder.length = 0;
|
||||||
|
Arrays.fill(stringBuilder.chars, Character.MIN_VALUE);
|
||||||
|
|
||||||
|
stringBuilder.append("LAT: ");
|
||||||
|
FormatDM(stringBuilder, latitude, "N", "S");
|
||||||
|
stringBuilder.append(" LON: ");
|
||||||
|
FormatDM(stringBuilder, longitude, "E", "W");
|
||||||
|
stringBuilder.append(" ZOOM: ");
|
||||||
|
stringBuilder.append(zoomLevel);
|
||||||
|
stringBuilder.append(" Center Tile: X=");
|
||||||
|
stringBuilder.append(MercatorProjection.longitudeToTileX(longitude, zoomLevel));
|
||||||
|
stringBuilder.append(" Y= ");
|
||||||
|
stringBuilder.append(MercatorProjection.latitudeToTileY(latitude, zoomLevel));
|
||||||
|
stringBuilder.append(" Z= ");
|
||||||
|
stringBuilder.append(zoomLevel);
|
||||||
|
posMenu.setText(stringBuilder.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final StringBuilder stringBuilder = new StringBuilder(13);
|
||||||
|
|
||||||
|
private void FormatDM(StringBuilder stringBuilder, double coord, String positiveDirection, String negativeDirection) {
|
||||||
|
|
||||||
|
stringBuilder.append(Math.abs(((int) coord)));
|
||||||
|
stringBuilder.append("\u00B0 ");
|
||||||
|
stringBuilder.append(String.format("%.3f", Math.abs((coord - ((int) coord)) * 60)));
|
||||||
|
if (coord < 0)
|
||||||
|
stringBuilder.append(negativeDirection);
|
||||||
|
else
|
||||||
|
stringBuilder.append(positiveDirection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setThemeLoader(ThemeLoader themeLoader) {
|
||||||
|
this.themeLoader = themeLoader;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
|
||||||
|
import org.oscim.theme.comparator.mapsforge.MapsforgeMapPanel;
|
||||||
|
import org.oscim.theme.comparator.vtm.MapApplicationAdapter;
|
||||||
|
import org.oscim.theme.comparator.vtm.VtmPanel;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JSplitPane;
|
||||||
|
|
||||||
|
class MainWindow extends JFrame {
|
||||||
|
|
||||||
|
private final VtmPanel vtmPanel;
|
||||||
|
private final MapLoader mapLoader;
|
||||||
|
private final BothMapPositionHandler bothMapPositionHandler;
|
||||||
|
private final MapsforgeMapPanel mapsforgeMapPanel;
|
||||||
|
private final InfoPanel infoPanel;
|
||||||
|
private final MapsPanel mapsPanel;
|
||||||
|
|
||||||
|
MainWindow() {
|
||||||
|
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
this.setLayout(new BorderLayout());
|
||||||
|
MapApplicationAdapter.MapReadyCallback callback = new MapApplicationAdapter.MapReadyCallback() {
|
||||||
|
@Override
|
||||||
|
public void ready() {
|
||||||
|
mapLoader.loadPrefsMapFile();
|
||||||
|
Gdx.app.postRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
bothMapPositionHandler.loadPrefsPosition();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vtmPanel = new VtmPanel(callback);
|
||||||
|
mapsforgeMapPanel = new MapsforgeMapPanel();
|
||||||
|
|
||||||
|
mapsPanel = new MapsPanel(vtmPanel, mapsforgeMapPanel);
|
||||||
|
|
||||||
|
bothMapPositionHandler = new BothMapPositionHandler(mapsforgeMapPanel, vtmPanel);
|
||||||
|
mapsforgeMapPanel.setMapPositionHandler(bothMapPositionHandler);
|
||||||
|
vtmPanel.setMapPositionHandler(bothMapPositionHandler);
|
||||||
|
|
||||||
|
mapLoader = new MapLoader(mapsforgeMapPanel, vtmPanel, bothMapPositionHandler);
|
||||||
|
|
||||||
|
MainMenu mainMenu = new MainMenu(mapLoader, bothMapPositionHandler);
|
||||||
|
setJMenuBar(mainMenu);
|
||||||
|
|
||||||
|
infoPanel = new InfoPanel(vtmPanel, mapsforgeMapPanel, mainMenu);
|
||||||
|
|
||||||
|
this.setMinimumSize(new Dimension(600, 400));
|
||||||
|
mapsPanel.setMinimumSize(new Dimension(200, 100));
|
||||||
|
infoPanel.setMinimumSize(new Dimension(200, 100));
|
||||||
|
|
||||||
|
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
|
||||||
|
splitPane.setTopComponent(mapsPanel);
|
||||||
|
splitPane.setBottomComponent(infoPanel);
|
||||||
|
|
||||||
|
splitPane.setResizeWeight(0.5);
|
||||||
|
|
||||||
|
this.add(splitPane);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
|
||||||
|
import org.mapsforge.core.model.LatLong;
|
||||||
|
import org.mapsforge.map.reader.MapFile;
|
||||||
|
import org.oscim.theme.comparator.mapsforge.MapsforgeMapPanel;
|
||||||
|
import org.oscim.theme.comparator.vtm.VtmPanel;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.prefs.BackingStoreException;
|
||||||
|
|
||||||
|
class MapLoader {
|
||||||
|
|
||||||
|
private final MapsforgeMapPanel mapsforgeMapPanel;
|
||||||
|
private final VtmPanel vtmPanel;
|
||||||
|
private final BothMapPositionHandler mapPosition;
|
||||||
|
private File mapFile;
|
||||||
|
|
||||||
|
MapLoader(MapsforgeMapPanel mapsforgeMapPanel, VtmPanel vtmPanel, BothMapPositionHandler mapPosition) {
|
||||||
|
|
||||||
|
this.vtmPanel = vtmPanel;
|
||||||
|
this.mapsforgeMapPanel = mapsforgeMapPanel;
|
||||||
|
this.mapPosition = mapPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadPrefsMapFile() {
|
||||||
|
String path = Main.prefs.get("loadedMap", "");
|
||||||
|
|
||||||
|
if (!path.isEmpty()) {
|
||||||
|
loadMap(new File(path), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loadMap(final File file, final boolean setCenter) {
|
||||||
|
Gdx.app.postRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mapFile = file;
|
||||||
|
|
||||||
|
//store prefs
|
||||||
|
Main.prefs.put("loadedMap", file.getAbsolutePath());
|
||||||
|
try {
|
||||||
|
Main.prefs.flush();
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
mapsforgeMapPanel.loadMap(mapFile, null);
|
||||||
|
vtmPanel.loadMap(mapFile, null);
|
||||||
|
if (setCenter) {
|
||||||
|
MapFile mapsforgeFile = new MapFile(mapFile);
|
||||||
|
LatLong centerPoint = mapsforgeFile.boundingBox().getCenterPoint();
|
||||||
|
mapPosition.setCoordinate(centerPoint.latitude, centerPoint.longitude, (byte) 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator;
|
||||||
|
|
||||||
|
import org.oscim.theme.comparator.mapsforge.MapsforgeMapPanel;
|
||||||
|
import org.oscim.theme.comparator.vtm.VtmPanel;
|
||||||
|
|
||||||
|
import java.awt.event.ComponentAdapter;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
class MapsPanel extends JPanel {
|
||||||
|
|
||||||
|
private final VtmPanel vtmPanel;
|
||||||
|
private final MapsforgeMapPanel mapsforgeMapPanel;
|
||||||
|
|
||||||
|
MapsPanel(VtmPanel vtm, MapsforgeMapPanel map) {
|
||||||
|
this.setLayout(null);
|
||||||
|
vtmPanel = vtm;
|
||||||
|
mapsforgeMapPanel = map;
|
||||||
|
this.add(vtmPanel);
|
||||||
|
this.add(mapsforgeMapPanel);
|
||||||
|
this.addComponentListener(new ComponentAdapter() {
|
||||||
|
@Override
|
||||||
|
public void componentResized(ComponentEvent e) {
|
||||||
|
int halfWidth = getWidth() / 2;
|
||||||
|
vtmPanel.setBounds(0, 0, halfWidth, getHeight());
|
||||||
|
mapsforgeMapPanel.setBounds(halfWidth, 0, halfWidth, getHeight());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.filechooser.FileFilter;
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
|
||||||
|
public static String getFile(String initialPath, final String extension, String TitleText) {
|
||||||
|
|
||||||
|
final String ext = extension.replace("*", "");
|
||||||
|
|
||||||
|
JFileChooser chooser = new JFileChooser();
|
||||||
|
|
||||||
|
chooser.setCurrentDirectory(new java.io.File(initialPath));
|
||||||
|
chooser.setDialogTitle(TitleText);
|
||||||
|
|
||||||
|
FileFilter filter = new FileFilter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(File f) {
|
||||||
|
return f.isDirectory() || f.getAbsolutePath().endsWith(ext);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
chooser.setFileFilter(filter);
|
||||||
|
|
||||||
|
int returnVal = chooser.showOpenDialog(null);
|
||||||
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||||
|
return chooser.getSelectedFile().getAbsolutePath();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.editor;
|
||||||
|
|
||||||
|
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||||
|
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
||||||
|
import org.fife.ui.rsyntaxtextarea.Theme;
|
||||||
|
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||||
|
import org.oscim.theme.comparator.Main;
|
||||||
|
import org.oscim.theme.comparator.MainMenu;
|
||||||
|
import org.oscim.theme.comparator.mapsforge.MapsforgeMapPanel;
|
||||||
|
import org.oscim.theme.comparator.vtm.VtmPanel;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
public class EditorPane extends JPanel {
|
||||||
|
|
||||||
|
private final RSyntaxTextArea textArea;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It's used the RSyntaxTextArea. Show https://github.com/bobbylight/RSyntaxTextArea/wiki
|
||||||
|
*/
|
||||||
|
public EditorPane(VtmPanel vtmPanel, MapsforgeMapPanel mapsforgeMapPanel, MainMenu mainMenu) {
|
||||||
|
super(new BorderLayout());
|
||||||
|
textArea = new RSyntaxTextArea(5, 60);
|
||||||
|
textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML);
|
||||||
|
textArea.setCodeFoldingEnabled(true);
|
||||||
|
RTextScrollPane sp = new RTextScrollPane(textArea);
|
||||||
|
this.add(sp);
|
||||||
|
setTheme(Main.useDarkTheme);
|
||||||
|
add(new Menu(vtmPanel, mapsforgeMapPanel, textArea, mainMenu), BorderLayout.NORTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void setTheme(boolean dark) {
|
||||||
|
try {
|
||||||
|
Theme theme;
|
||||||
|
if (dark) {
|
||||||
|
theme = Theme.load(getClass().getResourceAsStream(
|
||||||
|
"/org/fife/ui/rsyntaxtextarea/themes/dark.xml"));
|
||||||
|
} else {
|
||||||
|
theme = Theme.load(getClass().getResourceAsStream(
|
||||||
|
"/org/fife/ui/rsyntaxtextarea/themes/default.xml"));
|
||||||
|
}
|
||||||
|
theme.apply(textArea);
|
||||||
|
} catch (IOException ioe) { // Never happens
|
||||||
|
ioe.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.editor;
|
||||||
|
|
||||||
|
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||||
|
import org.oscim.theme.comparator.MainMenu;
|
||||||
|
import org.oscim.theme.comparator.mapsforge.MapsforgeMapPanel;
|
||||||
|
import org.oscim.theme.comparator.vtm.VtmPanel;
|
||||||
|
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JToolBar;
|
||||||
|
|
||||||
|
import static org.oscim.theme.comparator.Main.ICON_OPEN;
|
||||||
|
import static org.oscim.theme.comparator.Main.ICON_SAVE;
|
||||||
|
|
||||||
|
class Menu extends JToolBar {
|
||||||
|
|
||||||
|
private final ThemeLoader themeLoader;
|
||||||
|
|
||||||
|
Menu(VtmPanel vtmPanel, MapsforgeMapPanel mapsforgeMapPanel, RSyntaxTextArea textArea, MainMenu mainMenu) {
|
||||||
|
this.setRollover(false);
|
||||||
|
|
||||||
|
|
||||||
|
JButton openButton = new JButton(ICON_OPEN);
|
||||||
|
openButton.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
try {
|
||||||
|
themeLoader.selectThemeFile();
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.add(openButton);
|
||||||
|
this.addSeparator();
|
||||||
|
|
||||||
|
|
||||||
|
JButton saveButton = new JButton(ICON_SAVE);
|
||||||
|
saveButton.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
// Save xml File and reload Theme
|
||||||
|
try {
|
||||||
|
themeLoader.saveAndReload();
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.add(saveButton);
|
||||||
|
|
||||||
|
|
||||||
|
themeLoader = new ThemeLoader(vtmPanel, mapsforgeMapPanel, textArea, mainMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.editor;
|
||||||
|
|
||||||
|
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||||
|
import org.oscim.theme.comparator.Main;
|
||||||
|
import org.oscim.theme.comparator.MainMenu;
|
||||||
|
import org.oscim.theme.comparator.Utils;
|
||||||
|
import org.oscim.theme.comparator.mapsforge.MapsforgeMapPanel;
|
||||||
|
import org.oscim.theme.comparator.vtm.VtmPanel;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.prefs.BackingStoreException;
|
||||||
|
|
||||||
|
public class ThemeLoader {
|
||||||
|
|
||||||
|
final private Logger vtmLog = LoggerFactory.getLogger("org.oscim.ThemeLoader");
|
||||||
|
final private Logger mapsforgeLog = LoggerFactory.getLogger("org.mapsforge.ThemeLoader");
|
||||||
|
|
||||||
|
|
||||||
|
final private VtmPanel vtmPanel;
|
||||||
|
final private MapsforgeMapPanel mapsforgeMapPanel;
|
||||||
|
final private RSyntaxTextArea syntaxTextArea;
|
||||||
|
|
||||||
|
private String themePath;
|
||||||
|
private String editorText;
|
||||||
|
|
||||||
|
ThemeLoader(VtmPanel vtmPanel, MapsforgeMapPanel mapsforgeMapPanel, RSyntaxTextArea editorPane, MainMenu mainMenu) {
|
||||||
|
this.vtmPanel = vtmPanel;
|
||||||
|
this.mapsforgeMapPanel = mapsforgeMapPanel;
|
||||||
|
this.syntaxTextArea = editorPane;
|
||||||
|
mainMenu.setThemeLoader(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void selectThemeFile() throws IOException {
|
||||||
|
String themePath = Utils.getFile(Main.prefs.get("lastTheme", ""), "*.xml", "Load Theme File");
|
||||||
|
|
||||||
|
if (themePath == null) return;
|
||||||
|
|
||||||
|
//store last selected folder
|
||||||
|
File file = new File(themePath);
|
||||||
|
if (!file.exists() || !file.canRead()) return;
|
||||||
|
File dir = file.getParentFile();
|
||||||
|
Main.prefs.put("lastTheme", dir.getAbsolutePath());
|
||||||
|
try {
|
||||||
|
Main.prefs.flush();
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme(themePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTheme(String themePath) throws IOException {
|
||||||
|
if (themePath != null) {
|
||||||
|
this.themePath = themePath;
|
||||||
|
BufferedReader br = new BufferedReader(new FileReader(this.themePath));
|
||||||
|
try {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
String line = br.readLine();
|
||||||
|
|
||||||
|
while (line != null) {
|
||||||
|
sb.append(line);
|
||||||
|
sb.append(System.lineSeparator());
|
||||||
|
line = br.readLine();
|
||||||
|
}
|
||||||
|
editorText = sb.toString();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
br.close();
|
||||||
|
}
|
||||||
|
syntaxTextArea.setText(editorText);
|
||||||
|
|
||||||
|
syntaxTextArea.setCaretPosition(0);
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.mapsforgeMapPanel.setTheme(this.themePath);
|
||||||
|
} catch (Exception e) {
|
||||||
|
mapsforgeLog.error("LoadTheme", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.vtmPanel.setTheme(this.themePath);
|
||||||
|
} catch (Exception e) {
|
||||||
|
vtmLog.error("LoadTheme", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveAndReload() throws IOException {
|
||||||
|
int lastCaretPosition = syntaxTextArea.getCaretPosition();
|
||||||
|
|
||||||
|
editorText = syntaxTextArea.getText();
|
||||||
|
|
||||||
|
Writer out = new BufferedWriter(new OutputStreamWriter(
|
||||||
|
new FileOutputStream(this.themePath), "UTF-8"));
|
||||||
|
try {
|
||||||
|
out.write(editorText);
|
||||||
|
} finally {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme(themePath);
|
||||||
|
syntaxTextArea.setCaretPosition(lastCaretPosition);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.location;
|
||||||
|
|
||||||
|
import org.oscim.theme.comparator.BothMapPositionHandler;
|
||||||
|
|
||||||
|
import java.util.Vector;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
public final class LocationData {
|
||||||
|
|
||||||
|
|
||||||
|
public enum Orientation {
|
||||||
|
EAST, WEST, NORTH, SOUTH;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.name().substring(0, 1) + this.name().substring(1).toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double latitude;
|
||||||
|
private static double longitude;
|
||||||
|
private static int zoom;
|
||||||
|
private static Orientation ns;
|
||||||
|
private static Orientation ew;
|
||||||
|
|
||||||
|
static {
|
||||||
|
latitude = 47.48135;
|
||||||
|
longitude = 8.20797;
|
||||||
|
ns = Orientation.NORTH;
|
||||||
|
ew = Orientation.EAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vector<LocationDataListener> listeners = new Vector<>();
|
||||||
|
|
||||||
|
public static void addChangeListener(LocationDataListener listener) {
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void notifyChange() {
|
||||||
|
if (blockCircleEvent.get()) return;
|
||||||
|
notifyChange(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AtomicBoolean blockCircleEvent = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
private static void notifyChange(boolean all) {
|
||||||
|
|
||||||
|
if (!all) blockCircleEvent.set(true);
|
||||||
|
|
||||||
|
for (LocationDataListener l : listeners) {
|
||||||
|
if (all) {
|
||||||
|
l.valueChanged();
|
||||||
|
} else {
|
||||||
|
if (!(l instanceof BothMapPositionHandler))
|
||||||
|
l.valueChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blockCircleEvent.set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LocationData() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getZoom() {
|
||||||
|
return zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public synchronized static double getLatitude() {
|
||||||
|
return latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized static void setLatitude(double latitude) {
|
||||||
|
if (LocationData.latitude != latitude) {
|
||||||
|
LocationData.latitude = latitude;
|
||||||
|
notifyChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized static double getLongitude() {
|
||||||
|
return longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized static void setLongitude(double longitude) {
|
||||||
|
if (LocationData.longitude != longitude) {
|
||||||
|
LocationData.longitude = longitude;
|
||||||
|
notifyChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Orientation getEW() {
|
||||||
|
return ew;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setEW(Orientation ew) {
|
||||||
|
if (ew == Orientation.NORTH || ew == Orientation.SOUTH)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
if (LocationData.ew != ew) {
|
||||||
|
LocationData.ew = ew;
|
||||||
|
notifyChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Orientation getNS() {
|
||||||
|
return ns;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setNS(Orientation ns) {
|
||||||
|
if (ns == Orientation.EAST || ns == Orientation.WEST)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
if (LocationData.ns != ns) {
|
||||||
|
LocationData.ns = ns;
|
||||||
|
notifyChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setZoom(int zoomLevel) {
|
||||||
|
if (LocationData.zoom != zoomLevel) {
|
||||||
|
LocationData.zoom = zoomLevel;
|
||||||
|
notifyChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void set(double latitude, double longitude, byte zoomLevel) {
|
||||||
|
|
||||||
|
boolean change = false;
|
||||||
|
|
||||||
|
//set orientation
|
||||||
|
Orientation ns = Orientation.NORTH;
|
||||||
|
Orientation ew = Orientation.EAST;
|
||||||
|
|
||||||
|
if (latitude < 0) {
|
||||||
|
ns = Orientation.SOUTH;
|
||||||
|
latitude *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (longitude < 0) {
|
||||||
|
ew = Orientation.WEST;
|
||||||
|
longitude *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LocationData.ns != ns) {
|
||||||
|
LocationData.ns = ns;
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LocationData.ew != ew) {
|
||||||
|
LocationData.ew = ew;
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LocationData.latitude != latitude) {
|
||||||
|
LocationData.latitude = latitude;
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LocationData.longitude != longitude) {
|
||||||
|
LocationData.longitude = longitude;
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LocationData.zoom != zoomLevel) {
|
||||||
|
LocationData.zoom = zoomLevel;
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (change) {
|
||||||
|
notifyChange(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.location;
|
||||||
|
|
||||||
|
public interface LocationDataListener {
|
||||||
|
void valueChanged();
|
||||||
|
}
|
@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.location;
|
||||||
|
|
||||||
|
import org.oscim.theme.comparator.Main;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
import javax.swing.SpinnerNumberModel;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
|
public class LocationGPS extends JPanel implements LocationDataListener {
|
||||||
|
|
||||||
|
private final JSpinner latitude = new JSpinner();
|
||||||
|
private final JSpinner longitude = new JSpinner();
|
||||||
|
private final JSpinner zoom = new JSpinner();
|
||||||
|
private final JComboBox<LocationData.Orientation> ew = new JComboBox<>();
|
||||||
|
private final JComboBox<LocationData.Orientation> ns = new JComboBox<>();
|
||||||
|
|
||||||
|
LocationGPS() {
|
||||||
|
LocationData.addChangeListener(this);
|
||||||
|
|
||||||
|
JPanel labels = new JPanel(new GridLayout(3, 1));
|
||||||
|
labels.add(new JLabel("Latitude: [Deg]", JLabel.RIGHT));
|
||||||
|
labels.add(new JLabel("Longitude: [Deg]", JLabel.RIGHT));
|
||||||
|
labels.add(new JLabel("Zoom:", JLabel.RIGHT));
|
||||||
|
|
||||||
|
JPanel p1 = new JPanel();
|
||||||
|
p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
p1.add(latitude);
|
||||||
|
latitude.setPreferredSize(new Dimension(100, 20));
|
||||||
|
p1.add(ns);
|
||||||
|
ns.setPreferredSize(new Dimension(80, 20));
|
||||||
|
{
|
||||||
|
JLabel spacer = new JLabel("");
|
||||||
|
spacer.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p1.add(spacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
JPanel p2 = new JPanel();
|
||||||
|
p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
p2.add(longitude);
|
||||||
|
longitude.setPreferredSize(new Dimension(100, 20));
|
||||||
|
p2.add(ew);
|
||||||
|
ew.setPreferredSize(new Dimension(80, 20));
|
||||||
|
{
|
||||||
|
JLabel spacer = new JLabel("");
|
||||||
|
spacer.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p2.add(spacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeListener latitudeChangeListener = new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
LocationData.setLatitude((Double) latitude.getValue());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
latitude.setModel(new SpinnerNumberModel(LocationData.getLatitude(), 0, 180, 0.001));
|
||||||
|
latitude.addChangeListener(latitudeChangeListener);
|
||||||
|
|
||||||
|
ns.addItem(LocationData.Orientation.NORTH);
|
||||||
|
ns.addItem(LocationData.Orientation.SOUTH);
|
||||||
|
ns.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
LocationData.setNS((LocationData.Orientation) ns.getSelectedItem());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ChangeListener longitudeChangeListener = new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
LocationData.setLongitude((Double) longitude.getValue());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
longitude.setModel(new SpinnerNumberModel(LocationData.getLongitude(), 0, 180, 0.001));
|
||||||
|
longitude.addChangeListener(longitudeChangeListener);
|
||||||
|
|
||||||
|
ew.addItem(LocationData.Orientation.EAST);
|
||||||
|
ew.addItem(LocationData.Orientation.WEST);
|
||||||
|
ew.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
LocationData.setEW((LocationData.Orientation) ew.getSelectedItem());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JPanel p3 = new JPanel();
|
||||||
|
p3.setLayout(new BoxLayout(p3, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
p3.add(zoom);
|
||||||
|
zoom.setPreferredSize(new Dimension(50, 20));
|
||||||
|
zoom.setModel(new SpinnerNumberModel(LocationData.getZoom(), Main.MIN_ZOOM_LEVEL, Main.MAX_ZOOM_LEVEL, 1));
|
||||||
|
zoom.addChangeListener(new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
LocationData.setZoom((int) zoom.getValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
this.add(labels);
|
||||||
|
this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
|
||||||
|
JPanel aroundThis = new JPanel();
|
||||||
|
aroundThis.setLayout(new BoxLayout(aroundThis, BoxLayout.Y_AXIS));
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p1);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p2);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p3);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
this.add(aroundThis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChanged() {
|
||||||
|
latitude.setValue(LocationData.getLatitude());
|
||||||
|
longitude.setValue(LocationData.getLongitude());
|
||||||
|
|
||||||
|
ns.setSelectedItem(LocationData.getNS());
|
||||||
|
ew.setSelectedItem(LocationData.getEW());
|
||||||
|
zoom.setValue(LocationData.getZoom());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.location;
|
||||||
|
|
||||||
|
import org.oscim.theme.comparator.Main;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
import javax.swing.SpinnerNumberModel;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
|
public class LocationNMEA extends JPanel implements LocationDataListener {
|
||||||
|
|
||||||
|
|
||||||
|
private final JSpinner latitude = new JSpinner();
|
||||||
|
private final JSpinner longitude = new JSpinner();
|
||||||
|
private final JSpinner zoom = new JSpinner();
|
||||||
|
private final JComboBox<LocationData.Orientation> ew = new JComboBox<>();
|
||||||
|
private final JComboBox<LocationData.Orientation> ns = new JComboBox<>();
|
||||||
|
|
||||||
|
LocationNMEA() {
|
||||||
|
LocationData.addChangeListener(this);
|
||||||
|
|
||||||
|
JPanel labels = new JPanel(new GridLayout(3, 1));
|
||||||
|
labels.add(new JLabel("Latitude:", JLabel.RIGHT));
|
||||||
|
labels.add(new JLabel("Longitude:", JLabel.RIGHT));
|
||||||
|
labels.add(new JLabel("Zoom:", JLabel.RIGHT));
|
||||||
|
|
||||||
|
JPanel p1 = new JPanel();
|
||||||
|
p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
p1.add(latitude);
|
||||||
|
latitude.setPreferredSize(new Dimension(100, 20));
|
||||||
|
p1.add(ns);
|
||||||
|
ns.setPreferredSize(new Dimension(80, 20));
|
||||||
|
{
|
||||||
|
JLabel spacer = new JLabel("");
|
||||||
|
spacer.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p1.add(spacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
JPanel p2 = new JPanel();
|
||||||
|
p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
p2.add(longitude);
|
||||||
|
longitude.setPreferredSize(new Dimension(100, 20));
|
||||||
|
p2.add(ew);
|
||||||
|
ew.setPreferredSize(new Dimension(80, 20));
|
||||||
|
{
|
||||||
|
JLabel spacer = new JLabel("");
|
||||||
|
spacer.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p2.add(spacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeListener latitudeChangeListener = new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
LocationData.setLatitude(nmea2degree((Double) latitude.getValue()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
latitude.setModel(new SpinnerNumberModel(degree2nmea(LocationData.getLatitude()), 0, 9000, 0.002));
|
||||||
|
latitude.addChangeListener(latitudeChangeListener);
|
||||||
|
|
||||||
|
ns.addItem(LocationData.Orientation.NORTH);
|
||||||
|
ns.addItem(LocationData.Orientation.SOUTH);
|
||||||
|
ns.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
LocationData.setNS((LocationData.Orientation) ns.getSelectedItem());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ChangeListener longitudeChangeListener = new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
LocationData.setLongitude(nmea2degree((Double) longitude.getValue()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
longitude.setModel(new SpinnerNumberModel(degree2nmea(LocationData.getLongitude()), 0, 18000, 0.002));
|
||||||
|
longitude.addChangeListener(longitudeChangeListener);
|
||||||
|
|
||||||
|
ew.addItem(LocationData.Orientation.EAST);
|
||||||
|
ew.addItem(LocationData.Orientation.WEST);
|
||||||
|
ew.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
LocationData.setEW((LocationData.Orientation) ew.getSelectedItem());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
JPanel p3 = new JPanel();
|
||||||
|
p3.setLayout(new BoxLayout(p3, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
p3.add(zoom);
|
||||||
|
zoom.setPreferredSize(new Dimension(50, 20));
|
||||||
|
zoom.setModel(new SpinnerNumberModel(LocationData.getZoom(), Main.MIN_ZOOM_LEVEL, Main.MAX_ZOOM_LEVEL, 1));
|
||||||
|
zoom.addChangeListener(new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
LocationData.setZoom((int) zoom.getValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.add(labels);
|
||||||
|
this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
|
||||||
|
JPanel aroundThis = new JPanel();
|
||||||
|
aroundThis.setLayout(new BoxLayout(aroundThis, BoxLayout.Y_AXIS));
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p1);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p2);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p3);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.add(aroundThis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChanged() {
|
||||||
|
latitude.setValue(degree2nmea(LocationData.getLatitude()));
|
||||||
|
longitude.setValue(degree2nmea(LocationData.getLongitude()));
|
||||||
|
|
||||||
|
ns.setSelectedItem(LocationData.getNS());
|
||||||
|
ew.setSelectedItem(LocationData.getEW());
|
||||||
|
|
||||||
|
zoom.setValue(LocationData.getZoom());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private double degree2nmea(double value) {
|
||||||
|
double degree = (int) value;
|
||||||
|
double minute = (int) (value * 60 - degree * 60);
|
||||||
|
double second = value * 60 - (int) (value * 60);
|
||||||
|
|
||||||
|
return (double) Math.round((degree * 100 + minute + second) * 1000) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double nmea2degree(double value) {
|
||||||
|
int degree = (int) value / 100;
|
||||||
|
int minute = (int) (value - degree * 100);
|
||||||
|
double second = ((value - (int) value) * 60);
|
||||||
|
|
||||||
|
return degree + ((double) minute / 60) + second / 60 / 60;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,319 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.location;
|
||||||
|
|
||||||
|
import org.oscim.theme.comparator.Main;
|
||||||
|
import org.oscim.theme.comparator.location.LocationData.Orientation;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
import javax.swing.SpinnerNumberModel;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
|
public class LocationNormal extends JPanel implements LocationDataListener {
|
||||||
|
|
||||||
|
private final JSpinner latitudeDegree = new JSpinner();
|
||||||
|
private final JSpinner longitudeDegree = new JSpinner();
|
||||||
|
private final JSpinner latitudeMinute = new JSpinner();
|
||||||
|
private final JSpinner longitudeMinute = new JSpinner();
|
||||||
|
private final JSpinner latitudeSecond = new JSpinner();
|
||||||
|
private final JSpinner longitudeSecond = new JSpinner();
|
||||||
|
private final JSpinner zoom = new JSpinner();
|
||||||
|
private final JComboBox<Orientation> ew = new JComboBox<>();
|
||||||
|
private final JComboBox<Orientation> ns = new JComboBox<>();
|
||||||
|
private final AtomicBoolean blockChangeListener = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
LocationNormal() {
|
||||||
|
LocationData.addChangeListener(this);
|
||||||
|
|
||||||
|
JPanel labels = new JPanel(new GridLayout(3, 1));
|
||||||
|
labels.add(new JLabel("Latitude:", JLabel.RIGHT));
|
||||||
|
labels.add(new JLabel("Longitude:", JLabel.RIGHT));
|
||||||
|
labels.add(new JLabel("Zoom:", JLabel.RIGHT));
|
||||||
|
|
||||||
|
JPanel p1 = new JPanel();
|
||||||
|
p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
latitudeDegree.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p1.add(latitudeDegree);
|
||||||
|
latitudeDegree.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p1.add(latitudeMinute);
|
||||||
|
latitudeMinute.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p1.add(latitudeSecond);
|
||||||
|
latitudeSecond.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p1.add(ns);
|
||||||
|
ns.setPreferredSize(new Dimension(80, 20));
|
||||||
|
|
||||||
|
JPanel p2 = new JPanel();
|
||||||
|
p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
p2.add(longitudeDegree);
|
||||||
|
longitudeDegree.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p2.add(longitudeMinute);
|
||||||
|
longitudeMinute.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p2.add(longitudeSecond);
|
||||||
|
longitudeSecond.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p2.add(ew);
|
||||||
|
ew.setPreferredSize(new Dimension(80, 20));
|
||||||
|
|
||||||
|
ChangeListener latitudeChangeListener = new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
if (blockChangeListener.get()) {
|
||||||
|
double latitude = LocationData.getLatitude();
|
||||||
|
assert latitude >= 0;
|
||||||
|
int lat = (int) Math.round(latitude * 3600);
|
||||||
|
latitudeSecond.setValue(lat % 60);
|
||||||
|
lat = lat / 60;
|
||||||
|
latitudeMinute.setValue(lat % 60);
|
||||||
|
lat = lat / 60;
|
||||||
|
latitudeDegree.setValue(lat);
|
||||||
|
} else {
|
||||||
|
Integer degree = (Integer) latitudeDegree.getValue();
|
||||||
|
Integer minute = (Integer) latitudeMinute.getValue();
|
||||||
|
Integer second = (Integer) latitudeSecond.getValue();
|
||||||
|
|
||||||
|
if (degree == 90) {
|
||||||
|
if (minute == -1 && second == 0) {
|
||||||
|
latitudeSecond.setValue(59);
|
||||||
|
} else if (minute == 0 && second == -1) {
|
||||||
|
latitudeMinute.setValue(59);
|
||||||
|
} else if (minute == -1 && second == 59) {
|
||||||
|
latitudeMinute.setValue(59);
|
||||||
|
} else if (minute == 59 && second == -1) {
|
||||||
|
latitudeSecond.setValue(59);
|
||||||
|
} else if (minute == 59 && second == 59) {
|
||||||
|
latitudeDegree.setValue(89);
|
||||||
|
} else if (minute == 0 && second == 0) {
|
||||||
|
Double tmp = allInOne(degree, minute, second);
|
||||||
|
LocationData.setLatitude(tmp);
|
||||||
|
} else {
|
||||||
|
latitudeSecond.setValue(0);
|
||||||
|
latitudeMinute.setValue(0);
|
||||||
|
}
|
||||||
|
} else if (second == 60) {
|
||||||
|
latitudeSecond.setValue(0);
|
||||||
|
latitudeMinute.setValue((Integer) latitudeMinute.getValue() + 1);
|
||||||
|
} else if (second == -1) {
|
||||||
|
if (minute == 0) {
|
||||||
|
latitudeSecond.setValue(0);
|
||||||
|
} else {
|
||||||
|
latitudeSecond.setValue(59);
|
||||||
|
latitudeMinute.setValue((Integer) latitudeMinute.getValue() - 1);
|
||||||
|
}
|
||||||
|
} else if (minute == 60) {
|
||||||
|
latitudeMinute.setValue(0);
|
||||||
|
latitudeDegree.setValue((Integer) latitudeDegree.getValue() + 1);
|
||||||
|
} else if (minute == -1) {
|
||||||
|
if (degree == 0) {
|
||||||
|
latitudeMinute.setValue(0);
|
||||||
|
} else {
|
||||||
|
latitudeMinute.setValue(59);
|
||||||
|
latitudeDegree.setValue((Integer) latitudeDegree.getValue() - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LocationData.setLatitude(allInOne(degree, minute, second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
latitudeDegree.setModel(new SpinnerNumberModel(degree(LocationData.getLatitude()), 0, 90, 1));
|
||||||
|
latitudeDegree.addChangeListener(latitudeChangeListener);
|
||||||
|
|
||||||
|
latitudeMinute.setModel(new SpinnerNumberModel(minute(LocationData.getLatitude()), -1, 60, 1));
|
||||||
|
latitudeMinute.addChangeListener(latitudeChangeListener);
|
||||||
|
|
||||||
|
latitudeSecond.setModel(new SpinnerNumberModel(second(LocationData.getLatitude()), -1, 60, 1));
|
||||||
|
latitudeSecond.addChangeListener(latitudeChangeListener);
|
||||||
|
|
||||||
|
ns.addItem(Orientation.NORTH);
|
||||||
|
ns.addItem(Orientation.SOUTH);
|
||||||
|
ns.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
LocationData.setNS((Orientation) ns.getSelectedItem());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ChangeListener longitudeChangeListener = new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
if (blockChangeListener.get()) {
|
||||||
|
double longitude = LocationData.getLongitude();
|
||||||
|
assert longitude >= 0;
|
||||||
|
int lng = (int) Math.round(longitude * 3600);
|
||||||
|
longitudeSecond.setValue(lng % 60);
|
||||||
|
lng = lng / 60;
|
||||||
|
longitudeMinute.setValue(lng % 60);
|
||||||
|
lng = lng / 60;
|
||||||
|
longitudeDegree.setValue(lng);
|
||||||
|
} else {
|
||||||
|
Integer degree = (Integer) longitudeDegree.getValue();
|
||||||
|
Integer minute = (Integer) longitudeMinute.getValue();
|
||||||
|
Integer second = (Integer) longitudeSecond.getValue();
|
||||||
|
|
||||||
|
if (degree == 180) {
|
||||||
|
if (minute == -1 && second == 0) {
|
||||||
|
longitudeSecond.setValue(59);
|
||||||
|
} else if (minute == 0 && second == -1) {
|
||||||
|
longitudeMinute.setValue(59);
|
||||||
|
} else if (minute == -1 && second == 59) {
|
||||||
|
longitudeMinute.setValue(59);
|
||||||
|
} else if (minute == 59 && second == -1) {
|
||||||
|
longitudeSecond.setValue(59);
|
||||||
|
} else if (minute == 59 && second == 59) {
|
||||||
|
longitudeDegree.setValue(179);
|
||||||
|
} else if (minute == 0 && second == 0) {
|
||||||
|
Double tmp = allInOne(degree, minute, second);
|
||||||
|
LocationData.setLongitude(tmp);
|
||||||
|
} else {
|
||||||
|
longitudeSecond.setValue(0);
|
||||||
|
longitudeMinute.setValue(0);
|
||||||
|
}
|
||||||
|
} else if (second == 60) {
|
||||||
|
longitudeSecond.setValue(0);
|
||||||
|
longitudeMinute.setValue((Integer) longitudeMinute.getValue() + 1);
|
||||||
|
} else if (second == -1) {
|
||||||
|
if (minute == 0) {
|
||||||
|
longitudeSecond.setValue(0);
|
||||||
|
} else {
|
||||||
|
longitudeSecond.setValue(59);
|
||||||
|
longitudeMinute.setValue((Integer) longitudeMinute.getValue() - 1);
|
||||||
|
}
|
||||||
|
} else if (minute == 60) {
|
||||||
|
longitudeMinute.setValue(0);
|
||||||
|
longitudeDegree.setValue((Integer) longitudeDegree.getValue() + 1);
|
||||||
|
} else if (minute == -1) {
|
||||||
|
if (degree == 0) {
|
||||||
|
longitudeMinute.setValue(0);
|
||||||
|
} else {
|
||||||
|
longitudeMinute.setValue(59);
|
||||||
|
longitudeDegree.setValue((Integer) longitudeDegree.getValue() - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LocationData.setLongitude(allInOne(degree, minute, second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
longitudeDegree.setModel(new SpinnerNumberModel(degree(LocationData.getLongitude()), 0, 180, 1));
|
||||||
|
longitudeDegree.addChangeListener(longitudeChangeListener);
|
||||||
|
|
||||||
|
longitudeMinute.setModel(new SpinnerNumberModel(minute(LocationData.getLongitude()), -1, 60, 1));
|
||||||
|
longitudeMinute.addChangeListener(longitudeChangeListener);
|
||||||
|
|
||||||
|
longitudeSecond.setModel(new SpinnerNumberModel(second(LocationData.getLongitude()), -1, 60, 1));
|
||||||
|
longitudeSecond.addChangeListener(longitudeChangeListener);
|
||||||
|
|
||||||
|
ew.addItem(Orientation.EAST);
|
||||||
|
ew.addItem(Orientation.WEST);
|
||||||
|
ew.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
LocationData.setEW((Orientation) ew.getSelectedItem());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JPanel p3 = new JPanel();
|
||||||
|
p3.setLayout(new BoxLayout(p3, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
p3.add(zoom);
|
||||||
|
zoom.setPreferredSize(new Dimension(50, 20));
|
||||||
|
zoom.setModel(new SpinnerNumberModel(LocationData.getZoom(), Main.MIN_ZOOM_LEVEL, Main.MAX_ZOOM_LEVEL, 1));
|
||||||
|
zoom.addChangeListener(new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
if (blockChangeListener.get()) return;
|
||||||
|
LocationData.setZoom((int) zoom.getValue());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
this.add(labels);
|
||||||
|
this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
|
||||||
|
JPanel aroundThis = new JPanel();
|
||||||
|
aroundThis.setLayout(new BoxLayout(aroundThis, BoxLayout.Y_AXIS));
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p1);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p2);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p3);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
this.add(aroundThis);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChanged() {
|
||||||
|
blockChangeListener.set(true);
|
||||||
|
latitudeDegree.setValue(degree(LocationData.getLatitude()));
|
||||||
|
longitudeDegree.setValue(degree(LocationData.getLongitude()));
|
||||||
|
|
||||||
|
latitudeMinute.setValue(minute(LocationData.getLatitude()));
|
||||||
|
longitudeMinute.setValue(minute(LocationData.getLongitude()));
|
||||||
|
|
||||||
|
latitudeSecond.setValue(second(LocationData.getLatitude()));
|
||||||
|
longitudeSecond.setValue(second(LocationData.getLongitude()));
|
||||||
|
|
||||||
|
ns.setSelectedItem(LocationData.getNS());
|
||||||
|
ew.setSelectedItem(LocationData.getEW());
|
||||||
|
|
||||||
|
zoom.setValue(LocationData.getZoom());
|
||||||
|
|
||||||
|
blockChangeListener.set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double allInOne(int degree, int minute, int second) {
|
||||||
|
return degree + ((double) minute / 60) + (double) second / 60 / 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int degree(double value) {
|
||||||
|
return (int) (Math.round(value * 3600) / 3600);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int minute(double value) {
|
||||||
|
return (int) (Math.round(value * 3600) / 60 % 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int second(double value) {
|
||||||
|
return (int) (Math.round(value * 3600) % 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.location;
|
||||||
|
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JTabbedPane;
|
||||||
|
|
||||||
|
public class LocationPane extends JPanel {
|
||||||
|
|
||||||
|
public LocationPane() {
|
||||||
|
|
||||||
|
this.setBorder(BorderFactory.createTitledBorder("Location"));
|
||||||
|
|
||||||
|
JTabbedPane tabs = new JTabbedPane();
|
||||||
|
|
||||||
|
tabs.addTab("Normal", new LocationNormal());
|
||||||
|
tabs.addTab("NMEA Format", new LocationNMEA());
|
||||||
|
tabs.addTab("GPS Format", new LocationGPS());
|
||||||
|
tabs.addTab("Tile Format", new LocationTile());
|
||||||
|
|
||||||
|
this.add(tabs);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.location;
|
||||||
|
|
||||||
|
import org.mapsforge.core.model.LatLong;
|
||||||
|
import org.mapsforge.core.model.Tile;
|
||||||
|
import org.mapsforge.core.util.MercatorProjection;
|
||||||
|
import org.oscim.theme.comparator.Main;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
import javax.swing.SpinnerNumberModel;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
|
||||||
|
public class LocationTile extends JPanel implements LocationDataListener {
|
||||||
|
|
||||||
|
private final JSpinner tileX = new JSpinner();
|
||||||
|
private final JSpinner tileY = new JSpinner();
|
||||||
|
private final JSpinner tileZ = new JSpinner();
|
||||||
|
private final AtomicBoolean blockChangeListener = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
LocationTile() {
|
||||||
|
LocationData.addChangeListener(this);
|
||||||
|
|
||||||
|
JPanel labels = new JPanel(new GridLayout(3, 1));
|
||||||
|
labels.add(new JLabel("Tile X:", JLabel.RIGHT));
|
||||||
|
labels.add(new JLabel("Tile Y:", JLabel.RIGHT));
|
||||||
|
labels.add(new JLabel("Tile Z:", JLabel.RIGHT));
|
||||||
|
|
||||||
|
JPanel p1 = new JPanel();
|
||||||
|
p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
p1.add(tileX);
|
||||||
|
tileX.setPreferredSize(new Dimension(100, 20));
|
||||||
|
{
|
||||||
|
JLabel spacer = new JLabel("");
|
||||||
|
spacer.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p1.add(spacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
JPanel p2 = new JPanel();
|
||||||
|
p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
p2.add(tileY);
|
||||||
|
tileY.setPreferredSize(new Dimension(100, 20));
|
||||||
|
{
|
||||||
|
JLabel spacer = new JLabel("");
|
||||||
|
spacer.setPreferredSize(new Dimension(50, 20));
|
||||||
|
p2.add(spacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
JPanel p3 = new JPanel();
|
||||||
|
p3.setLayout(new BoxLayout(p3, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
p3.add(tileZ);
|
||||||
|
tileZ.setPreferredSize(new Dimension(50, 20));
|
||||||
|
|
||||||
|
|
||||||
|
ChangeListener tileNumberChangeListener = new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
if (blockChangeListener.get()) return;
|
||||||
|
try {
|
||||||
|
Tile tile = new Tile((int) tileX.getValue(), (int) tileY.getValue(), ((Integer) tileZ.getValue()).byteValue(), 256);
|
||||||
|
LatLong latLon = tile.getBoundingBox().getCenterPoint();
|
||||||
|
|
||||||
|
LocationData.setLatitude(latLon.latitude);
|
||||||
|
LocationData.setLongitude(latLon.longitude);
|
||||||
|
LocationData.setZoom((Integer) tileZ.getValue());
|
||||||
|
} catch (Exception e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ChangeListener zoomChangeListener = new ChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void stateChanged(ChangeEvent e) {
|
||||||
|
LocationData.setZoom((Integer) tileZ.getValue());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int maxTileNumber = Tile.getMaxTileNumber((byte) Main.MAX_ZOOM_LEVEL);
|
||||||
|
|
||||||
|
tileX.setModel(new SpinnerNumberModel(0, 0, maxTileNumber, 1));
|
||||||
|
tileY.setModel(new SpinnerNumberModel(0, 0, maxTileNumber, 1));
|
||||||
|
tileZ.setModel(new SpinnerNumberModel(0, Main.MIN_ZOOM_LEVEL, Main.MAX_ZOOM_LEVEL, 1));
|
||||||
|
|
||||||
|
|
||||||
|
tileX.addChangeListener(tileNumberChangeListener);
|
||||||
|
tileY.addChangeListener(tileNumberChangeListener);
|
||||||
|
tileZ.addChangeListener(zoomChangeListener);
|
||||||
|
|
||||||
|
|
||||||
|
this.add(labels);
|
||||||
|
this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
|
||||||
|
JPanel aroundThis = new JPanel();
|
||||||
|
aroundThis.setLayout(new BoxLayout(aroundThis, BoxLayout.Y_AXIS));
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p1);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p2);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
JPanel jPanel = new JPanel();
|
||||||
|
jPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
|
||||||
|
jPanel.add(p3);
|
||||||
|
aroundThis.add(jPanel);
|
||||||
|
}
|
||||||
|
this.add(aroundThis);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChanged() {
|
||||||
|
blockChangeListener.set(true);
|
||||||
|
tileX.setValue(MercatorProjection.longitudeToTileX(LocationData.getLongitude(), (byte) LocationData.getZoom()));
|
||||||
|
tileY.setValue(MercatorProjection.latitudeToTileY(LocationData.getLatitude(), (byte) LocationData.getZoom()));
|
||||||
|
tileZ.setValue(LocationData.getZoom());
|
||||||
|
blockChangeListener.set(false);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.logging;
|
||||||
|
|
||||||
|
public class AllAppender extends BaseAppender {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean canLogClass(String className) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.logging;
|
||||||
|
|
||||||
|
import org.oscim.theme.comparator.Main;
|
||||||
|
|
||||||
|
public class AllLoggingPane extends BaseLoggingPane {
|
||||||
|
public AllLoggingPane() {
|
||||||
|
super(Main.ALL_APPENDER);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.logging;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.StringBuilder;
|
||||||
|
|
||||||
|
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.pattern.ThrowableProxyConverter;
|
||||||
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
|
import ch.qos.logback.classic.spi.IThrowableProxy;
|
||||||
|
import ch.qos.logback.core.AppenderBase;
|
||||||
|
import ch.qos.logback.core.CoreConstants;
|
||||||
|
import ch.qos.logback.core.util.CachingDateFormatter;
|
||||||
|
|
||||||
|
public abstract class BaseAppender extends AppenderBase<ILoggingEvent> {
|
||||||
|
private RSyntaxTextArea textArea;
|
||||||
|
private StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
private final CachingDateFormatter cachingDateFormatter = new CachingDateFormatter("HH:mm:ss.SSS");
|
||||||
|
private final ThrowableProxyConverter tpc = new ThrowableProxyConverter();
|
||||||
|
|
||||||
|
|
||||||
|
//Layout settings
|
||||||
|
private final boolean writeTime = true;
|
||||||
|
private final boolean writeThread = false;
|
||||||
|
private final boolean writeLevel = true;
|
||||||
|
private final boolean writeShortLoggerName = true;
|
||||||
|
|
||||||
|
BaseAppender() {
|
||||||
|
|
||||||
|
//set stackTrace count to 10
|
||||||
|
List<String> optionList = new ArrayList<>();
|
||||||
|
optionList.add("10");
|
||||||
|
tpc.setOptionList(optionList);
|
||||||
|
tpc.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void append(ILoggingEvent eventObject) {
|
||||||
|
if (eventObject != null && canLogClass(eventObject.getLoggerName())) {
|
||||||
|
stringBuilder.append(doLayout(eventObject));
|
||||||
|
String areaText = stringBuilder.toString();
|
||||||
|
this.textArea.setText(areaText);
|
||||||
|
this.textArea.setCaretPosition(areaText.length());
|
||||||
|
}
|
||||||
|
//TODO set Highlight for LogLevel [WARN], [ERROR]
|
||||||
|
}
|
||||||
|
|
||||||
|
String doLayout(ILoggingEvent event) {
|
||||||
|
if (!isStarted()) {
|
||||||
|
return CoreConstants.EMPTY_STRING;
|
||||||
|
}
|
||||||
|
java.lang.StringBuilder sb = new java.lang.StringBuilder();
|
||||||
|
|
||||||
|
if (writeTime) {
|
||||||
|
sb.append(cachingDateFormatter.format(event.getTimeStamp()));
|
||||||
|
sb.append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writeThread) {
|
||||||
|
sb.append("[");
|
||||||
|
sb.append(event.getThreadName());
|
||||||
|
sb.append("] ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writeLevel) {
|
||||||
|
sb.append(event.getLevel().toString());
|
||||||
|
sb.append(" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writeShortLoggerName) {
|
||||||
|
String name = event.getLoggerName();
|
||||||
|
int pos = name.lastIndexOf(".") + 1;
|
||||||
|
sb.append(name.substring(pos));
|
||||||
|
} else {
|
||||||
|
sb.append(event.getLoggerName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sb.append(" - ");
|
||||||
|
sb.append(event.getFormattedMessage());
|
||||||
|
sb.append(CoreConstants.LINE_SEPARATOR);
|
||||||
|
IThrowableProxy tp = event.getThrowableProxy();
|
||||||
|
if (tp != null) {
|
||||||
|
String stackTrace = tpc.convert(event);
|
||||||
|
sb.append(stackTrace);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTextArea(RSyntaxTextArea textArea) {
|
||||||
|
this.textArea = textArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract boolean canLogClass(String className);
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.logging;
|
||||||
|
|
||||||
|
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||||
|
import org.fife.ui.rsyntaxtextarea.Theme;
|
||||||
|
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||||
|
import org.oscim.theme.comparator.Main;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
abstract class BaseLoggingPane extends JPanel {
|
||||||
|
|
||||||
|
private final RSyntaxTextArea textArea;
|
||||||
|
|
||||||
|
BaseLoggingPane(BaseAppender appender) {
|
||||||
|
super(new BorderLayout());
|
||||||
|
textArea = new RSyntaxTextArea(5, 60);
|
||||||
|
textArea.enableInputMethods(false);
|
||||||
|
RTextScrollPane sp = new RTextScrollPane(textArea);
|
||||||
|
sp.setLineNumbersEnabled(false);
|
||||||
|
this.add(sp);
|
||||||
|
setTheme(Main.useDarkTheme);
|
||||||
|
appender.setTextArea(textArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTheme(boolean dark) {
|
||||||
|
try {
|
||||||
|
Theme theme;
|
||||||
|
if (dark) {
|
||||||
|
theme = Theme.load(getClass().getResourceAsStream(
|
||||||
|
"/org/fife/ui/rsyntaxtextarea/themes/dark.xml"));
|
||||||
|
} else {
|
||||||
|
theme = Theme.load(getClass().getResourceAsStream(
|
||||||
|
"/org/fife/ui/rsyntaxtextarea/themes/default.xml"));
|
||||||
|
}
|
||||||
|
theme.apply(textArea);
|
||||||
|
} catch (IOException ioe) { // Never happens
|
||||||
|
ioe.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.logging;
|
||||||
|
|
||||||
|
public class MapsforgeAppender extends BaseAppender {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean canLogClass(String className) {
|
||||||
|
return className.startsWith("org.mapsforge.");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.logging;
|
||||||
|
|
||||||
|
import org.oscim.theme.comparator.Main;
|
||||||
|
|
||||||
|
public class MapsforgeLoggingPane extends BaseLoggingPane {
|
||||||
|
public MapsforgeLoggingPane() {
|
||||||
|
super(Main.MAPSFORGE_APPENDER);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.logging;
|
||||||
|
|
||||||
|
public class VtmAppender extends BaseAppender {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean canLogClass(String className) {
|
||||||
|
return className.startsWith("org.oscim.") && !className.startsWith("org.oscim.theme.comparator.");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.logging;
|
||||||
|
|
||||||
|
import org.oscim.theme.comparator.Main;
|
||||||
|
|
||||||
|
public class VtmLoggingPane extends BaseLoggingPane {
|
||||||
|
public VtmLoggingPane() {
|
||||||
|
super(Main.VTM_APPENDER);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.mapsforge;
|
||||||
|
|
||||||
|
import org.mapsforge.map.awt.input.MapViewComponentListener;
|
||||||
|
import org.mapsforge.map.awt.view.MapView;
|
||||||
|
import org.oscim.theme.comparator.BothMapPositionHandler;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
|
||||||
|
public class AwtMapView extends MapView {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private final MapPanelMouseListener mouseEventListener = new MapPanelMouseListener(this);
|
||||||
|
|
||||||
|
AwtMapView() {
|
||||||
|
super();
|
||||||
|
addMyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint(Graphics graphics) {
|
||||||
|
super.paint(graphics);
|
||||||
|
int xc = this.getWidth() / 2;
|
||||||
|
int yc = this.getHeight() / 2;
|
||||||
|
|
||||||
|
graphics.setColor(Color.RED);
|
||||||
|
graphics.drawLine(xc - 50, yc - 50, xc + 50, yc + 50);
|
||||||
|
graphics.drawLine(xc - 50, yc + 50, xc + 50, yc - 50);
|
||||||
|
graphics.drawOval(xc - 25, yc - 25, 50, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addListeners() {
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void addMyListeners() {
|
||||||
|
addComponentListener(new MapViewComponentListener(this));
|
||||||
|
addMouseListener(mouseEventListener);
|
||||||
|
addMouseMotionListener(mouseEventListener);
|
||||||
|
addMouseWheelListener(mouseEventListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMapPositionHandler(BothMapPositionHandler mapPositionHandler) {
|
||||||
|
mouseEventListener.setMapPositionHandler(mapPositionHandler);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.mapsforge;
|
||||||
|
|
||||||
|
import org.mapsforge.map.awt.input.MouseEventListener;
|
||||||
|
import org.mapsforge.map.view.MapView;
|
||||||
|
import org.oscim.theme.comparator.BothMapPositionHandler;
|
||||||
|
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
|
||||||
|
public class MapPanelMouseListener extends MouseEventListener {
|
||||||
|
|
||||||
|
private BothMapPositionHandler mapPositionHandler;
|
||||||
|
private final MapView mapView;
|
||||||
|
|
||||||
|
MapPanelMouseListener(MapView mapView) {
|
||||||
|
super(mapView);
|
||||||
|
this.mapView = mapView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged(MouseEvent e) {
|
||||||
|
super.mouseDragged(e);
|
||||||
|
if (this.mapPositionHandler != null) {
|
||||||
|
this.mapPositionHandler.mapPositionChangedFromMapPanel(this.mapView.getModel().mapViewPosition.getMapPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||||
|
super.mouseWheelMoved(e);
|
||||||
|
if (this.mapPositionHandler != null) {
|
||||||
|
this.mapPositionHandler.mapPositionChangedFromMapPanel(this.mapView.getModel().mapViewPosition.getMapPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMapPositionHandler(BothMapPositionHandler mapPositionHandler) {
|
||||||
|
this.mapPositionHandler = mapPositionHandler;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.mapsforge;
|
||||||
|
|
||||||
|
import org.mapsforge.core.graphics.GraphicFactory;
|
||||||
|
import org.mapsforge.core.model.LatLong;
|
||||||
|
import org.mapsforge.map.awt.graphics.AwtGraphicFactory;
|
||||||
|
import org.mapsforge.map.awt.input.MapViewComponentListener;
|
||||||
|
import org.mapsforge.map.awt.util.JavaPreferences;
|
||||||
|
import org.mapsforge.map.awt.view.MapView;
|
||||||
|
import org.mapsforge.map.layer.Layer;
|
||||||
|
import org.mapsforge.map.layer.LayerManager;
|
||||||
|
import org.mapsforge.map.layer.Layers;
|
||||||
|
import org.mapsforge.map.layer.cache.FileSystemTileCache;
|
||||||
|
import org.mapsforge.map.layer.cache.InMemoryTileCache;
|
||||||
|
import org.mapsforge.map.layer.cache.TileCache;
|
||||||
|
import org.mapsforge.map.layer.cache.TwoLevelTileCache;
|
||||||
|
import org.mapsforge.map.layer.renderer.TileRendererLayer;
|
||||||
|
import org.mapsforge.map.model.MapViewPosition;
|
||||||
|
import org.mapsforge.map.model.Model;
|
||||||
|
import org.mapsforge.map.model.common.PreferencesFacade;
|
||||||
|
import org.mapsforge.map.reader.MapFile;
|
||||||
|
import org.mapsforge.map.rendertheme.ExternalRenderTheme;
|
||||||
|
import org.mapsforge.map.rendertheme.InternalRenderTheme;
|
||||||
|
import org.mapsforge.map.rendertheme.XmlRenderTheme;
|
||||||
|
import org.oscim.theme.comparator.BothMapPositionHandler;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.awt.event.ComponentAdapter;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
public class MapsforgeMapPanel extends JPanel {
|
||||||
|
private final static Logger log = LoggerFactory.getLogger(MapsforgeMapPanel.class);
|
||||||
|
private final GraphicFactory GRAPHIC_FACTORY = AwtGraphicFactory.INSTANCE;
|
||||||
|
private AwtMapView mapView;
|
||||||
|
|
||||||
|
private File mapFile, themeFile;
|
||||||
|
|
||||||
|
public MapsforgeMapPanel() {
|
||||||
|
this.setLayout(null);
|
||||||
|
mapView = createMapView();
|
||||||
|
|
||||||
|
PreferencesFacade preferencesFacade = new JavaPreferences(Preferences.userNodeForPackage(MapView.class));
|
||||||
|
final Model model = mapView.getModel();
|
||||||
|
model.init(preferencesFacade);
|
||||||
|
|
||||||
|
this.setBorder(BorderFactory.createTitledBorder("MAPSFORGE-Map"));
|
||||||
|
this.add(mapView);
|
||||||
|
mapView.setVisible(true);
|
||||||
|
|
||||||
|
this.addComponentListener(new ComponentAdapter() {
|
||||||
|
@Override
|
||||||
|
public void componentResized(ComponentEvent e) {
|
||||||
|
super.componentResized(e);
|
||||||
|
mapView.setBounds(10, 20, getWidth() - 20, getHeight() - 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void componentMoved(ComponentEvent e) {
|
||||||
|
super.componentMoved(e);
|
||||||
|
mapView.setBounds(10, 20, getWidth() - 20, getHeight() - 30);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addLayers(MapView mapView, File mapPath, File themePath) {
|
||||||
|
LayerManager layerManager = mapView.getLayerManager();
|
||||||
|
Layers layers = layerManager.getLayers();
|
||||||
|
TileCache tileCache = createTileCache();
|
||||||
|
layers.clear();
|
||||||
|
layers.add(createTileRendererLayer(tileCache, mapView.getModel().mapViewPosition, mapPath, themePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Layer createTileRendererLayer(TileCache tileCache, MapViewPosition mapViewPosition, File mapFile, File themeFile) {
|
||||||
|
|
||||||
|
TileRendererLayer tileRendererLayer = new TileRendererLayer(tileCache, new MapFile(mapFile), mapViewPosition, false, true, true, GRAPHIC_FACTORY);
|
||||||
|
|
||||||
|
if (themeFile != null) {
|
||||||
|
|
||||||
|
XmlRenderTheme renderTheme;
|
||||||
|
try {
|
||||||
|
renderTheme = new ExternalRenderTheme(themeFile);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
renderTheme = InternalRenderTheme.OSMARENDER;
|
||||||
|
}
|
||||||
|
tileRendererLayer.setXmlRenderTheme(renderTheme);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
tileRendererLayer.setXmlRenderTheme(InternalRenderTheme.OSMARENDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tileRendererLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AwtMapView createMapView() {
|
||||||
|
AwtMapView mapView = new AwtMapView();
|
||||||
|
mapView.getFpsCounter().setVisible(false);
|
||||||
|
mapView.addComponentListener(new MapViewComponentListener(mapView));
|
||||||
|
return mapView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TileCache createTileCache() {
|
||||||
|
TileCache firstLevelTileCache = new InMemoryTileCache(64);
|
||||||
|
File cacheDirectory = new File(System.getProperty("java.io.tmpdir"), "mapsforge");
|
||||||
|
TileCache secondLevelTileCache = new FileSystemTileCache(1024, cacheDirectory, GRAPHIC_FACTORY);
|
||||||
|
return new TwoLevelTileCache(firstLevelTileCache, secondLevelTileCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadMap(File mapFile, File themeFile) {
|
||||||
|
log.debug("reload MAP:{} THEME:{}", mapFile, themeFile);
|
||||||
|
this.mapFile = mapFile;
|
||||||
|
this.themeFile = themeFile;
|
||||||
|
addLayers(mapView, this.mapFile, this.themeFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCoordinate(double latidude, double longitude, byte zoomLevel) {
|
||||||
|
mapView.setCenter(new LatLong(latidude, longitude));
|
||||||
|
mapView.setZoomLevel(zoomLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMapPositionHandler(BothMapPositionHandler mapPositionHandler) {
|
||||||
|
mapView.setMapPositionHandler(mapPositionHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTheme(String themePath) {
|
||||||
|
loadMap(this.mapFile, new File(themePath));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.vtm;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
|
||||||
|
import org.oscim.backend.canvas.Color;
|
||||||
|
import org.oscim.backend.canvas.Paint;
|
||||||
|
import org.oscim.core.GeometryBuffer;
|
||||||
|
import org.oscim.layers.GenericLayer;
|
||||||
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.renderer.BucketRenderer;
|
||||||
|
import org.oscim.renderer.GLViewport;
|
||||||
|
import org.oscim.renderer.bucket.LineBucket;
|
||||||
|
import org.oscim.theme.styles.LineStyle;
|
||||||
|
|
||||||
|
public class CenterCrossLayer extends GenericLayer implements Disposable {
|
||||||
|
|
||||||
|
private static final float crossLength = 50;
|
||||||
|
private static final float crossWidth = 1.7f;
|
||||||
|
private static final float circleRadius = 25;
|
||||||
|
private static final int drawingColor = Color.RED;
|
||||||
|
|
||||||
|
CenterCrossLayer(Map map) {
|
||||||
|
super(map, new Renderer());
|
||||||
|
((Renderer) this.mRenderer).setLayer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
((Renderer) this.mRenderer).dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Renderer extends BucketRenderer {
|
||||||
|
|
||||||
|
final LineBucket ll = buckets.addLineBucket(0,
|
||||||
|
new LineStyle(drawingColor, crossWidth, Paint.Cap.ROUND));
|
||||||
|
|
||||||
|
|
||||||
|
final GeometryBuffer g1 = new GeometryBuffer(2, 1);
|
||||||
|
final GeometryBuffer g2 = new GeometryBuffer(2, 1);
|
||||||
|
final GeometryBuffer g3 = new GeometryBuffer(2, 1);
|
||||||
|
|
||||||
|
private CenterCrossLayer centerCrossLayer;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(GLViewport v) {
|
||||||
|
buckets.clear();
|
||||||
|
if (!centerCrossLayer.isEnabled()) return;
|
||||||
|
mMapPosition.copy(v.pos);
|
||||||
|
buckets.set(ll);
|
||||||
|
|
||||||
|
g1.clear();
|
||||||
|
g1.startLine();
|
||||||
|
g1.addPoint(-crossLength, -crossLength);
|
||||||
|
g1.addPoint(crossLength, crossLength);
|
||||||
|
ll.addLine(g1);
|
||||||
|
|
||||||
|
g2.clear();
|
||||||
|
g2.startLine();
|
||||||
|
g2.addPoint(-crossLength, crossLength);
|
||||||
|
g2.addPoint(crossLength, -crossLength);
|
||||||
|
ll.addLine(g2);
|
||||||
|
|
||||||
|
g3.clear();
|
||||||
|
// calculate segment count
|
||||||
|
float alpha = (360 * 5) / (MathUtils.PI2 * circleRadius);
|
||||||
|
int segmente = Math.max(16, (int) (360 / alpha));
|
||||||
|
|
||||||
|
// calculate theta step
|
||||||
|
float thetaStep = (MathUtils.PI2 / segmente);
|
||||||
|
|
||||||
|
g3.startLine();
|
||||||
|
for (float i = 0, n = MathUtils.PI2 + thetaStep; i < n; i += thetaStep) {
|
||||||
|
g3.addPoint(circleRadius * MathUtils.cos(i), circleRadius * MathUtils.sin(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
ll.addLine(g3);
|
||||||
|
|
||||||
|
compile();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLayer(CenterCrossLayer centerCrossLayer) {
|
||||||
|
this.centerCrossLayer = centerCrossLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
centerCrossLayer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.vtm;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.utils.Timer;
|
||||||
|
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.event.Event;
|
||||||
|
import org.oscim.event.Gesture;
|
||||||
|
import org.oscim.event.MotionEvent;
|
||||||
|
import org.oscim.map.Map;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class MapAdapter extends Map implements Map.UpdateListener {
|
||||||
|
|
||||||
|
private final static Logger log = LoggerFactory.getLogger(MapAdapter.class);
|
||||||
|
|
||||||
|
MapAdapter() {
|
||||||
|
super();
|
||||||
|
events.bind(this); //register Update listener
|
||||||
|
this.viewport().setMaxTilt(65f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean mRenderWait;
|
||||||
|
private boolean mRenderRequest;
|
||||||
|
private int width = Gdx.graphics.getWidth(), height = Gdx.graphics.getHeight();
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Runnable mRedrawCb = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
prepareFrame();
|
||||||
|
Gdx.graphics.requestRendering();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateMap(boolean forceRender) {
|
||||||
|
synchronized (mRedrawCb) {
|
||||||
|
if (!mRenderRequest) {
|
||||||
|
mRenderRequest = true;
|
||||||
|
Gdx.app.postRunnable(mRedrawCb);
|
||||||
|
} else {
|
||||||
|
mRenderWait = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render() {
|
||||||
|
synchronized (mRedrawCb) {
|
||||||
|
mRenderRequest = true;
|
||||||
|
if (mClearMap)
|
||||||
|
updateMap(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean post(Runnable runnable) {
|
||||||
|
Gdx.app.postRunnable(runnable);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean postDelayed(final Runnable action, long delay) {
|
||||||
|
Timer.schedule(new Timer.Task() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
action.run();
|
||||||
|
}
|
||||||
|
}, delay / 1000f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginFrame() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doneFrame(boolean animate) {
|
||||||
|
synchronized (mRedrawCb) {
|
||||||
|
mRenderRequest = false;
|
||||||
|
if (animate || mRenderWait) {
|
||||||
|
mRenderWait = false;
|
||||||
|
updateMap(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean handleGesture(Gesture g, MotionEvent e) {
|
||||||
|
this.updateMap(true);
|
||||||
|
return super.handleGesture(g, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMapEvent(Event e, MapPosition mapPosition) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,233 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.vtm;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Application;
|
||||||
|
import com.badlogic.gdx.ApplicationAdapter;
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.InputMultiplexer;
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.input.GestureDetector;
|
||||||
|
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.event.Event;
|
||||||
|
import org.oscim.gdx.GestureHandlerImpl;
|
||||||
|
import org.oscim.gdx.MotionHandler;
|
||||||
|
import org.oscim.layers.AbstractMapEventLayer;
|
||||||
|
import org.oscim.layers.GroupLayer;
|
||||||
|
import org.oscim.layers.tile.buildings.BuildingLayer;
|
||||||
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
|
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||||
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.renderer.GLViewport;
|
||||||
|
import org.oscim.renderer.MapRenderer;
|
||||||
|
import org.oscim.scalebar.DefaultMapScaleBar;
|
||||||
|
import org.oscim.scalebar.ImperialUnitAdapter;
|
||||||
|
import org.oscim.scalebar.MapScaleBar;
|
||||||
|
import org.oscim.scalebar.MapScaleBarLayer;
|
||||||
|
import org.oscim.scalebar.MetricUnitAdapter;
|
||||||
|
import org.oscim.theme.ExternalRenderTheme;
|
||||||
|
import org.oscim.theme.VtmThemes;
|
||||||
|
import org.oscim.theme.comparator.BothMapPositionHandler;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import static org.oscim.backend.GLAdapter.gl;
|
||||||
|
|
||||||
|
public class MapApplicationAdapter extends ApplicationAdapter {
|
||||||
|
|
||||||
|
Logger log = LoggerFactory.getLogger(MapApplicationAdapter.class);
|
||||||
|
|
||||||
|
private int x, y, width, height;
|
||||||
|
private MapScaleBarLayer mapScaleBarLayer;
|
||||||
|
private CenterCrossLayer centerCrossLayer;
|
||||||
|
private DefaultMapScaleBar mapScaleBar;
|
||||||
|
private BothMapPositionHandler bothMapPositionHandler;
|
||||||
|
private AtomicInteger iniCount = new AtomicInteger();
|
||||||
|
private AtomicBoolean drawMap = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
MapApplicationAdapter(MapReadyCallback callback) {
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBounds(int x, int y, int width, int height) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
|
||||||
|
if (map != null && mapRenderer != null) {
|
||||||
|
Gdx.app.postRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
map.viewport().setScreenSize(MapApplicationAdapter.this.width, MapApplicationAdapter.this.height);
|
||||||
|
mapRenderer.onSurfaceChanged(MapApplicationAdapter.this.width, MapApplicationAdapter.this.height);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMapPositionHandler(BothMapPositionHandler bothMapPositionHandler) {
|
||||||
|
this.bothMapPositionHandler = bothMapPositionHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTheme(String themePath) {
|
||||||
|
ExternalRenderTheme externalRenderTheme = new ExternalRenderTheme(themePath);
|
||||||
|
try {
|
||||||
|
map.setTheme(externalRenderTheme, true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("SetTheme", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface MapReadyCallback {
|
||||||
|
void ready();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapRenderer mapRenderer;
|
||||||
|
private MapAdapter map;
|
||||||
|
private VectorTileLayer vectorTileLayer;
|
||||||
|
private final MapReadyCallback callback;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create() {
|
||||||
|
map = new MapAdapter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginFrame() {
|
||||||
|
super.beginFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMapEvent(Event e, final MapPosition mapPosition) {
|
||||||
|
super.onMapEvent(e, mapPosition);
|
||||||
|
if (e == Map.MOVE_EVENT || e == Map.SCALE_EVENT) {
|
||||||
|
bothMapPositionHandler.mapPositionChangedFromVtmMap(mapPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mapRenderer = new MapRenderer(map);
|
||||||
|
Gdx.graphics.setContinuousRendering(true);
|
||||||
|
Gdx.app.setLogLevel(Application.LOG_DEBUG);
|
||||||
|
|
||||||
|
int w = Gdx.graphics.getWidth();
|
||||||
|
int h = Gdx.graphics.getHeight();
|
||||||
|
|
||||||
|
map.viewport().setScreenSize(w, h);
|
||||||
|
mapRenderer.onSurfaceCreated();
|
||||||
|
mapRenderer.onSurfaceChanged(w, h);
|
||||||
|
|
||||||
|
InputMultiplexer mux = new InputMultiplexer();
|
||||||
|
mux.addProcessor(new MotionHandler(map) {
|
||||||
|
@Override
|
||||||
|
public boolean scrolled(int amount) {
|
||||||
|
super.scrolled(amount);
|
||||||
|
MapPosition mapPosition = map.getMapPosition();
|
||||||
|
int zoomLevel = mapPosition.getZoomLevel() - amount;
|
||||||
|
mapPosition.setZoomLevel(zoomLevel);
|
||||||
|
map.setMapPosition(mapPosition);
|
||||||
|
bothMapPositionHandler.mapPositionChangedFromVtmMap(mapPosition);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mux.addProcessor(new GestureDetector(new GestureHandlerImpl(map)));
|
||||||
|
|
||||||
|
|
||||||
|
Gdx.input.setInputProcessor(mux);
|
||||||
|
|
||||||
|
mapScaleBar = new DefaultMapScaleBar(map);
|
||||||
|
mapScaleBar.setScaleBarMode(DefaultMapScaleBar.ScaleBarMode.BOTH);
|
||||||
|
mapScaleBar.setDistanceUnitAdapter(MetricUnitAdapter.INSTANCE);
|
||||||
|
mapScaleBar.setSecondaryDistanceUnitAdapter(ImperialUnitAdapter.INSTANCE);
|
||||||
|
mapScaleBarLayer = new MapScaleBarLayer(map, mapScaleBar);
|
||||||
|
mapScaleBarLayer.getRenderer().setPosition(GLViewport.Position.BOTTOM_LEFT);
|
||||||
|
|
||||||
|
centerCrossLayer = new CenterCrossLayer(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render() {
|
||||||
|
gl.viewport(0, 0, width, height);
|
||||||
|
|
||||||
|
try {
|
||||||
|
mapRenderer.onDrawFrame();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (iniCount.get() == 10) {
|
||||||
|
mapRenderer.onSurfaceCreated();
|
||||||
|
|
||||||
|
Gdx.app.postRunnable(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
drawMap.set(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
callback.ready();
|
||||||
|
iniCount.incrementAndGet();
|
||||||
|
} else {
|
||||||
|
iniCount.incrementAndGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
System.out.print("Dispose");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadMap(File mapFile, File themeFile) {
|
||||||
|
FileHandle fileHandle = Gdx.files.absolute(mapFile.getAbsolutePath());
|
||||||
|
MapsforgeVectorSingleMap mapLayer = new MapsforgeVectorSingleMap(fileHandle);
|
||||||
|
if (vectorTileLayer == null) {
|
||||||
|
vectorTileLayer = (VectorTileLayer) mapLayer.getTileLayer(map);
|
||||||
|
} else {
|
||||||
|
vectorTileLayer.setTileSource(mapLayer.getVectorTileSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractMapEventLayer eventLayer = null;
|
||||||
|
if (map.layers().size() > 1) {
|
||||||
|
map.layers().clear();
|
||||||
|
eventLayer = map.getEventLayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
map.layers().add(vectorTileLayer);
|
||||||
|
map.setTheme(VtmThemes.OSMARENDER);
|
||||||
|
if (eventLayer != null) map.layers().add(eventLayer);
|
||||||
|
map.layers().add(new BuildingLabelLayer(map, vectorTileLayer));
|
||||||
|
map.layers().add(centerCrossLayer);
|
||||||
|
map.layers().add(mapScaleBarLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCoordinate(double latitude, double longitude, byte zoomLevel) {
|
||||||
|
map.setMapPosition(latitude, longitude, 1 << zoomLevel);
|
||||||
|
mapScaleBar.setScaleBarPosition(MapScaleBar.ScaleBarPosition.BOTTOM_CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class BuildingLabelLayer extends GroupLayer {
|
||||||
|
final BuildingLayer buildingLayer;
|
||||||
|
|
||||||
|
BuildingLabelLayer(Map map, VectorTileLayer vectorTileLayer) {
|
||||||
|
super(map);
|
||||||
|
this.buildingLayer = new BuildingLayer(map, vectorTileLayer);
|
||||||
|
this.layers.add(this.buildingLayer);
|
||||||
|
this.layers.add(new LabelLayer(map, vectorTileLayer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.vtm;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
|
||||||
|
import org.oscim.layers.tile.TileLayer;
|
||||||
|
import org.oscim.layers.tile.vector.OsmTileLayer;
|
||||||
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.tiling.TileSource;
|
||||||
|
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
||||||
|
|
||||||
|
class MapsforgeVectorSingleMap {
|
||||||
|
private VectorTileLayer vectorTileLayer;
|
||||||
|
private final FileHandle mapFile;
|
||||||
|
private MapFileTileSource tileSource;
|
||||||
|
|
||||||
|
MapsforgeVectorSingleMap(FileHandle mapFile) {
|
||||||
|
this.mapFile = mapFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
TileSource getVectorTileSource() {
|
||||||
|
if (tileSource == null) {
|
||||||
|
tileSource = new MapFileTileSource();
|
||||||
|
tileSource.setMapFile(mapFile.path());
|
||||||
|
tileSource.setPreferredLanguage("en");
|
||||||
|
}
|
||||||
|
return tileSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
TileLayer getTileLayer(Map map) {
|
||||||
|
if (vectorTileLayer == null) {
|
||||||
|
if (tileSource == null) {
|
||||||
|
tileSource = new MapFileTileSource();
|
||||||
|
tileSource.setMapFile(mapFile.path());
|
||||||
|
tileSource.setPreferredLanguage("en");
|
||||||
|
}
|
||||||
|
vectorTileLayer = new OsmTileLayer(map);
|
||||||
|
vectorTileLayer.setTileSource(tileSource);
|
||||||
|
}
|
||||||
|
return vectorTileLayer;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Longri
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.theme.comparator.vtm;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
||||||
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
||||||
|
|
||||||
|
import org.oscim.theme.comparator.BothMapPositionHandler;
|
||||||
|
|
||||||
|
import java.awt.Canvas;
|
||||||
|
import java.awt.event.ComponentAdapter;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
public class VtmPanel extends JPanel {
|
||||||
|
|
||||||
|
private final MapApplicationAdapter appListener;
|
||||||
|
private final Canvas vtmCanvas = new Canvas();
|
||||||
|
|
||||||
|
public VtmPanel(MapApplicationAdapter.MapReadyCallback callback) {
|
||||||
|
this.setLayout(null);
|
||||||
|
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
|
||||||
|
config.width = 300;
|
||||||
|
config.height = 300;
|
||||||
|
|
||||||
|
appListener = new MapApplicationAdapter(callback);
|
||||||
|
|
||||||
|
new LwjglApplication(appListener, config, vtmCanvas);
|
||||||
|
|
||||||
|
this.add(vtmCanvas);
|
||||||
|
this.setSize(350, 350);
|
||||||
|
this.setBorder(BorderFactory.createTitledBorder("VTM-Map"));
|
||||||
|
|
||||||
|
this.addComponentListener(new ComponentAdapter() {
|
||||||
|
@Override
|
||||||
|
public void componentResized(ComponentEvent e) {
|
||||||
|
super.componentResized(e);
|
||||||
|
boundsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentMoved(ComponentEvent e) {
|
||||||
|
super.componentMoved(e);
|
||||||
|
boundsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
boundsChanged();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void boundsChanged() {
|
||||||
|
vtmCanvas.setBounds(getX() + 10, getY() + 20, getWidth() - 20, getHeight() - 30);
|
||||||
|
appListener.setBounds(getX() + 10, getY() + 20, getWidth() - 20, getHeight() - 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadMap(File mapFile, File themeFile) {
|
||||||
|
appListener.loadMap(mapFile, themeFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCoordinate(double latidude, double longitude, byte zoomLevel) {
|
||||||
|
appListener.setCoordinate(latidude, longitude, zoomLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMapPositionHandler(BothMapPositionHandler bothMapPositionHandler) {
|
||||||
|
appListener.setMapPositionHandler(bothMapPositionHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTheme(String themePath) {
|
||||||
|
appListener.setTheme(themePath);
|
||||||
|
}
|
||||||
|
}
|