[josm-dev] [PATCH] Tile Box download tab plugin
Robert Fitzsimons
robfitz at 273k.net
Sun Nov 11 18:46:08 GMT 2007
New plugin which adds a Tile Box tab to the OSM data download dialog.
The user enters a tile zoom level and tile coordinates and a suitable
bounding box is used to download the OSM data.
Signed-off-by: Robert Fitzsimons <robfitz at 273k.net>
---
Thanks for the comments, heres a new patch to adds the code as a plugin.
Robert
Index: plugins/tilebox/src/tilebox/TileBoxPlugin.java
===================================================================
--- plugins/tilebox/src/tilebox/TileBoxPlugin.java (revision 0)
+++ plugins/tilebox/src/tilebox/TileBoxPlugin.java (revision 0)
@@ -0,0 +1,17 @@
+package tilebox;
+
+import java.util.List;
+
+import org.openstreetmap.josm.gui.download.DownloadSelection;
+import org.openstreetmap.josm.plugins.Plugin;
+
+public class TileBoxPlugin extends Plugin {
+ public TileBoxPlugin() {
+ }
+
+ @Override
+ public void addDownloadSelection(final List<DownloadSelection> list) {
+ list.add(new TileBoxSelection());
+ }
+}
+
Index: plugins/tilebox/src/tilebox/TileBoxSelection.java
===================================================================
--- plugins/tilebox/src/tilebox/TileBoxSelection.java (revision 0)
+++ plugins/tilebox/src/tilebox/TileBoxSelection.java (revision 0)
@@ -0,0 +1,154 @@
+// License: GPL. Copyright 2007 by Robert Fitzsimons, Immanuel Scholz and others
+package tilebox;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.GridBagLayout;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+import org.openstreetmap.josm.gui.download.DownloadDialog;
+import org.openstreetmap.josm.gui.download.DownloadSelection;
+import org.openstreetmap.josm.plugins.Plugin;
+import org.openstreetmap.josm.tools.GBC;
+
+/**
+ * Tile box selector.
+ *
+ * @author Robert Fitzsimons <robfitz at 273k.net>
+ *
+ */
+public class TileBoxSelection implements DownloadSelection {
+ private final JTextField xField = new JTextField(8);
+ private final JTextField yField = new JTextField(8);
+ private final JTextField zoomField = new JTextField(4);
+
+ public void addGui(final DownloadDialog gui) {
+ final JPanel dlg = new JPanel(new GridBagLayout());
+
+ final FocusListener dialogUpdater = new FocusAdapter() {
+ @Override public void focusLost(final FocusEvent e) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ try {
+ final int zoom = TileBoxSelection.this.getZoom();
+ final int tileCount = tileCount(zoom);
+ final int x = Integer.parseInt(TileBoxSelection.this.xField.getText());
+ final int y = Integer.parseInt(TileBoxSelection.this.yField.getText());
+
+ if ((x < 0) || (x > tileCount) || (y < 0) || (x > tileCount)) {
+ return;
+ }
+
+ final double minlon = tileXToLongitude(x, zoom);
+ final double maxlon = minlon + tileXSize(zoom);
+
+ final double minlat = tileYToLatitude(y + 1, zoom);
+ final double maxlat = tileYToLatitude(y, zoom);
+
+ if (minlat != gui.minlat || minlon != gui.minlon || maxlat != gui.maxlat || maxlon != gui.maxlon) {
+ gui.minlat = minlat; gui.minlon = minlon;
+ gui.maxlat = maxlat; gui.maxlon = maxlon;
+ gui.boundingBoxChanged(TileBoxSelection.this);
+ }
+ } catch (final NumberFormatException x) {
+ // ignore
+ }
+ }
+ });
+ }
+ };
+
+ this.zoomField.addFocusListener(dialogUpdater);
+ this.zoomField.setText("12");
+ this.xField.addFocusListener(dialogUpdater);
+ this.yField.addFocusListener(dialogUpdater);
+
+ dlg.add(new JLabel(tr("Enter the Zoom level, and X & Y coordinates for a tile image.")), GBC.eol().insets(10, 5, 5, 0));
+ dlg.add(new JLabel(tr("Zoom")), GBC.std().insets(10, 5, 5, 0));
+ dlg.add(this.zoomField, GBC.eol().insets(10, 5, 5, 0));
+ dlg.add(new JLabel(tr("X")), GBC.std().insets(10, 5, 5, 0));
+ dlg.add(this.xField, GBC.eol().insets(10, 5, 5, 0));
+ dlg.add(new JLabel(tr("Y")), GBC.std().insets(10, 5, 5, 0));
+ dlg.add(this.yField, GBC.eol().insets(10, 5, 5, 0));
+
+ gui.tabpane.addTab("Tile Box", dlg);
+ }
+
+ public void boundingBoxChanged(final DownloadDialog gui) {
+ final int zoom = this.getZoom();
+ final double clon = (gui.minlon + gui.maxlon) / 2;
+ final double clat = (gui.minlat + gui.maxlat) / 2;
+
+ final int x = longitudeToTileX(clon, zoom);
+ final int y = latitudeToTileY(clat, zoom);
+
+ this.xField.setText(Integer.toString(x));
+ this.yField.setText(Integer.toString(y));
+ }
+
+ private int getZoom() {
+ try {
+ final int zoom = Integer.parseInt(this.zoomField.getText());
+ if ((zoom >= 10) && (zoom <= 20)) {
+ return zoom;
+ }
+ } catch (final NumberFormatException x) {
+ // ignore
+ }
+ return 12;
+ }
+
+ private static int tileCount(final int zoom) {
+ return (int)Math.pow(2.0d, zoom);
+ }
+
+ private static double tileXSize(final int zoom) {
+ return 360.0d / tileCount(zoom);
+ }
+
+ private static double mercatorProjectionYToLatitude(final double mpy) {
+ return Math.atan(Math.sinh(mpy));
+ }
+ private static double tileYToLatitude(final int y, final int zoom) {
+ double mpy = y * (1.0d / tileCount(zoom)); // Value from 0 to 1
+ mpy = Math.PI * 2 * mpy; // Value from 0 to 2pi
+ mpy = Math.PI - mpy; // Value from -pi to +pi
+ return Math.toDegrees(mercatorProjectionYToLatitude(mpy));
+ }
+
+ private static double latitudeToMercatorProjectionY(final double radlat) {
+ return Math.log(Math.tan((Math.PI / 4) + (radlat / 2)));
+ }
+ private static int latitudeToTileY(final double lat, final int zoom) {
+ double mpy = latitudeToMercatorProjectionY(Math.toRadians(lat));
+ mpy = mpy / Math.PI; // Values from +1 to -1
+ mpy = (1.0d - mpy) / 2.0d; // Values from 0 to 1
+ mpy = mpy * tileCount(zoom); // Scale up to zoom level
+ return (int)Math.floor(mpy); // Round to integer value
+ }
+
+ private static double mercatorProjectionXToLongitude(final double mpx) {
+ return mpx - 180.0d; // Values from -180 to 180
+ }
+ private static double tileXToLongitude(final int x, final int zoom) {
+ return mercatorProjectionXToLongitude(x * tileXSize(zoom));
+ }
+
+ private static double longitudeToMercatorProjectionX(final double lon) {
+ return lon + 180.0d; // Values from 0 to 360
+ }
+ private static int longitudeToTileX(final double lon, final int zoom) {
+ double mpx = longitudeToMercatorProjectionX(lon);
+ mpx = mpx / 360.0d; // Values from 0 to 1
+ mpx = mpx * tileCount(zoom); // Scale up to zoom level
+ return (int)Math.floor(mpx); // Round to integer value
+ }
+}
+
Index: plugins/tilebox/build.xml
===================================================================
--- plugins/tilebox/build.xml (revision 0)
+++ plugins/tilebox/build.xml (revision 0)
@@ -0,0 +1,48 @@
+<project name="tilebox" default="dist" basedir=".">
+ <!-- josm "user home" directory depends on the platform used (windows has a different place than unix/linux) -->
+ <property environment="env"/>
+ <condition property="josm.home.dir" value="${env.APPDATA}/JOSM" else="${user.home}/.josm">
+ <and>
+ <os family="windows"/>
+ </and>
+ </condition>
+
+ <!-- compilation properties -->
+ <property name="josm.build.dir" value="../../core"/>
+ <property name="josm.plugins.dir" value="${josm.home.dir}/plugins"/>
+ <property name="josm" location="../../core/dist/josm-custom.jar" />
+ <property name="plugin.build.dir" value="build"/>
+ <property name="plugin.dist.dir" value="../dist"/>
+ <property name="plugin.name" value="${ant.project.name}"/>
+ <property name="plugin.jar" value="../dist/${plugin.name}.jar"/>
+
+ <property name="ant.build.javac.target" value="1.5"/>
+
+ <target name="init">
+ <mkdir dir="build"/>
+ </target>
+
+ <target name="compile" depends="init">
+ <javac srcdir="src" classpath="${josm}" destdir="build" debug="true"/>
+ </target>
+
+ <target name="dist" depends="clean, compile">
+ <jar destfile="${plugin.jar}" basedir="build">
+ <manifest>
+ <attribute name="Plugin-Class" value="tilebox.TileBoxPlugin"/>
+ <attribute name="Plugin-Description" value="Tile Box adds a new tab which allows the user to download date from OSM database based on the entered tile coordinates and zoom level."/>
+ <attribute name="Plugin-Version" value="0.1"/>
+ <attribute name="Author" value="Robert Fitzsimons <robfitz at 273k.net>"/>
+ </manifest>
+ </jar>
+ </target>
+
+ <target name="clean">
+ <delete dir="${plugin.build.dir}" />
+ <delete file="${plugin.jar}" />
+ </target>
+
+ <target name="install" depends="dist">
+ <copy file="${plugin.jar}" todir="${josm.plugins.dir}"/>
+ </target>
+</project>
More information about the josm-dev
mailing list