Rotate Image Marker on an Unfolding map
in
Contributed Library Questions
•
4 months ago
I just got started using Unfolding and am excited at the possibilities. My first project is to map a GPS log over a map, with an arrow PNG image file that rotates based on the GPS direction.
Without rotation, the icon displays correctly on the map. With rotation however, the pivot point of rotation appears to be the in upper left corner of the screen. I know from lots of Googling that you can use transform() and an image location of (0,0) to hack around this.
However, I've found that when dealing with an Unfolding Map that translate() has no effect on the pivot point. It merely shifts the pivot point that many pixels, with the icon still way out from the center of rotation. The icon's distance from the pivot point seems to be about half the map's height and width.
Obviously I'm doing something wrong here. Here's my stripped down code below, using the ImageMarker class I found online. I would like for it rotate the icon in place on the map center. If I comment out the rotate(), it shows up at the map center.
Thanks for any insight!
---
import processing.core.PApplet;
import processing.core.PGraphics;
import processing.core.PImage;
import codeanticode.glgraphics.GLConstants;
import de.fhpotsdam.unfolding.UnfoldingMap;
import de.fhpotsdam.unfolding.geo.Location;
import de.fhpotsdam.unfolding.marker.AbstractMarker;
import de.fhpotsdam.unfolding.providers.OpenStreetMap;
public class GPSMap extends PApplet {
//public class HelloUnfoldingWorld extends PShape {
UnfoldingMap map;
String CAR_ICON_FILE = "http://www.blueskybust.com/gpsicon-north.png";
int MAP_WIDTH_HEIGHT = 800;
float TEST_LAT = 44.95f;
float TEST_LON = -93.55f;
public void setup() {
size(MAP_WIDTH_HEIGHT, MAP_WIDTH_HEIGHT, GLConstants.GLGRAPHICS);
background(0);
map = new UnfoldingMap(this, new OpenStreetMap.OpenStreetMapProvider());
map.zoomAndPanTo(new Location(TEST_LAT, TEST_LON), 5);
PImage carimage = loadImage(CAR_ICON_FILE);
ImageMarker carMarker = new ImageMarker(new Location(TEST_LAT, TEST_LON), carimage); // Just to initialize
map.addMarkers(carMarker);
}
public void draw() {
background(0);
map.draw();
}
public class ImageMarker extends AbstractMarker {
PImage img;
int testheading = 0;
public ImageMarker(Location location, PImage img) {
super(location);
this.img = img;
}
@Override
public void draw(PGraphics pg, float x, float y) {
testheading = testheading + 1;
pg.pushMatrix();
pg.rotateZ((float)Math.toRadians(testheading));
//pg.rotate((float)Math.toRadians(testheading)); // Same result as rotateZ
pg.image(img, x, y);
pg.popMatrix();
}
@Override
protected boolean isInside(float checkX, float checkY, float x, float y) {
return checkX > x && checkX < x + img.width && checkY > y && checkY < y + img.height;
}
}
}
Without rotation, the icon displays correctly on the map. With rotation however, the pivot point of rotation appears to be the in upper left corner of the screen. I know from lots of Googling that you can use transform() and an image location of (0,0) to hack around this.
However, I've found that when dealing with an Unfolding Map that translate() has no effect on the pivot point. It merely shifts the pivot point that many pixels, with the icon still way out from the center of rotation. The icon's distance from the pivot point seems to be about half the map's height and width.
Obviously I'm doing something wrong here. Here's my stripped down code below, using the ImageMarker class I found online. I would like for it rotate the icon in place on the map center. If I comment out the rotate(), it shows up at the map center.
Thanks for any insight!
---
import processing.core.PApplet;
import processing.core.PGraphics;
import processing.core.PImage;
import codeanticode.glgraphics.GLConstants;
import de.fhpotsdam.unfolding.UnfoldingMap;
import de.fhpotsdam.unfolding.geo.Location;
import de.fhpotsdam.unfolding.marker.AbstractMarker;
import de.fhpotsdam.unfolding.providers.OpenStreetMap;
public class GPSMap extends PApplet {
//public class HelloUnfoldingWorld extends PShape {
UnfoldingMap map;
String CAR_ICON_FILE = "http://www.blueskybust.com/gpsicon-north.png";
int MAP_WIDTH_HEIGHT = 800;
float TEST_LAT = 44.95f;
float TEST_LON = -93.55f;
public void setup() {
size(MAP_WIDTH_HEIGHT, MAP_WIDTH_HEIGHT, GLConstants.GLGRAPHICS);
background(0);
map = new UnfoldingMap(this, new OpenStreetMap.OpenStreetMapProvider());
map.zoomAndPanTo(new Location(TEST_LAT, TEST_LON), 5);
PImage carimage = loadImage(CAR_ICON_FILE);
ImageMarker carMarker = new ImageMarker(new Location(TEST_LAT, TEST_LON), carimage); // Just to initialize
map.addMarkers(carMarker);
}
public void draw() {
background(0);
map.draw();
}
public class ImageMarker extends AbstractMarker {
PImage img;
int testheading = 0;
public ImageMarker(Location location, PImage img) {
super(location);
this.img = img;
}
@Override
public void draw(PGraphics pg, float x, float y) {
testheading = testheading + 1;
pg.pushMatrix();
pg.rotateZ((float)Math.toRadians(testheading));
//pg.rotate((float)Math.toRadians(testheading)); // Same result as rotateZ
pg.image(img, x, y);
pg.popMatrix();
}
@Override
protected boolean isInside(float checkX, float checkY, float x, float y) {
return checkX > x && checkX < x + img.width && checkY > y && checkY < y + img.height;
}
}
}
1