vtm-theme-comparator module (#386) #387

This commit is contained in:
Longri 2017-08-21 14:21:10 +02:00 committed by Emux
parent 27a39fbfd7
commit 9c5fd29ff1
43 changed files with 3302 additions and 0 deletions

View File

@ -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'

View 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']
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 B

View File

@ -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);
}
}

View File

@ -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);
}
});
}
}

View 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);
}
}
});
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
});
}
}

View File

@ -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());
}
});
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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();
}
}
}

View File

@ -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.");
}
}

View File

@ -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);
}
}

View File

@ -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.");
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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));
}
}

View File

@ -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;
}
}
}

View File

@ -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) {
}
}

View File

@ -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));
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}