OSM get current map perspective - java

I'm wondering how to get my current camera perspective in an OSM map. I want to save my current camera perspective so that when I refresh the map (with mapView.invalidate()), it will go back to where I was before the refresh (zoom level and latitude/longitude). Right now, I'm only going back to a default location, which is not what I want. I've been searching for a while to no avail, any help is appreciated.
I currently have an update() method which, when called, attempts to reset the zoom level:
void update(boolean zoomToFit) {
if(selectedStop != null) {
new GetBusInfo().execute(selectedStop);
selectedBus = null;
}
busLocnOverlay.removeAllItems();
mapView.invalidate();
Log.d(LOG_TAG, "update - ZOOM_TO_SPAN1: " + ZOOM_TO_SPAN_1);
if (ZOOM_TO_SPAN_1 != 0 && ZOOM_TO_SPAN_2 != 0)
mapView.getController().zoomToSpan(ZOOM_TO_SPAN_1, ZOOM_TO_SPAN_2);
}
It's currently not working, which leads me to think that there's something else responsible for setting the zoom level. ZOOM_TO_SPAN1/2 are set when I plot objects onto the map - the code snippet is quite long so I won't put all of it, but it basically looks like this:
private void plotBuses(boolean zoomToFit) {
// bunch of stuff here
for (GeoPoint p : points) {
int lat = p.getLatitudeE6();
int lon = p.getLongitudeE6();
maxLat = Math.max(lat, maxLat);
minLat = Math.min(lat, minLat);
maxLon = Math.max(lon, maxLon);
minLon = Math.min(lon, minLon);
}
mapController.zoomToSpan(Math.abs(maxLat - minLat), Math.abs(maxLon - minLon));
mapController.animateTo(new GeoPoint( (maxLat + minLat)/2, (maxLon + minLon)/2 ));
ZOOM_TO_SPAN_1 = Math.abs(maxLat - minLat);
ZOOM_TO_SPAN_2 = Math.abs(maxLon - minLon);
}
}

Related

new items destroy layout of grid

By refreshing the items within a grid sometimes it happen that the grid shows completely crazy:
That's how I update the data every time. The instance of the Grid stays the same:
dataProvider = new ListDataProvider<>(newItems);
grid.setItems(dataProvider);
Does someone have an idea whether I do something wrong or there is a bug within Vaadin?
Complete code:
if (!columnsIntialized) {
for (Method method : gridProperties) {
Column<T> column = grid.addColumn(data -> {
Object value = method.invoke(data);
return getFormattedValue(value, method.getReturnType());
});
String resourceKey = method.getDeclaredAnnotation(GridProperties.class).resourceKey();
column.setKey(resourceKey);
column.setHeader(AppResources.getString(resourceKey));
int width = method.getDeclaredAnnotation(GridProperties.class).width();
if (width == -1) {
column.setAutoWidth(true);
} else {
column.setWidth(width + "px");
}
}
columnsIntialized = true;
}
dataProvider = new ListDataProvider<>(items);
grid.setItems(dataProvider);
grid.recalculateColumnWidths();
Vaadin 22.0.3 is scheduled to be released on Monday with the fix.

Spring-hibernate debug

