@ -15,6 +15,7 @@ include ':vtm-json'
|
||||
include ':vtm-jts'
|
||||
include ':vtm-playground'
|
||||
include ':vtm-tests'
|
||||
include ':vtm-theme-comparator'
|
||||
include ':vtm-themes'
|
||||
include ':vtm-web'
|
||||
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);
|
||||
}
|
||||
}
|