/* GNU General Public License CacheWolf is a software for PocketPC, Win and Linux that enables paperless caching. It supports the sites geocaching.com and opencaching.de Copyright (C) 2006 CacheWolf development team See http://www.cachewolf.de/ for more information. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package CacheWolf; import CacheWolf.controls.ExecutePanel; import CacheWolf.controls.GuiImageBroker; import CacheWolf.controls.InfoBox; import CacheWolf.controls.MyScrollBarPanel; import CacheWolf.database.CWPoint; import CacheWolf.imp.GCImporter; import CacheWolf.navi.Navigate; import CacheWolf.navi.ProjectedPoint; import CacheWolf.navi.TransformCoordinates; import CacheWolf.utils.Common; import CacheWolf.utils.MyLocale; import CacheWolf.utils.STRreplace; import CacheWolf.utils.UrlFetcher; import ewe.io.InputStreamReader; import ewe.io.StringStream; import ewe.sys.Vm; import ewe.ui.CardPanel; import ewe.ui.CellConstants; import ewe.ui.CellPanel; import ewe.ui.CheckBoxGroup; import ewe.ui.Control; import ewe.ui.ControlConstants; import ewe.ui.ControlEvent; import ewe.ui.Event; import ewe.ui.Form; import ewe.ui.FormBase; import ewe.ui.Gui; import ewe.ui.ScrollBarPanel; import ewe.ui.mButton; import ewe.ui.mCheckBox; import ewe.ui.mChoice; import ewe.ui.mInput; import ewe.ui.mLabel; import ewe.ui.mList; import ewe.util.Vector; import ewesoft.xml.XMLDecoder; import ewesoft.xml.XMLElement; /** * Class for entering coordinates<br> * Class IDs 1400 and 600 (same as calc panel and preferences screen)<br> */ public class CoordsInput extends Form { CellPanel dp, zp; CardPanel tp; mCheckBox chkDMM, chkDMS, chkDD, chkCustom; CheckBoxGroup chkFormat = new CheckBoxGroup(); mChoice localCooSystem; mChoice chcNS, chcEW; mInput inpNSDeg, inpNSm, inpNSs, inpEWDeg, inpEWm, inpEWs; mInput inpUTMZone, inpUTMNorthing, inpUTMEasting; mInput inpText; mButton btnCopy, btnPaste, btnParse, btnGps, btnClear, btnSearch; private ExecutePanel executePanel = null; CWPoint coordInp = new CWPoint(); CellPanel topLinePanel = new CellPanel(); CellPanel mainPanel = new CellPanel(); int exitKeys[] = { 75009 }; int currFormat; boolean bNSDeg = false; boolean bNSm = false; boolean bNSs = false; boolean bEWDeg = false; boolean bEWm = false; boolean bEWs = false; boolean bUTMNorthing = false; boolean bUTMEasting = false; private boolean allowInvalid = false; public CoordsInput(boolean allowInvalidCoords) { allowInvalid = allowInvalidCoords; InitCoordsInput(); } public CoordsInput() { InitCoordsInput(); } private void InitCoordsInput() { this.setTitle(""); // Radiobuttons for format topLinePanel.addNext(chkDD = new mCheckBox("d.d�"), DONTSTRETCH, LEFT); topLinePanel.addNext(chkDMM = new mCheckBox("d�m.m\'"), DONTSTRETCH, LEFT); topLinePanel.addNext(chkDMS = new mCheckBox("d�m\'s\""), DONTSTRETCH, LEFT); // topLinePanel.addNext(chkUTM =new mCheckBox("UTM"),DONTSTRETCH, LEFT); topLinePanel.addNext(chkCustom = new mCheckBox(""), DONTSTRETCH, LEFT); topLinePanel.addLast(localCooSystem = new mChoice(TransformCoordinates.localSystemsFriendlyShortname(), 0), DONTSTRETCH, LEFT); chkDD.setGroup(chkFormat); chkDD.exitKeys = exitKeys; chkDMM.setGroup(chkFormat); chkDMM.exitKeys = exitKeys; chkDMS.setGroup(chkFormat); chkDMS.exitKeys = exitKeys; chkCustom.setGroup(chkFormat); chkCustom.exitKeys = exitKeys; this.addLast(topLinePanel, DONTSTRETCH, LEFT); // Input for degrees dp = new CellPanel(); dp.equalWidths = true; dp.addNext(chcNS = new mChoice(new String[] { "N", "S" }, 0)); chcNS.setInt(0); dp.addNext(inpNSDeg = new mInput()); dp.addNext(inpNSm = new mInput()); dp.addLast(inpNSs = new mInput()); dp.addNext(chcEW = new mChoice(new String[] { "E", "W" }, 0)); chcEW.setInt(0); dp.addNext(inpEWDeg = new mInput()); dp.addNext(inpEWm = new mInput()); dp.addLast(inpEWs = new mInput()); tp = new CardPanel(); tp.addItem(dp, "dp", null); zp = new CellPanel(); zp.equalWidths = true; zp.addNext(new mLabel(MyLocale.getMsg(1400, "Zone"))); zp.addNext(new mLabel(MyLocale.getMsg(1402, "Easting"))); zp.addLast(new mLabel(MyLocale.getMsg(1401, "Northing"))); zp.addNext(inpUTMZone = new mInput()); zp.addNext(inpUTMEasting = new mInput()); zp.addLast(inpUTMNorthing = new mInput()); tp.addItem(zp, "zp", null); mainPanel.addLast(tp); mainPanel.addLast(inpText = new mInput()); inpText.toolTip = MyLocale.getMsg(1406, "Enter coordinates in any format or GCxxxxx"); CellPanel ep = new CellPanel(); ep.equalWidths = true; ep.addNext(btnCopy = GuiImageBroker.getButton(MyLocale.getMsg(618, "Copy"), "toclipboard")); ep.addNext(btnClear = GuiImageBroker.getButton(MyLocale.getMsg(1413, "Clear"), "illegal")); if (!allowInvalid) { btnClear.set(ControlConstants.Invisible, true); btnClear.set(ControlConstants.Disabled, true); } ep.addLast(btnParse = GuiImageBroker.getButton(MyLocale.getMsg(619, "Parse"), "examine")); mainPanel.addLast(ep); CellPanel ip = new CellPanel(); ip.equalWidths = true; ip.addNext(btnPaste = GuiImageBroker.getButton(MyLocale.getMsg(617, "Paste"), "fromclipboard")); ip.addNext(btnGps = GuiImageBroker.getButton("GPS", "gps")); ip.addLast(btnSearch = GuiImageBroker.getButton(MyLocale.getMsg(1414, "Search"), "search")); mainPanel.addLast(ip); executePanel = new ExecutePanel(mainPanel); chcNS.exitKeys = exitKeys; chcEW.exitKeys = exitKeys; // add Panels this.addLast(mainPanel, DONTSTRETCH, LEFT); chcNS.takeFocus(ControlConstants.ByKeyboard); } public void activateFields(int format) { // inpEWDeg.wantReturn=false; inpEWm.wantReturn=false; inpEWs.wantReturn=false; inpUTMNorthing.wantReturn=false; tp.select(dp); switch (format) { case TransformCoordinates.DD: disable(inpNSm); disable(inpNSs); disable(inpEWm); disable(inpEWs); break; case TransformCoordinates.DMM: enable(inpNSm); disable(inpNSs); enable(inpEWm); disable(inpEWs); break; case TransformCoordinates.DMS: enable(inpNSm); enable(inpNSs); enable(inpEWm); enable(inpEWs); break; default: tp.select(zp); if (TransformCoordinates.localSystems[localCooSystem.getInt()].zoneSeperatly) enable(inpUTMZone); else disable(inpUTMZone); break; } this.stretchLastColumn = true; this.stretchLastRow = true; this.repaintNow(); } private void disable(Control c) { c.set(ControlConstants.Invisible, true); c.set(ControlConstants.Disabled, true); } private void enable(Control c) { c.set(ControlConstants.Invisible, false); c.set(ControlConstants.Disabled, false); } public void readFields(CWPoint coords) { String NS, EW; if (localSystemToformatSel(currFormat) >= formatSelToLocalSystem.length) { if (TransformCoordinates.getLocalSystem(currFormat).zoneSeperatly) coords.set(inpUTMNorthing.getText(), inpUTMEasting.getText(), inpUTMZone.getText(), currFormat); else coords.set(inpUTMNorthing.getText(), inpUTMEasting.getText(), currFormat); } else { NS = chcNS.getInt() == 0 ? "N" : "S"; EW = chcEW.getInt() == 0 ? "E" : "W"; coords.set(NS, inpNSDeg.getText(), inpNSm.getText(), inpNSs.getText(), EW, inpEWDeg.getText(), inpEWm.getText(), inpEWs.getText(), currFormat); } int formatsel = combineToFormatSel(chkFormat.getSelectedIndex(), localCooSystem.getInt()); currFormat = getLocalSystem(formatsel); return; } public void setFields(CWPoint coords, int format) { int formatsel = localSystemToformatSel(format); if (formatsel >= formatSelToLocalSystem.length) { // projected point = neither dd, dd� mm.mm nor dd� mm' ss.s" if (coords.isValid()) { localCooSystem.setInt(formatsel - formatSelToLocalSystem.length); ProjectedPoint pp = TransformCoordinates.wgs84ToLocalsystem(coords, format); inpText.setText(pp.toHumanReadableString()); inpUTMNorthing.setText(Common.DoubleToString(pp.getNorthing(), 0, 0)); inpUTMEasting.setText(Common.DoubleToString(pp.getEasting(), 0, 0)); if (TransformCoordinates.getLocalSystem(format).zoneSeperatly) inpUTMZone.setText(pp.getZoneString()); else inpUTMZone.setText(""); } else { inpUTMNorthing.setText("0"); inpUTMEasting.setText("0"); } } else { chcNS.setInt(coords.getNSLetter().equals("N") ? 0 : 1); chcEW.setInt(coords.getEWLetter().equals("E") ? 0 : 1); inpNSDeg.setText(STRreplace.replace(coords.getLatDeg(format), "-", "")); inpNSm.setText(coords.getLatMin(format)); inpNSs.setText(coords.getLatSec(format)); inpEWDeg.setText(STRreplace.replace(coords.getLonDeg(format), "-", "")); inpEWm.setText(coords.getLonMin(format)); inpEWs.setText(coords.getLonSec(format)); } chkFormat.selectIndex(java.lang.Math.min(localSystemToformatSel(format), formatSelToLocalSystem.length)); inpText.setText(coords.toString(format)); currFormat = format; activateFields(format); } public CWPoint getCoords() { return coordInp; } public void onEvent(Event ev) { // Ensure that the Enter key moves to the appropriate field // for Checkboxes and Choice controls this is done via the exitKeys // For input fields we use the wantReturn field if (ev instanceof ControlEvent && ev.type == ControlEvent.EXITED) { if (((ControlEvent) ev).target == chkDD || ((ControlEvent) ev).target == chkDMM || ((ControlEvent) ev).target == chkDMS) Gui.takeFocus(chcNS, ControlConstants.ByKeyboard); if (((ControlEvent) ev).target == chkCustom) Gui.takeFocus(inpUTMEasting, ControlConstants.ByKeyboard); if (((ControlEvent) ev).target == chcNS) Gui.takeFocus(inpNSDeg, ControlConstants.ByKeyboard); if (((ControlEvent) ev).target == chcEW) Gui.takeFocus(inpEWDeg, ControlConstants.ByKeyboard); } if (ev instanceof ControlEvent && ev.type == ControlEvent.PRESSED) { if (((ControlEvent) ev).target == inpEWDeg || ((ControlEvent) ev).target == inpEWm || ((ControlEvent) ev).target == inpEWs || ((ControlEvent) ev).target == inpUTMNorthing) Gui.takeFocus(executePanel.applyButton, ControlConstants.ByKeyboard); if (ev.target == chkFormat || ev.target == localCooSystem) { if (ev.target == localCooSystem) chkFormat.selectIndex(3); readFields(coordInp); setFields(coordInp, currFormat); this.repaintNow(); } if (ev.target == executePanel.cancelButton) { this.close(IDCANCEL); } if (ev.target == executePanel.applyButton) { currFormat = getLocalSystem(combineToFormatSel(chkFormat.getSelectedIndex(), localCooSystem.getInt())); readFields(coordInp); if (coordInp.isValid()) this.close(IDOK); else { if (allowInvalid) { if ((new InfoBox(MyLocale.getMsg(144, "Warnung"), MyLocale.getMsg(1412, "Coordinates invalid. Apply anyway?"))).wait(FormBase.DEFOKB | FormBase.NOB) == FormBase.IDOK) { this.close(IDOK); } } else { new InfoBox(MyLocale.getMsg(5500, "Error"), MyLocale.getMsg(1411, "Please enter valid coordinates")).wait(FormBase.OKB); } } } if (ev.target == btnPaste) { inpText.setText(Vm.getClipboardText("")); } if (ev.target == btnCopy) { readFields(coordInp); Vm.setClipboardText(coordInp.toString(currFormat)); } if (ev.target == btnParse) { // try to parse coords CWPoint coord; String inp = inpText.getText().trim().toUpperCase(); if (inp.startsWith("GC")) { GCImporter spider = new GCImporter(); coord = new CWPoint(spider.fetchCacheCoordinates(inp)); spider.setOldGCLanguage(); } else { coord = new CWPoint(inp); } if (!coord.isValid()) { new InfoBox(MyLocale.getMsg(5500, "Error"), MyLocale.getMsg(4111, "Coordinates must be entered in the format N DD MM.MMM E DDD MM.MMM")).wait(FormBase.OKB); } else { currFormat = getLocalSystem(combineToFormatSel(chkFormat.getSelectedIndex(), localCooSystem.getInt())); setFields(coord, currFormat); this.repaintNow(); } } if (ev.target == btnGps) { if (Navigate.gpsPos.isValid()) { CWPoint coord = Navigate.gpsPos; currFormat = getLocalSystem(combineToFormatSel(chkFormat.getSelectedIndex(), localCooSystem.getInt())); setFields(coord, currFormat); } } if (ev.target == btnClear) { CWPoint coord = new CWPoint(91, 361); currFormat = getLocalSystem(combineToFormatSel(chkFormat.getSelectedIndex(), localCooSystem.getInt())); setFields(coord, currFormat); } if (ev.target == btnSearch) { GeoCodeGui s = new GeoCodeGui(); int ok = s.execute(); if (ok == FormBase.IDOK) { currFormat = getLocalSystem(combineToFormatSel(chkFormat.getSelectedIndex(), localCooSystem.getInt())); setFields(s.coordInp, currFormat); } } } super.onEvent(ev); } private static final int[] formatSelToLocalSystem = { TransformCoordinates.DD, TransformCoordinates.DMM, TransformCoordinates.DMS, }; public int localSystemToformatSel(int cwpointformat) { for (int i = 0; i < formatSelToLocalSystem.length; i++) if (formatSelToLocalSystem[i] == cwpointformat) return i; for (int i = 0; i < TransformCoordinates.localSystems.length; i++) if (TransformCoordinates.localSystems[i].code == cwpointformat) return i + formatSelToLocalSystem.length; throw new IllegalArgumentException("CoordScreen.CWPointformatToformatSel: cwpointformat " + cwpointformat + "not supported"); } public static final int getLocalSystem(int formatsel) { // be carefull: this method is also used by CalcPanel if (formatsel < formatSelToLocalSystem.length) return formatSelToLocalSystem[formatsel]; return TransformCoordinates.localSystems[formatsel - formatSelToLocalSystem.length].code; } public static final int combineToFormatSel(int radiobuttonindex, int choiceindex) { int ret = radiobuttonindex; if (ret == formatSelToLocalSystem.length) ret += choiceindex; return ret; } } /** * Class for entering an address and convert it to lat/lon * starting index in language files: 7300 */ class GeoCodeGui extends Form { mInput streetInp, cityInp; mButton searchBtn, searchCancelBtn; private final ExecutePanel executePanel; CWPoint coordInp = new CWPoint(); CellPanel topLinePanel = new CellPanel(); CellPanel mainPanel = new CellPanel(); // HtmlDisplay foundTxt; mList choice; int exitKeys[] = { 75009 }; Vector geoCodeAnsw; String searchText; public GeoCodeGui() { topLinePanel.addNext(new mLabel(MyLocale.getMsg(7300, "Street/POI")), CellConstants.DONTSTRETCH, CellConstants.WEST); topLinePanel.addLast(streetInp = new mInput(MyLocale.getMsg(7305, "Hauptbahnhof")), CellConstants.STRETCH, CellConstants.FILL | CellConstants.WEST); //streetInp.setPreferredSize(500, 20); topLinePanel.addNext(new mLabel(MyLocale.getMsg(7301, "City")), CellConstants.DONTSTRETCH, CellConstants.WEST); topLinePanel.addNext(cityInp = new mInput(MyLocale.getMsg(7304, "M�nchen, Deutschland")), CellConstants.HSTRETCH, CellConstants.HFILL | CellConstants.WEST); topLinePanel.addNext(searchBtn = new mButton(MyLocale.getMsg(7302, "Search")), CellConstants.DONTSTRETCH, CellConstants.WEST); topLinePanel.addLast(searchCancelBtn = new mButton(MyLocale.getMsg(7303, "Cancel")), CellConstants.DONTSTRETCH, CellConstants.WEST); // inpText.toolTip=MyLocale.getMsg(1406,"Enter coordinates in any format or GCxxxxx"); this.addLast(topLinePanel, CellConstants.STRETCH, CellConstants.FILL | CellConstants.WEST); // Description of found sites choice = new mList(8, 50, false); ScrollBarPanel sbp = new MyScrollBarPanel(choice, 0); sbp.setOptions(MyScrollBarPanel.NeverShowVerticalScrollers); mainPanel.addLast(sbp, CellConstants.STRETCH, CellConstants.FILL | CellConstants.WEST); executePanel = new ExecutePanel(mainPanel); //add Panels this.addLast(mainPanel, CellConstants.STRETCH, CellConstants.FILL | CellConstants.WEST); } public void onEvent(Event ev) { if (ev instanceof ControlEvent && ev.type == ControlEvent.PRESSED) { if (ev.target == searchBtn) { Vm.showWait(true); try { geoCodeAnsw = GeocoderOsm.geocode(cityInp.text.trim(), streetInp.text.trim()); } catch (Exception e) { geoCodeAnsw = new Vector(); geoCodeAnsw.add(new GeocodeAnswer(new CWPoint(), e.getMessage())); } Vm.showWait(false); if (geoCodeAnsw.size() == 0) { geoCodeAnsw = new Vector(); geoCodeAnsw.add(new GeocodeAnswer(new CWPoint(), "nothing found")); } choice.items.clear(); for (int i = 0; i < geoCodeAnsw.size(); i++) { GeocodeAnswer ga = (GeocodeAnswer) geoCodeAnsw.get(i); choice.addItem(ga.where.toString() + " | " + ga.foundname); } choice.updateItems(); } if (ev.target == searchCancelBtn) { } if (ev.target == executePanel.cancelButton) { this.close(IDCANCEL); } if (ev.target == executePanel.applyButton) { if (geoCodeAnsw != null && geoCodeAnsw.size() > 0) { int i = choice.selectedIndex; coordInp = ((GeocodeAnswer) geoCodeAnsw.get(i)).where; } else coordInp.makeInvalid(); this.close(IDOK); } } super.onEvent(ev); } } class GeocoderOsm { //private static final String geocoderUrl = "http://gazetteer.openstreetmap.org/namefinder/search.xml?max=1&find="; private static final String geocoderUrl = "http://nominatim.openstreetmap.org/search?"; //q=135+pilkington+avenue,+birmingham&format=xml&polygon=1&addressdetails=1 public static Vector geocode(String city, String street) throws Exception { String searchFor; if (street.equals("")) { searchFor = UrlFetcher.toUtf8Url(city); } else { searchFor = UrlFetcher.toUtf8Url(street) + "+" + UrlFetcher.toUtf8Url(city); } String answer = UrlFetcher.fetch(geocoderUrl + "q=" + searchFor + "&format=xml", false); answer = STRreplace.replace(answer, "\'", "\' "); answer = STRreplace.replace(answer, " ", " "); XMLDecoder xmldec = new XMLDecoder(); Vector erg = new Vector(); try { xmldec.parse(new InputStreamReader(new StringStream(answer))); if ("searchresults".equalsIgnoreCase((String) xmldec.document.tag)) { XMLElement xe; String desc, lat, lon; desc = null; CWPoint where = new CWPoint(); if (xmldec.document != null && xmldec.document.subElements != null) { for (int i = 0; i < xmldec.document.subElements.size(); i++) { xe = (XMLElement) xmldec.document.subElements.elementAt(i); if (xe.tag.equalsIgnoreCase("place")) { lat = (String) xe.attributes.getPropertyValues("lat").get(0); lon = (String) xe.attributes.getPropertyValues("lon").get(0); where.set(Common.parseDouble(lat.trim()), Common.parseDouble(lon.trim())); desc = (String) xe.attributes.getPropertyValues("display_name").get(0); erg.add(new GeocodeAnswer(where, desc)); } } } } } catch (Exception e) { throw new Exception(e.getMessage()); } return erg; } } class GeocodeAnswer { String foundname; CWPoint where; public GeocodeAnswer(CWPoint where_, String desc_) { where = new CWPoint(where_); foundname = desc_; } }