I have a very strange problem. I'm trying to show in a basket the price of products. When I run the code and add a product to the basket, I can see the name of the product but I can't see its price. When I click back to a previous page and add another product, I am able to see its price. There is no error message.
Also, when I try to debug this program, everything works. The problem appears only when I'm not debugging. The problem is closely connected with these two variables as indicated below. I think that these variables are 0 which is later printed on the screen. But I don't know why they are sometimes 0 and sometimes not. I also tried to set breakpoints on:
dataService.getQuantityOfDays();
dataService.getQuantityOfBreakfasts();
When I assign values to these two variables in Data class everything is ok (not 0).
Controller code:
#RequestMapping("/basket/{roomName}")
public String createBasket(Model model, #PathVariable("roomName") String roomName){
Floor currentFloor = floorService.getCurrentFloor();
User currentUser = userService.getCurrentUser();
this.roomName = roomName;
if(currentFloor != null){
Room currentRoom = roomService.getRoomByName(roomName, currentFloor);
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName();
if(currentUser == null){
userService.setCurrentUser(userService.getUserByName(name)); // wykona sie jesli nie zakladamy konta w danej sesji
}
Basket basketToSave = new Basket(userService.getCurrentUser());
BasketItem basketItem = new BasketItem(currentRoom);
int quantityOfDays = dataService.getQuantityOfDays(); //<--problem
int quantityOfBreakfast = dataService.getQuantityOfBreakfasts(); //<--problem
int priceForOneBreakfast = 17;
int priceForOneDay = currentRoom.getPriceForOneDay();
int wholePrice = quantityOfDays * priceForOneDay + quantityOfBreakfast * priceForOneBreakfast;
basketItem.setPrice(wholePrice);
basketItem.setQuantityOfDays(quantityOfDays);
basketItem.setQuantityOfBreakfast(quantityOfBreakfast);
Set<BasketItem> basketItemList = new HashSet<BasketItem>();
basketItemList.add(basketItem);
basketService.countBasketPrice(basketItemList, basketToSave);
basketToSave.setBasketItems(basketItemList);
basketItem.setBasket(basketToSave);
currentRoom.setBasketItemList(basketItemList);
boolean ifWasAnUpdate = basketService.save(basketToSave); // metoda save oprócz zapisu lub nadpisania zwraca co się wydarzyło (true - jesli nadpisywaliśmy koszyk)
if(ifWasAnUpdate){
basketItem.setBasket(basketService.get(basketToSave.getUser())); // jeżeli dodaje coś do koszyka (a nie tworzę go od nowa), muszę ustawić basketItemowi
} // koszyk, który już istnieje, a nie ten, który stworzyłem wcześniej w klasie BasketController.
// W tym celu pobieram go z bazy.
basketItemService.save(basketItem);
}
model.addAttribute("basket", basketService.get(currentUser));
model.addAttribute("days", dataService.getQuantityOfDays());
return "basket";
}
EDIT:
It's a repository code.
#Repository
public class DataRepositoryImpl implements DataRepository {
private int quantityOfDays;
private int quantityOfBreakfasts;
public void setQuantityOfDaysAndBreakfasts(String text) {
List<Integer> listOfIndexes = new ArrayList<Integer>();
for(int i=0;i<text.length();i++){
if(text.charAt(i) != '1'){
listOfIndexes.add(i);
}
}
char znak = text.charAt(listOfIndexes.get(0));
this.quantityOfDays = Character.getNumericValue(text.charAt(listOfIndexes.get(0))); // <- I put breakpoint here
this.quantityOfBreakfasts = Character.getNumericValue(text.charAt(listOfIndexes.get(1))); // <- I put breakpoint here
}
public int getQuantityOfDays() {
return this.quantityOfDays;
}
public int getQuantityOfBreakfasts() {
return this.quantityOfBreakfasts;
}
}
A problem can be also in basket save. Firslty when I can see only zeros I persist basket, then I'm only updating it.
Save & update methods:
public boolean save(Basket basketToSave) {
List<Basket> listOfAllBaskets = getAll();
boolean save = true;
boolean ifWasAnUpdate = false;
for(Basket basket: listOfAllBaskets){
if(basketToSave.getUser().equals(basket.getUser())){
save = false;
}
}
if(save){
emManager.persist(basketToSave);
}else{
updateBasket(basketToSave);
ifWasAnUpdate = true;
}
return ifWasAnUpdate;
}
public void updateBasket(Basket basket) {
Basket basketFromDatabase = get(basket.getUser());
basketFromDatabase.setBasketItems(basket.getBasketItems());
basketFromDatabase.setPrice(basket.getPrice());
emManager.merge(basketFromDatabase);
}
EDIT
I'm calling setQuantityOfDaysAndBreakfasts(text) earlier in this apllication. In this controller I'm only setting these values to basketItem class. I'll change this controller. Here another controller where I call setQuantityOfDaysAndBreakfasts(text).
#RequestMapping(value = "/room/rest", method = RequestMethod.POST, consumes = {"application/json"})
public void data(#RequestBody Data request){
String text = request.getText();
dataService.setQuantityOfDaysAndBreakfasts(text);
}
You are calling setQuantityOfDaysAndBreakfasts() after you get the value from your dataService. The value for quantityOfDays and quantityOfBreakfasts are only set when that method is called.
There are several things you should also examine.
As #NathanHughes points out, it's best to put your complex logic in your service layer and leave the controller to simply route requests. This is also true of your repository class. You should keep this very simple as the next developer reading your code is not going to expect to find any logic that doesn't simply read or write to your data source. (See Single Responsibility Principle.) It will also reduce code duplication in the future and as a result, reduce your time maintaining and fixing bugs.
For example, this code:
List<Integer> listOfIndexes = new ArrayList<Integer>();
for(int i=0;i<text.length();i++){
if(text.charAt(i) != '1'){
listOfIndexes.add(i);
}
}
char znak = text.charAt(listOfIndexes.get(0));
Should be refactored to a separate method entirely that can be made static and would not belong in that class.

