add transport route search

git-svn-id: https://osmand.googlecode.com/svn/trunk@161 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-06-14 21:14:36 +00:00
parent de0bae2b38
commit 5fc0951cf8
9 changed files with 271 additions and 105 deletions

View file

@ -26,7 +26,7 @@ public class ExceptionHandler {
String text;
String title;
if (e != null) {
text = e.getMessage();
text = e+" ";
title = msg;
} else {
title = "Error occured";

View file

@ -6,6 +6,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -20,6 +21,7 @@ public class Region extends MapObject {
private DataTileManager<Amenity> amenities = new DataTileManager<Amenity>();
private OsmBaseStorage storage;
private DataTileManager<City> cityManager = new DataTileManager<City>();
private Map<String, List<TransportRoute>> routes = new LinkedHashMap<String, List<TransportRoute>>();
private Map<CityType, List<City>> cities = new HashMap<CityType, List<City>>();
{
cityManager.setZoom(10);
@ -155,6 +157,10 @@ public class Region extends MapObject {
return null;
}
public Map<String, List<TransportRoute>> getTransportRoutes() {
return routes;
}
public void doDataPreparation(){
CityComparator comp = new CityComparator(false);
@ -164,6 +170,17 @@ public class Region extends MapObject {
c.doDataPreparation();
}
}
for(String s : routes.keySet()){
List<TransportRoute> trans = routes.get(s);
Collections.sort(trans, new Comparator<TransportRoute>(){
@Override
public int compare(TransportRoute o1, TransportRoute o2) {
int i1 = Algoritms.extractFirstIntegerNumber(o1.getRef());
int i2 = Algoritms.extractFirstIntegerNumber(o2.getRef());
return i1 - i2;
}
});
}
}

View file

@ -0,0 +1,52 @@
package com.osmand.data;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.osmand.osm.Relation;
import com.osmand.osm.Way;
public class TransportRoute extends MapObject {
private List<Way> ways;
private List<TransportStop> forwardStops = new ArrayList<TransportStop>();
private List<TransportStop> backwardStops = new ArrayList<TransportStop>();
private String ref;
public TransportRoute(Relation r, String ref){
super(r);
this.ref = ref;
}
public List<TransportStop> getForwardStops() {
return forwardStops;
}
public List<TransportStop> getBackwardStops() {
return backwardStops;
}
public List<Way> getWays() {
if(ways == null){
return Collections.emptyList();
}
return ways;
}
public void addWay(Way w){
if(ways == null){
ways = new ArrayList<Way>();
}
ways.add(w);
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
}

View file

@ -0,0 +1,11 @@
package com.osmand.data;
import com.osmand.osm.Entity;
public class TransportStop extends MapObject {
public TransportStop(Entity e){
super(e);
}
}

View file

@ -11,8 +11,11 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.parsers.ParserConfigurationException;
@ -32,6 +35,8 @@ import com.osmand.data.DataTileManager;
import com.osmand.data.MapObject;
import com.osmand.data.Region;
import com.osmand.data.Street;
import com.osmand.data.TransportRoute;
import com.osmand.data.TransportStop;
import com.osmand.data.City.CityType;
import com.osmand.impl.ConsoleProgressImplementation;
import com.osmand.osm.Entity;
@ -39,6 +44,7 @@ import com.osmand.osm.LatLon;
import com.osmand.osm.MapUtils;
import com.osmand.osm.Node;
import com.osmand.osm.OSMSettings;
import com.osmand.osm.Relation;
import com.osmand.osm.Way;
import com.osmand.osm.OSMSettings.OSMTagKey;
import com.osmand.osm.io.IOsmStorageFilter;
@ -88,14 +94,18 @@ public class DataExtraction {
private final boolean indexAddress;
private final boolean indexPOI;
private final boolean parseEntityInfo;
private final boolean indexTransport;
private File workingDir = null;
public DataExtraction(boolean indexAddress, boolean indexPOI, boolean normalizeStreets,
public DataExtraction(boolean indexAddress, boolean indexPOI, boolean indexTransport, boolean normalizeStreets,
boolean loadAllObjects, boolean parseEntityInfo, File workingDir){
this.indexAddress = indexAddress;
this.indexPOI = indexPOI;
this.indexTransport = indexTransport;
this.normalizeStreets = normalizeStreets;
this.loadAllObjects = loadAllObjects;
this.parseEntityInfo = parseEntityInfo;
@ -109,17 +119,20 @@ public class DataExtraction {
final ArrayList<Entity> buildings;
final ArrayList<Entity> amenities;
final ArrayList<Way> ways;
final ArrayList<Relation> transport;
int currentCount = 0;
private Connection conn;
private PreparedStatement prep;
public DataExtractionOsmFilter(ArrayList<Entity> amenities, ArrayList<Entity> buildings, ArrayList<Node> places,
ArrayList<Way> ways) {
ArrayList<Way> ways, ArrayList<Relation> transport) {
this.amenities = amenities;
this.buildings = buildings;
this.places = places;
this.ways = ways;
this.transport = transport;
}
public void initDatabase() throws SQLException {
@ -158,20 +171,27 @@ public class DataExtraction {
final PreparedStatement pselect = conn.prepareStatement("select * from node where id = ?");
Map<Long, Entity> map = new LinkedHashMap<Long, Entity>();
progress.startTask("Correlating data...", storage.getRegisteredEntities().size());
for (Entity e : storage.getRegisteredEntities().values()) {
Collection<Entity> values = new ArrayList<Entity>(storage.getRegisteredEntities().values());
for (Entity e : values) {
progress.progress(1);
if (e instanceof Way) {
if (e instanceof Way || e instanceof Relation) {
map.clear();
for (Long i : ((Way) e).getNodeIds()) {
Collection<Long> ids = e instanceof Way ? ((Way) e).getNodeIds() : ((Relation) e).getMemberIds();
for (Long i : ids) {
if (!storage.getRegisteredEntities().containsKey(i)) {
pselect.setLong(1, i);
if (pselect.execute()) {
ResultSet rs = pselect.getResultSet();
if (rs.next()) {
map.put(i, new Node(rs.getDouble(2), rs.getDouble(3), rs.getLong(1)));
storage.getRegisteredEntities().put(i, new Node(rs.getDouble(2), rs.getDouble(3), rs.getLong(1)));
}
rs.close();
}
}
if(storage.getRegisteredEntities().containsKey(i)){
map.put(i, storage.getRegisteredEntities().get(i));
}
}
e.initializeLinks(map);
}
}
@ -213,9 +233,18 @@ public class DataExtraction {
processed = true;
}
}
if(indexTransport){
if(e instanceof Relation && e.getTag(OSMTagKey.ROUTE) != null){
transport.add((Relation) e);
processed = true;
}
if(e instanceof Way){
processed = true;
}
}
// put all nodes into temporary db to get only required nodes after loading all data
try {
if (e instanceof Node && indexAddress) {
if (e instanceof Node) {
currentCount++;
prep.setLong(1, e.getId());
prep.setDouble(2, ((Node) e).getLatitude());
@ -233,6 +262,7 @@ public class DataExtraction {
}
}
// netherlands.osm.bz2 1674 seconds - read
// Information about progress for belarus.osm [165 seconds] - 580mb
// FINE: Loading file E:\Information\OSM maps\belarus_2010_06_02.osm started - 61%
@ -289,6 +319,7 @@ public class DataExtraction {
final ArrayList<Entity> buildings = new ArrayList<Entity>();
final ArrayList<Entity> amenities = new ArrayList<Entity>();
final ArrayList<Way> ways = new ArrayList<Way>();
final ArrayList<Relation> transport = new ArrayList<Relation>();
File f = new File(path);
InputStream stream = new FileInputStream(f);
@ -311,7 +342,7 @@ public class DataExtraction {
storage.getFilters().add(addFilter);
}
DataExtractionOsmFilter filter = new DataExtractionOsmFilter(amenities, buildings, places, ways);
DataExtractionOsmFilter filter = new DataExtractionOsmFilter(amenities, buildings, places, ways, transport);
storage.getFilters().add(filter);
// 0. Loading osm file
try {
@ -371,9 +402,14 @@ public class DataExtraction {
normalizingStreets(progress, country);
}
// 7. Call data preparation to sort cities, calculate center location, assign id to objects
// 7. Indexing transport
if(indexTransport){
readingTransport(transport, country, progress);
}
// 8. Call data preparation to sort cities, calculate center location, assign id to objects
country.doDataPreparation();
// 8. Transliterate names to english
// 9. Transliterate names to english
convertEnglishName(country);
for (CityType c : CityType.values()) {
@ -390,6 +426,17 @@ public class DataExtraction {
for (Amenity a : country.getAmenityManager().getAllObjects()) {
convertEnglishName(a);
}
for(List<TransportRoute> r : country.getTransportRoutes().values()){
for(TransportRoute route : r){
convertEnglishName(route);
for(TransportStop s : route.getBackwardStops()){
convertEnglishName(s);
}
for(TransportStop s : route.getForwardStops()){
convertEnglishName(s);
}
}
}
return country;
}
// icu4j example - icu is not good in transliteration russian names
@ -462,6 +509,62 @@ public class DataExtraction {
}
public void readingTransport(final ArrayList<Relation> transport, Region country, IProgress progress){
progress.startTask("Reading transport...", -1);
Map<String, List<TransportRoute>> routes = country.getTransportRoutes();
Map<Long, TransportStop> routeStops = new LinkedHashMap<Long, TransportStop>();
for(Relation rel : transport){
String ref = rel.getTag(OSMTagKey.REF);
String route = rel.getTag(OSMTagKey.ROUTE);
if(route == null || ref == null){
continue;
}
String operator = rel.getTag(OSMTagKey.OPERATOR);
if(operator != null){
route = operator + " : " + route;
}
if(!routes.containsKey(route)){
routes.put(route, new ArrayList<TransportRoute>());
}
TransportRoute r = new TransportRoute(rel, ref);
for(Entry<Entity, String> e: rel.getMemberEntities().entrySet()){
if(e.getValue().contains("stop")){
if(e.getKey() instanceof Node){
if(!routeStops.containsKey(e.getKey().getId())){
routeStops.put(e.getKey().getId(), new TransportStop(e.getKey()));
}
TransportStop stop = routeStops.get(e.getKey().getId());
boolean forward = e.getValue().contains("forward") || !e.getValue().contains("backward");
if(forward){
r.getForwardStops().add(stop);
} else {
r.getBackwardStops().add(stop);
}
}
} else if(e.getKey() instanceof Way){
r.addWay((Way) e.getKey());
}
}
if(r.getBackwardStops().isEmpty() && !r.getForwardStops().isEmpty()){
List<TransportStop> stops = r.getBackwardStops();
for(TransportStop s : r.getForwardStops()){
stops.add(0, s);
}
} else if(!r.getForwardStops().isEmpty()){
if(r.getForwardStops().get(0) != r.getBackwardStops().get(r.getBackwardStops().size() - 1)){
r.getBackwardStops().add(r.getForwardStops().get(0));
}
} else {
continue;
}
routes.get(route).add(r);
}
progress.finishTask();
}
private void readingAmenities(final ArrayList<Entity> amenities, Region country) {
for(Entity a: amenities){
country.registerAmenity(new Amenity(a));
@ -564,6 +667,7 @@ public class DataExtraction {
ArrayList<Entity> amenities = new ArrayList<Entity>();
ArrayList<Entity> buildings = new ArrayList<Entity>();
ArrayList<Node> places = new ArrayList<Node>();
ArrayList<Relation> transport = new ArrayList<Relation>();
ArrayList<Way> ways = new ArrayList<Way>();
long time = System.currentTimeMillis();
@ -598,9 +702,9 @@ public class DataExtraction {
return false;
}
});
DataExtraction e = new DataExtraction(true, true, true, false, true, new File(wDir));
DataExtraction e = new DataExtraction(true, true, true, true, false, true, new File(wDir));
DataExtractionOsmFilter filter = e.new DataExtractionOsmFilter(amenities, buildings, places, ways);
DataExtractionOsmFilter filter = e.new DataExtractionOsmFilter(amenities, buildings, places, ways, transport);
filter.initDatabase();
storage.getFilters().add(filter);

View file

@ -8,6 +8,10 @@ public class OSMSettings {
// ways
HIGHWAY("highway"),
BUILDING("building"),
// transport
ROUTE("route"),
OPERATOR("operator"),
REF("ref"),
// address
PLACE("place"),

View file

@ -68,6 +68,10 @@ public class Relation extends Entity {
return l;
}
public Map<Entity, String> getMemberEntities() {
return memberEntities;
}
public Collection<Entity> getMembers(String role) {
if (memberEntities == null) {
return Collections.emptyList();

View file

@ -30,23 +30,24 @@ public class OsmBoundsFilter implements IOsmStorageFilter {
}
return false;
}
// filter if one of the instance exists
// IMPORTANT : The main assumption is that order is preserved in osm file (first are node, way, relation)!!!
if(entity instanceof Way){
for(Long l : ((Way) entity).getNodeIds()){
if(!storage.getRegisteredEntities().containsKey(l)){
return false;
}
}
if(storage.getRegisteredEntities().containsKey(l)){
return true;
}
}
return false;
}
if(entity instanceof Relation){
for(Long l : ((Relation) entity).getMemberIds()){
if(!storage.getRegisteredEntities().containsKey(l)){
return false;
}
}
if(storage.getRegisteredEntities().containsKey(l)){
return true;
}
}
return false;
}
return false;
}

View file

@ -1,7 +1,6 @@
package com.osmand.swing;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
@ -27,7 +26,6 @@ import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
@ -46,14 +44,10 @@ import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;
@ -78,6 +72,8 @@ import com.osmand.data.DataTileManager;
import com.osmand.data.MapObject;
import com.osmand.data.Region;
import com.osmand.data.Street;
import com.osmand.data.TransportRoute;
import com.osmand.data.TransportStop;
import com.osmand.data.City.CityType;
import com.osmand.data.index.DataIndexWriter;
import com.osmand.data.preparation.DataExtraction;
@ -85,6 +81,7 @@ import com.osmand.map.IMapLocationListener;
import com.osmand.osm.Entity;
import com.osmand.osm.LatLon;
import com.osmand.osm.MapUtils;
import com.osmand.osm.Node;
import com.osmand.osm.Way;
import com.osmand.osm.io.IOsmStorageFilter;
import com.osmand.osm.io.OsmBoundsFilter;
@ -131,6 +128,7 @@ public class OsmExtractionUI implements IMapLocationListener {
private JButton generateDataButton;
private JCheckBox buildPoiIndex;
private JCheckBox buildAddressIndex;
private JCheckBox buildTransportIndex;
private JCheckBox normalizingStreets;
private TreeModelListener treeModelListener;
private JCheckBox loadingAllData;
@ -159,6 +157,19 @@ public class OsmExtractionUI implements IMapLocationListener {
}
root.add(amenitiesTree);
DataExtractionTreeNode transport = new DataExtractionTreeNode("Transport", region);
root.add(transport);
for(String s : region.getTransportRoutes().keySet()){
DataExtractionTreeNode trRoute = new DataExtractionTreeNode(s, s);
transport.add(trRoute);
List<TransportRoute> list = region.getTransportRoutes().get(s);
for(TransportRoute r : list){
DataExtractionTreeNode route = new DataExtractionTreeNode(r.getRef(), r);
trRoute.add(route);
}
}
for (CityType t : CityType.values()) {
DefaultMutableTreeNode cityTree = new DataExtractionTreeNode(Algoritms.capitalizeFirstLetterAndLowercase(t.toString()), t);
root.add(cityTree);
@ -178,14 +189,6 @@ public class OsmExtractionUI implements IMapLocationListener {
}
}
// amenities could be displayed as dots
// DataTileManager<LatLon> amenitiesManager = new DataTileManager<LatLon>();
// if (region != null) {
// for (Amenity a : region.getAmenityManager().getAllObjects()) {
// amenitiesManager.registerObject(a.getNode().getLatitude(), a.getNode().getLongitude(), a.getNode().getLatLon());
// }
// }
// mapPanel.setPoints(amenitiesManager);
if (searchList != null) {
updateListCities(region, searchTextField.getText(), searchList);
}
@ -282,6 +285,25 @@ public class OsmExtractionUI implements IMapLocationListener {
mapPanel.setLatLon(location.getLatitude(), location.getLongitude());
mapPanel.requestFocus();
}
if(o instanceof TransportRoute){
DataTileManager<Entity> ways = new DataTileManager<Entity>();
for(Way w : ((TransportRoute)o).getWays()){
LatLon l = w.getLatLon();
ways.registerObject(l.getLatitude(), l.getLongitude(), w);
}
for(TransportStop w : ((TransportRoute)o).getBackwardStops()){
LatLon l = w.getLocation();
ways.registerObject(l.getLatitude(), l.getLongitude(),
new Node(l.getLatitude(), l.getLongitude(), w.getId()));
}
for(TransportStop w : ((TransportRoute)o).getForwardStops()){
LatLon l = w.getLocation();
ways.registerObject(l.getLatitude(), l.getLongitude(),
new Node(l.getLatitude(), l.getLongitude(), w.getId()));
}
mapPanel.setPoints(ways);
mapPanel.requestFocus();
}
} else if (o instanceof Entity) {
Entity c = (Entity) o;
@ -340,7 +362,10 @@ public class OsmExtractionUI implements IMapLocationListener {
buildAddressIndex.setEnabled(true);
}
if(region == null && !buildPoiIndex.isEnabled()){
buildPoiIndex.setEnabled(false);
buildPoiIndex.setEnabled(true);
}
if(region == null && !buildTransportIndex.isEnabled()){
buildTransportIndex.setEnabled(true);
}
}
@ -375,6 +400,11 @@ public class OsmExtractionUI implements IMapLocationListener {
panel.add(normalizingStreets);
normalizingStreets.setSelected(true);
buildTransportIndex = new JCheckBox();
buildTransportIndex.setText("Build transport index");
panel.add(buildTransportIndex);
buildTransportIndex.setSelected(true);
loadingAllData = new JCheckBox();
loadingAllData.setText("Loading all osm data");
panel.add(loadingAllData);
@ -405,6 +435,9 @@ public class OsmExtractionUI implements IMapLocationListener {
builder.writeAddress();
msg.append(", Address index ").append("successfully created");
}
if(buildTransportIndex.isSelected()){
// TODO
}
// new DataIndexReader().testIndex(new File(
// DataExtractionSettings.getSettings().getDefaultWorkingDir(),
@ -429,69 +462,6 @@ public class OsmExtractionUI implements IMapLocationListener {
}
public void createCitySearchPanel(Container content){
JPanel panel = new JPanel(new BorderLayout());
searchTextField = new JTextField();
final JButton button = new JButton();
button.setText("Set town");
panel.add(searchTextField, BorderLayout.CENTER);
panel.add(button, BorderLayout.WEST);
content.add(panel, BorderLayout.NORTH);
searchList = new JList();
searchList.setCellRenderer(new DefaultListCellRenderer(){
private static final long serialVersionUID = 4661949460526837891L;
@Override
public Component getListCellRendererComponent(JList list,
Object value, int index, boolean isSelected,
boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
if(value instanceof City){
setText(((City)value).getName());
}
return this;
}
});
updateListCities(region, searchTextField.getText(), searchList);
searchTextField.getDocument().addUndoableEditListener(new UndoableEditListener(){
@Override
public void undoableEditHappened(UndoableEditEvent e) {
updateListCities(region, searchTextField.getText(), searchList);
}
});
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
selectedCity = (City)searchList.getSelectedValue();
}
});
searchList.addListSelectionListener(new ListSelectionListener(){
@Override
public void valueChanged(ListSelectionEvent e) {
if(searchList.getSelectedValue() != null){
LatLon node = ((City)searchList.getSelectedValue()).getLocation();
String text = "Lat : " + node.getLatitude() + " Lon " + node.getLongitude();
if(selectedCity != null){
text += " distance " + MapUtils.getDistance(node, node);
}
mapPanel.setLatLon(node.getLatitude(), node.getLongitude());
}
}
});
}
public void fillPopupMenuWithActions(JPopupMenu menu) {
Action delete = new AbstractAction("Delete") {
@ -751,12 +721,15 @@ public class OsmExtractionUI implements IMapLocationListener {
Region res;
try {
DataExtraction dataExtraction = new DataExtraction(buildAddressIndex.isSelected(), buildPoiIndex.isSelected(),
normalizingStreets.isSelected(), loadingAllData.isSelected(),
buildTransportIndex.isSelected(), normalizingStreets.isSelected(), loadingAllData.isSelected(),
DataExtractionSettings.getSettings().getLoadEntityInfo(),
DataExtractionSettings.getSettings().getDefaultWorkingDir());
if(!buildAddressIndex.isSelected()){
buildAddressIndex.setEnabled(false);
}
if(!buildTransportIndex.isSelected()){
buildTransportIndex.setEnabled(false);
}
if(!buildPoiIndex.isSelected()){
buildPoiIndex.setEnabled(false);
}