diff --git a/DataExtractionOSM/src/com/osmand/DataExtraction.java b/DataExtractionOSM/src/com/osmand/DataExtraction.java index 164bae5134..2446b3c384 100644 --- a/DataExtractionOSM/src/com/osmand/DataExtraction.java +++ b/DataExtractionOSM/src/com/osmand/DataExtraction.java @@ -9,6 +9,7 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -150,6 +151,7 @@ public class DataExtraction implements IMapLocationListener { n.putTag("amenity", "shop"); amenities.add(n); } + // TODO leisure if (n.getTag("place") != null) { places.add(n); if (places.size() % 500 == 0) System.out.println(); @@ -230,12 +232,19 @@ public class DataExtraction implements IMapLocationListener { runUI(country); + List interestedObjects = new ArrayList(); + NodeUtil.fillList(places, interestedObjects); + NodeUtil.fillList(amenities, interestedObjects); + NodeUtil.fillList(mapWays, interestedObjects); +// NodeUtil.fillList(buildings, interestedObjects); + + storage.saveStorage(new FileOutputStream("C:/1_tmp.osm"), interestedObjects, true); System.out.println(); System.out.println("USED Memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1e6); System.out.println("TIME : " + (System.currentTimeMillis() - st)); } - + /////////////////////////////////////////// // 2. Showing UI diff --git a/DataExtractionOSM/src/com/osmand/MapPanel.java b/DataExtractionOSM/src/com/osmand/MapPanel.java index fa5df73fac..a68cb55340 100644 --- a/DataExtractionOSM/src/com/osmand/MapPanel.java +++ b/DataExtractionOSM/src/com/osmand/MapPanel.java @@ -112,12 +112,22 @@ public class MapPanel extends JPanel { 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) { - g.setColor(Color.gray); - } else { - g.setColor(Color.white); - } - g.fillRect(i * tileSize+xStartingImage, j * tileSize + yStartingImage, tileSize, tileSize); + int div = 4; + int tileDiv = tileSize / div; + for(int k1 = 0; k1 < div; k1++){ + for(int k2 = 0; k2 < div; k2++){ + if ((k1 + k2) % 2 == 0) { + g.setColor(Color.gray); + } else { + g.setColor(Color.white); + } + g.fillRect(i * tileSize+xStartingImage + k1*tileDiv, + j * tileSize + yStartingImage + k2*tileDiv, tileDiv, tileDiv); + + } + } + + } else { g.drawImage(images[i][j], i * tileSize+xStartingImage, j * tileSize + yStartingImage, this); } @@ -179,35 +189,29 @@ public class MapPanel extends JPanel { } } } - double xTile = getXTile(); - double yTile = getYTile(); - double leftX = (getSize().width/2d - (xTile - Math.floor(xTile)) *tileSize)/tileSize; - double leftY = (getSize().height/2d - (yTile - Math.floor(yTile)) *tileSize)/tileSize; - int xStartInd = (int) (Math.floor(xTile) - Math.ceil(leftX)); - int yStartInd = (int) (Math.floor(yTile) - Math.ceil(leftY)); + double xTileLeft = getXTile() -getSize().width/(2d*tileSize); + double xTileRight = getXTile() + getSize().width/(2d*tileSize); + double yTileUp = getYTile() -getSize().height/(2d*tileSize); + double yTileDown = getYTile() + getSize().height/(2d*tileSize); + + xStartingImage = - (int) ((xTileLeft - Math.floor(xTileLeft))*tileSize); + yStartingImage = - (int) ((yTileUp - Math.floor(yTileUp))*tileSize); - xStartingImage = (int) ((leftX - Math.ceil(leftX))*tileSize); - yStartingImage = (int) ((leftY - Math.ceil(leftY))*tileSize); - - int tileXCount = (int) Math.ceil((getSize().width - xStartingImage)/ (double)tileSize ); - int tileYCount = (int) Math.ceil((getSize().height- yStartingImage)/ (double)tileSize ); + int tileXCount = ((int)xTileRight - (int) xTileLeft + 1); + int tileYCount = ((int)yTileDown - (int) yTileUp + 1); images = new BufferedImage[tileXCount][tileYCount]; for(int i=0; i objects = points.getObjects(latUp, longUp, latDown, longDown); pointsToDraw.clear(); for(LatLon n : objects){ diff --git a/DataExtractionOSM/src/com/osmand/NodeUtil.java b/DataExtractionOSM/src/com/osmand/NodeUtil.java index 10e980ce4b..1cc55253aa 100644 --- a/DataExtractionOSM/src/com/osmand/NodeUtil.java +++ b/DataExtractionOSM/src/com/osmand/NodeUtil.java @@ -2,6 +2,7 @@ package com.osmand; import java.util.Collection; +import java.util.List; import com.osmand.osm.Entity; import com.osmand.osm.LatLon; @@ -22,6 +23,12 @@ public class NodeUtil { return getDistance(e1.getLatitude(), e1.getLongitude(), point.getLatitude(), point.getLongitude()); } + public static void fillList(Collection source, List ids){ + for(Entity e : source){ + ids.add(e.getId()); + } + } + /** * Gets distance in meters */ diff --git a/DataExtractionOSM/src/com/osmand/WayUtil.java b/DataExtractionOSM/src/com/osmand/WayUtil.java index 3ce46e8573..0aaa2fe7a2 100644 --- a/DataExtractionOSM/src/com/osmand/WayUtil.java +++ b/DataExtractionOSM/src/com/osmand/WayUtil.java @@ -7,7 +7,7 @@ public class WayUtil { 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" }; + "tertiary_link", "track" }; for(String c : cars){ if(c.equals(tagHighway)){ return true; diff --git a/DataExtractionOSM/src/com/osmand/osm/Entity.java b/DataExtractionOSM/src/com/osmand/osm/Entity.java index 8703609511..08f00ccf9e 100644 --- a/DataExtractionOSM/src/com/osmand/osm/Entity.java +++ b/DataExtractionOSM/src/com/osmand/osm/Entity.java @@ -33,6 +33,9 @@ public abstract class Entity { } public Map getTags() { + if(tags == null){ + return Collections.emptyMap(); + } return Collections.unmodifiableMap(tags); } diff --git a/DataExtractionOSM/src/com/osmand/osm/Relation.java b/DataExtractionOSM/src/com/osmand/osm/Relation.java index 10f188105a..3d980a9b5c 100644 --- a/DataExtractionOSM/src/com/osmand/osm/Relation.java +++ b/DataExtractionOSM/src/com/osmand/osm/Relation.java @@ -41,6 +41,17 @@ public class Relation extends Entity { return members.get(id); } + public Collection getMemberIds() { + return getMemberIds(null); + } + + public Map getMembersMap() { + if(members == null){ + return Collections.emptyMap(); + } + return Collections.unmodifiableMap(members); + } + public Collection getMemberIds(String role) { if (members == null) { return Collections.emptyList(); diff --git a/DataExtractionOSM/src/com/osmand/osm/Way.java b/DataExtractionOSM/src/com/osmand/osm/Way.java index 25657c7815..48cbcbe2c7 100644 --- a/DataExtractionOSM/src/com/osmand/osm/Way.java +++ b/DataExtractionOSM/src/com/osmand/osm/Way.java @@ -1,6 +1,7 @@ package com.osmand.osm; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -31,10 +32,16 @@ public class Way extends Entity { } public List getNodeIds(){ + if(nodeIds == null){ + return Collections.emptyList(); + } return nodeIds; } public List getNodes() { + if(nodes == null){ + return Collections.emptyList(); + } return nodes; } diff --git a/DataExtractionOSM/src/com/osmand/osm/io/OsmBaseStorage.java b/DataExtractionOSM/src/com/osmand/osm/io/OsmBaseStorage.java index 93c4d8c8e2..502f0d02c1 100644 --- a/DataExtractionOSM/src/com/osmand/osm/io/OsmBaseStorage.java +++ b/DataExtractionOSM/src/com/osmand/osm/io/OsmBaseStorage.java @@ -2,12 +2,23 @@ package com.osmand.osm.io; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.Map.Entry; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.transform.OutputKeys; import org.xml.sax.Attributes; import org.xml.sax.SAXException; @@ -17,6 +28,8 @@ import com.osmand.osm.Entity; import com.osmand.osm.Node; import com.osmand.osm.Relation; import com.osmand.osm.Way; +import com.sun.org.apache.xerces.internal.impl.PropertyManager; +import com.sun.xml.internal.stream.writers.XMLStreamWriterImpl; public class OsmBaseStorage extends DefaultHandler { @@ -96,10 +109,19 @@ public class OsmBaseStorage extends DefaultHandler { return ret; } + private static final Set supportedVersions = new HashSet(); + static { + supportedVersions.add("0.6"); + supportedVersions.add("0.5"); + } + + private final String INDENT = " "; + private final String INDENT2 = INDENT + INDENT; + @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))){ + if(!ELEM_OSM.equals(name) || !supportedVersions.contains(attributes.getValue(ATTR_VERSION))){ throw new OsmVersionNotSupported(); } parseStarted = true; @@ -147,6 +169,8 @@ public class OsmBaseStorage extends DefaultHandler { if(oldEntity!= null){ throw new UnsupportedOperationException("Entity with id=" + oldEntity.getId() +" is duplicated in osm map"); } + } else { +// System.gc(); } currentParsedEntity = null; } @@ -161,6 +185,111 @@ public class OsmBaseStorage extends DefaultHandler { } } + public void saveStorage(OutputStream output, Collection interestedObjects, boolean includeLinks) throws XMLStreamException, IOException { + PropertyManager propertyManager = new PropertyManager(PropertyManager.CONTEXT_WRITER); +// transformer.setOutputProperty(OutputKeys.INDENT, "yes"); +// String indent = "{http://xml.apache.org/xslt}indent-amount"; +// transformer.setOutputProperty(indent, "4"); + + + XMLStreamWriter streamWriter = new XMLStreamWriterImpl(output, propertyManager); + List nodes = new ArrayList(); + List ways = new ArrayList(); + List relations = new ArrayList(); + if(interestedObjects == null){ + interestedObjects = entities.keySet(); + } + Stack toResolve = new Stack(); + toResolve.addAll(interestedObjects); + while(!toResolve.isEmpty()){ + Long l = toResolve.pop(); + if(entities.get(l) instanceof Node){ + nodes.add((Node) entities.get(l)); + } else if(entities.get(l) instanceof Way){ + ways.add((Way) entities.get(l)); + toResolve.addAll(((Way)entities.get(l)).getNodeIds()); + } else if(entities.get(l) instanceof Relation){ + relations.add((Relation) entities.get(l)); + toResolve.addAll(((Relation)entities.get(l)).getMemberIds()); + } + } + + + streamWriter.writeStartDocument(); + + writeStartElement(streamWriter, ELEM_OSM, ""); + streamWriter.writeAttribute(ATTR_VERSION, "0.6"); + for(Node n : nodes){ + writeStartElement(streamWriter, ELEM_NODE, INDENT); + streamWriter.writeAttribute(ATTR_LAT, n.getLatitude()+""); + streamWriter.writeAttribute(ATTR_LON, n.getLongitude()+""); + streamWriter.writeAttribute(ATTR_ID, n.getId()+""); + writeTags(streamWriter, n); + streamWriter.writeEndElement(); + } + + for(Way w : ways){ + writeStartElement(streamWriter, ELEM_WAY, INDENT); + streamWriter.writeAttribute(ATTR_ID, w.getId()+""); + for(Long r : w.getNodeIds()){ + writeStartElement(streamWriter, ELEM_ND, INDENT2); + streamWriter.writeAttribute(ATTR_REF, r+""); + streamWriter.writeEndElement(); + } + writeTags(streamWriter, w); + streamWriter.writeEndElement(); + } + + for(Relation r : relations){ + writeStartElement(streamWriter, ELEM_RELATION, INDENT); + streamWriter.writeAttribute(ATTR_ID, r.getId()+""); + for(Entry e : r.getMembersMap().entrySet()){ + writeStartElement(streamWriter, ELEM_MEMBER, INDENT2); + streamWriter.writeAttribute(ATTR_REF, e.getKey()+""); + String s = e.getValue(); + if(s == null){ + s = ""; + } + streamWriter.writeAttribute(ATTR_ROLE, s); + streamWriter.writeAttribute(ATTR_TYPE, getEntityType(e.getKey())); + streamWriter.writeEndElement(); + } + writeTags(streamWriter, r); + streamWriter.writeEndElement(); + } + + streamWriter.writeEndElement(); // osm + streamWriter.writeEndDocument(); + streamWriter.flush(); + } + + private String getEntityType(Long id){ + Entity e = entities.get(id); + if(e instanceof Way){ + return "way"; + } else if(e instanceof Relation){ + return "relation"; + } + return "node"; + } + + private void writeStartElement(XMLStreamWriter writer, String name, String indent) throws XMLStreamException{ + writer.writeCharacters("\n"+indent); + writer.writeStartElement(name); + } + + + private void writeTags(XMLStreamWriter writer, Entity e) throws XMLStreamException{ + for(Entry en : e.getTags().entrySet()){ + writeStartElement(writer, ELEM_TAG, INDENT2); + writer.writeAttribute(ATTR_K, en.getKey()); + writer.writeAttribute(ATTR_V, en.getValue()); + writer.writeEndElement(); + } + } + + + public boolean acceptEntityToLoad(Entity e){ if(e instanceof Way){ return acceptWayToLoad((Way) e);