Why does the spaceship not appear?

I use jmonkeyengine and I downloaded a spaceship model from blendswap and converted it to j3o to load it with jmonkeyengine for a space scene where I can control the ship and travel around. However the spaceship is not loaded. The space and planets appear but I want the spaceship to be what the player controls and not first-person like it appears.
I expect the spaceship to appear because I load it without errors and add it to the scene but it stil doesn't show.
//add saucer
ufoNode = (Node) assetManager
.loadModel("usaucer_v01.j3o");
rootNode.attachChild(ufoNode);
What should I do to make the spaceship appear? The program is
public class PlanetSimpleTest extends SimpleApplication {
private PlanetAppState planetAppState;
private Geometry mark;
private Node ufoNode;
private GameCharControl ufoControl;
Camera cam2;
public static void main(String[] args){
AppSettings settings = new AppSettings(true);
settings.setResolution(1024,768);
PlanetSimpleTest app = new PlanetSimpleTest();
app.setSettings(settings);
//app.showSettings = true;
app.start();
}
#Override
public void simpleInitApp() {
// Only show severe errors in log
java.util.logging.Logger.getLogger("com.jme3").setLevel(java.util.logging.Level.SEVERE);
// Toggle mouse cursor
inputManager.addMapping("TOGGLE_CURSOR",
new MouseButtonTrigger(MouseInput.BUTTON_LEFT),
new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(actionListener, "TOGGLE_CURSOR");
// Toggle wireframe
inputManager.addMapping("TOGGLE_WIREFRAME",
new KeyTrigger(KeyInput.KEY_T));
inputManager.addListener(actionListener, "TOGGLE_WIREFRAME");
// Collision test
inputManager.addMapping("COLLISION_TEST",
new MouseButtonTrigger(MouseInput.BUTTON_RIGHT));
inputManager.addListener(actionListener, "COLLISION_TEST");
// Setup camera
// In orbit
this.getCamera().setLocation(new Vector3f(0f, 0f, 180000f));
// On surface
//this.getCamera().setLocation(new Vector3f(-6657.5254f, 27401.822f, 57199.777f));
//this.getCamera().lookAtDirection(new Vector3f(0.06276598f, 0.94458306f, -0.3222158f), Vector3f.UNIT_Y);
// Add sun
//PointLight sun = new PointLight();
//sun.setPosition(new Vector3f(-100000f,0,180000f));
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-.1f, 0f, -1f));
sun.setColor(new ColorRGBA(0.75f,0.75f,0.75f,1.0f));
rootNode.addLight(sun);
// Add sky
Node sceneNode = new Node("Scene");
sceneNode.attachChild(Utility.createSkyBox(this.getAssetManager(), "Textures/blue-glow-1024.dds"));
rootNode.attachChild(sceneNode);
// Create collision test mark
Sphere sphere = new Sphere(30, 30, 5f);
mark = new Geometry("mark", sphere);
Material mark_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mark_mat.setColor("Color", ColorRGBA.Red);
mark.setMaterial(mark_mat);
// Add planet app state
planetAppState = new PlanetAppState(rootNode, sun);
stateManager.attach(planetAppState);
// Add planet
FractalDataSource planetDataSource = new FractalDataSource(4);
planetDataSource.setHeightScale(900f);
Planet planet = Utility.createEarthLikePlanet(getAssetManager(), 63710.0f, null, planetDataSource);
planetAppState.addPlanet(planet);
rootNode.attachChild(planet);
// Add moon
FractalDataSource moonDataSource = new FractalDataSource(5);
moonDataSource.setHeightScale(300f);
Planet moon = Utility.createMoonLikePlanet(getAssetManager(), 20000, moonDataSource);
planetAppState.addPlanet(moon);
rootNode.attachChild(moon);
moon.setLocalTranslation(-150000f, 0f, 0f);
//add saucer
ufoNode = (Node) assetManager
.loadModel("usaucer_v01.j3o");
ufoNode.setLocalScale(100f);
rootNode.attachChild(ufoNode);
}
#Override
public void simpleUpdate(float tpf) {
// slow camera down as we approach a planet
Planet planet = planetAppState.getNearestPlanet();
if (planet != null && planet.getPlanetToCamera() != null) {
this.getFlyByCamera().setMoveSpeed(
FastMath.clamp(planet.getDistanceToCamera(), 100, 100000));
}
}
private ActionListener actionListener = new ActionListener(){
public void onAction(String name, boolean pressed, float tpf){
if (name.equals("TOGGLE_CURSOR") && !pressed) {
if (inputManager.isCursorVisible()) {
inputManager.setCursorVisible(false);
} else {
inputManager.setCursorVisible(true);
}
}
if (name.equals("TOGGLE_WIREFRAME") && !pressed) {
for (Planet planet: planetAppState.getPlanets()) {
planet.toogleWireframe();
}
}
if (name.equals("COLLISION_TEST") && !pressed) {
CollisionResults results = new CollisionResults();
Ray ray = new Ray(cam.getLocation(), cam.getDirection());
// Test collision with closest planet's terrain only
planetAppState.getNearestPlanet().getTerrainNode().collideWith(ray, results);
System.out.println("----- Collisions? " + results.size() + "-----");
for (int i = 0; i < results.size(); i++) {
// For each hit, we know distance, impact point, name of geometry.
float dist = results.getCollision(i).getDistance();
Vector3f pt = results.getCollision(i).getContactPoint();
String hit = results.getCollision(i).getGeometry().getName();
System.out.println("* Collision #" + i);
System.out.println(" You shot " + hit + " at " + pt + ", " + dist + " wu away.");
}
if (results.size() > 0) {
// The closest collision point is what was truly hit:
CollisionResult closest = results.getClosestCollision();
// Let's interact - we mark the hit with a red dot.
mark.setLocalTranslation(closest.getContactPoint());
rootNode.attachChild(mark);
} else {
// No hits? Then remove the red mark.
rootNode.detachChild(mark);
}
}
}
};
}
The spaceship I took from here and converted to jme3:s binary format j3o and added to the game, but I'm obviously not doing everything to make it appear in the scene. I've gotten this far in the jmonkeyengine IDE but then when I load it in Eclipse it doesn't work so I'm trying to create the scene with the jmonkeyengine IDE first.
I then try and create a scene with the spaceship but I get an Exception in the JME SDK.
After adding the lines
ufoNode.setLocalScale(300f);
ufoNode.setLocalTranslation((new Vector3f(10f, 10f, 180010f)));
the spaceship does appear but maybe not perfect. Can it be improved?
Update 140104 17:54 CET
It seems the spaceship was upside down(?) so I've rotated it now.
//add saucer
ufoNode = (Node) assetManager.loadModel("usaucer_v01.j3o");
ufoNode.setLocalScale(1000f);
ufoNode.setLocalTranslation((new Vector3f(10f, 10f, 165000f)));
/* This quaternion stores a 180 degree rolling rotation */
Quaternion roll180 = new Quaternion();
roll180.fromAngleAxis(FastMath.PI , new Vector3f(0,0,1));
/* The rotation is applied: The object rolls by 180 degrees. */
ufoNode.setLocalRotation(roll180);
rootNode.attachChild(ufoNode);
You add the spaceship at 0,0,0 (as you don't move it) but have moved your camera to 0f, 0f, 180000f. Most likely it is out of shot or far too small to see.
Try loading the spaceship within the jME SDK and confirm that it works within the engine using the scene editor there.
If that works then try a simple test scene just dropping the spaceship and camera in - then once that works move a step at a time towards your desired setting.

Android using SharedPreferences

I found out a common way to store data is Android's SharedPreferences. So I went out and tried to implement it with my application.
What I want to do:
My application retrieves weather details from the users current location, if the user desires he/she can add the location by pressing add to favorites. They can have up to 10 favorite locations. So I want to store the location description (exp: Dayton, OH), the latitude and longitude (So I may fetch the details when they want to see that weather). So Shared Preferences seem to fit my need.
What I did:
- I created a loop that would cycle through 10 keys (for 10 locations) an as long as the keys were null the location information would be saved. If the key was not null, it means the key has already been created.
My code:
public void writeNewLocation(String stringLat, String stringLon, String location) {
this.latitude = stringLat;
this.longitude = stringLon;
this.location = location;
pref = mContext.getSharedPreferences("favoritelocations", 0); // 0 - for private mode
Editor editor = pref.edit();
//Loop through all the favorite keys to find an open spot:
for(int i = 1; i <= 10; i++) {
//Test for current favorite key:
String value = pref.getString("favorite"+ i +"_location",null);
if (value == null) {
//The key does not exist so it can be created and written to:
//First write the location description:
editor.putString("favorite" + i + "_location", location);
//Next the write the latitude and lonitude values:
editor.putString("favorite" + i + "_latitude", latitude);
editor.putString("favorite" + i + "_longitude", longitude);
editor.commit();
i = 11;
} else {
//If at end of loop; Inform user:
if(i == 10) {
//Display an error:
//Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
//Create the AlertDialog characteristics:
builder.setMessage("You can only have up to 10 favorite locations. Delete some to make room.");
builder.setTitle("Message");
//Show the AlertDialog:
msgDialog = builder.create();
editor.commit();
i = 11;
} else {
//Back to top of loop.
}
}
}
//Commit to changes:
editor.commit(); // commit changes
}
So I loop through ten possible keys, if it hits 10, and all spots are taken, I alert the user. But when I call this method to create a favorite location, then call 1 of the 10 getters to display the information that should've been saved, I get a null. :( Is it too early in the morning over here or am I doing something wrong...
Thanks c:

SWT StyledText getCaretOffset giving wrong line number

I'm trying to make the bullet of active line have a highlighted background. I'm using
int activeLine = styledText.getLineAtOffset(styledText.getCaretOffset());
To get the like that is currently active. This seems to work except when I hit enter and get a new line.
getCaretOffset returns 35 and getCharCount returns 36.
However, if I click on the last line (for now I call redraw() on clicks) the line highlights correctly and getCaretOffset returns 36.
Here is the relevant code
public void lineGetStyle(LineStyleEvent event) {
// Set the line number
int activeLine = styledText.getLineAtOffset(styledText.getCaretOffset());
System.out.println("Offset " + styledText.getCaretOffset() + " max " + styledText.getCharCount());
int currentLine = styledText.getLineAtOffset(event.lineOffset);
event.bulletIndex = currentLine;
// Set the style, 12 pixles wide for each digit
StyleRange style = new StyleRange();
style.metrics = new GlyphMetrics(0, 0, 36);
if (activeLine == currentLine) {
style.background = highlightedLine;
if (curActiveLine != activeLine){
System.out.println("ActiveLine " + activeLine + " old " + curActiveLine);
int redrawLine = curActiveLine;
curActiveLine = activeLine;
styledText.redraw(0, styledText.getLinePixel(redrawLine), 36, styledText.getLineHeight(),true);
}
}
style.foreground = mainBackground;
// Create and set the bullet
event.bullet = new Bullet(ST.BULLET_NUMBER, style);
event.styles = matchKeywords(event);
}
I just realized that you can set a CaretListener to get notifications for each move of the caret. By issuing the redraws from that it works great now.

Categories

Resources