diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
diff --git a/INSTALL b/INSTALL
old mode 100644
new mode 100755
diff --git a/Java6/modestmaps/library/modestmaps.jar b/Java6/modestmaps/library/modestmaps.jar
new file mode 100644
index 0000000..f2fae47
Binary files /dev/null and b/Java6/modestmaps/library/modestmaps.jar differ
diff --git a/Java7/modestmaps/library/modestmaps.jar b/Java7/modestmaps/library/modestmaps.jar
new file mode 100644
index 0000000..c9bb37f
Binary files /dev/null and b/Java7/modestmaps/library/modestmaps.jar differ
diff --git a/Java8/modestmaps/library/modestmaps.jar b/Java8/modestmaps/library/modestmaps.jar
new file mode 100644
index 0000000..8f309db
Binary files /dev/null and b/Java8/modestmaps/library/modestmaps.jar differ
diff --git a/LICENSE b/LICENSE
old mode 100644
new mode 100755
diff --git a/Makefile b/Makefile
old mode 100644
new mode 100755
index 8e62794..47afb61
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,57 @@
# change these if you're not on a Mac, or don't run "make install" :)
-PROCESSING_PATH = "/Applications/Processing.app/Contents/Resources/Java/core.jar"
-LIBRARY_PATH = "/Users/$(USER)/Documents/Processing/libraries/"
+#PROCESSING_PATH = "/Applications/Processing.app/Contents/Resources/Java/core.jar"
+#LIBRARY_PATH = "/Users/$(USER)/Documents/Processing/libraries/"
-modestmaps/library/modestmaps.jar:
+# change these if you're on Linux and set them to actual paths
+PROCESSING_PATH = "/opt/processing-3.3.7/core/library/core.jar"
+LIBRARY_PATH = "/opt/sketchbook/libraries/"
+
+#modestmaps/library/modestmaps.jar:
+java6:
+ mkdir -p classes
+ javac -sourcepath src/ -cp $(PROCESSING_PATH) -d classes src/com/modestmaps/*.java src/com/modestmaps/core/*.java src/com/modestmaps/providers/*.java src/com/modestmaps/geo/*.java -source 6 -target 6
+ mkdir -p Java6/modestmaps/library
+ jar cvf Java6/modestmaps/library/modestmaps.jar -C classes .
+
+java7:
+ mkdir -p classes
+ javac -sourcepath src/ -cp $(PROCESSING_PATH) -d classes src/com/modestmaps/*.java src/com/modestmaps/core/*.java src/com/modestmaps/providers/*.java src/com/modestmaps/geo/*.java -source 7 -target 7
+ mkdir -p Java7/modestmaps/library
+ jar cvf Java7/modestmaps/library/modestmaps.jar -C classes .
+
+java8:
+ mkdir -p classes
+ javac -sourcepath src/ -cp $(PROCESSING_PATH) -d classes src/com/modestmaps/*.java src/com/modestmaps/core/*.java src/com/modestmaps/providers/*.java src/com/modestmaps/geo/*.java -source 8 -target 8
+ mkdir -p Java8/modestmaps/library
+ jar cvf Java8/modestmaps/library/modestmaps.jar -C classes .
+
+all:
+ #Java6 build
+ mkdir -p classes
+ javac -sourcepath src/ -cp $(PROCESSING_PATH) -d classes src/com/modestmaps/*.java src/com/modestmaps/core/*.java src/com/modestmaps/providers/*.java src/com/modestmaps/geo/*.java -source 6 -target 6
+ mkdir -p Java6/modestmaps/library
+ jar cvf Java6/modestmaps/library/modestmaps.jar -C classes .
+ rm -rf classes/*
+ #Java7 build
mkdir -p classes
- javac -sourcepath src/ -cp $(PROCESSING_PATH) -d classes src/com/modestmaps/*.java src/com/modestmaps/core/*.java src/com/modestmaps/providers/*.java src/com/modestmaps/geo/*.java
- mkdir -p modestmaps/library
- jar cvf modestmaps/library/modestmaps.jar -C classes .
+ javac -sourcepath src/ -cp $(PROCESSING_PATH) -d classes src/com/modestmaps/*.java src/com/modestmaps/core/*.java src/com/modestmaps/providers/*.java src/com/modestmaps/geo/*.java -source 7 -target 7
+ mkdir -p Java7/modestmaps/library
+ jar cvf Java7/modestmaps/library/modestmaps.jar -C classes .
+ rm -rf classes/*
+ #Java8 build
+ mkdir -p classes
+ javac -sourcepath src/ -cp $(PROCESSING_PATH) -d classes src/com/modestmaps/*.java src/com/modestmaps/core/*.java src/com/modestmaps/providers/*.java src/com/modestmaps/geo/*.java -source 8 -target 8
+ mkdir -p Java8/modestmaps/library
+ jar cvf Java8/modestmaps/library/modestmaps.jar -C classes .
+
-install: modestmaps/library/modestmaps.jar
- cp -r modestmaps $(LIBRARY_PATH)
+#install: modestmaps/library/modestmaps.jar
+install: java6
+ cp -r Java6/modestmaps $(LIBRARY_PATH)
clean:
rm -rf classes/*
rm -rf modestmaps
+ rm -rf Java6
+ rm -rf Java7
+ rm -rf Java8
diff --git a/README b/README
old mode 100644
new mode 100755
diff --git a/examples/modest_maps_interactive/AndroidManifest.xml b/examples/modest_maps_interactive/AndroidManifest.xml
new file mode 100755
index 0000000..5dfce5c
--- /dev/null
+++ b/examples/modest_maps_interactive/AndroidManifest.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/modest_maps_interactive/Button.pde b/examples/modest_maps_interactive/Button.pde
old mode 100644
new mode 100755
diff --git a/examples/modest_maps_interactive/code/sketch.properties b/examples/modest_maps_interactive/code/sketch.properties
new file mode 100755
index 0000000..cedc49b
--- /dev/null
+++ b/examples/modest_maps_interactive/code/sketch.properties
@@ -0,0 +1,3 @@
+mode=Java
+component=app
+mode.id=processing.mode.java.JavaMode
diff --git a/examples/modest_maps_interactive/modest_maps_interactive.pde b/examples/modest_maps_interactive/modest_maps_interactive.pde
old mode 100644
new mode 100755
index f6ee2e0..32af8ad
--- a/examples/modest_maps_interactive/modest_maps_interactive.pde
+++ b/examples/modest_maps_interactive/modest_maps_interactive.pde
@@ -31,8 +31,7 @@ boolean gui = true;
double tx, ty, sc;
void setup() {
- size(640, 480, OPENGL);
- smooth();
+ size(1280, 720);
// create a new map, optionally specify a provider
@@ -42,10 +41,11 @@ void setup() {
// AOL/MapQuest provides open tiles too
// see http://developer.mapquest.com/web/products/open/map for terms
- // and this is how to use them:
- String template = "http://{S}.mqcdn.com/tiles/1.0.0/osm/{Z}/{X}/{Y}.png";
- String[] subdomains = new String[] { "otile1", "otile2", "otile3", "otile4" }; // optional
- map = new InteractiveMap(this, new TemplatedMapProvider(template, subdomains));
+ //// and this is how to use them:
+ //String template = "http://{S}.mqcdn.com/tiles/1.0.0/osm/{Z}/{X}/{Y}.png";
+ //String[] subdomains = new String[] { "otile1", "otile2", "otile3", "otile4" }; // optional
+ //map = new InteractiveMap(this, new TemplatedMapProvider(template, subdomains));
+ map = new InteractiveMap(this);
// others would be "new Microsoft.HybridProvider()" or "new Microsoft.AerialProvider()"
// the Google ones get blocked after a few hundred tiles
@@ -58,14 +58,6 @@ void setup() {
// set a default font for labels
font = createFont("Helvetica", 12);
-
- // enable the mouse wheel, for zooming
- addMouseWheelListener(new java.awt.event.MouseWheelListener() {
- public void mouseWheelMoved(java.awt.event.MouseWheelEvent evt) {
- mouseWheel(evt.getWheelRotation());
- }
- });
-
}
void draw() {
@@ -227,4 +219,3 @@ void mouseClicked() {
map.panRight();
}
}
-
diff --git a/examples/modest_maps_static/atkinson.pde b/examples/modest_maps_static/atkinson.pde
old mode 100644
new mode 100755
diff --git a/examples/modest_maps_static/modest_maps_lib.pde b/examples/modest_maps_static/modest_maps_static.pde
similarity index 65%
rename from examples/modest_maps_static/modest_maps_lib.pde
rename to examples/modest_maps_static/modest_maps_static.pde
index 81ddce0..f5a604e 100644
--- a/examples/modest_maps_static/modest_maps_lib.pde
+++ b/examples/modest_maps_static/modest_maps_static.pde
@@ -14,24 +14,22 @@ import com.modestmaps.providers.*;
//
void setup() {
- size(screen.width/2, screen.height/2);
- if (!runTests(false)) {
- println("one or more tests failed");
- exit();
- }
- noLoop();
-}
-
-void draw() {
-
+ size(1280, 720);
+ if (!runTests(false)) {
+ println("one or more tests failed");
+ exit();
+ }
+ noLoop();
+ }
+
+ void draw() {
StaticMap m = new StaticMap(this, new Microsoft.AerialProvider(), new Point2f(width/2, height), new Location(51.5, -0.137), 12);
-
- PImage img = m.draw(true);
- image(img,0,0);
-
+
+ PImage img = m.draw(true);
+ image(img,0,0);
+
img = atkinsonDither(img);
- image(img,width/2,0);
-
- println("done");
-
-}
+ image(img,width/2,0);
+
+ println("done");
+ }
diff --git a/examples/modest_maps_static/tests.pde b/examples/modest_maps_static/tests.pde
old mode 100644
new mode 100755
diff --git a/modestmaps/library/modestmaps.jar b/modestmaps/library/modestmaps.jar
deleted file mode 100644
index e355d82..0000000
Binary files a/modestmaps/library/modestmaps.jar and /dev/null differ
diff --git a/src/com/modestmaps/InteractiveMap.java b/src/com/modestmaps/InteractiveMap.java
old mode 100644
new mode 100755
index 6c8469f..6614c8d
--- a/src/com/modestmaps/InteractiveMap.java
+++ b/src/com/modestmaps/InteractiveMap.java
@@ -1,307 +1,472 @@
- package com.modestmaps;
-
- import processing.core.*;
- import java.util.*;
- import com.modestmaps.geo.*;
- import com.modestmaps.core.*;
- import com.modestmaps.providers.*;
-
- public class InteractiveMap implements PConstants {
-
- // I have made the dumb mistake of getting these wrong before...
- // it's REALLY unlikely you'll want to change them:
- public int TILE_WIDTH = 256;
- public int TILE_HEIGHT = 256;
-
- // unavoidable right now, for loadImage and float maths
- public PApplet p;
-
- // pan and zoom
- public double tx = -TILE_WIDTH/2; // half the world width, at zoom 0
- public double ty = -TILE_HEIGHT/2; // half the world height, at zoom 0
- public double sc = 1;
-
- // limit simultaneous calls to loadImage
- public int MAX_PENDING = 4;
-
- // limit tiles in memory
- // 256 would be 64 MB, you may want to lower this quite a bit for your app
- public int MAX_IMAGES_TO_KEEP = 256;
-
- // upping this can help appearances when zooming out, but also loads many more tiles
- public int GRID_PADDING = 1;
-
- // what kinda maps?
- public AbstractMapProvider provider;
-
- // how big?
- public float width, height;
-
- // loading tiles
- public Hashtable pending = new Hashtable(); // coord -> TileLoader
- // loaded tiles
- public Hashtable images = new Hashtable(); // coord -> PImage
- // coords waiting to load
- public Vector queue = new Vector();
- // a list of the most recent MAX_IMAGES_TO_KEEP PImages we've seen
- public Vector recentImages = new Vector();
-
- // for sorting coordinates by zoom
- public ZoomComparator zoomComparator = new ZoomComparator();
-
- // for loading tiles from the inside first
- public QueueSorter queueSorter = new QueueSorter();
-
- /** default to Microsoft Hybrid */
- public InteractiveMap(PApplet p) {
- this(p, new Microsoft.HybridProvider());
- }
-
- /** new map using applet width and height, and given provider */
- public InteractiveMap(PApplet p, AbstractMapProvider provider) {
- this(p, provider, p.width, p.height);
- }
-
- /** make a new interactive map, using the given provider, of the given width and height */
- public InteractiveMap(PApplet p, AbstractMapProvider provider, float width, float height) {
-
- this.p = p;
- this.provider = provider;
- this.width = width;
- this.height = height;
-
- // fit to screen
- sc = p.ceil(p.min(height/(float)TILE_WIDTH, width/(float)TILE_HEIGHT));
-
- }
-
- /** draw the map on the given PApplet */
- public void draw() {
-
- // remember smooth setting so it can be reset
- boolean smooth = p.g.smooth;
- int imageMode = p.g.imageMode;
-
- // !!! VERY IMPORTANT
- // (all the renderers apart from OpenGL will choke if you ask for smooth scaling of image calls)
- p.noSmooth();
-
- // we need this, or our tiles will not be drawn in the right place
- p.imageMode(p.CORNER);
-
- // translate and scale, from the middle
- p.pushMatrix();
- p.translate(width/2, height/2);
- p.scale((float)sc);
- p.translate((float)tx, (float)ty);
-
- // find the bounds of the ur-tile in screen-space:
- float minX = p.screenX(0,0);
- float minY = p.screenY(0,0);
- float maxX = p.screenX(TILE_WIDTH, TILE_HEIGHT);
- float maxY = p.screenY(TILE_WIDTH, TILE_HEIGHT);
-
- // what power of 2 are we at?
- // 0 when scale is around 1, 1 when scale is around 2,
- // 2 when scale is around 4, 3 when scale is around 8, etc.
- int zoom = bestZoomForScale((float)sc);
-
- // how many columns and rows of tiles at this zoom?
- // (this is basically (int)sc, but let's derive from zoom to be sure
- int cols = (int)p.pow(2,zoom);
- int rows = (int)p.pow(2,zoom);
-
- // find the biggest box the screen would fit in:, aligned with the map:
- float screenMinX = 0;
- float screenMinY = 0;
- float screenMaxX = width;
- float screenMaxY = height;
- // TODO: align this, and fix the next bit to work with rotated maps
-
- // find start and end columns
- int minCol = (int)p.floor(cols * (screenMinX-minX) / (maxX-minX));
- int maxCol = (int)p.ceil(cols * (screenMaxX-minX) / (maxX-minX)) - 1;
- int minRow = (int)p.floor(rows * (screenMinY-minY) / (maxY-minY));
- int maxRow = (int)p.ceil(rows * (screenMaxY-minY) / (maxY-minY)) - 1;
-
- // pad a bit, for luck (well, because we might be zooming out between zoom levels)
- minCol -= GRID_PADDING;
- minRow -= GRID_PADDING;
- maxCol += GRID_PADDING;
- maxRow += GRID_PADDING;
-
- // we don't wrap around the world yet, so:
- minCol = p.constrain(minCol, 0, cols);
- maxCol = p.constrain(maxCol, 0, cols);
- minRow = p.constrain(minRow, 0, rows);
- maxRow = p.constrain(maxRow, 0, rows);
-
- // keep track of what we can see already:
- Vector visibleKeys = new Vector();
-
- // grab coords for visible tiles
- for (int col = minCol; col <= maxCol; col++) {
- for (int row = minRow; row <= maxRow; row++) {
-
- // source coordinate wraps around the world:
- Coordinate coord = provider.sourceCoordinate(new Coordinate(row,col,zoom));
-
- // let's make sure we still have ints:
- coord.row = p.round(coord.row);
- coord.column = p.round(coord.column);
- coord.zoom = p.round(coord.zoom);
-
- // keep this for later:
- visibleKeys.add(coord);
-
- if (!images.containsKey(coord)) {
- // fetch it if we don't have it
- grabTile(coord);
-
- // see if we have a parent coord for this tile?
- boolean gotParent = false;
- for (int i = (int)coord.zoom; i > 0; i--) {
- Coordinate zoomed = coord.zoomTo(i).container();
- // make sure we still have ints:
- zoomed.row = p.round(zoomed.row);
- zoomed.column = p.round(zoomed.column);
- zoomed.zoom = p.round(zoomed.zoom);
- if (images.containsKey(zoomed)) {
- visibleKeys.add(zoomed);
- gotParent = true;
- break;
- }
- }
-
- // or if we have any of the children
- if (!gotParent) {
- Coordinate zoomed = coord.zoomBy(1).container();
- Coordinate[] kids = { zoomed, zoomed.right(), zoomed.down(), zoomed.right().down() };
- for (int i = 0; i < kids.length; i++) {
- zoomed = kids[i];
- // make sure we still have ints:
- zoomed.row = p.round(zoomed.row);
- zoomed.column = p.round(zoomed.column);
- zoomed.zoom = p.round(zoomed.zoom);
- if (images.containsKey(zoomed)) {
- visibleKeys.add(zoomed);
- }
- }
- }
-
- }
-
- } // rows
- } // columns
-
- // sort by zoom so we draw small zoom levels (big tiles) first:
- Collections.sort(visibleKeys, zoomComparator);
-
- if (visibleKeys.size() > 0) {
- Coordinate previous = (Coordinate)visibleKeys.get(0);
- p.pushMatrix();
- // correct the scale for this zoom level:
- p.scale(1.0f/p.pow(2, previous.zoom));
- for (int i = 0; i < visibleKeys.size(); i++) {
- Coordinate coord = (Coordinate)visibleKeys.get(i);
-
- if (coord.zoom != previous.zoom) {
- p.popMatrix();
- p.pushMatrix();
- // correct the scale for this zoom level:
- p.scale(1.0f/p.pow(2,coord.zoom));
- }
-
- if (images.containsKey(coord)) {
- PImage tile = (PImage)images.get(coord);
- p.image(tile,coord.column*TILE_WIDTH,coord.row*TILE_HEIGHT,TILE_WIDTH,TILE_HEIGHT);
- if (recentImages.contains(tile)) {
- recentImages.remove(tile);
- }
- recentImages.add(tile);
- }
- }
- p.popMatrix();
- }
-
- p.popMatrix();
-
- // stop fetching things we can't see:
- // (visibleKeys also has the parents and children, if needed, but that shouldn't matter)
- queue.retainAll(visibleKeys);
-
- // sort what's left by distance from center:
- queueSorter.setCenter(new Coordinate( (minRow + maxRow) / 2.0f, (minCol + maxCol) / 2.0f, zoom));
- Collections.sort(queue, queueSorter);
-
- // load up to 4 more things:
- processQueue();
-
- // clear some images away if we have too many...
- if (recentImages.size() > MAX_IMAGES_TO_KEEP) {
- recentImages.subList(0, recentImages.size()-MAX_IMAGES_TO_KEEP).clear();
- images.values().retainAll(recentImages);
- }
-
- // restore smoothing, if needed
- if (smooth) {
- p.smooth();
- }
- // restore image mode
- p.imageMode(imageMode);
-
- }
-
- /** @return zoom level of currently visible tile layer */
- public int getZoom() {
- return bestZoomForScale((float)sc);
- }
-
- public Location getCenter() {
- return provider.coordinateLocation(getCenterCoordinate());
- }
-
- public Coordinate getCenterCoordinate() {
- float row = (float)(ty*sc/-TILE_WIDTH);
- float column = (float)(tx*sc/-TILE_HEIGHT);
- float zoom = zoomForScale((float)sc);
- return new Coordinate(row, column, zoom);
- }
-
- public void setCenter(Coordinate center) {
- //println("setting center to " + center);
- sc = p.pow(2.0f, center.zoom);
- tx = -TILE_WIDTH*center.column/sc;
- ty = -TILE_HEIGHT*center.row/sc;
- }
-
- public void setCenter(Location location) {
- setCenter(provider.locationCoordinate(location).zoomTo(getZoom()));
- }
-
- public void setCenterZoom(Location location, int zoom) {
- setCenter(provider.locationCoordinate(location).zoomTo(zoom));
- }
-
- /** sets scale according to given zoom level, should leave you with pixel perfect tiles */
- public void setZoom(int zoom) {
- sc = p.pow(2.0f, zoom);
- }
-
- public void zoom(int dir) {
- sc = p.pow(2.0f, getZoom()+dir);
- }
-
- public void zoomIn() {
- sc = p.pow(2.0f, getZoom()+1);
- }
-
- public void zoomOut() {
- sc = p.pow(2.0f, getZoom()-1);
- }
-
- // public function setExtent(extent:MapExtent):void
- // public function getExtent():MapExtent
+package com.modestmaps;
+
+import processing.core.*;
+import java.util.*;
+import com.modestmaps.geo.*;
+import com.modestmaps.core.*;
+import com.modestmaps.providers.*;
+
+import static processing.core.PApplet.floor;
+
+public class InteractiveMap implements PConstants {
+
+ // I have made the dumb mistake of getting these wrong before...
+ // it's REALLY unlikely you'll want to change them:
+ public int TILE_WIDTH = 256;
+ public int TILE_HEIGHT = 256;
+
+ // unavoidable right now, for loadImage and float maths
+ public PApplet p;
+
+ // pan and zoom
+ public double tx = -TILE_WIDTH/2; // half the world width, at zoom 0
+ public double ty = -TILE_HEIGHT/2; // half the world height, at zoom 0
+ public double sc = 1;
+
+ // limit simultaneous calls to loadImage
+ public int MAX_PENDING = 4;
+
+ // limit tiles in memory
+ // 256 would be 64 MB, you may want to lower this quite a bit for your app
+ public int MAX_IMAGES_TO_KEEP = 256;
+
+ // upping this can help appearances when zooming out, but also loads many more tiles
+ public int GRID_PADDING = 1;
+
+ // what kinda maps?
+ public AbstractMapProvider provider;
+
+ // how big?
+ public float width, height;
+
+ // loading tiles
+ public Hashtable pending = new Hashtable(); // coord -> TileLoader
+ // loaded tiles
+ public Hashtable images = new Hashtable(); // coord -> PImage
+ // coords waiting to load
+ public Vector queue = new Vector();
+ // a list of the most recent MAX_IMAGES_TO_KEEP PImages we've seen
+ public Vector recentImages = new Vector();
+
+ // for sorting coordinates by zoom
+ public ZoomComparator zoomComparator = new ZoomComparator();
+
+ // for loading tiles from the inside first
+ public QueueSorter queueSorter = new QueueSorter();
+
+ /** default to Microsoft Hybrid */
+ public InteractiveMap(PApplet p) {
+ this(p, new Microsoft.HybridProvider());
+ }
+
+ /** new map using applet width and height, and given provider */
+ public InteractiveMap(PApplet p, AbstractMapProvider provider) {
+ this(p, provider, p.width, p.height);
+ }
+
+ /** make a new interactive map, using the given provider, of the given width and height */
+ public InteractiveMap(PApplet p, AbstractMapProvider provider, float width, float height) {
+
+ this.p = p;
+ this.provider = provider;
+ this.width = width;
+ this.height = height;
+
+ // fit to screen
+ sc = PApplet.ceil(PApplet.min(height/(float)TILE_WIDTH, width/(float)TILE_HEIGHT));
+
+ }
+
+ /** draw the map on the given PApplet */
+ public void draw() {
+
+ // remember smooth setting so it can be reset
+ int imageMode = p.g.imageMode;
+
+ // we need this, or our tiles will not be drawn in the right place
+ p.imageMode(p.CORNER);
+
+ // translate and scale, from the middle
+ p.pushMatrix();
+ p.translate(width/2, height/2);
+ p.scale((float)sc);
+ p.translate((float)tx, (float)ty);
+
+ // find the bounds of the ur-tile in screen-space:
+ float minX = p.screenX(0,0);
+ float minY = p.screenY(0,0);
+ float maxX = p.screenX(TILE_WIDTH, TILE_HEIGHT);
+ float maxY = p.screenY(TILE_WIDTH, TILE_HEIGHT);
+
+ // what power of 2 are we at?
+ // 0 when scale is around 1, 1 when scale is around 2,
+ // 2 when scale is around 4, 3 when scale is around 8, etc.
+ int zoom = bestZoomForScale((float)sc);
+
+ // how many columns and rows of tiles at this zoom?
+ // (this is basically (int)sc, but let's derive from zoom to be sure
+ int cols = (int)p.pow(2,zoom);
+ int rows = (int)p.pow(2,zoom);
+
+ // find the biggest box the screen would fit in:, aligned with the map:
+ float screenMinX = 0;
+ float screenMinY = 0;
+ float screenMaxX = width;
+ float screenMaxY = height;
+ // TODO: align this, and fix the next bit to work with rotated maps
+
+ // find start and end columns
+ int minCol = (int) floor(cols * (screenMinX-minX) / (maxX-minX));
+ int maxCol = (int)p.ceil(cols * (screenMaxX-minX) / (maxX-minX)) - 1;
+ int minRow = (int) floor(rows * (screenMinY-minY) / (maxY-minY));
+ int maxRow = (int)p.ceil(rows * (screenMaxY-minY) / (maxY-minY)) - 1;
+
+ // pad a bit, for luck (well, because we might be zooming out between zoom levels)
+ minCol -= GRID_PADDING;
+ minRow -= GRID_PADDING;
+ maxCol += GRID_PADDING;
+ maxRow += GRID_PADDING;
+
+ // we don't wrap around the world yet, so:
+ minCol = p.constrain(minCol, 0, cols);
+ maxCol = p.constrain(maxCol, 0, cols);
+ minRow = p.constrain(minRow, 0, rows);
+ maxRow = p.constrain(maxRow, 0, rows);
+
+ // keep track of what we can see already:
+ Vector visibleKeys = new Vector();
+
+ // grab coords for visible tiles
+ for (int col = minCol; col <= maxCol; col++) {
+ for (int row = minRow; row <= maxRow; row++) {
+
+ // source coordinate wraps around the world:
+ Coordinate coord = provider.sourceCoordinate(new Coordinate(row,col,zoom));
+
+ // let's make sure we still have ints:
+ coord.row = p.round(coord.row);
+ coord.column = p.round(coord.column);
+ coord.zoom = p.round(coord.zoom);
+
+ // keep this for later:
+ visibleKeys.add(coord);
+
+ if (!images.containsKey(coord)) {
+ // fetch it if we don't have it
+ grabTile(coord);
+
+ // see if we have a parent coord for this tile?
+ boolean gotParent = false;
+ for (int i = (int)coord.zoom; i > 0; i--) {
+ Coordinate zoomed = coord.zoomTo(i).container();
+ // make sure we still have ints:
+ zoomed.row = p.round(zoomed.row);
+ zoomed.column = p.round(zoomed.column);
+ zoomed.zoom = p.round(zoomed.zoom);
+ if (images.containsKey(zoomed)) {
+ visibleKeys.add(zoomed);
+ gotParent = true;
+ break;
+ }
+ }
+
+ // or if we have any of the children
+ if (!gotParent) {
+ Coordinate zoomed = coord.zoomBy(1).container();
+ Coordinate[] kids = { zoomed, zoomed.right(), zoomed.down(), zoomed.right().down() };
+ for (int i = 0; i < kids.length; i++) {
+ zoomed = kids[i];
+ // make sure we still have ints:
+ zoomed.row = p.round(zoomed.row);
+ zoomed.column = p.round(zoomed.column);
+ zoomed.zoom = p.round(zoomed.zoom);
+ if (images.containsKey(zoomed)) {
+ visibleKeys.add(zoomed);
+ }
+ }
+ }
+
+ }
+
+ } // rows
+ } // columns
+
+ // sort by zoom so we draw small zoom levels (big tiles) first:
+ Collections.sort(visibleKeys, zoomComparator);
+
+ if (visibleKeys.size() > 0) {
+ Coordinate previous = visibleKeys.get(0);
+ p.pushMatrix();
+ // correct the scale for this zoom level:
+ p.scale(1.0f/p.pow(2, previous.zoom));
+ for (int i = 0; i < visibleKeys.size(); i++) {
+ Coordinate coord = visibleKeys.get(i);
+
+ if (coord.zoom != previous.zoom) {
+ p.popMatrix();
+ p.pushMatrix();
+ // correct the scale for this zoom level:
+ p.scale(1.0f/p.pow(2,coord.zoom));
+ }
+
+ if (images.containsKey(coord)) {
+ PImage tile = images.get(coord);
+ p.image(tile,coord.column*TILE_WIDTH,coord.row*TILE_HEIGHT,TILE_WIDTH,TILE_HEIGHT);
+ if (recentImages.contains(tile)) {
+ recentImages.remove(tile);
+ }
+ recentImages.add(tile);
+ }
+ }
+ p.popMatrix();
+ }
+
+ p.popMatrix();
+
+ // stop fetching things we can't see:
+ // (visibleKeys also has the parents and children, if needed, but that shouldn't matter)
+ queue.retainAll(visibleKeys);
+
+ // sort what's left by distance from center:
+ queueSorter.setCenter(new Coordinate( (minRow + maxRow) / 2.0f, (minCol + maxCol) / 2.0f, zoom));
+ Collections.sort(queue, queueSorter);
+
+ // load up to 4 more things:
+ processQueue();
+
+ // clear some images away if we have too many...
+ if (recentImages.size() > MAX_IMAGES_TO_KEEP) {
+ recentImages.subList(0, recentImages.size()-MAX_IMAGES_TO_KEEP).clear();
+ images.values().retainAll(recentImages);
+ }
+
+ // restore image mode
+ p.imageMode(imageMode);
+
+ }
+
+ /** return the map as a PImage */
+ public PImage getImage() {
+ PGraphics img = p.createGraphics(floor(width), floor(height));
+ img.beginDraw();
+// img.fill(51);
+// img.rect(0, 0, img.width, img.height);
+ // remember smooth setting so it can be reset
+ int imageMode = p.g.imageMode;
+
+ // we need this, or our tiles will not be drawn in the right place
+ img.imageMode(p.CORNER);
+
+ // translate and scale, from the middle
+ img.pushMatrix();
+ img.translate(width/2, height/2);
+ img.scale((float)sc);
+ img.translate((float)tx, (float)ty);
+
+ // find the bounds of the ur-tile in screen-space:
+ float minX = img.screenX(0,0);
+ float minY = img.screenY(0,0);
+ float maxX = img.screenX(TILE_WIDTH, TILE_HEIGHT);
+ float maxY = img.screenY(TILE_WIDTH, TILE_HEIGHT);
+
+ // what power of 2 are we at?
+ // 0 when scale is around 1, 1 when scale is around 2,
+ // 2 when scale is around 4, 3 when scale is around 8, etc.
+ int zoom = bestZoomForScale((float)sc);
+
+ // how many columns and rows of tiles at this zoom?
+ // (this is basically (int)sc, but let's derive from zoom to be sure
+ int cols = (int) PApplet.pow(2,zoom);
+ int rows = (int) PApplet.pow(2,zoom);
+
+ // find the biggest box the screen would fit in:, aligned with the map:
+ float screenMinX = 0;
+ float screenMinY = 0;
+ float screenMaxX = width;
+ float screenMaxY = height;
+ // TODO: align this, and fix the next bit to work with rotated maps
+
+ // find start and end columns
+ int minCol = (int) floor(cols * (screenMinX-minX) / (maxX-minX));
+ int maxCol = (int) PApplet.ceil(cols * (screenMaxX-minX) / (maxX-minX)) - 1;
+ int minRow = (int) floor(rows * (screenMinY-minY) / (maxY-minY));
+ int maxRow = (int) PApplet.ceil(rows * (screenMaxY-minY) / (maxY-minY)) - 1;
+
+ // pad a bit, for luck (well, because we might be zooming out between zoom levels)
+ minCol -= GRID_PADDING;
+ minRow -= GRID_PADDING;
+ maxCol += GRID_PADDING;
+ maxRow += GRID_PADDING;
+
+ // we don't wrap around the world yet, so:
+ minCol = PApplet.constrain(minCol, 0, cols);
+ maxCol = PApplet.constrain(maxCol, 0, cols);
+ minRow = PApplet.constrain(minRow, 0, rows);
+ maxRow = PApplet.constrain(maxRow, 0, rows);
+
+ // keep track of what we can see already:
+ Vector visibleKeys = new Vector();
+
+ // grab coords for visible tiles
+ for (int col = minCol; col <= maxCol; col++) {
+ for (int row = minRow; row <= maxRow; row++) {
+
+ // source coordinate wraps around the world:
+ Coordinate coord = provider.sourceCoordinate(new Coordinate(row,col,zoom));
+
+ // let's make sure we still have ints:
+ coord.row = PApplet.round(coord.row);
+ coord.column = PApplet.round(coord.column);
+ coord.zoom = PApplet.round(coord.zoom);
+
+ // keep this for later:
+ visibleKeys.add(coord);
+
+ if (!images.containsKey(coord)) {
+ // fetch it if we don't have it
+ grabTile(coord);
+
+ // see if we have a parent coord for this tile?
+ boolean gotParent = false;
+ for (int i = (int)coord.zoom; i > 0; i--) {
+ Coordinate zoomed = coord.zoomTo(i).container();
+ // make sure we still have ints:
+ zoomed.row = PApplet.round(zoomed.row);
+ zoomed.column = PApplet.round(zoomed.column);
+ zoomed.zoom = PApplet.round(zoomed.zoom);
+ if (images.containsKey(zoomed)) {
+ visibleKeys.add(zoomed);
+ gotParent = true;
+ break;
+ }
+ }
+
+ // or if we have any of the children
+ if (!gotParent) {
+ Coordinate zoomed = coord.zoomBy(1).container();
+ Coordinate[] kids = { zoomed, zoomed.right(), zoomed.down(), zoomed.right().down() };
+ for (Coordinate kid : kids) {
+ zoomed = kid;
+ // make sure we still have ints:
+ zoomed.row = PApplet.round(zoomed.row);
+ zoomed.column = PApplet.round(zoomed.column);
+ zoomed.zoom = PApplet.round(zoomed.zoom);
+ if (images.containsKey(zoomed)) {
+ visibleKeys.add(zoomed);
+ }
+ }
+ }
+
+ }
+
+ } // rows
+ } // columns
+
+ // sort by zoom so we draw small zoom levels (big tiles) first:
+ Collections.sort(visibleKeys, zoomComparator);
+
+ if (visibleKeys.size() > 0) {
+ Coordinate previous = visibleKeys.get(0);
+ img.pushMatrix();
+ // correct the scale for this zoom level:
+ img.scale(1.0f/ PApplet.pow(2, previous.zoom));
+ for (int i = 0; i < visibleKeys.size(); i++) {
+ Coordinate coord = visibleKeys.get(i);
+
+ if (coord.zoom != previous.zoom) {
+ img.popMatrix();
+ img.pushMatrix();
+ // correct the scale for this zoom level:
+ img.scale(1.0f/ PApplet.pow(2,coord.zoom));
+ }
+
+ if (images.containsKey(coord)) {
+ PImage tile = images.get(coord);
+ img.image(tile,coord.column*TILE_WIDTH,coord.row*TILE_HEIGHT,TILE_WIDTH,TILE_HEIGHT);
+ if (recentImages.contains(tile)) {
+ recentImages.remove(tile);
+ }
+ recentImages.add(tile);
+ }
+ }
+ img.popMatrix();
+ }
+
+ img.popMatrix();
+
+ // stop fetching things we can't see:
+ // (visibleKeys also has the parents and children, if needed, but that shouldn't matter)
+ queue.retainAll(visibleKeys);
+
+ // sort what's left by distance from center:
+ queueSorter.setCenter(new Coordinate( (minRow + maxRow) / 2.0f, (minCol + maxCol) / 2.0f, zoom));
+ Collections.sort(queue, queueSorter);
+
+ // load up to 4 more things:
+ processQueue();
+
+ // clear some images away if we have too many...
+ if (recentImages.size() > MAX_IMAGES_TO_KEEP) {
+ recentImages.subList(0, recentImages.size()-MAX_IMAGES_TO_KEEP).clear();
+ images.values().retainAll(recentImages);
+ }
+
+ // restore image mode
+ img.imageMode(imageMode);
+ img.endDraw();
+ return img;
+ }
+
+ /** @return zoom level of currently visible tile layer */
+ public int getZoom() {
+ return bestZoomForScale((float)sc);
+ }
+
+ public Location getCenter() {
+ return provider.coordinateLocation(getCenterCoordinate());
+ }
+
+ public Coordinate getCenterCoordinate() {
+ float row = (float)(ty*sc/-TILE_WIDTH);
+ float column = (float)(tx*sc/-TILE_HEIGHT);
+ float zoom = zoomForScale((float)sc);
+ return new Coordinate(row, column, zoom);
+ }
+
+ public void setCenter(Coordinate center) {
+ //println("setting center to " + center);
+ sc = p.pow(2.0f, center.zoom);
+ tx = -TILE_WIDTH*center.column/sc;
+ ty = -TILE_HEIGHT*center.row/sc;
+ }
+
+ public void setCenter(Location location) {
+ setCenter(provider.locationCoordinate(location).zoomTo(getZoom()));
+ }
+
+ public void setCenterZoom(Location location, int zoom) {
+ setCenter(provider.locationCoordinate(location).zoomTo(zoom));
+ }
+
+ /** sets scale according to given zoom level, should leave you with pixel perfect tiles */
+ public void setZoom(int zoom) {
+ sc = p.pow(2.0f, zoom);
+ }
+
+ public void zoom(int dir) {
+ sc = p.pow(2.0f, getZoom()+dir);
+ }
+
+ public void zoomIn() {
+ sc = p.pow(2.0f, getZoom()+1);
+ }
+
+ public void zoomOut() {
+ sc = p.pow(2.0f, getZoom()-1);
+ }
+
+ // public function setExtent(extent:MapExtent):void
+ // public function getExtent():MapExtent
/*
protected function coordinatePosition(centerCoord:Coordinate):MapPosition
@@ -309,94 +474,94 @@ public function locationsPosition(locations:Array):MapPosition
protected function extentPosition(extent:MapExtent):MapPosition
*/
- // public function getCenterZoom():Array
-
- public AbstractMapProvider getMapProvider() {
- return this.provider;
- }
-
- public void setMapProvider(AbstractMapProvider provider) {
- if (this.provider.getClass() != provider.getClass()) {
- this.provider = provider;
- images.clear();
- queue.clear();
- pending.clear();
- }
- }
-
- public Point2f locationPoint(Location location) {
- PMatrix2D m = new PMatrix2D();
- m.translate(width/2, height/2);
- m.scale((float)sc);
- m.translate((float)tx, (float)ty);
-
- Coordinate coord = provider.locationCoordinate(location).zoomTo(0);
- float[] out = new float[2];
- m.mult(new float[] {
- coord.column*TILE_WIDTH, coord.row*TILE_HEIGHT }
- , out);
-
- return new Point2f(out[0], out[1]);
- }
-
- public Location pointLocation(Point2f point) {
- return pointLocation(point.x, point.y);
- }
-
- public Location pointLocation(float x, float y) {
-
- // TODO: create this matrix once and keep it around for drawing and projecting
- PMatrix2D m = new PMatrix2D();
- m.translate(width/2, height/2);
- m.scale((float)sc);
- m.translate((float)tx, (float)ty);
-
- // find top left and bottom right positions of map in screenspace:
- float tl[] = new float[2];
- m.mult(new float[] {
- 0,0 }
- , tl);
- float br[] = new float[2];
- m.mult(new float[] {
- TILE_WIDTH, TILE_HEIGHT }
- , br);
-
- float col = (x - tl[0]) / (br[0] - tl[0]);
- float row = (y - tl[1]) / (br[1] - tl[1]);
- Coordinate coord = new Coordinate(row, col, 0);
-
- return provider.coordinateLocation(coord);
- }
-
- // TODO: pan by proportion of screen size, not by coordinate grid
- public void panUp() {
- setCenter(getCenterCoordinate().up());
- }
- public void panDown() {
- setCenter(getCenterCoordinate().down());
- }
- public void panLeft() {
- setCenter(getCenterCoordinate().left());
- }
- public void panRight() {
- setCenter(getCenterCoordinate().right());
- }
-
- public void panAndZoomIn(Location location) {
- // TODO: animate
- setCenterZoom(location, getZoom() + 1);
- }
-
- public void panTo(Location location) {
- // TODO: animate
- setCenter(location);
- }
+ // public function getCenterZoom():Array
+
+ public AbstractMapProvider getMapProvider() {
+ return this.provider;
+ }
+
+ public void setMapProvider(AbstractMapProvider provider) {
+ if (this.provider.getClass() != provider.getClass()) {
+ this.provider = provider;
+ images.clear();
+ queue.clear();
+ pending.clear();
+ }
+ }
+
+ public Point2f locationPoint(Location location) {
+ PMatrix2D m = new PMatrix2D();
+ m.translate(width/2, height/2);
+ m.scale((float)sc);
+ m.translate((float)tx, (float)ty);
+
+ Coordinate coord = provider.locationCoordinate(location).zoomTo(0);
+ float[] out = new float[2];
+ m.mult(new float[] {
+ coord.column*TILE_WIDTH, coord.row*TILE_HEIGHT }
+ , out);
+
+ return new Point2f(out[0], out[1]);
+ }
+
+ public Location pointLocation(Point2f point) {
+ return pointLocation(point.x, point.y);
+ }
+
+ public Location pointLocation(float x, float y) {
+
+ // TODO: create this matrix once and keep it around for drawing and projecting
+ PMatrix2D m = new PMatrix2D();
+ m.translate(width/2, height/2);
+ m.scale((float)sc);
+ m.translate((float)tx, (float)ty);
+
+ // find top left and bottom right positions of map in screenspace:
+ float tl[] = new float[2];
+ m.mult(new float[] {
+ 0,0 }
+ , tl);
+ float br[] = new float[2];
+ m.mult(new float[] {
+ TILE_WIDTH, TILE_HEIGHT }
+ , br);
+
+ float col = (x - tl[0]) / (br[0] - tl[0]);
+ float row = (y - tl[1]) / (br[1] - tl[1]);
+ Coordinate coord = new Coordinate(row, col, 0);
+
+ return provider.coordinateLocation(coord);
+ }
+
+ // TODO: pan by proportion of screen size, not by coordinate grid
+ public void panUp() {
+ setCenter(getCenterCoordinate().up());
+ }
+ public void panDown() {
+ setCenter(getCenterCoordinate().down());
+ }
+ public void panLeft() {
+ setCenter(getCenterCoordinate().left());
+ }
+ public void panRight() {
+ setCenter(getCenterCoordinate().right());
+ }
+
+ public void panAndZoomIn(Location location) {
+ // TODO: animate
+ setCenterZoom(location, getZoom() + 1);
+ }
+
+ public void panTo(Location location) {
+ // TODO: animate
+ setCenter(location);
+ }
/*
public function putMarker(location:Location, marker:DisplayObject=null):void
public function getMarker(id:String):DisplayObject
public function removeMarker(id:String):void
-
+
public function setCopyright(copyright:String):void {
*/
@@ -404,141 +569,141 @@ public function setCopyright(copyright:String):void {
public function onStartZoom():void
public function onStopZoom():void
public function onZoomed(delta:Number):void
-
+
public function onStartPan():void
public function onStopPan():void
public function onPanned(delta:Point):void
-
+
public function onResized():void
-
+
public function onExtentChanged(extent:MapExtent):void
*/
- ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
- public float scaleForZoom(int zoom) {
- return p.pow(2.0f, zoom);
- }
-
- public float zoomForScale(float scale) {
- return p.log(scale) / p.log(2);
- }
+ public float scaleForZoom(int zoom) {
+ return p.pow(2.0f, zoom);
+ }
- public int bestZoomForScale(float scale) {
- return (int)p.min(20, p.max(1, (int)p.round(p.log(scale) / p.log(2))));
- }
+ public float zoomForScale(float scale) {
+ return p.log(scale) / p.log(2);
+ }
- //////////////////////////////////////////////////////////////////////////
+ public int bestZoomForScale(float scale) {
+ return (int)p.min(20, p.max(1, (int)p.round(p.log(scale) / p.log(2))));
+ }
- public void mouseDragged() {
- double dx = (double)(p.mouseX - p.pmouseX) / sc;
- double dy = (double)(p.mouseY - p.pmouseY) / sc;
- // float angle = radians(-a);
- // float rx = cos(angle)*dx - sin(angle)*dy;
- // float ry = sin(angle)*dx + cos(angle)*dy;
- // tx += rx;
- // ty += ry;
- tx += dx;
- ty += dy;
- }
+ //////////////////////////////////////////////////////////////////////////
+
+ public void mouseDragged() {
+ double dx = (double)(p.mouseX - p.pmouseX) / sc;
+ double dy = (double)(p.mouseY - p.pmouseY) / sc;
+ // float angle = radians(-a);
+ // float rx = cos(angle)*dx - sin(angle)*dy;
+ // float ry = sin(angle)*dx + cos(angle)*dy;
+ // tx += rx;
+ // ty += ry;
+ tx += dx;
+ ty += dy;
+ }
- /////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////
- public void grabTile(Coordinate coord) {
- if (!pending.containsKey(coord) && !queue.contains(coord) && !images.containsKey(coord)) {
- // println("adding " + coord.toString() + " to queue");
- queue.add(coord);
+ public void grabTile(Coordinate coord) {
+ if (!pending.containsKey(coord) && !queue.contains(coord) && !images.containsKey(coord)) {
+ // println("adding " + coord.toString() + " to queue");
+ queue.add(coord);
+ }
}
- }
- public class TileLoader implements Runnable {
- Coordinate coord;
- TileLoader(Coordinate coord) {
- this.coord = coord;
+ public class TileLoader implements Runnable {
+ Coordinate coord;
+ TileLoader(Coordinate coord) {
+ this.coord = coord;
+ }
+ public void run() {
+ String[] urls = provider.getTileUrls(coord);
+ PImage img = p.loadImage(urls[0]); // use unknown to let loadImage decide
+ if (img != null) {
+ for (int i = 1; i < urls.length; i++) {
+ PImage img2 = p.loadImage(urls[i]);
+ if (img2 != null) {
+ img.blend(img2, 0, 0, img.width, img.height, 0, 0, img.width, img.height, BLEND);
+ }
+ }
+ }
+ tileDone(coord, img);
+ }
}
- public void run() {
- String[] urls = provider.getTileUrls(coord);
- PImage img = p.loadImage(urls[0], "unknown"); // use unknown to let loadImage decide
- if (img != null) {
- for (int i = 1; i < urls.length; i++) {
- PImage img2 = p.loadImage(urls[i], "unknown");
- if (img2 != null) {
- img.blend(img2, 0, 0, img.width, img.height, 0, 0, img.width, img.height, BLEND);
- }
+
+ // TODO: there could be issues when this is called from within a thread
+ // probably needs synchronizing on images / pending / queue
+ public void tileDone(Coordinate coord, PImage img) {
+ // check if we're still waiting for this (new provider clears pending)
+ // also check if we got something
+ if (pending.containsKey(coord) && img != null) {
+ // p.println("got " + coord + " image");
+ images.put(coord, img);
+ pending.remove(coord);
}
- }
- tileDone(coord, img);
- }
- }
-
- // TODO: there could be issues when this is called from within a thread
- // probably needs synchronizing on images / pending / queue
- public void tileDone(Coordinate coord, PImage img) {
- // check if we're still waiting for this (new provider clears pending)
- // also check if we got something
- if (pending.containsKey(coord) && img != null) {
- // p.println("got " + coord + " image");
- images.put(coord, img);
- pending.remove(coord);
- }
- else {
- // p.println("failed to get " + coord + " image");
- // if (img == null) {
- // p.println("but got a null one");
- // }
- // try again?
- // but this is a bit risky, TODO: keep track of attempts
- queue.add(coord);
- pending.remove(coord);
- }
- }
-
- public void processQueue() {
- while (pending.size() < MAX_PENDING && queue.size() > 0) {
- Coordinate coord = (Coordinate)queue.remove(0);
- TileLoader tileLoader = new TileLoader(coord);
- pending.put(coord, tileLoader);
- new Thread(tileLoader).start();
- }
- }
-
- public class QueueSorter implements Comparator {
- Coordinate center;
- public void setCenter(Coordinate center) {
- this.center = center;
- }
- public int compare(Object o1, Object o2) {
- Coordinate c1 = (Coordinate)o1;
- Coordinate c2 = (Coordinate)o2;
- if (c1.zoom == center.zoom) {
- if (c2.zoom == center.zoom) {
- float d1 = p.dist(center.column, center.row, c1.column, c1.row);
- float d2 = p.dist(center.column, center.row, c2.column, c2.row);
- return d1 < d2 ? -1 : d1 > d2 ? 1 : 0;
- }
else {
- return -1;
+ // p.println("failed to get " + coord + " image");
+ // if (img == null) {
+ // p.println("but got a null one");
+ // }
+ // try again?
+ // but this is a bit risky, TODO: keep track of attempts
+ queue.add(coord);
+ pending.remove(coord);
+ }
+ }
+
+ public void processQueue() {
+ while (pending.size() < MAX_PENDING && queue.size() > 0) {
+ Coordinate coord = queue.remove(0);
+ TileLoader tileLoader = new TileLoader(coord);
+ pending.put(coord, tileLoader);
+ new Thread(tileLoader).start();
+ }
+ }
+
+ public class QueueSorter implements Comparator {
+ Coordinate center;
+ public void setCenter(Coordinate center) {
+ this.center = center;
}
- }
- else if (c2.zoom == center.zoom) {
- return 1;
- }
- else {
- float d1 = p.abs(c1.zoom - center.zoom);
- float d2 = p.abs(c2.zoom - center.zoom);
- return d1 < d2 ? -1 : d1 > d2 ? 1 : 0;
- }
- }
- }
-
- public class ZoomComparator implements Comparator {
- public int compare(Object o1, Object o2) {
- Coordinate c1 = (Coordinate)o1;
- Coordinate c2 = (Coordinate)o2;
- return c1.zoom < c2.zoom ? -1 : c1.zoom > c2.zoom ? 1 : 0;
- }
- }
+ public int compare(Object o1, Object o2) {
+ Coordinate c1 = (Coordinate)o1;
+ Coordinate c2 = (Coordinate)o2;
+ if (c1.zoom == center.zoom) {
+ if (c2.zoom == center.zoom) {
+ float d1 = p.dist(center.column, center.row, c1.column, c1.row);
+ float d2 = p.dist(center.column, center.row, c2.column, c2.row);
+ return d1 < d2 ? -1 : d1 > d2 ? 1 : 0;
+ }
+ else {
+ return -1;
+ }
+ }
+ else if (c2.zoom == center.zoom) {
+ return 1;
+ }
+ else {
+ float d1 = p.abs(c1.zoom - center.zoom);
+ float d2 = p.abs(c2.zoom - center.zoom);
+ return d1 < d2 ? -1 : d1 > d2 ? 1 : 0;
+ }
+ }
+ }
+
+ public class ZoomComparator implements Comparator {
+ public int compare(Object o1, Object o2) {
+ Coordinate c1 = (Coordinate)o1;
+ Coordinate c2 = (Coordinate)o2;
+ return c1.zoom < c2.zoom ? -1 : c1.zoom > c2.zoom ? 1 : 0;
+ }
+ }
}
diff --git a/src/com/modestmaps/StaticMap.java b/src/com/modestmaps/StaticMap.java
old mode 100644
new mode 100755
index f66bb47..9447b56
--- a/src/com/modestmaps/StaticMap.java
+++ b/src/com/modestmaps/StaticMap.java
@@ -222,7 +222,7 @@ public PImage render_tiles(TileQueue tiles, int img_width, int img_height, boole
// # hang around until they are loaded or we run out of time...
// time.sleep(1)
- PGraphics mapImg = parent.createGraphics(img_width, img_height, PApplet.JAVA2D);
+ PGraphics mapImg = parent.createGraphics(img_width, img_height);
mapImg.beginDraw();
for (int i = 0; i < tiles.size(); i++) {
@@ -400,7 +400,6 @@ public void load(boolean verbose, int attempt) {
}
-
public class TileQueue extends Vector {
// List of TileRequest objects, that's sensitive to when they're loaded.
public boolean pending() {
@@ -412,6 +411,4 @@ public boolean pending() {
return false;
}
}
-
-
}
diff --git a/src/com/modestmaps/core/Coordinate.java b/src/com/modestmaps/core/Coordinate.java
old mode 100644
new mode 100755
diff --git a/src/com/modestmaps/core/MapCenter.java b/src/com/modestmaps/core/MapCenter.java
old mode 100644
new mode 100755
diff --git a/src/com/modestmaps/core/Point2f.java b/src/com/modestmaps/core/Point2f.java
old mode 100644
new mode 100755
diff --git a/src/com/modestmaps/geo/AbstractProjection.java b/src/com/modestmaps/geo/AbstractProjection.java
old mode 100644
new mode 100755
diff --git a/src/com/modestmaps/geo/LinearProjection.java b/src/com/modestmaps/geo/LinearProjection.java
old mode 100644
new mode 100755
diff --git a/src/com/modestmaps/geo/Location.java b/src/com/modestmaps/geo/Location.java
old mode 100644
new mode 100755
diff --git a/src/com/modestmaps/geo/MercatorProjection.java b/src/com/modestmaps/geo/MercatorProjection.java
old mode 100644
new mode 100755
diff --git a/src/com/modestmaps/geo/Transformation.java b/src/com/modestmaps/geo/Transformation.java
old mode 100644
new mode 100755
diff --git a/src/com/modestmaps/package.html b/src/com/modestmaps/package.html
old mode 100644
new mode 100755
diff --git a/src/com/modestmaps/providers/AbstractMapProvider.java b/src/com/modestmaps/providers/AbstractMapProvider.java
old mode 100644
new mode 100755
diff --git a/src/com/modestmaps/providers/Microsoft.java b/src/com/modestmaps/providers/Microsoft.java
old mode 100644
new mode 100755
diff --git a/src/com/modestmaps/providers/Yahoo.java b/src/com/modestmaps/providers/Yahoo.java
old mode 100644
new mode 100755