diff --git a/core/src/main/java/de/jetsli/graph/coll/MyBitSet.java b/core/src/main/java/de/jetsli/graph/coll/MyBitSet.java index cd97cf9fb37..d0fdd253be8 100644 --- a/core/src/main/java/de/jetsli/graph/coll/MyBitSet.java +++ b/core/src/main/java/de/jetsli/graph/coll/MyBitSet.java @@ -16,7 +16,9 @@ package de.jetsli.graph.coll; /** - * Wrapper interface for different implementations like OpenBitset, BitSet,... + * Wrapper interface for different implementations like OpenBitset, BitSet, ... + * + * Supports only integer value indices. * * @author Peter Karich, info@jetsli.de */ @@ -26,5 +28,7 @@ public interface MyBitSet { void add(int index); - long cardinality(); + int getCardinality(); + + void clear(); } diff --git a/core/src/main/java/de/jetsli/graph/coll/MyBitSetImpl.java b/core/src/main/java/de/jetsli/graph/coll/MyBitSetImpl.java new file mode 100644 index 00000000000..cdb9364d74a --- /dev/null +++ b/core/src/main/java/de/jetsli/graph/coll/MyBitSetImpl.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012 Peter Karich info@jetsli.de + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.jetsli.graph.coll; + +import java.util.BitSet; + +/** + * @author Peter Karich + */ +public class MyBitSetImpl extends BitSet implements MyBitSet { + + public MyBitSetImpl() { + } + + public MyBitSetImpl(int nbits) { + super(nbits); + } + + @Override + public boolean contains(int index) { + return super.get(index); + } + + @Override + public void add(int index) { + super.set(index); + } + + @Override + public int getCardinality() { + return super.cardinality(); + } +} diff --git a/core/src/main/java/de/jetsli/graph/coll/MyOpenBitSet.java b/core/src/main/java/de/jetsli/graph/coll/MyOpenBitSet.java index 913365927ad..580e769c2e0 100644 --- a/core/src/main/java/de/jetsli/graph/coll/MyOpenBitSet.java +++ b/core/src/main/java/de/jetsli/graph/coll/MyOpenBitSet.java @@ -44,21 +44,26 @@ public MyOpenBitSet() { @Override public String toString() { try { - StringBuilder sb = new StringBuilder(); - for(DocIdSetIterator iter = bitSet.iterator(); iter.nextDoc() != DocIdSetIterator.NO_MORE_DOCS; ) { - if(sb.length() != 0) + StringBuilder sb = new StringBuilder(); + for (DocIdSetIterator iter = bitSet.iterator(); iter.nextDoc() != DocIdSetIterator.NO_MORE_DOCS;) { + if (sb.length() != 0) sb.append(", "); - + sb.append(iter.docID()); } return sb.toString(); - } catch(Exception ex) { + } catch (Exception ex) { return "error constructing bitset string representation"; } } @Override - public long cardinality() { - return bitSet.cardinality(); + public int getCardinality() { + return (int) bitSet.cardinality(); } + + @Override + public void clear() { + bitSet.clear(0, bitSet.length()); + } } diff --git a/core/src/main/java/de/jetsli/graph/coll/MyTBitSet.java b/core/src/main/java/de/jetsli/graph/coll/MyTBitSet.java index a7af6eee386..b575e63d415 100644 --- a/core/src/main/java/de/jetsli/graph/coll/MyTBitSet.java +++ b/core/src/main/java/de/jetsli/graph/coll/MyTBitSet.java @@ -46,7 +46,12 @@ public MyTBitSet() { } @Override - public long cardinality() { + public int getCardinality() { return tHash.size(); + } + + @Override + public void clear() { + tHash.clear(); } } diff --git a/core/src/main/java/de/jetsli/graph/reader/OSMReaderRouting.java b/core/src/main/java/de/jetsli/graph/reader/OSMReaderRouting.java index bc84787039d..197b74d543c 100644 --- a/core/src/main/java/de/jetsli/graph/reader/OSMReaderRouting.java +++ b/core/src/main/java/de/jetsli/graph/reader/OSMReaderRouting.java @@ -44,7 +44,7 @@ public class OSMReaderRouting { public static void main(String[] args) throws Exception { - new OSMReaderRouting("mmap-graph", 40 * 1000 * 1000) { + new OSMReaderRouting("mmap-graph-unterfranken", 40 * 1000 * 1000) { @Override public boolean isInBounds(double lat, double lon) { @@ -92,18 +92,17 @@ public static Graph defaultRead(String osmFile, String mmapFile) throws FileNotF } public void read(String[] args) throws Exception { - // get osm file via wget -O muenchen.osm "http://api.openstreetmap.org/api/0.6/map?bbox=11.54,48.14,11.543,48.145" - // or if that does not work for you get them here - // http://download.geofabrik.de/osm/europe/germany/bayern/ - if (args.length < 1) - throw new IllegalStateException(".osm file missing"); - - // I'm having the osm on an external usb drive - File osmFile = new File(args[0]); - if (!osmFile.exists()) - throw new IllegalStateException("File does not exist:" + args[0]); - if (!loadExisting()) { + // get osm file via wget -O muenchen.osm "http://api.openstreetmap.org/api/0.6/map?bbox=11.54,48.14,11.543,48.145" + // or if that does not work for you get them here + // http://download.geofabrik.de/osm/europe/germany/bayern/ + if (args.length < 1) + throw new IllegalStateException(".osm file missing"); + + // I'm having the osm on an external usb drive which should boost import time + File osmFile = new File(args[0]); + if (!osmFile.exists()) + throw new IllegalStateException("File does not exist:" + args[0]); logger.info("size for osm2id-map is " + maxLocs + " - start creating graph from " + osmFile + "\n\n WARNING: be sure you have enough RAM so that the mmap file does not swap. " + "check this with the script ./check-swap-usage.sh | grep java"); @@ -159,6 +158,7 @@ public boolean loadExisting() { } public void createNewFromOSM(File osmFile) throws FileNotFoundException { + // or could we use new PushbackInputStream(new FileInputStream(osmFile)); ??? acceptHighwaysOnly(new FileInputStream(osmFile)); writeOsm2Binary(new FileInputStream(osmFile)); } diff --git a/core/src/main/java/de/jetsli/graph/storage/GraphWrapper.java b/core/src/main/java/de/jetsli/graph/storage/GraphWrapper.java index 86db4eda557..d23e708d1a8 100644 --- a/core/src/main/java/de/jetsli/graph/storage/GraphWrapper.java +++ b/core/src/main/java/de/jetsli/graph/storage/GraphWrapper.java @@ -34,7 +34,7 @@ public GraphWrapper(Graph g) { public void setIgnoreNodes(MyBitSet bitSet) { ignoreNodes = bitSet; - ignoreNodesSize = (int) bitSet.cardinality(); + ignoreNodesSize = (int) bitSet.getCardinality(); } @Override diff --git a/core/src/main/java/de/jetsli/graph/ui/MiniGraphUI.java b/core/src/main/java/de/jetsli/graph/ui/MiniGraphUI.java index 3b53d8d7d2b..a30a7addbe5 100644 --- a/core/src/main/java/de/jetsli/graph/ui/MiniGraphUI.java +++ b/core/src/main/java/de/jetsli/graph/ui/MiniGraphUI.java @@ -15,6 +15,8 @@ */ package de.jetsli.graph.ui; +import de.jetsli.graph.coll.MyBitSet; +import de.jetsli.graph.coll.MyTBitSet; import de.jetsli.graph.dijkstra.DijkstraBidirection; import de.jetsli.graph.dijkstra.DijkstraPath; import de.jetsli.graph.reader.OSMReaderRouting; @@ -44,7 +46,7 @@ public static void main(String[] args) throws Exception { throw new IllegalArgumentException("Osm file missing"); String osmFile = args[0]; - Graph g = OSMReaderRouting.defaultRead(osmFile, "mmap-graph"); + Graph g = OSMReaderRouting.defaultRead(osmFile, "mmap-graph-unterfranken"); new MiniGraphUI(g).visualize(); } private Logger logger = LoggerFactory.getLogger(getClass()); @@ -67,11 +69,11 @@ public static void main(String[] args) throws Exception { private JPanel infoPanel; private JPanel mainPanel; - public MiniGraphUI(Graph g) { - this.graph = g; - logger.info("locations:" + g.getLocations()); + public MiniGraphUI(Graph tmpG) { + this.graph = tmpG; + logger.info("locations:" + tmpG.getLocations()); // prepare location quadtree to 'enter' the graph. create a 313*313 grid => <3km - this.index = new Location2IDQuadtree(g).prepareIndex(100000); + this.index = new Location2IDQuadtree(tmpG).prepareIndex(100000); // this.quadTree = new QuadTreeSimple(8, 7 * 8); // this.quadTree = new SpatialHashtable(2, 3).init(graph.getLocations()); @@ -94,8 +96,8 @@ public MiniGraphUI(Graph g) { // TODO PERFORMANCE draw graph on an offscreen image for faster translation and use // different layer for routing! redraw only on scaling =>but then memory problems for bigger zooms!? // final BufferedImage offscreenImage = new BufferedImage(11000, 11000, BufferedImage.TYPE_INT_ARGB); - // final Graphics2D g2 = offscreenImage.createGraphics(); - + // final Graphics2D g2 = offscreenImage.createGraphics(); + final MyBitSet bitset = new MyTBitSet(graph.getLocations()); mainPanel = new JPanel() { @Override protected void paintComponent(Graphics g) { @@ -112,9 +114,6 @@ public MiniGraphUI(Graph g) { minY = Integer.MAX_VALUE; maxX = 0; maxY = 0; -// g.setColor(Color.RED); -// g.drawOval((int) MiniGraphUI.this.getX(49.990532), (int) MiniGraphUI.this.getY(9.020827), 10, 10); - int size; if (scaleX < 3e-5) size = 2; @@ -122,14 +121,28 @@ else if (scaleX < 3e-4) size = 1; else size = 0; - StopWatch sw = new StopWatch().start(); - for (int i = 0; i < locs; i++) { - int count = MyIteratorable.count(graph.getEdges(i)); - double lat = graph.getLatitude(i); - double lon = graph.getLongitude(i); - plot(g2, lat, lon, count, size); - for (DistEntry de : graph.getOutgoing(i)) { + Dimension d = getSize(); + double maxLat = getLat(0); + double minLat = getLat(d.height); + double minLon = getLon(0); + double maxLon = getLon(d.width); + bitset.clear(); + StopWatch sw = new StopWatch().start(); + for (int nodeIndex = 0; nodeIndex < locs; nodeIndex++) { + double lat = graph.getLatitude(nodeIndex); + double lon = graph.getLongitude(nodeIndex); + if (lat < minLat || lat > maxLat || lon < minLon || lon > maxLon) + continue; + +// int count = MyIteratorable.count(graph.getEdges(nodeIndex)); +// plot(g2, lat, lon, count, size); + + for (DistEntry de : graph.getOutgoing(nodeIndex)) { + int sum = nodeIndex + de.node; + if (bitset.contains(sum)) + continue; + bitset.add(sum); double lat2 = graph.getLatitude(de.node); double lon2 = graph.getLongitude(de.node); if (lat2 <= 0 || lon2 <= 0) @@ -178,14 +191,22 @@ private void plotEdge(Graphics g, double lat, double lon, double lat2, double lo plotEdge(g, lat, lon, lat2, lon2, 1); } - private double getX(double lon) { + double getX(double lon) { return (lon + offsetX) / scaleX; } - private double getY(double lat) { + double getY(double lat) { return (90 - lat + offsetY) / scaleY; } + double getLon(int x) { + return x * scaleX - offsetX; + } + + double getLat(int y) { + return 90 - (y * scaleY - offsetY); + } + private void plot(Graphics g, double lat, double lon, int count, int width) { double x = getX(lon); double y = getY(lat); @@ -251,17 +272,15 @@ public void visualize() { scaleY = resY; // TODO respect mouse x,y when scaling - offsetX -= offsetX * scaleX; - offsetY -= offsetY * scaleY; + offsetX -= offsetX * scaleX - currentPosX; + offsetY -= offsetY * scaleY - currentPosY; + logger.info("mouse wheel moved => repaint"); mainPanel.repaint(); } }); MouseAdapter ml = new MouseAdapter() { - // for moving - int currentPosX; - int currentPosY; // for routing: double fromLat, fromLon; boolean fromDone = false; @@ -291,16 +310,7 @@ public void visualize() { @Override public void mouseDragged(MouseEvent e) { update(e); - } - - @Override public void mouseMoved(MouseEvent e) { updateLatLon(e); - infoPanel.repaint(); - } - - @Override public void mousePressed(MouseEvent e) { - currentPosX = e.getX(); - currentPosY = e.getY(); } public void update(MouseEvent e) { @@ -308,6 +318,14 @@ public void update(MouseEvent e) { offsetY += (e.getY() - currentPosY) * scaleY; mainPanel.repaint(); } + + @Override public void mouseMoved(MouseEvent e) { + updateLatLon(e); + } + + @Override public void mousePressed(MouseEvent e) { + updateLatLon(e); + } }; // important: calculate x/y for mouse event relative to mainPanel not frame! // move graph via dragging and do something on click @@ -372,16 +390,14 @@ public void update(MouseEvent e) { throw new RuntimeException(ex); } } + // for moving + int currentPosX; + int currentPosY; void updateLatLon(MouseEvent e) { latLon = getLat(e.getY()) + "," + getLon(e.getX()); - } - - double getLon(int x) { - return x * scaleX - offsetX; - } - - double getLat(int y) { - return 90 - (y * scaleY - offsetY); + infoPanel.repaint(); + currentPosX = e.getX(); + currentPosY = e.getY(); } } diff --git a/core/src/test/java/de/jetsli/graph/coll/AbstractMyBitSetTest.java b/core/src/test/java/de/jetsli/graph/coll/AbstractMyBitSetTest.java new file mode 100644 index 00000000000..b1c7022230e --- /dev/null +++ b/core/src/test/java/de/jetsli/graph/coll/AbstractMyBitSetTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012 Peter Karich info@jetsli.de + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.jetsli.graph.coll; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author Peter Karich, info@jetsli.de + */ +public abstract class AbstractMyBitSetTest { + + public abstract MyBitSet createBitSet(int no); + + @Test + public void testToString() { + MyBitSet bs = createBitSet(100); + bs.add(12); + bs.add(1); + assertEquals("1, 12", bs.toString()); + } + + @Test + public void testClear() { + MyBitSet bs = createBitSet(100); + bs.add(12); + bs.add(1); + assertTrue(bs.contains(1)); + assertFalse(bs.contains(2)); + assertTrue(bs.contains(12)); + bs.clear(); + assertFalse(bs.contains(1)); + assertFalse(bs.contains(2)); + assertFalse(bs.contains(12)); + assertEquals(0, bs.getCardinality()); + bs.add(12); + bs.add(1); + assertTrue(bs.contains(1)); + assertFalse(bs.contains(2)); + assertTrue(bs.contains(12)); + } +} diff --git a/core/src/test/java/de/jetsli/graph/coll/MyOpenBitSetTest.java b/core/src/test/java/de/jetsli/graph/coll/MyOpenBitSetTest.java index 6a6e0c20bea..b4b9dba6856 100644 --- a/core/src/test/java/de/jetsli/graph/coll/MyOpenBitSetTest.java +++ b/core/src/test/java/de/jetsli/graph/coll/MyOpenBitSetTest.java @@ -15,20 +15,13 @@ */ package de.jetsli.graph.coll; -import org.junit.Test; -import static org.junit.Assert.*; - /** - * - * @author Peter Karich, info@jetsli.de + * @author Peter Karich */ -public class MyOpenBitSetTest { - - @Test - public void testToString() { - MyOpenBitSet bs = new MyOpenBitSet(); - bs.add(12); - bs.add(1); - assertEquals("1, 12", bs.toString()); +public class MyOpenBitSetTest extends AbstractMyBitSetTest { + + @Override + public MyBitSet createBitSet(int no) { + return new MyOpenBitSet(no); } }