add filtered area to load

git-svn-id: https://osmand.googlecode.com/svn/trunk@59 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-05-15 12:54:26 +00:00
parent 5a66576ee7
commit db441f5179
10 changed files with 248 additions and 72 deletions

View file

@ -46,5 +46,6 @@ public class ToDoConstants {
// 4. Config file log & see log from file // 4. Config file log & see log from file
// 5. specify area to load map (filter for osm loading) // 5. specify area to load map (filter for osm loading)
// 6. Predefine what should be extracted from osm (building, poi or roads) // 6. Predefine what should be extracted from osm (building, poi or roads)
// 7. Fix TODO in files (accept amenity - way)
} }

View file

@ -4,6 +4,7 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import com.osmand.Algoritms; import com.osmand.Algoritms;
import com.osmand.osm.Entity;
import com.osmand.osm.Node; import com.osmand.osm.Node;
import com.osmand.osm.OSMSettings.OSMTagKey; import com.osmand.osm.OSMSettings.OSMTagKey;
@ -108,7 +109,10 @@ public class Amenity extends MapObject<Node> {
return AmenityType.OTHER; return AmenityType.OTHER;
} }
public static boolean isAmenity(Node n){ public static boolean isAmenity(Entity n){
if(!(n instanceof Node)){
return false;
}
if(n.getTag(OSMTagKey.AMENITY) != null){ if(n.getTag(OSMTagKey.AMENITY) != null){
return true; return true;
} else if(n.getTag(OSMTagKey.SHOP) != null){ } else if(n.getTag(OSMTagKey.SHOP) != null){

View file

@ -40,7 +40,7 @@ public class Street extends MapObject<Entity> {
if(center == null){ if(center == null){
calculateCenter(); calculateCenter();
} }
return center.getLatLon(); return center == null ? null : center.getLatLon();
} }
protected void calculateCenter(){ protected void calculateCenter(){
@ -51,10 +51,12 @@ public class Street extends MapObject<Entity> {
LatLon c = MapUtils.getWeightCenterForNodes(wayNodes); LatLon c = MapUtils.getWeightCenterForNodes(wayNodes);
double dist = Double.POSITIVE_INFINITY; double dist = Double.POSITIVE_INFINITY;
for(Node n : wayNodes){ for(Node n : wayNodes){
double nd = MapUtils.getDistance(n, c); if (n != null) {
if(nd < dist){ double nd = MapUtils.getDistance(n, c);
center = n; if (nd < dist) {
dist = nd; center = n;
dist = nd;
}
} }
} }
} }

View file

@ -23,15 +23,16 @@ import com.osmand.data.City;
import com.osmand.data.DataTileManager; import com.osmand.data.DataTileManager;
import com.osmand.data.Region; import com.osmand.data.Region;
import com.osmand.data.Street; import com.osmand.data.Street;
import com.osmand.data.City.CityType;
import com.osmand.impl.ConsoleProgressImplementation; import com.osmand.impl.ConsoleProgressImplementation;
import com.osmand.osm.Entity; import com.osmand.osm.Entity;
import com.osmand.osm.LatLon; import com.osmand.osm.LatLon;
import com.osmand.osm.MapUtils; import com.osmand.osm.MapUtils;
import com.osmand.osm.Node; import com.osmand.osm.Node;
import com.osmand.osm.OSMSettings; import com.osmand.osm.OSMSettings;
import com.osmand.osm.Relation;
import com.osmand.osm.Way; import com.osmand.osm.Way;
import com.osmand.osm.OSMSettings.OSMTagKey; import com.osmand.osm.OSMSettings.OSMTagKey;
import com.osmand.osm.io.IOsmStorageFilter;
import com.osmand.osm.io.OSMStorageWriter; import com.osmand.osm.io.OSMStorageWriter;
import com.osmand.osm.io.OsmBaseStorage; import com.osmand.osm.io.OsmBaseStorage;
import com.osmand.swing.OsmExtractionUI; import com.osmand.swing.OsmExtractionUI;
@ -140,7 +141,7 @@ public class DataExtraction {
} }
public Region readCountry(String path, IProgress progress) throws IOException, SAXException{ public Region readCountry(String path, IProgress progress, IOsmStorageFilter... filters) throws IOException, SAXException{
InputStream stream = new FileInputStream(path); InputStream stream = new FileInputStream(path);
InputStream streamFile = stream; InputStream streamFile = stream;
long st = System.currentTimeMillis(); long st = System.currentTimeMillis();
@ -163,45 +164,40 @@ public class DataExtraction {
// highways count // highways count
ways = new ArrayList<Way>(); ways = new ArrayList<Way>();
OsmBaseStorage storage = new OsmBaseStorage(){ IOsmStorageFilter filter = new IOsmStorageFilter(){
@Override @Override
public boolean acceptEntityToLoad(Entity e) { public boolean acceptEntityToLoad(OsmBaseStorage storage, Entity e) {
if ("yes".equals(e.getTag(OSMTagKey.BUILDING))) { if ("yes".equals(e.getTag(OSMTagKey.BUILDING))) {
if (e.getTag(OSMTagKey.ADDR_HOUSE_NUMBER) != null && e.getTag(OSMTagKey.ADDR_STREET) != null) { if (e.getTag(OSMTagKey.ADDR_HOUSE_NUMBER) != null && e.getTag(OSMTagKey.ADDR_STREET) != null) {
buildings.add(e); buildings.add(e);
return true; return true;
} }
} }
return super.acceptEntityToLoad(e); if(Amenity.isAmenity(e)){
} amenities.add(new Amenity((Node) e));
@Override
public boolean acceptNodeToLoad(Node n) {
// TODO accept amenity for way! hospital, university, parking, fast_food...
if(Amenity.isAmenity(n)){
amenities.add(new Amenity(n));
}
if (n.getTag(OSMTagKey.PLACE) != null) {
places.add(n);
}
return true;
}
@Override
public boolean acceptRelationToLoad(Relation w) {
return false;
}
@Override
public boolean acceptWayToLoad(Way w) {
if (OSMSettings.wayForCar(w.getTag(OSMTagKey.HIGHWAY))) {
ways.add(w);
return true; return true;
} }
return false; if (e instanceof Node && e.getTag(OSMTagKey.PLACE) != null) {
places.add((Node) e);
return true;
}
if (e instanceof Way && OSMSettings.wayForCar(e.getTag(OSMTagKey.HIGHWAY))) {
ways.add((Way) e);
return true;
}
return e instanceof Node;
} }
}; };
OsmBaseStorage storage = new OsmBaseStorage();
if(filters != null){
for(IOsmStorageFilter f : filters){
if(f != null){
storage.getFilters().add(f);
}
}
}
storage.getFilters().add(filter);
storage.parseOSM(stream, progress, streamFile); storage.parseOSM(stream, progress, streamFile);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
@ -236,14 +232,24 @@ public class DataExtraction {
if (w.getTag(OSMTagKey.NAME) != null) { if (w.getTag(OSMTagKey.NAME) != null) {
String street = w.getTag(OSMTagKey.NAME); String street = w.getTag(OSMTagKey.NAME);
LatLon center = MapUtils.getWeightCenterForNodes(w.getNodes()); LatLon center = MapUtils.getWeightCenterForNodes(w.getNodes());
City city = country.getClosestCity(center); if (center != null) {
if (city != null) { City city = country.getClosestCity(center);
Street str = city.registerStreet(street); if(city == null){
for(Node n : w.getNodes()){ Node n = new Node(center.getLatitude(), center.getLongitude(), -1);
str.getWayNodes().add(n); n.putTag(OSMTagKey.PLACE.getValue(), CityType.TOWN.name());
n.putTag(OSMTagKey.NAME.getValue(), "Uknown city");
country.registerCity(n);
city = country.getClosestCity(center);
} }
if (city != null) {
Street str = city.registerStreet(street);
for (Node n : w.getNodes()) {
str.getWayNodes().add(n);
}
}
waysManager.registerObject(center.getLatitude(), center.getLongitude(), w);
} }
waysManager.registerObject(center.getLatitude(), center.getLongitude(), w);
} }
} }
progress.finishTask(); progress.finishTask();
@ -260,6 +266,13 @@ public class DataExtraction {
// no nodes where loaded for this way // no nodes where loaded for this way
} else { } else {
City city = country.getClosestCity(center); City city = country.getClosestCity(center);
if(city == null){
Node n = new Node(center.getLatitude(), center.getLongitude(), -1);
n.putTag(OSMTagKey.PLACE.getValue(), CityType.TOWN.name());
n.putTag(OSMTagKey.NAME.getValue(), "Uknown city");
country.registerCity(n);
city = country.getClosestCity(center);
}
if (city != null) { if (city != null) {
city.registerBuilding(b); city.registerBuilding(b);
} }
@ -271,4 +284,5 @@ public class DataExtraction {
return country; return country;
} }
} }

View file

@ -81,16 +81,23 @@ public class MapUtils {
} }
public static LatLon getWeightCenterForNodes(Collection<Node> nodes){ public static LatLon getWeightCenterForNodes(Collection<Node> nodes){
if(nodes.isEmpty()){ if (nodes.isEmpty()) {
return null; return null;
} }
double longitude = 0; double longitude = 0;
double latitude = 0; double latitude = 0;
for(Node n : nodes){ int count = 0;
longitude += n.getLongitude(); for (Node n : nodes) {
latitude += n.getLatitude(); if (n != null) {
count++;
longitude += n.getLongitude();
latitude += n.getLatitude();
}
} }
return new LatLon(latitude/nodes.size(), longitude/nodes.size()); if (count == 0) {
return null;
}
return new LatLon(latitude/count, longitude/count);
} }

View file

@ -0,0 +1,9 @@
package com.osmand.osm.io;
import com.osmand.osm.Entity;
public interface IOsmStorageFilter {
public boolean acceptEntityToLoad(OsmBaseStorage storage, Entity entity);
}

View file

@ -2,8 +2,10 @@ package com.osmand.osm.io;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -53,7 +55,7 @@ public class OsmBaseStorage extends DefaultHandler {
protected IProgress progress; protected IProgress progress;
protected InputStream inputStream; protected InputStream inputStream;
protected InputStream streamForProgress; protected InputStream streamForProgress;
protected List<IOsmStorageFilter> filters = new ArrayList<IOsmStorageFilter>();
public synchronized void parseOSM(InputStream stream, IProgress progress, InputStream streamForProgress) throws IOException, SAXException { public synchronized void parseOSM(InputStream stream, IProgress progress, InputStream streamForProgress) throws IOException, SAXException {
@ -203,6 +205,15 @@ public class OsmBaseStorage extends DefaultHandler {
} }
protected boolean acceptEntityToLoad(Entity entity) {
for(IOsmStorageFilter f : filters){
if(!f.acceptEntityToLoad(this, entity)){
return false;
}
}
return true;
}
public void completeReading(){ public void completeReading(){
for(Entity e : entities.values()){ for(Entity e : entities.values()){
e.initializeLinks(entities); e.initializeLinks(entities);
@ -213,32 +224,14 @@ public class OsmBaseStorage extends DefaultHandler {
public boolean acceptEntityToLoad(Entity e){
if(e instanceof Way){
return acceptWayToLoad((Way) e);
} else if(e instanceof Relation){
return acceptRelationToLoad((Relation) e);
} else if(e instanceof Node){
return acceptNodeToLoad((Node) e);
}
return false;
}
public boolean acceptWayToLoad(Way w){
return true;
}
public boolean acceptRelationToLoad(Relation w){
return true;
}
public boolean acceptNodeToLoad(Node n){
return true;
}
public Map<Long, Entity> getRegisteredEntities() { public Map<Long, Entity> getRegisteredEntities() {
return entities; return entities;
} }
public List<IOsmStorageFilter> getFilters() {
return filters;
}
} }

View file

@ -0,0 +1,53 @@
package com.osmand.osm.io;
import com.osmand.osm.Entity;
import com.osmand.osm.Node;
import com.osmand.osm.Relation;
import com.osmand.osm.Way;
public class OsmBoundsFilter implements IOsmStorageFilter {
private final double lonEnd;
private final double latDown;
private final double latUp;
private final double lonStart;
public OsmBoundsFilter(double latStart, double lonStart, double latEnd, double lonEnd){
this.latUp = latStart;
this.lonStart = lonStart;
this.latDown = latEnd;
this.lonEnd = lonEnd;
}
@Override
public boolean acceptEntityToLoad(OsmBaseStorage storage, Entity entity) {
if(entity instanceof Node){
double lon = ((Node) entity).getLongitude();
double lat = ((Node) entity).getLatitude();
if (latDown <= lat && lat <= latUp && lonStart <= lon && lon <= lonEnd) {
return true;
}
return false;
}
// 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;
}
}
return true;
}
if(entity instanceof Relation){
for(Long l : ((Relation) entity).getMemberIds()){
if(!storage.getRegisteredEntities().containsKey(l)){
return false;
}
}
return true;
}
return false;
}
}

View file

@ -9,7 +9,9 @@ import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -56,6 +58,7 @@ import javax.xml.stream.XMLStreamException;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.tools.bzip2.CBZip2OutputStream;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import com.osmand.Algoritms; import com.osmand.Algoritms;
@ -75,6 +78,10 @@ import com.osmand.osm.Entity;
import com.osmand.osm.LatLon; import com.osmand.osm.LatLon;
import com.osmand.osm.MapUtils; import com.osmand.osm.MapUtils;
import com.osmand.osm.Node; import com.osmand.osm.Node;
import com.osmand.osm.io.IOsmStorageFilter;
import com.osmand.osm.io.OSMStorageWriter;
import com.osmand.osm.io.OsmBoundsFilter;
import com.osmand.swing.MapPanel.MapSelectionArea;
public class OsmExtractionUI implements IMapLocationListener { public class OsmExtractionUI implements IMapLocationListener {
@ -101,9 +108,11 @@ public class OsmExtractionUI implements IMapLocationListener {
private JButton generateDataButton; private JButton generateDataButton;
private JCheckBox buildPoiIndex; private JCheckBox buildPoiIndex;
private JCheckBox buildAddressIndex; private JCheckBox buildAddressIndex;
private JCheckBox filterAreaToLoad;
private TreeModelListener treeModelListener; private TreeModelListener treeModelListener;
public OsmExtractionUI(final Region r){ public OsmExtractionUI(final Region r){
this.region = r; this.region = r;
mapPanel = new MapPanel(DataExtractionSettings.getSettings().getTilesDirectory()); mapPanel = new MapPanel(DataExtractionSettings.getSettings().getTilesDirectory());
@ -315,6 +324,11 @@ public class OsmExtractionUI implements IMapLocationListener {
panel.add(buildAddressIndex); panel.add(buildAddressIndex);
buildAddressIndex.setSelected(true); buildAddressIndex.setSelected(true);
filterAreaToLoad = new JCheckBox();
filterAreaToLoad.setText("Filtering area when load file");
panel.add(filterAreaToLoad);
filterAreaToLoad.setSelected(false);
updateButtonsBar(); updateButtonsBar();
} }
@ -387,6 +401,8 @@ public class OsmExtractionUI implements IMapLocationListener {
bar.add(menu); bar.add(menu);
JMenuItem loadFile = new JMenuItem("Load osm file..."); JMenuItem loadFile = new JMenuItem("Load osm file...");
menu.add(loadFile); menu.add(loadFile);
JMenuItem saveOsmFile = new JMenuItem("Save data to osm file...");
menu.add(saveOsmFile);
JMenuItem specifyWorkingDir = new JMenuItem("Specify working directory..."); JMenuItem specifyWorkingDir = new JMenuItem("Specify working directory...");
menu.add(specifyWorkingDir); menu.add(specifyWorkingDir);
menu.addSeparator(); menu.addSeparator();
@ -431,7 +447,7 @@ public class OsmExtractionUI implements IMapLocationListener {
fc.setDialogTitle("Choose osm file"); fc.setDialogTitle("Choose osm file");
fc.setFileSelectionMode(JFileChooser.FILES_ONLY); fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
fc.setAcceptAllFileFilterUsed(true); fc.setAcceptAllFileFilterUsed(true);
fc.setCurrentDirectory(DataExtractionSettings.getSettings().getDefaultWorkingDir()); fc.setCurrentDirectory(DataExtractionSettings.getSettings().getDefaultWorkingDir().getParentFile());
//System.out.println("opening fc for extension " + extension); //System.out.println("opening fc for extension " + extension);
fc.setFileFilter(new FileFilter(){ fc.setFileFilter(new FileFilter(){
@ -453,9 +469,49 @@ public class OsmExtractionUI implements IMapLocationListener {
} }
}); });
saveOsmFile.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
if(region == null){
return;
}
JFileChooser fc = new JFileChooser();
fc.setDialogTitle("Choose osm file to save");
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
fc.setAcceptAllFileFilterUsed(true);
fc.setCurrentDirectory(DataExtractionSettings.getSettings().getDefaultWorkingDir().getParentFile());
//System.out.println("opening fc for extension " + extension);
fc.setFileFilter(new FileFilter(){
@Override
public boolean accept(File f) {
return f.isDirectory() || f.getName().endsWith(".bz2") || f.getName().endsWith(".osm");
}
@Override
public String getDescription() {
return "Osm Files (*.bz2, *.osm)";
}
});
int answer = fc.showSaveDialog(frame);
if (answer == JFileChooser.APPROVE_OPTION && fc.getSelectedFile() != null){
saveCountry(fc.getSelectedFile());
}
}
});
} }
public void loadCountry(final File f){ public void loadCountry(final File f){
final IOsmStorageFilter filter;
if(filterAreaToLoad.isSelected() && mapPanel.getSelectionArea().isVisible()){
MapSelectionArea area = mapPanel.getSelectionArea();
filter = new OsmBoundsFilter(area.getLat1(), area.getLon1(), area.getLat2(), area.getLon2());
} else {
filter = null;
}
try { try {
final ProgressDialog dlg = new ProgressDialog(frame, "Loading osm file"); final ProgressDialog dlg = new ProgressDialog(frame, "Loading osm file");
dlg.setRunnable(new Runnable(){ dlg.setRunnable(new Runnable(){
@ -464,7 +520,7 @@ public class OsmExtractionUI implements IMapLocationListener {
public void run() { public void run() {
Region res; Region res;
try { try {
res = new DataExtraction().readCountry(f.getAbsolutePath(), dlg); res = new DataExtraction().readCountry(f.getAbsolutePath(), dlg, filter);
} catch (IOException e) { } catch (IOException e) {
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} catch (SAXException e) { } catch (SAXException e) {
@ -491,6 +547,40 @@ public class OsmExtractionUI implements IMapLocationListener {
} }
} }
public void saveCountry(final File f){
final OSMStorageWriter writer = new OSMStorageWriter(region.getStorage().getRegisteredEntities());
try {
final ProgressDialog dlg = new ProgressDialog(frame, "Saving osm file");
dlg.setRunnable(new Runnable() {
@Override
public void run() {
try {
OutputStream output = new FileOutputStream(f);
try {
if (f.getName().endsWith(".bz2")) {
output.write('B');
output.write('Z');
output = new CBZip2OutputStream(output);
}
writer.saveStorage(output, null, false);
} finally {
output.close();
}
} catch (IOException e) {
throw new IllegalArgumentException(e);
} catch (XMLStreamException e) {
throw new IllegalArgumentException(e);
}
}
});
dlg.run();
} catch (InterruptedException e1) {
log.error("Interrupted", e1);
} catch (InvocationTargetException e1) {
log.error("Exception during operation", e1.getCause());
}
}
@Override @Override
public void locationChanged(final double newLatitude, final double newLongitude, Object source){ public void locationChanged(final double newLatitude, final double newLongitude, Object source){
if (amenitiesTree != null) { if (amenitiesTree != null) {

View file

@ -88,6 +88,9 @@ public class ProgressDialog extends JDialog implements IProgress {
label.setText("Please waiting..."); label.setText("Please waiting...");
progressBar.setIndeterminate(true); progressBar.setIndeterminate(true);
setSize(550, 100); setSize(550, 100);
double x = getParent().getBounds().getCenterX();
double y = getParent().getBounds().getCenterY();
setLocation((int) x - getWidth() / 2, (int) y - getHeight() / 2);
} }
public Object getResult() { public Object getResult() {