From eec0c2a48907bc131a4b475920941889cc81c8b4 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 7 Jun 2010 18:07:04 +0000 Subject: [PATCH] 1. fix progress info 2. add possibility to extract region from osm file 3. add test routing git-svn-id: https://osmand.googlecode.com/svn/trunk@143 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8 --- .../src/com/osmand/ToDoConstants.java | 34 +++- .../src/com/osmand/data/Amenity.java | 1 + .../data/preparation/DataExtraction.java | 9 +- .../src/com/osmand/osm/EntityInfo.java | 52 +++++++ .../src/com/osmand/osm/OSMSettings.java | 4 + .../src/com/osmand/osm/io/OsmBaseStorage.java | 35 ++++- .../com/osmand/osm/io/OsmStorageWriter.java | 46 ++++-- .../com/osmand/osm/util/MinskTransReader.java | 145 ++++++++++++++++++ .../osmand/swing/DataExtractionSettings.java | 8 + .../src/com/osmand/swing/MapPanel.java | 110 ++++++++++++- .../swing/OsmExtractionPreferencesDialog.java | 14 +- .../src/com/osmand/swing/OsmExtractionUI.java | 1 + .../src/com/osmand/swing/ProgressDialog.java | 2 +- .../src/com/osmand/swing/RoutingHelper.java | 113 ++++++++++++++ 14 files changed, 542 insertions(+), 32 deletions(-) create mode 100644 DataExtractionOSM/src/com/osmand/osm/EntityInfo.java create mode 100644 DataExtractionOSM/src/com/osmand/osm/util/MinskTransReader.java create mode 100644 DataExtractionOSM/src/com/osmand/swing/RoutingHelper.java diff --git a/DataExtractionOSM/src/com/osmand/ToDoConstants.java b/DataExtractionOSM/src/com/osmand/ToDoConstants.java index 4c60b1fa72..2296c6dd5d 100644 --- a/DataExtractionOSM/src/com/osmand/ToDoConstants.java +++ b/DataExtractionOSM/src/com/osmand/ToDoConstants.java @@ -1,10 +1,22 @@ package com.osmand; + + /** * This class is designed to put all to do's and link them with code. * The whole methods could be paste or just constants. * Do not worry to put ugly code here (just a little piece) */ public class ToDoConstants { + // FIXES for 0.1 versions : + // 1. Map tile downloader : +// while(!threadPoolExecutor.getQueue().isEmpty()){ +// try { +// threadPoolExecutor.getQueue().take(); +// } catch (InterruptedException e) { +// } +// } + + /** * Write activity to show something about authors / donation .... @@ -13,7 +25,6 @@ public class ToDoConstants { // TODO ANDROID // 8. Enable change POI directly on map (requires OSM login) -// 16. Support open street bugs api. // 20. Implement save track/route to gpx (?) // 26. Show the whole street on map (when it is chosen in search activity). Possibly extend that story to show layer with streets. // 30. Performance issue with map drawing : @@ -23,15 +34,28 @@ public class ToDoConstants { // 32. Introduce POI predefined filters (car filter(other-fuel, transportation-car_wash, show-car) and others) // 33. Build transport locations (investigate) // 34. Investigate routing (bicycle, car) -// 35. Enable trackball navigation in android - +// 35. Enable trackball navigation in android +// 36. Postcode search - // TODO swing + + // BUGS Android + // 1. Fix bug with navigation layout (less zoom controls) (fixed). + // 3. Implement clear existing area with tiles (update map) + // 2. Include to amenity index : historic, sport, .... + // 4. Fix layout problems with add comment + + + // TODO swing + // 2. Internal (Simplify MapPanel - introduce layers for it)ю + // 3. Implement clear progress. // 1. Download tiles without using dir tiles - // 2. Internal (Simplify MapPanel - introduce layers for it) + + + // DONE ANDROID : +// 16. Support open street bugs api (supports viewing, deleting). // 13. Save point as favorite & introduce favorite points dialog // 29. Show opened/closed amenities (in search poi). // 3. Revise osmand UI. Preparing new icons (revise UI 18, 2, ). Main application icon, back to location icon. diff --git a/DataExtractionOSM/src/com/osmand/data/Amenity.java b/DataExtractionOSM/src/com/osmand/data/Amenity.java index bdb3ad6e09..509ff96b26 100644 --- a/DataExtractionOSM/src/com/osmand/data/Amenity.java +++ b/DataExtractionOSM/src/com/osmand/data/Amenity.java @@ -9,6 +9,7 @@ import com.osmand.osm.OSMSettings.OSMTagKey; public class Amenity extends MapObject { // http://wiki.openstreetmap.org/wiki/Amenity + // POI tags : amenity, leisure, shop, sport, tourism, historic; accessories (internet-access), natural ? public enum AmenityType { SUSTENANCE, // restaurant, cafe ... EDUCATION, // school, ... diff --git a/DataExtractionOSM/src/com/osmand/data/preparation/DataExtraction.java b/DataExtractionOSM/src/com/osmand/data/preparation/DataExtraction.java index 65fca8aa15..139a210f5a 100644 --- a/DataExtractionOSM/src/com/osmand/data/preparation/DataExtraction.java +++ b/DataExtractionOSM/src/com/osmand/data/preparation/DataExtraction.java @@ -84,13 +84,18 @@ public class DataExtraction { private final boolean normalizeStreets; private final boolean indexAddress; private final boolean indexPOI; + private final boolean parseEntityInfo; private File workingDir = null; + - public DataExtraction(boolean indexAddress, boolean indexPOI, boolean normalizeStreets, boolean loadAllObjects, File workingDir){ + + public DataExtraction(boolean indexAddress, boolean indexPOI, boolean normalizeStreets, + boolean loadAllObjects, boolean parseEntityInfo, File workingDir){ this.indexAddress = indexAddress; this.indexPOI = indexPOI; this.normalizeStreets = normalizeStreets; this.loadAllObjects = loadAllObjects; + this.parseEntityInfo = parseEntityInfo; this.workingDir = workingDir; } @@ -263,7 +268,7 @@ public class DataExtraction { filter.initDatabase(); // 0.2 parsing osm itself - storage.parseOSM(stream, progress, streamFile); + storage.parseOSM(stream, progress, streamFile, parseEntityInfo); if (log.isInfoEnabled()) { log.info("File parsed : " + (System.currentTimeMillis() - st)); } diff --git a/DataExtractionOSM/src/com/osmand/osm/EntityInfo.java b/DataExtractionOSM/src/com/osmand/osm/EntityInfo.java new file mode 100644 index 0000000000..1ff7b983a2 --- /dev/null +++ b/DataExtractionOSM/src/com/osmand/osm/EntityInfo.java @@ -0,0 +1,52 @@ +package com.osmand.osm; + +/** + * Additional entity info + */ +public class EntityInfo { + String timestamp; + String uid; + String user; + String visible; + String version; + String changeset; + + + public String getTimestamp() { + return timestamp; + } + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + public String getUid() { + return uid; + } + public void setUid(String uid) { + this.uid = uid; + } + public String getUser() { + return user; + } + public void setUser(String user) { + this.user = user; + } + public String getVisible() { + return visible; + } + public void setVisible(String visible) { + this.visible = visible; + } + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + public String getChangeset() { + return changeset; + } + public void setChangeset(String changeset) { + this.changeset = changeset; + } + +} diff --git a/DataExtractionOSM/src/com/osmand/osm/OSMSettings.java b/DataExtractionOSM/src/com/osmand/osm/OSMSettings.java index 8c3cbc7c45..5d7da76144 100644 --- a/DataExtractionOSM/src/com/osmand/osm/OSMSettings.java +++ b/DataExtractionOSM/src/com/osmand/osm/OSMSettings.java @@ -19,6 +19,10 @@ public class OSMSettings { SHOP("shop"), LEISURE("leisure"), TOURISM("tourism"), + SPORT("sport"), + HISTORIC("historic"), + NATURAL("natural"), + INTERNET_ACCESS("internet_access"), OPENING_HOURS("opening_hours"), ; diff --git a/DataExtractionOSM/src/com/osmand/osm/io/OsmBaseStorage.java b/DataExtractionOSM/src/com/osmand/osm/io/OsmBaseStorage.java index 41456aab29..1196accc3d 100644 --- a/DataExtractionOSM/src/com/osmand/osm/io/OsmBaseStorage.java +++ b/DataExtractionOSM/src/com/osmand/osm/io/OsmBaseStorage.java @@ -19,6 +19,7 @@ import org.xml.sax.helpers.DefaultHandler; import com.osmand.IProgress; import com.osmand.osm.Entity; +import com.osmand.osm.EntityInfo; import com.osmand.osm.Node; import com.osmand.osm.Relation; import com.osmand.osm.Way; @@ -38,6 +39,11 @@ public class OsmBaseStorage extends DefaultHandler { protected static final String ATTR_ID = "id"; protected static final String ATTR_LAT = "lat"; protected static final String ATTR_LON = "lon"; + protected static final String ATTR_TIMESTAMP = "timestamp"; + protected static final String ATTR_UID = "uid"; + protected static final String ATTR_USER = "user"; + protected static final String ATTR_VISIBLE = "visible"; + protected static final String ATTR_CHANGESET = "changeset"; protected static final String ATTR_K = "k"; protected static final String ATTR_V = "v"; @@ -46,10 +52,12 @@ public class OsmBaseStorage extends DefaultHandler { protected static final String ATTR_ROLE = "role"; protected Entity currentParsedEntity = null; + protected EntityInfo currentParsedEntityInfo = null; protected boolean parseStarted; protected Map entities = new LinkedHashMap(); + protected Map entityInfo = new LinkedHashMap(); // this is used to show feedback to user protected IProgress progress; @@ -57,11 +65,15 @@ public class OsmBaseStorage extends DefaultHandler { protected InputStream streamForProgress; protected List filters = new ArrayList(); protected boolean supressWarnings = true; + protected boolean parseEntityInfo; - public synchronized void parseOSM(InputStream stream, IProgress progress, InputStream streamForProgress) throws IOException, SAXException { + + public synchronized void parseOSM(InputStream stream, IProgress progress, InputStream streamForProgress, + boolean entityInfo) throws IOException, SAXException { this.inputStream = stream; this.progress = progress; + parseEntityInfo = entityInfo; if(streamForProgress == null){ streamForProgress = inputStream; } @@ -69,6 +81,7 @@ public class OsmBaseStorage extends DefaultHandler { SAXParser parser = initSaxParser(); parseStarted = false; entities.clear(); + this.entityInfo.clear(); if(progress != null){ progress.startWork(streamForProgress.available()); } @@ -80,6 +93,11 @@ public class OsmBaseStorage extends DefaultHandler { completeReading(); } + public synchronized void parseOSM(InputStream stream, IProgress progress, InputStream streamForProgress) + throws IOException, SAXException{ + parseOSM(stream, progress, streamForProgress, true); + } + /** * @param stream * @throws IOException @@ -170,6 +188,15 @@ public class OsmBaseStorage extends DefaultHandler { } else { // this situation could be logged as unhandled } + if(parseEntityInfo && currentParsedEntity != null){ + currentParsedEntityInfo = new EntityInfo(); + currentParsedEntityInfo.setChangeset(attributes.getValue(ATTR_CHANGESET)); + currentParsedEntityInfo.setTimestamp(attributes.getValue(ATTR_TIMESTAMP)); + currentParsedEntityInfo.setUser(attributes.getValue(ATTR_USER)); + currentParsedEntityInfo.setVersion(attributes.getValue(ATTR_VERSION)); + currentParsedEntityInfo.setVisible(attributes.getValue(ATTR_VISIBLE)); + currentParsedEntityInfo.setUid(attributes.getValue(ATTR_UID)); + } } else { if (ELEM_TAG.equals(name)) { String key = attributes.getValue(ATTR_K); @@ -200,6 +227,9 @@ public class OsmBaseStorage extends DefaultHandler { if(currentParsedEntity != null){ if(acceptEntityToLoad(currentParsedEntity)){ Entity oldEntity = entities.put(currentParsedEntity.getId(), currentParsedEntity); + if(parseEntityInfo && currentParsedEntityInfo != null){ + entityInfo.put(currentParsedEntity.getId(), currentParsedEntityInfo); + } if(!supressWarnings && oldEntity!= null){ throw new UnsupportedOperationException("Entity with id=" + oldEntity.getId() +" is duplicated in osm map"); } @@ -228,6 +258,9 @@ public class OsmBaseStorage extends DefaultHandler { } } + public Map getRegisteredEntityInfo() { + return entityInfo; + } public Map getRegisteredEntities() { return entities; diff --git a/DataExtractionOSM/src/com/osmand/osm/io/OsmStorageWriter.java b/DataExtractionOSM/src/com/osmand/osm/io/OsmStorageWriter.java index 4c3d3bab77..2658155a68 100644 --- a/DataExtractionOSM/src/com/osmand/osm/io/OsmStorageWriter.java +++ b/DataExtractionOSM/src/com/osmand/osm/io/OsmStorageWriter.java @@ -1,14 +1,19 @@ package com.osmand.osm.io; +import static com.osmand.osm.io.OsmBaseStorage.ATTR_CHANGESET; import static com.osmand.osm.io.OsmBaseStorage.ATTR_ID; import static com.osmand.osm.io.OsmBaseStorage.ATTR_K; import static com.osmand.osm.io.OsmBaseStorage.ATTR_LAT; import static com.osmand.osm.io.OsmBaseStorage.ATTR_LON; import static com.osmand.osm.io.OsmBaseStorage.ATTR_REF; import static com.osmand.osm.io.OsmBaseStorage.ATTR_ROLE; +import static com.osmand.osm.io.OsmBaseStorage.ATTR_TIMESTAMP; import static com.osmand.osm.io.OsmBaseStorage.ATTR_TYPE; +import static com.osmand.osm.io.OsmBaseStorage.ATTR_UID; +import static com.osmand.osm.io.OsmBaseStorage.ATTR_USER; import static com.osmand.osm.io.OsmBaseStorage.ATTR_V; import static com.osmand.osm.io.OsmBaseStorage.ATTR_VERSION; +import static com.osmand.osm.io.OsmBaseStorage.ATTR_VISIBLE; import static com.osmand.osm.io.OsmBaseStorage.ELEM_MEMBER; import static com.osmand.osm.io.OsmBaseStorage.ELEM_ND; import static com.osmand.osm.io.OsmBaseStorage.ELEM_NODE; @@ -32,6 +37,7 @@ import javax.xml.stream.XMLStreamWriter; import com.osmand.Algoritms; import com.osmand.data.MapObject; import com.osmand.osm.Entity; +import com.osmand.osm.EntityInfo; import com.osmand.osm.Node; import com.osmand.osm.Relation; import com.osmand.osm.Way; @@ -50,6 +56,7 @@ public class OsmStorageWriter { public void saveStorage(OutputStream output, OsmBaseStorage storage, Collection interestedObjects, boolean includeLinks) throws XMLStreamException, IOException { Map entities = storage.getRegisteredEntities(); + Map entityInfo = storage.getRegisteredEntityInfo(); PropertyManager propertyManager = new PropertyManager(PropertyManager.CONTEXT_WRITER); // transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // String indent = "{http://xml.apache.org/xslt}indent-amount"; @@ -92,6 +99,7 @@ public class OsmStorageWriter { streamWriter.writeAttribute(ATTR_LAT, n.getLatitude()+""); streamWriter.writeAttribute(ATTR_LON, n.getLongitude()+""); streamWriter.writeAttribute(ATTR_ID, n.getId()+""); + writeEntityAttributes(streamWriter, entityInfo.get(n.getId())); writeTags(streamWriter, n); writeEndElement(streamWriter, INDENT); } @@ -99,6 +107,7 @@ public class OsmStorageWriter { for(Way w : ways){ writeStartElement(streamWriter, ELEM_WAY, INDENT); streamWriter.writeAttribute(ATTR_ID, w.getId()+""); + writeEntityAttributes(streamWriter, entityInfo.get(w.getId())); for(Long r : w.getNodeIds()){ writeStartElement(streamWriter, ELEM_ND, INDENT2); streamWriter.writeAttribute(ATTR_REF, r+""); @@ -111,6 +120,7 @@ public class OsmStorageWriter { for(Relation r : relations){ writeStartElement(streamWriter, ELEM_RELATION, INDENT); streamWriter.writeAttribute(ATTR_ID, r.getId()+""); + writeEntityAttributes(streamWriter, entityInfo.get(r.getId())); for(Entry e : r.getMembersMap().entrySet()){ writeStartElement(streamWriter, ELEM_MEMBER, INDENT2); streamWriter.writeAttribute(ATTR_REF, e.getKey()+""); @@ -131,6 +141,29 @@ public class OsmStorageWriter { streamWriter.flush(); } + private void writeEntityAttributes(XMLStreamWriter writer, EntityInfo info) throws XMLStreamException{ + if(info != null){ + if(info.getChangeset() != null){ + writer.writeAttribute(ATTR_CHANGESET, info.getChangeset()); + } + if(info.getTimestamp() != null){ + writer.writeAttribute(ATTR_TIMESTAMP, info.getTimestamp()); + } + if(info.getUid() != null){ + writer.writeAttribute(ATTR_UID, info.getUid()); + } + if(info.getUser() != null){ + writer.writeAttribute(ATTR_USER, info.getUser()); + } + if(info.getVisible() != null){ + writer.writeAttribute(ATTR_VISIBLE, info.getVisible()); + } + if(info.getVersion() != null){ + writer.writeAttribute(ATTR_VERSION, info.getVersion()); + } + } + } + private String getEntityType(Map entities , Long id){ Entity e = entities.get(id); if(e instanceof Way){ @@ -169,18 +202,5 @@ public class OsmStorageWriter { writer.writeEndElement(); } } - - /*public static void main(String[] args) { - -// Transliterator inst = Transliterator.getInstance("Any-Latin;NFD;[:Nonspacing Mark:] Remove;NFKC"); - Transliterator inst = Transliterator.getInstance("Any-Latin;"); - Enumeration e = Transliterator.getAvailableIDs(); - while(e.hasMoreElements()){ - System.out.println(e.nextElement()); - } - String str = "Привет Гомель жаль прощаться до скорой встречи когда ы "; - System.out.println(Junidecode.unidecode(str)); - System.out.println(inst.transliterate(str)); - }*/ } diff --git a/DataExtractionOSM/src/com/osmand/osm/util/MinskTransReader.java b/DataExtractionOSM/src/com/osmand/osm/util/MinskTransReader.java new file mode 100644 index 0000000000..295e35d5f1 --- /dev/null +++ b/DataExtractionOSM/src/com/osmand/osm/util/MinskTransReader.java @@ -0,0 +1,145 @@ +package com.osmand.osm.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +public class MinskTransReader { + // Routes RouteNum; Authority; City; Transport; Operator; ValidityPeriods; SpecialDates;RouteTag;RouteType;Commercial;RouteName;Weekdays;RouteID;Entry;RouteStops;Datestart + public static class TransportRoute { + public String routeNum; // 0 + public String transport; // 3 + public String routeType; // 8 + public String routeName; // 10 + public String routeId; // 12 + public List routeStops = new ArrayList(); // 14 + } + + // ID;City;Area;Street;Name;Lng;Lat;Stops + public static class TransportStop { + public String stopId; // 0 + public double longitude; // 5 + public double latitude; // 6 + public String name ; //4 + } + + public static void main(String[] args) throws IOException { + FileInputStream fis = new FileInputStream(new File("E:/routes.txt")); + BufferedReader reader = new BufferedReader(new InputStreamReader(fis, Charset.forName("cp1251"))); + List routes = readRoutes(reader); + + fis = new FileInputStream(new File("E:/stops.txt")); + reader = new BufferedReader(new InputStreamReader(fis, Charset.forName("cp1251"))); + List stops = readStopes(reader); + OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("E:/routes_out.txt"), Charset.forName("cp1251")); + + for(TransportStop r : stops){ + writer.write(r.stopId + " lat : " + r.latitude + " lon : " + r.longitude +" " + r.name + "\n"); + } + for(TransportRoute r : routes){ + writer.write(r.routeId +" " + r.routeNum +" " + r.routeType + " " + r.routeName+"\n"); + } + } + + protected static List readRoutes(BufferedReader reader) throws IOException { + String st = null; + int line = 0; + TransportRoute previous = null; + List routes = new ArrayList(); + while((st = reader.readLine()) != null){ + if(line++ == 0){ + continue; + } + + TransportRoute current = new TransportRoute(); + int stI=0; + int endI = 0; + int i=0; + while ((endI = st.indexOf(';', stI)) != -1) { + + String newS = st.substring(stI, endI); + if(i==0){ + if(newS.length() > 0){ + current.routeNum = newS; + } else if(previous != null){ + current.routeNum = previous.routeNum; + } + } else if(i==3){ + if(newS.length() > 0){ + current.transport = newS; + } else if(previous != null){ + current.transport = previous.transport; + } + } else if(i==8){ + if(newS.length() > 0){ + current.routeType = newS; + } else if(previous != null){ + current.routeType = previous.routeType ; + } + } else if(i==10){ + if(newS.length() > 0){ + current.routeName = newS; + } else if(previous != null){ + current.routeName = previous.routeName ; + } + } else if(i==12){ + current.routeId = newS; + } else if(i==14){ + String[] strings = newS.split(","); + for(String s : strings){ + s = s.trim(); + if(s.length() > 0){ + current.routeStops.add(s); + } + } + } + stI = endI + 1; + i++; + } + previous = current; + routes.add(current); + } + return routes; + } + + protected static List readStopes(BufferedReader reader) throws IOException { + String st = null; + int line = 0; + List stopes = new ArrayList(); + while((st = reader.readLine()) != null){ + if(line++ == 0){ + continue; + } + + TransportStop current = new TransportStop(); + int stI=0; + int endI = 0; + int i=0; + while ((endI = st.indexOf(';', stI)) != -1) { + + String newS = st.substring(stI, endI); + if(i==0){ + current.stopId = newS.trim(); + } else if(i==4){ + current.name = newS; + } else if(i==5){ + current.latitude = Double.parseDouble(newS)/1e5; + } else if(i==6){ + current.longitude = Double.parseDouble(newS)/1e5; + } + stI = endI + 1; + i++; + } + stopes.add(current); + } + return stopes; + } + +} \ No newline at end of file diff --git a/DataExtractionOSM/src/com/osmand/swing/DataExtractionSettings.java b/DataExtractionOSM/src/com/osmand/swing/DataExtractionSettings.java index 25e5cf4111..3c09409e0d 100644 --- a/DataExtractionOSM/src/com/osmand/swing/DataExtractionSettings.java +++ b/DataExtractionOSM/src/com/osmand/swing/DataExtractionSettings.java @@ -58,6 +58,14 @@ public class DataExtractionSettings { preferences.putInt("default_zoom", zoom); } + public boolean getLoadEntityInfo(){ + return preferences.getBoolean("load_entity_info", true); + } + + public void setLoadEntityInfo(boolean loadEntityInfo){ + preferences.putBoolean("load_entity_info", loadEntityInfo); + } + public Rectangle getWindowBounds(){ Rectangle r = new Rectangle(); r.x = preferences.getInt("window_x", 0); diff --git a/DataExtractionOSM/src/com/osmand/swing/MapPanel.java b/DataExtractionOSM/src/com/osmand/swing/MapPanel.java index cb9eb9cacc..e7e1def2e5 100644 --- a/DataExtractionOSM/src/com/osmand/swing/MapPanel.java +++ b/DataExtractionOSM/src/com/osmand/swing/MapPanel.java @@ -44,6 +44,7 @@ import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.UIManager; import org.apache.commons.logging.Log; @@ -152,6 +153,9 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback { private MapSelectionArea selectionArea = new MapSelectionArea(); + private LatLon startRoute; + private LatLon endRoute; + // cached data to draw image private Image[][] images; @@ -167,6 +171,11 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback { private JButton areaButton; + private JPopupMenu popupMenu; + private Point popupMenuPoint; + + private boolean willBePopupShown = false; + public MapPanel(File fileWithTiles) { @@ -221,6 +230,25 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback { return map == null ? 256 : map.getTileSize(); } + + public int getMapXForPoint(double longitude){ + double tileX = MapUtils.getTileNumberX(zoom, longitude); + return (int) ((tileX - getXTile()) * getTileSize() + getCenterPointX()); + } + private double getCenterPointX() { + return getWidth() / 2; + } + + + public int getMapYForPoint(double latitude){ + double tileY = MapUtils.getTileNumberY(zoom, latitude); + return (int) ((tileY - getYTile()) * getTileSize() + getCenterPointY()); + } + + private double getCenterPointY() { + return getHeight() / 2; + } + @Override protected void paintComponent(Graphics g) { @@ -254,8 +282,21 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback { g.drawOval(p.x, p.y, 3, 3); g.fillOval(p.x, p.y, 3, 3); } - - g.setColor(Color.orange); + g.setColor(Color.green); + if(startRoute != null){ + int x = getMapXForPoint(startRoute.getLongitude()); + int y = getMapYForPoint(startRoute.getLatitude()); + g.drawOval(x, y, 12, 12); + g.fillOval(x, y, 12, 12); + } + g.setColor(Color.red); + if(endRoute != null){ + int x = getMapXForPoint(endRoute.getLongitude()); + int y = getMapYForPoint(endRoute.getLatitude()); + g.drawOval(x, y, 12, 12); + g.fillOval(x, y, 12, 12); + } + g.setColor(Color.black); // draw user points int[] xPoints = new int[4]; int[] yPoints = new int[4]; @@ -631,6 +672,54 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback { areaButton.setAlignmentY(Component.TOP_ALIGNMENT); zoomOut.setAlignmentY(Component.TOP_ALIGNMENT); zoomIn.setAlignmentY(Component.TOP_ALIGNMENT); + popupMenu = new JPopupMenu(); + fillPopupMenuWithActions(popupMenu); + } + + public void fillPopupMenuWithActions(JPopupMenu menu) { + Action start = new AbstractAction("Mark start point") { + private static final long serialVersionUID = 507156107455281238L; + + public void actionPerformed(ActionEvent e) { + double fy = (popupMenuPoint.y - getCenterPointY()) / getTileSize(); + double fx = (popupMenuPoint.x - getCenterPointX()) / getTileSize(); + double latitude = MapUtils.getLatitudeFromTile(zoom, getYTile() + fy); + double longitude = MapUtils.getLongitudeFromTile(zoom, getXTile() + fx); + startRoute = new LatLon(latitude, longitude); + repaint(); + } + }; + menu.add(start); + Action end= new AbstractAction("Mark end point") { + private static final long serialVersionUID = 4446789424902471319L; + + public void actionPerformed(ActionEvent e) { + double fy = (popupMenuPoint.y - getCenterPointY()) / getTileSize(); + double fx = (popupMenuPoint.x - getCenterPointX()) / getTileSize(); + double latitude = MapUtils.getLatitudeFromTile(zoom, getYTile() + fy); + double longitude = MapUtils.getLongitudeFromTile(zoom, getXTile() + fx); + endRoute = new LatLon(latitude, longitude); + repaint(); + } + }; + menu.add(end); + Action route = new AbstractAction("Calculate route") { + private static final long serialVersionUID = 507156107455281238L; + + public void actionPerformed(ActionEvent e) { + List ways = RoutingHelper.route(startRoute, endRoute); + DataTileManager points = new DataTileManager(); + points.setZoom(11); + for(Way w : ways){ + LatLon n = w.getLatLon(); + points.registerObject(n.getLatitude(), n.getLongitude(), w); + } + MapPanel.this.points = points; + prepareImage(); + } + }; + menu.add(route); + } public class MapSelectionArea { @@ -706,9 +795,7 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback { @Override public void mouseClicked(MouseEvent e) { - if(e.getButton() == MouseEvent.BUTTON1){ - requestFocus(); - } + requestFocus(); } public void dragTo(Point p){ @@ -721,6 +808,7 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback { @Override public void mouseDragged(MouseEvent e) { + willBePopupShown = false; if(startDragging != null){ if(Math.abs(e.getPoint().x - startDragging.x) + Math.abs(e.getPoint().y - startDragging.y) >= 8){ dragTo(e.getPoint()); @@ -751,7 +839,9 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback { } else if(e.getButton() == MouseEvent.BUTTON1){ startSelecting = e.getPoint(); } + willBePopupShown = true; } + @Override public void mouseReleased(MouseEvent e) { if(e.getButton() == MouseEvent.BUTTON3){ @@ -765,10 +855,16 @@ public class MapPanel extends JPanel implements IMapDownloaderCallback { if(startSelecting != null){ selectionArea.setSelectedArea(startSelecting.x, startSelecting.y, e.getPoint().x, e.getPoint().y); startSelecting = null; - updateUI(); } - } + + // possible bug if popup neither button1|| button3 + if(willBePopupShown && e.isPopupTrigger()){ + popupMenuPoint = new Point(e.getX(), e.getY()); + popupMenu.show(MapPanel.this, e.getX(), e.getY()); + + willBePopupShown = false; + } super.mouseReleased(e); } diff --git a/DataExtractionOSM/src/com/osmand/swing/OsmExtractionPreferencesDialog.java b/DataExtractionOSM/src/com/osmand/swing/OsmExtractionPreferencesDialog.java index f58f36f16c..fad7a1474f 100644 --- a/DataExtractionOSM/src/com/osmand/swing/OsmExtractionPreferencesDialog.java +++ b/DataExtractionOSM/src/com/osmand/swing/OsmExtractionPreferencesDialog.java @@ -28,11 +28,11 @@ public class OsmExtractionPreferencesDialog extends JDialog { private JButton cancelButton; private JTextField streetSuffixes; - private JTextField streetDefaultSuffixes; private JCheckBox useInternet; private JCheckBox supressWarning; + private JCheckBox loadWholeOsmInfo; public OsmExtractionPreferencesDialog(Component parent){ super(JOptionPane.getFrameForComponent(parent), true); @@ -42,7 +42,7 @@ public class OsmExtractionPreferencesDialog extends JDialog { } public void showDialog(){ - setSize(600, 250); + setSize(600, 280); double x = getParent().getBounds().getCenterX(); double y = getParent().getBounds().getCenterY(); setLocation((int) x - getWidth() / 2, (int) y - getHeight() / 2); @@ -75,7 +75,7 @@ public class OsmExtractionPreferencesDialog extends JDialog { private void createGeneralSection(JPanel root) { JPanel panel = new JPanel(); - panel.setLayout(new GridLayout(2, 1, 5, 5)); + panel.setLayout(new GridLayout(3, 1, 5, 5)); panel.setBorder(BorderFactory.createTitledBorder("General")); root.add(panel); @@ -88,6 +88,11 @@ public class OsmExtractionPreferencesDialog extends JDialog { supressWarning.setText("Supress warnings for duplicated id in osm file"); supressWarning.setSelected(DataExtractionSettings.getSettings().isSupressWarningsForDuplicatedId()); panel.add(supressWarning); + + loadWholeOsmInfo = new JCheckBox(); + loadWholeOsmInfo.setText("Load whole osm info (to save valid osm file - use in JOSM...)"); + loadWholeOsmInfo.setSelected(DataExtractionSettings.getSettings().getLoadEntityInfo()); + panel.add(loadWholeOsmInfo); panel.setMaximumSize(new Dimension(Short.MAX_VALUE, panel.getPreferredSize().height)); } @@ -173,6 +178,9 @@ public class OsmExtractionPreferencesDialog extends JDialog { if(settings.isSupressWarningsForDuplicatedId() != supressWarning.isSelected()){ settings.setSupressWarningsForDuplicatedId (supressWarning.isSelected()); } + if(settings.getLoadEntityInfo() != loadWholeOsmInfo.isSelected()){ + settings.setLoadEntityInfo(loadWholeOsmInfo.isSelected()); + } } diff --git a/DataExtractionOSM/src/com/osmand/swing/OsmExtractionUI.java b/DataExtractionOSM/src/com/osmand/swing/OsmExtractionUI.java index 7ce77b35cb..98cb83db5e 100644 --- a/DataExtractionOSM/src/com/osmand/swing/OsmExtractionUI.java +++ b/DataExtractionOSM/src/com/osmand/swing/OsmExtractionUI.java @@ -750,6 +750,7 @@ public class OsmExtractionUI implements IMapLocationListener { try { DataExtraction dataExtraction = new DataExtraction(buildAddressIndex.isSelected(), buildPoiIndex.isSelected(), normalizingStreets.isSelected(), loadingAllData.isSelected(), + DataExtractionSettings.getSettings().getLoadEntityInfo(), DataExtractionSettings.getSettings().getDefaultWorkingDir()); if(!buildAddressIndex.isSelected()){ buildAddressIndex.setEnabled(false); diff --git a/DataExtractionOSM/src/com/osmand/swing/ProgressDialog.java b/DataExtractionOSM/src/com/osmand/swing/ProgressDialog.java index 0aa078790b..edd1f77f36 100644 --- a/DataExtractionOSM/src/com/osmand/swing/ProgressDialog.java +++ b/DataExtractionOSM/src/com/osmand/swing/ProgressDialog.java @@ -28,7 +28,7 @@ public class ProgressDialog extends JDialog implements IProgress { // Progress variables - private static final float deltaToChange = 0.01f; + private static final float deltaToChange = 0.001f; private String taskName; private int deltaWork; private WorkerThread workerThread; diff --git a/DataExtractionOSM/src/com/osmand/swing/RoutingHelper.java b/DataExtractionOSM/src/com/osmand/swing/RoutingHelper.java new file mode 100644 index 0000000000..f86f3c5b48 --- /dev/null +++ b/DataExtractionOSM/src/com/osmand/swing/RoutingHelper.java @@ -0,0 +1,113 @@ +package com.osmand.swing; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.osmand.ExceptionHandler; +import com.osmand.osm.LatLon; +import com.osmand.osm.Way; + +public class RoutingHelper { + // for vector rendering we should extract from osm + // 1. Ways (different kinds) with tag highway= ?,highway=stop ... + // 2. Junction = roundabout + // 3. barrier, traffic_calming=bump + // 4. Save {name, ref} of way to unify it + + + // + for future routing we should extract from osm + // 1. oneway + // 2. max_speed + // 3. toll + // 4. traffic_signals + // 5. max_heigtht, max_width, min_speed, ... + // 6. incline ? + + + + public static List route(LatLon start, LatLon end){ + List res = new ArrayList(); + long time = System.currentTimeMillis(); + System.out.println("Route from " + start + " to " + end); + if (start != null && end != null) { + try { + StringBuilder uri = new StringBuilder(); + uri.append("http://www.yournavigation.org/api/1.0/gosmore.php?format=kml"); + uri.append("&flat=").append(start.getLatitude()); + uri.append("&flon=").append(start.getLongitude()); + uri.append("&tlat=").append(end.getLatitude()); + uri.append("&tlon=").append(end.getLongitude()); + uri.append("&v=motorcar").append("&fast=1").append("&layer=mapnik"); + + URL url = new URL(uri.toString()); + URLConnection connection = url.openConnection(); + StringBuilder content = new StringBuilder(); + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + { + String s = null; + boolean fist = true; + while ((s = reader.readLine()) != null) { + if (fist) { + fist = false; + System.out.println(s); + } + content.append(s).append("\n"); + } + System.out.println(content); + } + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dom = factory.newDocumentBuilder(); + Document doc = dom.parse(new InputSource(new StringReader(content.toString()))); + NodeList list = doc.getElementsByTagName("coordinates"); + for(int i=0; i