Skip to content

Commit

Permalink
improved draw performance by excluding edges not in visible area and …
Browse files Browse the repository at this point in the history
…excluding nodes at all
  • Loading branch information
Peter committed Jun 20, 2012
1 parent 2197446 commit 9faada5
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 77 deletions.
8 changes: 6 additions & 2 deletions core/src/main/java/de/jetsli/graph/coll/MyBitSet.java
Expand Up @@ -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
*/
Expand All @@ -26,5 +28,7 @@ public interface MyBitSet {

void add(int index);

long cardinality();
int getCardinality();

void clear();
}
46 changes: 46 additions & 0 deletions 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();
}
}
19 changes: 12 additions & 7 deletions core/src/main/java/de/jetsli/graph/coll/MyOpenBitSet.java
Expand Up @@ -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());
}
}
7 changes: 6 additions & 1 deletion core/src/main/java/de/jetsli/graph/coll/MyTBitSet.java
Expand Up @@ -46,7 +46,12 @@ public MyTBitSet() {
}

@Override
public long cardinality() {
public int getCardinality() {
return tHash.size();
}

@Override
public void clear() {
tHash.clear();
}
}
24 changes: 12 additions & 12 deletions core/src/main/java/de/jetsli/graph/reader/OSMReaderRouting.java
Expand Up @@ -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) {
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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));
}
Expand Down
Expand Up @@ -34,7 +34,7 @@ public GraphWrapper(Graph g) {

public void setIgnoreNodes(MyBitSet bitSet) {
ignoreNodes = bitSet;
ignoreNodesSize = (int) bitSet.cardinality();
ignoreNodesSize = (int) bitSet.getCardinality();
}

@Override
Expand Down
98 changes: 57 additions & 41 deletions core/src/main/java/de/jetsli/graph/ui/MiniGraphUI.java
Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand All @@ -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<Long>(8, 7 * 8);
// this.quadTree = new SpatialHashtable(2, 3).init(graph.getLocations());

Expand All @@ -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) {
Expand All @@ -112,24 +114,35 @@ 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;
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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -291,23 +310,22 @@ 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) {
offsetX += (e.getX() - currentPosX) * scaleX;
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
Expand Down Expand Up @@ -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();
}
}

0 comments on commit 9faada5

Please sign in to comment.