From 9c5fd29ff14d56b7e3f94fbc805c68a6f6277e6a Mon Sep 17 00:00:00 2001 From: Longri Date: Mon, 21 Aug 2017 14:21:10 +0200 Subject: [PATCH] vtm-theme-comparator module (#386) #387 --- settings.gradle | 1 + vtm-theme-comparator/build.gradle | 34 ++ vtm-theme-comparator/resources/debug_dark.png | Bin 0 -> 454 bytes .../resources/editSource_dark.png | Bin 0 -> 340 bytes vtm-theme-comparator/resources/exit_dark.png | Bin 0 -> 361 bytes vtm-theme-comparator/resources/gc_dark.png | Bin 0 -> 386 bytes .../resources/locate_dark.png | Bin 0 -> 225 bytes vtm-theme-comparator/resources/menu-open.png | Bin 0 -> 131 bytes .../resources/menu-saveall.png | Bin 0 -> 143 bytes .../comparator/BothMapPositionHandler.java | 115 +++++++ .../org/oscim/theme/comparator/InfoPanel.java | 62 ++++ .../src/org/oscim/theme/comparator/Main.java | 153 +++++++++ .../org/oscim/theme/comparator/MainMenu.java | 180 ++++++++++ .../oscim/theme/comparator/MainWindow.java | 83 +++++ .../org/oscim/theme/comparator/MapLoader.java | 74 ++++ .../org/oscim/theme/comparator/MapsPanel.java | 45 +++ .../src/org/oscim/theme/comparator/Utils.java | 54 +++ .../theme/comparator/editor/EditorPane.java | 66 ++++ .../oscim/theme/comparator/editor/Menu.java | 73 ++++ .../theme/comparator/editor/ThemeLoader.java | 129 +++++++ .../comparator/location/LocationData.java | 187 ++++++++++ .../location/LocationDataListener.java | 19 ++ .../comparator/location/LocationGPS.java | 163 +++++++++ .../comparator/location/LocationNMEA.java | 182 ++++++++++ .../comparator/location/LocationNormal.java | 319 ++++++++++++++++++ .../comparator/location/LocationPane.java | 36 ++ .../comparator/location/LocationTile.java | 148 ++++++++ .../theme/comparator/logging/AllAppender.java | 23 ++ .../comparator/logging/AllLoggingPane.java | 23 ++ .../comparator/logging/BaseAppender.java | 111 ++++++ .../comparator/logging/BaseLoggingPane.java | 57 ++++ .../comparator/logging/MapsforgeAppender.java | 23 ++ .../logging/MapsforgeLoggingPane.java | 23 ++ .../theme/comparator/logging/VtmAppender.java | 23 ++ .../comparator/logging/VtmLoggingPane.java | 23 ++ .../comparator/mapsforge/AwtMapView.java | 62 ++++ .../mapsforge/MapPanelMouseListener.java | 53 +++ .../mapsforge/MapsforgeMapPanel.java | 147 ++++++++ .../comparator/vtm/CenterCrossLayer.java | 105 ++++++ .../theme/comparator/vtm/MapAdapter.java | 129 +++++++ .../comparator/vtm/MapApplicationAdapter.java | 233 +++++++++++++ .../vtm/MapsforgeVectorSingleMap.java | 56 +++ .../oscim/theme/comparator/vtm/VtmPanel.java | 88 +++++ 43 files changed, 3302 insertions(+) create mode 100644 vtm-theme-comparator/build.gradle create mode 100644 vtm-theme-comparator/resources/debug_dark.png create mode 100644 vtm-theme-comparator/resources/editSource_dark.png create mode 100644 vtm-theme-comparator/resources/exit_dark.png create mode 100644 vtm-theme-comparator/resources/gc_dark.png create mode 100644 vtm-theme-comparator/resources/locate_dark.png create mode 100644 vtm-theme-comparator/resources/menu-open.png create mode 100644 vtm-theme-comparator/resources/menu-saveall.png create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/BothMapPositionHandler.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/InfoPanel.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/Main.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/MainMenu.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/MainWindow.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/MapLoader.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/MapsPanel.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/Utils.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/editor/EditorPane.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/editor/Menu.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/editor/ThemeLoader.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationData.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationDataListener.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationGPS.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationNMEA.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationNormal.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationPane.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationTile.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/logging/AllAppender.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/logging/AllLoggingPane.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/logging/BaseAppender.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/logging/BaseLoggingPane.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/logging/MapsforgeAppender.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/logging/MapsforgeLoggingPane.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/logging/VtmAppender.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/logging/VtmLoggingPane.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/AwtMapView.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/MapPanelMouseListener.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/MapsforgeMapPanel.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/CenterCrossLayer.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapAdapter.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapApplicationAdapter.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapsforgeVectorSingleMap.java create mode 100644 vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/VtmPanel.java diff --git a/settings.gradle b/settings.gradle index d4201927..5426f4a3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -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' diff --git a/vtm-theme-comparator/build.gradle b/vtm-theme-comparator/build.gradle new file mode 100644 index 00000000..10f42092 --- /dev/null +++ b/vtm-theme-comparator/build.gradle @@ -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'] + } +} diff --git a/vtm-theme-comparator/resources/debug_dark.png b/vtm-theme-comparator/resources/debug_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..370088082a54ab47bc55a6708dcaa4a4c334f4c8 GIT binary patch literal 454 zcmV;%0XhDOP)Ya^NREGkkf`MT~qNIV7St4qWL<%|F)aL{yT1s`tP(Y28g5o+i!{ZZ?z$4hVd#- zage&k#>Pz(Crin8)aVYx zuR%0OGlmNcS9u?`-W>VgVSB=V#~q1qY_~1$zuCGVGoa$bK>Qy{V|qbvru%o3`GNn< z76zkW!+C!Hb(Xnv0Tus%8t@sb3v?HHeKlSl^xtGfFbdXR?DJoJp##W(pLh+>S?+nj zXl>wsqjfG4AaLzf&urD4Z&%^xpU_j&@og_0of2j2E0bX*jz{01(RRQ z#K2HBPKOR1Vt`>>2AqdsGy^i)wsjraeRR(^pyqmf24HnT!KTv9K>Gju(~JHCHG^D-`0A84FF=%6TJItNMzcnyFhmd7ijm%ZGQ_W)!__sl4m<_wTLNFxm6Gyv$5|F@SXY(KT4 ms$|WawqTGLOdhKNe literal 0 HcmV?d00001 diff --git a/vtm-theme-comparator/resources/exit_dark.png b/vtm-theme-comparator/resources/exit_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..7f10751502a96f77b315c9fa3605989a766a899c GIT binary patch literal 361 zcmV-v0ha!WP) z#gx$hr@}p%$ui(hNy>i^zL*sJzpuS5hhzip0yRIX&G~=3DCz%&guwsJX-Nin4LBX) z`TuOR4;Wuc4*3r<;4#pEhgF&XZ{^4TKOg7+e^OG69!>+UriK5%ofi+rcMB8$KPXH4 z|EMw(j6v+1IkErG$M}N6LKLe3x3Z)EKP*ediSHFA{9lw7XHIk&+{;h+{{ZNJ5C*X) zWu=;t6o@y|BY+y?|K9;RePUZ{KFP6gEiw52?aZkESK literal 0 HcmV?d00001 diff --git a/vtm-theme-comparator/resources/gc_dark.png b/vtm-theme-comparator/resources/gc_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..d442900f0d3cf22d29326db557dd4a23bfeeef2c GIT binary patch literal 386 zcmV-|0e$|7P)Z84Wd}n#-gHPabfX0M7M$n)zpeqF(R(4OF?Oqw$b8jnw|cQG>h@w zH;H5tilK`Gm;27#riPT#a9uacJn>Ha#2_zZJ-juh415ts#9YiV@%`U`Nq9s=$SFjz zV`c~BENEY_=JXD$O|KAewJ!i$H$z!-M}>f!y!#v2dld5EIV=R++(7L?mG#b8)H@;P z{im@2st+Y@X;&NAXa`*G+<%JQSlGTB34n|ax3sGb*sVU7>+L{n-hObdUJnI8Mu%J4 z)dnobWYAlerrCn`crP1ZG-1J4IHQ>B@;R(QF)ZvzPwSnccw@LD- z?D#Sk1>j-olCi|q29{1=eL6sr7Rkt^^B#k2sR7P#a|4SfFJ`IH_31xHw)$L2nL$QJ gc>)J+ZeUh^0bLBA5y0uC6aWAK07*qoM6N<$g6r_IK>z>% literal 0 HcmV?d00001 diff --git a/vtm-theme-comparator/resources/locate_dark.png b/vtm-theme-comparator/resources/locate_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..6f3f64d20ae90934faf3c8b1da8689e390a5f3aa GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^d_XL~!3HGNrubO_sTH0sjv*Dd_D*)>YcddU-L2LB z!L35m+|L>D7N&pb*$efOC;-52skild-nVc z3h!n&U}R2TS7p2Lnd=uHod+k_MK2moD>i-+A`@}N`?i+Vvrm5)B;7mi+I4T@>q%Yw zmCbKCX6@eIm3=oWE7P>5(8BR(pZng9HA(01Z2c!QpXb0Ha|Wv-b%Q2pNy*!NcjEu| ZsV^2)5L==0b_3AO44$rjF6*2UngG)cSW5r^ literal 0 HcmV?d00001 diff --git a/vtm-theme-comparator/resources/menu-open.png b/vtm-theme-comparator/resources/menu-open.png new file mode 100644 index 0000000000000000000000000000000000000000..b8b43ec947e15bee3528168f3fb152cc4ddb204b GIT binary patch literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`UY;(FAr-fh6C~sku6^R2z2Sj~ z7caxZ8ZX`hotbG3#;T1L&z~hdH&CeaVzO(@X)yL^aA7`_z&0V@`U=CRTz1B;oOUUP ceQ%lh7$n}fwY}4L2C{;|)78&qol`;+0DMX*cmMzZ literal 0 HcmV?d00001 diff --git a/vtm-theme-comparator/resources/menu-saveall.png b/vtm-theme-comparator/resources/menu-saveall.png new file mode 100644 index 0000000000000000000000000000000000000000..40edbf1587725df37db6000f53831172e0d106f6 GIT binary patch literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`VV*9IAr-fhfBgS%&#XG5F^jFF zwDd1~qK3S. + */ +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); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/InfoPanel.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/InfoPanel.java new file mode 100644 index 00000000..7e97e684 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/InfoPanel.java @@ -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 . + */ +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); + } + }); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/Main.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/Main.java new file mode 100644 index 00000000..89270033 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/Main.java @@ -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 . + */ +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); + } + + } + }); + + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/MainMenu.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/MainMenu.java new file mode 100644 index 00000000..64ab1e32 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/MainMenu.java @@ -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 . + */ +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; + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/MainWindow.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/MainWindow.java new file mode 100644 index 00000000..0408437b --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/MainWindow.java @@ -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 . + */ +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); + } + +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/MapLoader.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/MapLoader.java new file mode 100644 index 00000000..d391ae78 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/MapLoader.java @@ -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 . + */ +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); + } + } + }); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/MapsPanel.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/MapsPanel.java new file mode 100644 index 00000000..89186cb7 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/MapsPanel.java @@ -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 . + */ +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()); + } + }); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/Utils.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/Utils.java new file mode 100644 index 00000000..68ec9685 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/Utils.java @@ -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 . + */ +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; + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/editor/EditorPane.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/editor/EditorPane.java new file mode 100644 index 00000000..8cad7dfb --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/editor/EditorPane.java @@ -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 . + */ +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(); + } + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/editor/Menu.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/editor/Menu.java new file mode 100644 index 00000000..14287971 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/editor/Menu.java @@ -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 . + */ +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); + } + + +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/editor/ThemeLoader.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/editor/ThemeLoader.java new file mode 100644 index 00000000..81bbfca1 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/editor/ThemeLoader.java @@ -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 . + */ +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); + + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationData.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationData.java new file mode 100644 index 00000000..24464dec --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationData.java @@ -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 . + */ +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 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); + } + + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationDataListener.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationDataListener.java new file mode 100644 index 00000000..d40db25a --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationDataListener.java @@ -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 . + */ +package org.oscim.theme.comparator.location; + +public interface LocationDataListener { + void valueChanged(); +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationGPS.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationGPS.java new file mode 100644 index 00000000..8371fb6b --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationGPS.java @@ -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 . + */ +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 ew = new JComboBox<>(); + private final JComboBox 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()); + + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationNMEA.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationNMEA.java new file mode 100644 index 00000000..53455a50 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationNMEA.java @@ -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 . + */ +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 ew = new JComboBox<>(); + private final JComboBox 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; + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationNormal.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationNormal.java new file mode 100644 index 00000000..ffd77817 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationNormal.java @@ -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 . + */ +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 ew = new JComboBox<>(); + private final JComboBox 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); + } + +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationPane.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationPane.java new file mode 100644 index 00000000..2aaedbd7 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationPane.java @@ -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 . + */ +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); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationTile.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationTile.java new file mode 100644 index 00000000..e92df2c6 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/location/LocationTile.java @@ -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 . + */ +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); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/AllAppender.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/AllAppender.java new file mode 100644 index 00000000..ae16e006 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/AllAppender.java @@ -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 . + */ +package org.oscim.theme.comparator.logging; + +public class AllAppender extends BaseAppender { + + @Override + boolean canLogClass(String className) { + return true; + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/AllLoggingPane.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/AllLoggingPane.java new file mode 100644 index 00000000..9b81084b --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/AllLoggingPane.java @@ -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 . + */ +package org.oscim.theme.comparator.logging; + +import org.oscim.theme.comparator.Main; + +public class AllLoggingPane extends BaseLoggingPane { + public AllLoggingPane() { + super(Main.ALL_APPENDER); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/BaseAppender.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/BaseAppender.java new file mode 100644 index 00000000..262d4ff1 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/BaseAppender.java @@ -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 . + */ +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 { + 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 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); +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/BaseLoggingPane.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/BaseLoggingPane.java new file mode 100644 index 00000000..3a18b243 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/BaseLoggingPane.java @@ -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 . + */ +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(); + } + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/MapsforgeAppender.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/MapsforgeAppender.java new file mode 100644 index 00000000..50f49586 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/MapsforgeAppender.java @@ -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 . + */ +package org.oscim.theme.comparator.logging; + +public class MapsforgeAppender extends BaseAppender { + + @Override + boolean canLogClass(String className) { + return className.startsWith("org.mapsforge."); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/MapsforgeLoggingPane.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/MapsforgeLoggingPane.java new file mode 100644 index 00000000..b3a8e570 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/MapsforgeLoggingPane.java @@ -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 . + */ +package org.oscim.theme.comparator.logging; + +import org.oscim.theme.comparator.Main; + +public class MapsforgeLoggingPane extends BaseLoggingPane { + public MapsforgeLoggingPane() { + super(Main.MAPSFORGE_APPENDER); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/VtmAppender.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/VtmAppender.java new file mode 100644 index 00000000..58856007 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/VtmAppender.java @@ -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 . + */ +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."); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/VtmLoggingPane.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/VtmLoggingPane.java new file mode 100644 index 00000000..31c0f73a --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/logging/VtmLoggingPane.java @@ -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 . + */ +package org.oscim.theme.comparator.logging; + +import org.oscim.theme.comparator.Main; + +public class VtmLoggingPane extends BaseLoggingPane { + public VtmLoggingPane() { + super(Main.VTM_APPENDER); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/AwtMapView.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/AwtMapView.java new file mode 100644 index 00000000..b0bb0bdd --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/AwtMapView.java @@ -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 . + */ +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); + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/MapPanelMouseListener.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/MapPanelMouseListener.java new file mode 100644 index 00000000..e76d19ef --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/MapPanelMouseListener.java @@ -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 . + */ +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; + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/MapsforgeMapPanel.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/MapsforgeMapPanel.java new file mode 100644 index 00000000..a651cc83 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/mapsforge/MapsforgeMapPanel.java @@ -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 . + */ +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)); + } +} \ No newline at end of file diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/CenterCrossLayer.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/CenterCrossLayer.java new file mode 100644 index 00000000..b5573962 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/CenterCrossLayer.java @@ -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 . + */ +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; + } + } + +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapAdapter.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapAdapter.java new file mode 100644 index 00000000..7aa874f4 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapAdapter.java @@ -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 . + */ +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) { + + } + + +} + diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapApplicationAdapter.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapApplicationAdapter.java new file mode 100644 index 00000000..d2e1a96e --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapApplicationAdapter.java @@ -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 . + */ +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)); + } + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapsforgeVectorSingleMap.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapsforgeVectorSingleMap.java new file mode 100644 index 00000000..637b3538 --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/MapsforgeVectorSingleMap.java @@ -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 . + */ +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; + } +} diff --git a/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/VtmPanel.java b/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/VtmPanel.java new file mode 100644 index 00000000..f22af2af --- /dev/null +++ b/vtm-theme-comparator/src/org/oscim/theme/comparator/vtm/VtmPanel.java @@ -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 . + */ +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); + } +}