diff --git a/DataExtractionOSM/.classpath b/DataExtractionOSM/.classpath
index ca43d9b9db..96b722cc37 100644
--- a/DataExtractionOSM/.classpath
+++ b/DataExtractionOSM/.classpath
@@ -4,6 +4,5 @@
-
diff --git a/DataExtractionOSM/lib/jpf.jar b/DataExtractionOSM/lib/jpf.jar
deleted file mode 100644
index 6d46124c5c..0000000000
Binary files a/DataExtractionOSM/lib/jpf.jar and /dev/null differ
diff --git a/DataExtractionOSM/lib/osmosis-0.32.jar b/DataExtractionOSM/lib/osmosis-0.32.jar
deleted file mode 100644
index d4d05d1b72..0000000000
Binary files a/DataExtractionOSM/lib/osmosis-0.32.jar and /dev/null differ
diff --git a/DataExtractionOSM/src/com/osmand/Constants.java b/DataExtractionOSM/src/com/osmand/Constants.java
index 95b4ee06a9..536c061d18 100644
--- a/DataExtractionOSM/src/com/osmand/Constants.java
+++ b/DataExtractionOSM/src/com/osmand/Constants.java
@@ -3,7 +3,7 @@ package com.osmand;
public interface Constants {
// TODO externalize proper way
- public String pathToTestDataDir = "E:\\Information\\gps\\OpenMap\\";
+ public String pathToTestDataDir = "E:\\Information\\OSM maps\\";
public String ADDR_HOUSE_NUMBER = "addr:housenumber";
public String ADDR_STREET = "addr:street";
diff --git a/DataExtractionOSM/src/com/osmand/DataExtraction.java b/DataExtractionOSM/src/com/osmand/DataExtraction.java
index b95754b315..164bae5134 100644
--- a/DataExtractionOSM/src/com/osmand/DataExtraction.java
+++ b/DataExtractionOSM/src/com/osmand/DataExtraction.java
@@ -15,8 +15,6 @@ import java.util.ArrayList;
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;
import java.util.TreeMap;
@@ -40,27 +38,23 @@ import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLStreamException;
import org.apache.tools.bzip2.CBZip2InputStream;
-import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer;
-import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer;
-import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
-import org.openstreetmap.osmosis.core.domain.v0_6.Node;
-import org.openstreetmap.osmosis.core.domain.v0_6.Tag;
-import org.openstreetmap.osmosis.core.domain.v0_6.Way;
-import org.openstreetmap.osmosis.core.task.v0_6.Sink;
-import org.openstreetmap.osmosis.core.xml.v0_6.impl.OsmHandler;
import org.xml.sax.SAXException;
import com.osmand.MapPanel.IMapLocationListener;
-import com.osmand.NodeUtil.LatLon;
import com.osmand.data.City;
+import com.osmand.data.DataTileManager;
import com.osmand.data.Region;
import com.osmand.data.Street;
import com.osmand.data.City.CityType;
+import com.osmand.osm.Entity;
+import com.osmand.osm.LatLon;
+import com.osmand.osm.Node;
+import com.osmand.osm.Relation;
+import com.osmand.osm.Way;
+import com.osmand.osm.io.OsmBaseStorage;
// TO implement
@@ -104,7 +98,7 @@ public class DataExtraction implements IMapLocationListener {
}
- private static boolean parseMinsk = true;
+ private static boolean parseMinsk = false;
private static boolean parseOSM = true;
///////////////////////////////////////////
@@ -113,11 +107,10 @@ public class DataExtraction implements IMapLocationListener {
InputStream stream ;
if(parseMinsk){
- stream = new FileInputStream(Constants.pathToTestDataDir+"minsk_old.osm");
+ stream = new FileInputStream(Constants.pathToTestDataDir+"minsk.osm");
} else {
-// stream = new FileInputStream(Constants.pathToTestDataDir+"belarus_2010_04_01.osm.bz2");
-// stream = new FileInputStream(Constants.pathToTestDataDir+"minsk_old.osm");
- stream = new FileInputStream(Constants.pathToTestDataDir+"minsk_2010_04_26.osm.bz2");
+ stream = new FileInputStream(Constants.pathToTestDataDir+"belarus_2010_04_01.osm.bz2");
+// stream = new FileInputStream(Constants.pathToTestDataDir+"minsk_2010_04_26.osm.bz2");
if (stream.read() != 66 || stream.read() != 90)
throw new RuntimeException(
"The source stream must start with the characters BZ if it is to be read as a BZip2 stream.");
@@ -132,75 +125,66 @@ public class DataExtraction implements IMapLocationListener {
// preloaded data
final List places = new ArrayList();
- final Map nodes = new HashMap();
final List buildings = new ArrayList();
final List amenities = new ArrayList();
-
-
// highways count
- final Map mapWays = new LinkedHashMap();
-
- if (parseOSM) {
- SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
- parser.parse(stream, new OsmHandler(new Sink() {
- @Override
- public void process(EntityContainer entityContainer) {
- if (entityContainer instanceof NodeContainer) {
- NodeContainer rc = (NodeContainer) entityContainer;
- if (NodeUtil.getTag(rc.getEntity(), "place") != null) {
- places.add(rc.getEntity());
- if (places.size() % 500 == 0) {
- System.out.println();
- }
- System.out.print("-");
- }
- nodes.put(rc.getEntity().getId(), new LatLon(rc.getEntity().getLatitude(),
- rc.getEntity().getLongitude()));
- if (NodeUtil.getTag(entityContainer.getEntity(), "amenity") != null) {
- amenities.add((Node) entityContainer.getEntity());
- } else if (NodeUtil.getTag(entityContainer.getEntity(), "shop") != null) {
- Entity n = entityContainer.getEntity();
- n.getTags().add(new Tag("amenity", "shop"));
- amenities.add((Node) n);
- }
-
-
- } else {
- if (NodeUtil.tag(entityContainer.getEntity(), "building", "yes")) {
- Entity e = entityContainer.getEntity();
- if (NodeUtil.getTag(e, Constants.ADDR_HOUSE_NUMBER) != null
- && NodeUtil.getTag(e, Constants.ADDR_STREET) != null) {
- buildings.add(e);
- }
- }
- if (NodeUtil.getTag(entityContainer.getEntity(), "highway") != null) {
- String h = NodeUtil.getTag(entityContainer.getEntity(), "highway");
- if(!mapWays.containsKey(h)){
- mapWays.put(h, 0);
- }
- mapWays.put(h, mapWays.get(h) + 1);
-
- }
+ final List mapWays = new ArrayList();
+
+ OsmBaseStorage storage = new OsmBaseStorage(){
+ @Override
+ public boolean acceptEntityToLoad(Entity e) {
+ if ("yes".equals(e.getTag("building"))) {
+ if (e.getTag(Constants.ADDR_HOUSE_NUMBER) != null && e.getTag(Constants.ADDR_STREET) != null) {
+ buildings.add(e);
+ return true;
}
}
-
- @Override
- public void complete() {
+ return super.acceptEntityToLoad(e);
+ }
+
+ @Override
+ public boolean acceptNodeToLoad(Node n) {
+ if (n.getTag("amenity") != null) {
+ amenities.add(n);
+ } else if (n.getTag("shop") != null) {
+ n.putTag("amenity", "shop");
+ amenities.add(n);
}
-
- @Override
- public void release() {
+ if (n.getTag("place") != null) {
+ places.add(n);
+ if (places.size() % 500 == 0) System.out.println();
+ System.out.print("-");
}
- }, false));
+
+ return true;
+ }
+
+ @Override
+ public boolean acceptRelationToLoad(Relation w) {
+ return false;
+ }
+ @Override
+ public boolean acceptWayToLoad(Way w) {
+ if (WayUtil.wayForCar(w.getTag("highway"))) {
+ mapWays.add(w);
+ return true;
+ }
+ return false;
+ }
+ };
+
+
+
+ if (parseOSM) {
+ storage.parseOSM(stream);
}
- System.out.println("\n"+mapWays);
System.out.println(System.currentTimeMillis() - st);
// 1. found towns !
Region country = new Region(null);
for (Node s : places) {
- String place = NodeUtil.getTag(s, "place");
+ String place = s.getTag("place");
if(place == null){
continue;
}
@@ -209,29 +193,40 @@ public class DataExtraction implements IMapLocationListener {
} else {
City registerCity = country.registerCity(s);
if(registerCity == null){
- System.out.println(place + " - " + NodeUtil.getTag(s, "name"));
+ System.out.println(place + " - " + s.getTag("name"));
}
}
}
// 2. found buildings (index addresses)
for(Entity b : buildings){
- LatLon center ;
- if(b instanceof Node){
- center = NodeUtil.getLatLon((Node) b);
- } else {
- center = NodeUtil.getWeightCenter((Way) b, nodes);
- }
+ LatLon center = b.getLatLon();
// TODO first of all tag could be checked NodeUtil.getTag(e, "addr:city")
- City city = country.getClosestCity(center);
- if(city != null){
- city.registerBuilding(center, b);
- }
+ if(center == null){
+ // no nodes where loaded for this way
+ } else {
+ City city = country.getClosestCity(center);
+ if (city != null) {
+ city.registerBuilding(center, b);
+ }
+ }
}
for(Node node : amenities){
country.registerAmenity(node);
}
+
+
+ DataTileManager waysManager = new DataTileManager();
+ for (Way w : mapWays) {
+ for (Node n : w.getNodes()) {
+ if(n != null){
+ LatLon latLon = n.getLatLon();
+ waysManager.registerObject(latLon.getLatitude(), latLon.getLongitude(), latLon);
+ }
+ }
+ }
+ mapPanel.setPoints(waysManager);
runUI(country);
@@ -274,7 +269,7 @@ public class DataExtraction implements IMapLocationListener {
DefaultMutableTreeNode strTree = new DataExtractionTreeNode(str.getName(), str);
cityNodeTree.add(strTree);
for(Entity e : str.getBuildings()){
- DefaultMutableTreeNode building = new DataExtractionTreeNode(NodeUtil.getTag(e, Constants.ADDR_HOUSE_NUMBER), e);
+ DefaultMutableTreeNode building = new DataExtractionTreeNode(e.getTag(Constants.ADDR_HOUSE_NUMBER), e);
strTree.add(building);
}
@@ -421,7 +416,7 @@ public class DataExtraction implements IMapLocationListener {
Map> filter = new TreeMap>();
for(Node n : closestAmenities){
- String type = NodeUtil.getTag(n, "amenity");
+ String type = n.getTag("amenity");
if(!filter.containsKey(type)){
filter.put(type, new ArrayList());
}
@@ -440,8 +435,8 @@ public class DataExtraction implements IMapLocationListener {
for(int i=0; i<15 && i < closestAmenities.size(); i++){
Node n = closestAmenities.get(i);
- String type = NodeUtil.getTag(n, "amenity");
- String name = NodeUtil.getTag(n, "name");
+ String type = n.getTag("amenity");
+ String name = n.getTag("name");
int dist = (int) (NodeUtil.getDistance(n, newLatitude, newLongitude));
String str = type +" "+(name == null ? n.getId() : name) +" [" +dist+" m ]";
((DefaultMutableTreeNode)amenitiesTree.getChildAt(0)).add(
@@ -459,31 +454,14 @@ public class DataExtraction implements IMapLocationListener {
if (p == null) {
p = new DefaultMutableTreeNode(s);
}
-// Map consists = new LinkedHashMap();
-// for(Node n : filter.get(s)){
-// consists.put(n, null);
-// }
-// for(int i=0; i points;
+
+ // zoom levle
private int zoom = 15;
// degree measurements (-180, 180)
@@ -72,7 +81,15 @@ public class MapPanel extends JPanel {
private List listeners = new ArrayList();
- private String map = "Mapnik";
+
+
+ // cached data to draw image
+ private BufferedImage[][] images;
+ private int xStartingImage = 0;
+ private int yStartingImage = 0;
+ private List pointsToDraw = new ArrayList();
+
+
public MapPanel(File fileWithTiles) {
this.fileWithTiles = fileWithTiles;
@@ -91,12 +108,11 @@ public class MapPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
- System.out.println("draw");
if (images != null) {
for (int i = 0; i < images.length; i++) {
for (int j = 0; j < images[i].length; j++) {
if(images[i][j] == null){
- if((i+j + (int)getXTile() + (int)getYTile()) % 2 == 0){
+ if ((i + j + (int) getXTile() + (int) getYTile()) % 2 == 0) {
g.setColor(Color.gray);
} else {
g.setColor(Color.white);
@@ -109,6 +125,12 @@ public class MapPanel extends JPanel {
}
}
g.setColor(Color.black);
+ // draw user points
+ for(Point p : pointsToDraw){
+ g.drawOval(p.x, p.y, 3, 3);
+ g.fillOval(p.x, p.y, 3, 3);
+ }
+
g.fillOval(getWidth()/2 - 2, getHeight()/2 -2, 4, 4);
g.drawOval(getWidth()/2 - 2, getHeight()/2 -2, 4, 4);
@@ -176,6 +198,31 @@ public class MapPanel extends JPanel {
images[i][j]= getImageFor(xStartInd + i, yStartInd + j);
}
}
+
+ if(points != null){
+ double latDown = NodeUtil.getLatitudeFromTile(zoom,
+ NodeUtil.getTileNumberY(zoom, latitude) + ((double)getHeight()/tileSize));
+ double longDown = NodeUtil.getLongitudeFromTile(zoom,
+ NodeUtil.getTileNumberX(zoom, longitude) + ((double)getWidth()/tileSize));
+ double latUp = NodeUtil.getLatitudeFromTile(zoom,
+ NodeUtil.getTileNumberY(zoom, latitude) - ((double)getHeight()/tileSize));
+ double longUp = NodeUtil.getLongitudeFromTile(zoom,
+ NodeUtil.getTileNumberX(zoom, longitude) - ((double)getWidth()/tileSize));
+ List objects = points.getObjects(latUp, longUp, latDown, longDown);
+ pointsToDraw.clear();
+ for(LatLon n : objects){
+ int pixX = NodeUtil.getPixelShiftX(zoom, n.getLongitude(), this.longitude, tileSize) +
+ getWidth() / 2;
+ int pixY = NodeUtil.getPixelShiftY(zoom, n.getLatitude(), this.latitude, tileSize) +
+ getHeight() / 2;
+ if(pixX >= 0 && pixY >= 0){
+ pointsToDraw.add(new Point(pixX, pixY));
+ }
+ }
+
+
+ }
+
repaint();
} catch (IOException e) {
e.printStackTrace();
@@ -249,17 +296,20 @@ public class MapPanel extends JPanel {
protected void processKeyEvent(KeyEvent e) {
boolean processed = false;
if (e.getID() == KeyEvent.KEY_RELEASED) {
-
if (e.getKeyCode() == 37) {
+ // LEFT button
longitude = NodeUtil.getLongitudeFromTile(zoom, getXTile()-0.5);
processed = true;
} else if (e.getKeyCode() == 39) {
+ // RIGHT button
longitude = NodeUtil.getLongitudeFromTile(zoom, getXTile()+0.5);
processed = true;
} else if (e.getKeyCode() == 38) {
+ // UP button
latitude = NodeUtil.getLatitudeFromTile(zoom, getYTile()-0.5);
processed = true;
} else if (e.getKeyCode() == 40) {
+ // DOWN button
latitude = NodeUtil.getLatitudeFromTile(zoom, getYTile()+0.5);
processed = true;
}
@@ -282,6 +332,14 @@ public class MapPanel extends JPanel {
super.processKeyEvent(e);
}
+ public DataTileManager getPoints() {
+ return points;
+ }
+
+ public void setPoints(DataTileManager points) {
+ this.points = points;
+ }
+
public class MapMouseAdapter extends MouseAdapter {
private Point startDragging = null;
diff --git a/DataExtractionOSM/src/com/osmand/NodeUtil.java b/DataExtractionOSM/src/com/osmand/NodeUtil.java
index 7db4507960..10e980ce4b 100644
--- a/DataExtractionOSM/src/com/osmand/NodeUtil.java
+++ b/DataExtractionOSM/src/com/osmand/NodeUtil.java
@@ -1,80 +1,15 @@
package com.osmand;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
-import org.openstreetmap.osmosis.core.domain.v0_6.Node;
-import org.openstreetmap.osmosis.core.domain.v0_6.Tag;
-import org.openstreetmap.osmosis.core.domain.v0_6.Way;
-import org.openstreetmap.osmosis.core.domain.v0_6.WayNode;
+import com.osmand.osm.Entity;
+import com.osmand.osm.LatLon;
+import com.osmand.osm.Node;
public class NodeUtil {
- public static class LatLon {
- private final double longitude;
- private final double latitude;
- public LatLon(double latitude, double longitude){
- this.latitude = latitude;
- this.longitude = longitude;
- }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- long temp;
- temp = Double.doubleToLongBits(latitude);
- result = prime * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(longitude);
- result = prime * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- LatLon other = (LatLon) obj;
- if (Double.doubleToLongBits(latitude) != Double
- .doubleToLongBits(other.latitude))
- return false;
- if (Double.doubleToLongBits(longitude) != Double
- .doubleToLongBits(other.longitude))
- return false;
- return true;
- }
- @Override
- public String toString() {
- return "Lat " + latitude +" Lon "+ longitude;
- }
-
- public double getLatitude() {
- return latitude;
- }
-
- public double getLongitude() {
- return longitude;
- }
-
- }
-
-
- public static String getTag(Entity e, String name){
- for(Tag t : e.getTags()){
- if(name.equals(t.getKey())){
- return t.getValue();
- }
- }
- return null;
- }
-
public static double getDistance(Node e1, Node e2){
return getDistance(e1.getLatitude(), e1.getLongitude(), e2.getLatitude(), e2.getLongitude());
}
@@ -131,28 +66,6 @@ public class NodeUtil {
return new LatLon(n.getLatitude(), n.getLongitude());
}
- public static LatLon getWeightCenter(Way way, Map nodes){
- List wayNodes = way.getWayNodes();
- ArrayList arrayList = new ArrayList(wayNodes.size());
- for(WayNode n : wayNodes){
- if(nodes.containsKey(n.getNodeId())){
- arrayList.add(nodes.get(n.getNodeId()));
- }
- }
- return getWeightCenter(arrayList);
- }
-
- public static LatLon getWeightCenterForNodes(Way way, Map nodes){
- List wayNodes = way.getWayNodes();
- ArrayList arrayList = new ArrayList(wayNodes.size());
- for(WayNode n : wayNodes){
- if(nodes.containsKey(n.getNodeId())){
- arrayList.add(nodes.get(n.getNodeId()));
- }
- }
- return getWeightCenterForNodes(arrayList);
- }
-
/**
@@ -191,13 +104,22 @@ public class NodeUtil {
return Math.atan(Math.sinh(Math.PI * (1 - 2 * y / (1 << zoom)))) * 180d / Math.PI;
}
- public static boolean isEmpty(String s){
- return s == null || s.length() == 0;
+ public static int getPixelShiftX(int zoom, double long1, double long2, int tileSize){
+ return (int) ((NodeUtil.getTileNumberX(zoom, long1) - NodeUtil.getTileNumberX(zoom, long2)) * tileSize);
+ }
+
+ public static int getPixelShiftY(int zoom, double lat1, double lat2, int tileSize){
+ return (int) ((NodeUtil.getTileNumberY(zoom, lat1) - NodeUtil.getTileNumberY(zoom, lat2)) * tileSize);
}
+ public static boolean isEmpty(String s){
+ return s == null || s.length() == 0;
+ }
+
+
public static boolean objectEquals(Object a, Object b){
if(a == null){
return b == null;
@@ -207,7 +129,7 @@ public class NodeUtil {
}
public static boolean tag(Entity e, String name, String value){
- String tag = getTag(e, name);
+ String tag = e.getTag(name);
return value.equals(tag);
}
}
diff --git a/DataExtractionOSM/src/com/osmand/WayUtil.java b/DataExtractionOSM/src/com/osmand/WayUtil.java
new file mode 100644
index 0000000000..3ce46e8573
--- /dev/null
+++ b/DataExtractionOSM/src/com/osmand/WayUtil.java
@@ -0,0 +1,19 @@
+package com.osmand;
+
+public class WayUtil {
+
+
+ public static boolean wayForCar(String tagHighway){
+ if(tagHighway != null){
+ String[] cars = new String[]{"trunk", "motorway", "primary", "secondary", "tertiary", "service", "residential",
+ "trunk_link", "motorway_link", "primary_link", "secondary_link", "residential_link",
+ "tertiary_link" };
+ for(String c : cars){
+ if(c.equals(tagHighway)){
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/DataExtractionOSM/src/com/osmand/data/City.java b/DataExtractionOSM/src/com/osmand/data/City.java
index 8d59307a89..08fe3a816f 100644
--- a/DataExtractionOSM/src/com/osmand/data/City.java
+++ b/DataExtractionOSM/src/com/osmand/data/City.java
@@ -4,11 +4,10 @@ import java.util.Collection;
import java.util.Map;
import java.util.TreeMap;
-import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
-import org.openstreetmap.osmosis.core.domain.v0_6.Node;
-
import com.osmand.NodeUtil;
-import com.osmand.NodeUtil.LatLon;
+import com.osmand.osm.Entity;
+import com.osmand.osm.LatLon;
+import com.osmand.osm.Node;
public class City {
@@ -31,7 +30,7 @@ public class City {
public City(Node el){
this.el = el;
- String place = NodeUtil.getTag(el, "place");
+ String place = el.getTag("place");
for(CityType t : CityType.values()){
if(t.name().equalsIgnoreCase(place)){
type = t;
@@ -41,8 +40,8 @@ public class City {
}
public Street registerBuilding(LatLon point, Entity e){
- String number = NodeUtil.getTag(e, "addr:housenumber");
- String street = NodeUtil.getTag(e, "addr:street");
+ String number = e.getTag("addr:housenumber");
+ String street = e.getTag("addr:street");
if( street != null && number != null){
if(!streets.containsKey(street)){
streets.put(street, new Street(street));
@@ -55,7 +54,7 @@ public class City {
public String getName(){
- return NodeUtil.getTag(el, "name");
+ return el.getTag("name");
}
public CityType getType(){
diff --git a/DataExtractionOSM/src/com/osmand/data/DataTileManager.java b/DataExtractionOSM/src/com/osmand/data/DataTileManager.java
index 0166ed5b61..9ef783b2f1 100644
--- a/DataExtractionOSM/src/com/osmand/data/DataTileManager.java
+++ b/DataExtractionOSM/src/com/osmand/data/DataTileManager.java
@@ -38,6 +38,20 @@ public class DataTileManager {
}
}
+ public List getObjects(double latitudeUp, double longitudeUp, double latitudeDown, double longitudeDown) {
+ int tileXUp = (int) NodeUtil.getTileNumberX(zoom, longitudeUp);
+ int tileYUp = (int) NodeUtil.getTileNumberY(zoom, latitudeUp);
+ int tileXDown = (int) NodeUtil.getTileNumberX(zoom, longitudeDown);
+ int tileYDown = (int) NodeUtil.getTileNumberY(zoom, latitudeDown);
+ List result = new ArrayList();
+ for (int i = tileXUp; i <= tileXDown; i++) {
+ for (int j = tileYUp; j <= tileYDown; j++) {
+ putObjects(i, j, result);
+ }
+ }
+ return result;
+ }
+
/**
* @depth of the neighbor tile to visit
* returns not exactly sorted list,
@@ -52,8 +66,8 @@ public class DataTileManager {
putObjects(tileX, tileY, result);
// that's very difficult way visiting node :
- // similar to visit like spiral
- // however the simplest way could visit by matrix & after that sort tiles by distance (that's less efficient)
+ // similar to visit by spiral
+ // however the simplest way could be to visit row by row & after sort tiles by distance (that's less efficient)
// go through circle
for (int i = 1; i <= depth; i++) {
diff --git a/DataExtractionOSM/src/com/osmand/data/Region.java b/DataExtractionOSM/src/com/osmand/data/Region.java
index 9eb23ac691..8a250d75b6 100644
--- a/DataExtractionOSM/src/com/osmand/data/Region.java
+++ b/DataExtractionOSM/src/com/osmand/data/Region.java
@@ -6,12 +6,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
-import org.openstreetmap.osmosis.core.domain.v0_6.Node;
-
import com.osmand.NodeUtil;
-import com.osmand.NodeUtil.LatLon;
import com.osmand.data.City.CityType;
+import com.osmand.osm.Entity;
+import com.osmand.osm.LatLon;
+import com.osmand.osm.Node;
public class Region {
private Entity entity;
@@ -36,7 +35,7 @@ public class Region {
}
public String getName(){
- return entity == null ? "" : NodeUtil.getTag(entity, "name");
+ return entity == null ? "" : entity.getTag("name");
}
public Collection getCitiesByType(CityType type){
diff --git a/DataExtractionOSM/src/com/osmand/data/Street.java b/DataExtractionOSM/src/com/osmand/data/Street.java
index b9072ea539..637c6bc264 100644
--- a/DataExtractionOSM/src/com/osmand/data/Street.java
+++ b/DataExtractionOSM/src/com/osmand/data/Street.java
@@ -4,9 +4,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
-
-import com.osmand.NodeUtil.LatLon;
+import com.osmand.osm.Entity;
+import com.osmand.osm.LatLon;
public class Street {
diff --git a/DataExtractionOSM/src/com/osmand/osm/Entity.java b/DataExtractionOSM/src/com/osmand/osm/Entity.java
new file mode 100644
index 0000000000..8703609511
--- /dev/null
+++ b/DataExtractionOSM/src/com/osmand/osm/Entity.java
@@ -0,0 +1,74 @@
+package com.osmand.osm;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public abstract class Entity {
+ // lazy initializing
+ private Map tags = null;
+ private final long id;
+
+ public Entity(long id) {
+ this.id = id;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public String putTag(String key, String value){
+ if(tags == null){
+ tags = new LinkedHashMap();
+ }
+ return tags.put(key, value);
+ }
+
+ public String getTag(String key){
+ if(tags == null){
+ return null;
+ }
+ return tags.get(key);
+ }
+
+ public Map getTags() {
+ return Collections.unmodifiableMap(tags);
+ }
+
+
+ public Collection getTagKeySet(){
+ if(tags == null){
+ return Collections.emptyList();
+ }
+ return tags.keySet();
+ }
+
+ public abstract void initializeLinks(Map entities);
+
+
+ /**
+ * @return middle point for entity
+ */
+ public abstract LatLon getLatLon();
+
+
+ @Override
+ public int hashCode() {
+ return (int) id;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Entity other = (Entity) obj;
+ if (id != other.id)
+ return false;
+ return true;
+ }
+}
diff --git a/DataExtractionOSM/src/com/osmand/osm/LatLon.java b/DataExtractionOSM/src/com/osmand/osm/LatLon.java
new file mode 100644
index 0000000000..6f63d64ada
--- /dev/null
+++ b/DataExtractionOSM/src/com/osmand/osm/LatLon.java
@@ -0,0 +1,52 @@
+package com.osmand.osm;
+
+public class LatLon {
+ private final double longitude;
+ private final double latitude;
+
+ public LatLon(double latitude, double longitude){
+ this.latitude = latitude;
+ this.longitude = longitude;
+ }
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ long temp;
+ temp = Double.doubleToLongBits(latitude);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(longitude);
+ result = prime * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ LatLon other = (LatLon) obj;
+ if (Double.doubleToLongBits(latitude) != Double
+ .doubleToLongBits(other.latitude))
+ return false;
+ if (Double.doubleToLongBits(longitude) != Double
+ .doubleToLongBits(other.longitude))
+ return false;
+ return true;
+ }
+ @Override
+ public String toString() {
+ return "Lat " + latitude +" Lon "+ longitude;
+ }
+
+ public double getLatitude() {
+ return latitude;
+ }
+
+ public double getLongitude() {
+ return longitude;
+ }
+
+ }
\ No newline at end of file
diff --git a/DataExtractionOSM/src/com/osmand/osm/Node.java b/DataExtractionOSM/src/com/osmand/osm/Node.java
new file mode 100644
index 0000000000..b580f6d4c9
--- /dev/null
+++ b/DataExtractionOSM/src/com/osmand/osm/Node.java
@@ -0,0 +1,45 @@
+package com.osmand.osm;
+
+import java.util.Map;
+
+public class Node extends Entity {
+
+ private double latitude;
+ private double longitude;
+ // currently not used
+// private boolean visible = true;
+
+ public Node(double latitude, double longitude, long id){
+ super(id);
+ this.latitude = latitude;
+ this.longitude = longitude;
+ }
+
+ public double getLatitude() {
+ return latitude;
+ }
+
+ public double getLongitude() {
+ return longitude;
+ }
+
+ public void setLatitude(double latitude) {
+ this.latitude = latitude;
+ }
+
+ public void setLongitude(double longitude) {
+ this.longitude = longitude;
+ }
+
+ @Override
+ public LatLon getLatLon() {
+ return new LatLon(latitude, longitude);
+ }
+
+ @Override
+ public void initializeLinks(Map entities) {
+ // nothing to initialize
+
+ }
+
+}
diff --git a/DataExtractionOSM/src/com/osmand/osm/Relation.java b/DataExtractionOSM/src/com/osmand/osm/Relation.java
new file mode 100644
index 0000000000..10f188105a
--- /dev/null
+++ b/DataExtractionOSM/src/com/osmand/osm/Relation.java
@@ -0,0 +1,98 @@
+package com.osmand.osm;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Relation extends Entity {
+
+ // lazyLoading
+ Map members = null;
+ Map memberEntities = null;
+
+
+
+ public Relation(long id) {
+ super(id);
+ }
+
+ public void addMember(Long id, String role){
+ if(members == null){
+ members = new LinkedHashMap();
+ }
+ members.put(id, role);
+ }
+
+ public String removeMember(Long id){
+ if(members == null){
+ return null;
+ }
+ return members.remove(id);
+ }
+
+ public String getRole(Entity e){
+ return members.get(e.getId());
+ }
+
+ public String getRole(Long id){
+ return members.get(id);
+ }
+
+ public Collection getMemberIds(String role) {
+ if (members == null) {
+ return Collections.emptyList();
+ }
+ if (role == null) {
+ return members.keySet();
+ }
+ List l = new ArrayList();
+ for (Long m : members.keySet()) {
+ if (role.equals(members.get(m))) {
+ l.add(m);
+ }
+ }
+ return l;
+ }
+
+ public Collection getMembers(String role) {
+ if (memberEntities == null) {
+ return Collections.emptyList();
+ }
+ if (role == null) {
+ return memberEntities.keySet();
+ }
+ List l = new ArrayList();
+ for (Entity m : memberEntities.keySet()) {
+ if (role.equals(memberEntities.get(m))) {
+ l.add(m);
+ }
+ }
+ return l;
+ }
+
+ @Override
+ public void initializeLinks(Map entities){
+ if (members != null) {
+ if(memberEntities == null){
+ memberEntities = new LinkedHashMap();
+ } else {
+ memberEntities.clear();
+ }
+ for(Long l : members.keySet()){
+ if(l != null && entities.get(l) != null){
+ memberEntities.put(entities.get(l), members.get(l));
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public LatLon getLatLon() {
+ return null;
+ }
+
+}
diff --git a/DataExtractionOSM/src/com/osmand/osm/Way.java b/DataExtractionOSM/src/com/osmand/osm/Way.java
new file mode 100644
index 0000000000..25657c7815
--- /dev/null
+++ b/DataExtractionOSM/src/com/osmand/osm/Way.java
@@ -0,0 +1,76 @@
+package com.osmand.osm;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.osmand.NodeUtil;
+
+public class Way extends Entity {
+
+ // lazy loading
+ private List nodeIds = null;
+ private List nodes = null;
+
+ public Way(long id) {
+ super(id);
+ }
+
+ public void addNode(long id){
+ if(nodeIds == null){
+ nodeIds = new ArrayList();
+ }
+ nodeIds.add(id);
+ }
+
+ public Long removeNodeByIndex(int i){
+ if(nodeIds == null){
+ return null;
+ }
+ return nodeIds.remove(i);
+ }
+
+ public List getNodeIds(){
+ return nodeIds;
+ }
+
+ public List getNodes() {
+ return nodes;
+ }
+
+ @Override
+ public void initializeLinks(Map entities) {
+ if (nodeIds != null) {
+ if(nodes == null){
+ nodes = new ArrayList();
+ } else {
+ nodes.clear();
+ }
+ for (int i = 0; i < nodeIds.size(); i++) {
+ if(entities.get(nodeIds.get(i)) instanceof Node){
+ nodes.add((Node) entities.get(nodeIds.get(i)));
+ } else {
+ nodes.add(null);
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public LatLon getLatLon() {
+ if(nodes == null){
+ return null;
+ }
+ List list = new ArrayList(nodes.size());
+ for(Node n : nodes){
+ if(n != null){
+ list.add(n.getLatLon());
+ }
+ }
+ return NodeUtil.getWeightCenter(list);
+ }
+
+
+
+}
diff --git a/DataExtractionOSM/src/com/osmand/osm/io/OsmBaseStorage.java b/DataExtractionOSM/src/com/osmand/osm/io/OsmBaseStorage.java
new file mode 100644
index 0000000000..93c4d8c8e2
--- /dev/null
+++ b/DataExtractionOSM/src/com/osmand/osm/io/OsmBaseStorage.java
@@ -0,0 +1,188 @@
+package com.osmand.osm.io;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import com.osmand.osm.Entity;
+import com.osmand.osm.Node;
+import com.osmand.osm.Relation;
+import com.osmand.osm.Way;
+
+public class OsmBaseStorage extends DefaultHandler {
+
+ protected static final String ELEM_OSM = "osm";
+ protected static final String ELEM_NODE = "node";
+ protected static final String ELEM_TAG = "tag";
+ protected static final String ELEM_WAY = "way";
+ protected static final String ELEM_ND = "nd";
+ protected static final String ELEM_RELATION = "relation";
+ protected static final String ELEM_MEMBER = "member";
+
+
+ protected static final String ATTR_VERSION = "version";
+ 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_K = "k";
+ protected static final String ATTR_V = "v";
+
+ protected static final String ATTR_TYPE = "type";
+ protected static final String ATTR_REF = "ref";
+ protected static final String ATTR_ROLE = "role";
+
+ protected Entity currentParsedEntity = null;
+
+ private boolean parseStarted;
+
+ protected Map entities = new LinkedHashMap();
+
+
+
+ /**
+ * @param stream
+ * @throws IOException
+ * @throws SAXException - could be
+ */
+ public synchronized void parseOSM(InputStream stream) throws IOException, SAXException {
+ SAXParser parser = initSaxParser();
+ parseStarted = false;
+ entities.clear();
+ parser.parse(stream, this);
+ completeReading();
+ }
+
+ private SAXParser saxParser;
+ public SAXParser initSaxParser(){
+ if(saxParser != null){
+ return saxParser;
+ }
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ try {
+ return saxParser = factory.newSAXParser();
+ } catch (ParserConfigurationException e) {
+ throw new IllegalStateException(e);
+ } catch (SAXException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ protected Long parseId(Attributes a, String name, long defId){
+ long id = defId;
+ String value = a.getValue(name);
+ try {
+ id = Long.parseLong(value);
+ } catch (NumberFormatException e) {
+ }
+ return id;
+ }
+
+ protected double parseDouble(Attributes a, String name, double defVal){
+ double ret = defVal;
+ String value = a.getValue(name);
+ try {
+ ret = Double.parseDouble(value);
+ } catch (NumberFormatException e) {
+ }
+ return ret;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
+ if(!parseStarted){
+ if(!ELEM_OSM.equals(name) || !"0.6".equals(attributes.getValue(ATTR_VERSION))){
+ throw new OsmVersionNotSupported();
+ }
+ parseStarted = true;
+ }
+ if (currentParsedEntity == null) {
+ if (ELEM_NODE.equals(name)) {
+ currentParsedEntity = new Node(parseDouble(attributes, ATTR_LAT, 0), parseDouble(attributes, ATTR_LON, 0),
+ parseId(attributes, ATTR_ID, -1));
+ } else if (ELEM_WAY.equals(name)) {
+ currentParsedEntity = new Way(parseId(attributes, ATTR_ID, -1));
+ } else if (ELEM_RELATION.equals(name)) {
+ currentParsedEntity = new Relation(parseId(attributes, ATTR_ID, -1));
+ } else {
+ // this situation could be logged as unhandled
+ }
+ } else {
+ if (ELEM_TAG.equals(name)) {
+ String key = attributes.getValue(ATTR_K);
+ if(key != null){
+ currentParsedEntity.putTag(key, attributes.getValue(ATTR_V));
+ }
+ } else if (ELEM_ND.equals(name)) {
+ Long id = parseId(attributes, ATTR_REF, -1);
+ if(id != -1 && currentParsedEntity instanceof Way){
+ ((Way)currentParsedEntity).addNode(id);
+ }
+ } else if (ELEM_MEMBER.equals(name)) {
+ Long id = parseId(attributes, ATTR_REF, -1);
+ if(id != -1 && currentParsedEntity instanceof Relation){
+ ((Relation)currentParsedEntity).addMember(id, attributes.getValue(ATTR_ROLE));
+ }
+
+ } else {
+ // this situation could be logged as unhandled
+ }
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String name) throws SAXException {
+ if (ELEM_NODE.equals(name) || ELEM_WAY.equals(name) || ELEM_RELATION.equals(name)) {
+ if(currentParsedEntity != null){
+ if(acceptEntityToLoad(currentParsedEntity)){
+ Entity oldEntity = entities.put(currentParsedEntity.getId(), currentParsedEntity);
+ if(oldEntity!= null){
+ throw new UnsupportedOperationException("Entity with id=" + oldEntity.getId() +" is duplicated in osm map");
+ }
+ }
+ currentParsedEntity = null;
+ }
+ }
+ super.endElement(uri, localName, name);
+ }
+
+
+ public void completeReading(){
+ for(Entity e : entities.values()){
+ e.initializeLinks(entities);
+ }
+ }
+
+ 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;
+ }
+
+
+}
diff --git a/DataExtractionOSM/src/com/osmand/osm/io/OsmVersionNotSupported.java b/DataExtractionOSM/src/com/osmand/osm/io/OsmVersionNotSupported.java
new file mode 100644
index 0000000000..6aa28aabf1
--- /dev/null
+++ b/DataExtractionOSM/src/com/osmand/osm/io/OsmVersionNotSupported.java
@@ -0,0 +1,11 @@
+package com.osmand.osm.io;
+
+import org.xml.sax.SAXException;
+
+/**
+ * Thrown when version is not supported
+ */
+public class OsmVersionNotSupported extends SAXException {
+ private static final long serialVersionUID = -127558215143984838L;
+
+}