Display points when there's great distance between them (GWT-Openlayers) - gwt

The case is the following: I have a layer and there are two points on it. The first is in Australia, the second is in the USA. The continent or the exact position of the points doesn't count. The essential part is the great distance between the points. When the application starts, the first point appears (zoomlevel is 18). The second point isn't displayed because it is far away from here and the zoomlevel is high. Then i call the panTo function with the location of the second point. The map jumps to the right location but the second point doesn't appear. The point appears only if i zoom in/out or resize the browser window. The GWT code:
LonLat center = new LonLat(151.304485, -33.807831);
final LonLat usaPoint = new LonLat(-106.356183, 35.842721);
MapOptions defaultMapOptions = new MapOptions();
defaultMapOptions.setNumZoomLevels(20);
// mapWidget
final MapWidget mapWidget = new MapWidget("100%", "100%", defaultMapOptions);
// google maps layer
GoogleV3Options gSatelliteOptions = new GoogleV3Options();
gSatelliteOptions.setIsBaseLayer(true);
gSatelliteOptions.setDisplayOutsideMaxExtent(true);
gSatelliteOptions.setSmoothDragPan(true);
gSatelliteOptions.setType(GoogleV3MapType.G_SATELLITE_MAP);
GoogleV3 gSatellite = new GoogleV3("Google Satellite", gSatelliteOptions);
mapWidget.getMap().addLayer(gSatellite);
// pointLayer
VectorOptions options = new VectorOptions();
options.setDisplayOutsideMaxExtent(true);
Vector vector = new Vector("layer1", options);
mapWidget.getMap().addLayer(vector);
mapWidget.getMap().addControl(new LayerSwitcher());
mapWidget.getMap().addControl(new MousePosition());
mapWidget.getMap().addControl(new ScaleLine());
mapWidget.getMap().addControl(new Scale());
// two points are added to the layer
center.transform(new Projection("EPSG:4326").getProjectionCode(), mapWidget.getMap().getProjection());
vector.addFeature(new VectorFeature(new Point(center.lon(), center.lat())));
usaPoint.transform(new Projection("EPSG:4326").getProjectionCode(), mapWidget.getMap().getProjection());
vector.addFeature(new VectorFeature(new Point(usaPoint.lon(), usaPoint.lat())));
// the center of the map is the first point
mapWidget.getMap().setCenter(center, 18);
// 3 sec later panTo second point
Timer t = new Timer() {
#Override
public void run() {
mapWidget.getMap().panTo(usaPoint);
}
};
t.schedule(3000);
I tried to reproduce this situation with pure Openlayers, but it worked fine. Here is the link
So i think the problem is with GWT-Openlayers. Has anybody experienced such behaviour? Or has anybody got a solution to this problem?

What a strange problem.
For now I did only found a way around it, but not a real fix. Seems to be a bug in GWT-OL as you say, but I can't imagine where.
What you can do is add the following 3 lines to your code :
mapWidget.getMap().panTo(usaPoint);
int zoom = mapWidget.getMap().getZoom();
mapWidget.getMap().setCenter(usaPoint, 0);
mapWidget.getMap().setCenter(usaPoint, zoom);
(note : I am a contributor to the GWT-OL project, I also informed other contributors of this problem, maybe they can find a better solution)
Edit : Another GWT-OL contributor looked into this but also couldn't find a real solution
but another workaround is to use zoomToExtend for the requested point :
Bounds b = new Bounds();
b.extend(new LonLat(usaPoint.getX(), usaPoint.getY()));
mapWidget.getMap().zoomToExtent(b);

Related

How to figure out resolution array from user inputted ArcGIS projection data

I have a Leaflet based mapping solution that uses ArcGIS map configuration supplied by a user (I have no idea what it will be, they will customize it with their own ArcGIS services). The issue is that the projection can be pretty much anything, and I will need to use Proj4Leaflet to configure the CRS of the map accordingly. The problem I'm running into is I'm not sure how to calculate the scale/resolution array. The user is inputting these values: projection key, Proj4 string, origin, bounds, zoom levels.
So, for example (yes I know EPSG:3857 is standard and I could just use L.CRS.EPSG3857 but it serves as a good example of how to set the same thing up using Proj4Leaflet):
Projection key = EPSG:3857
Proj4 string = +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=#null +wktext +no_defs
Origin = [0,0]
Bounds = [[-20026376.39, -20048966.10], [20026376.39, 20048966.10]]
Zoom levels = 18
With that I think I have enough to set up a L.Proj.CRS for it:
var crs = new L.Proj.CRS("EPSG:3857", "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=#null +wktext +no_defs",
{
resolutions : [?????],
origin : [0,0],
bounds : [[-20026376.39, -20048966.10], [20026376.39, 20048966.10]]
});
I have everything I need apart from the resolutions array, I am not sure exactly how to go about setting that up based on the data given and having a hard time finding answers to get me pointed in the right direction.
So bottom line, the only way I found to calculate resolutions is if it is a mercator projection and we know the longitude extents of it and the tile size. Otherwise the resolutions will need to be looked up at the ArcGIS Server tile server REST endpoint. Thus for my project I will need the user to supply the array themselves and cannot calculate it for them.
In the case of the mercator projection, I came up with this function that does the trick:
function parseResolutionsFromZoomLevels(zoomLevels, tileSize, mapWGS84Extent)
{
var metersPerExtent = 40075008/360;
var mapWGS84Meters = mapWGS84Extent*metersPerExtent;
var resolutionArray = [];
for (var i=0; i<zoomLevels; i++)
{
var tilesAtZoom = Math.pow(2,i);
var pixelsAtZoom = tilesAtZoom*tileSize;
resolutionArray.push(mapWGS84Meters/pixelsAtZoom);
}
return resolutionArray;
}
Hope this helps anyone else that happens to encounter this same situation.

Unity: Ignore collision of a plateform if jump to it from below. Using ContactFilter & rigidBody.Cast()

I am able to avoid a collision between my player and my entire plateform with the use of contactFilter2D.SetLayerMask() + rigidBody2D.Cast(Vector2, contactFilter, ...);
But I don't find a way to avoid the collision only if my player try to acces to the plateform from below it (with a vertical jump).
I'm pretty sure I should use the contactFilter2D.setNormalAngle() (after specify the minAngle and maxAngle) but no matter the size of my angles, I can't pass threw it.
This is how I initialize my contactFilter2D.
protected ContactFilter2D cf;
void Start () {
cf.useTriggers = false;
cf.minNormalAngle = 0;
cf.maxNormalAngle = 180;
cf.SetNormalAngle(cf.minNormalAngle, cf.maxNormalAngle);
cf.useNormalAngle = true;
}
void Update () {
}
I use it with
count = rb.Cast(move, contactFilter, hitBuffer, distance + shellRadius);
Any ideas ? If you want more code, tell me. But I don't think it will be usefull to understand the matter.
unity actualy has a ready made component for this: it is a physics component called "Platform Effector 2D" if you drag and drop it on your platform it will immediately work the way you want, and it has adjustable settings for tweaking the parameters. hope this helps!

Google maps V2 android get current location

Im trying to place a marker on the position i am, this way:
googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map_container)).getMap();
googleMap.setMyLocationEnabled(true);
My question is, how to get coordinates from myLocation, i tried, googleMap.getMyLocation().getLatitude() and googleMap.getMyLocation().getAltitude() right after googleMap.setMyLocationEnabled(true), but app crashes, another thing i did was Location loc=lm.getLastKnownLocation(provider) but are not the same coordinates and the marker is placed in the wrong place.
How can you people help me?
SupportMapFragment mf =(SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
mMap = mf.getMap();
mMap.setMyLocationEnabled(true);
mMap.setMapType(mMap.MAP_TYPE_NORMAL);
Just add these two lines of code to get current location on Maps
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
and when you long press on any location on map add this code to get its location
googleMap.setOnMapLongClickListener(new OnMapLongClickListener() {
#Override
public void onMapLongClick(LatLng arg0) {
double alt = arg0.latitude;
double alo = arg0.longitude;
MarkerOptions marker1 = new MarkerOptions().position(new LatLng(alt, alo)).title("Lat ="+alt+" Lang="+alo);
googleMap.addMarker(marker1);
}
});

remove graphics from inside a class as3

When I click a button in my game it draws shapes using the graphics in as3. simple shapes such as circles and rectangles.
I want to remove the graphics that have been drawn when something happens in one of my classes.
Basically when there is a hitTestObject (which works fine) I want all graphics on stage to be cleared.
if (gb2.hitTestObject(h1s2))
{
trace ("holed")
ySpeed2=0;
xSpeed2=0;
this.visible=false;
var mcSplash:MovieClip =parent.getChildByName("mcSplash") as MovieClip;
mcSplash.visible=true;
//parent.drawings.graphics.clear();
}
My attempt using parent.drawings.graphics.clear(); was unsuccessful, it gives me this error:
Line 481 1119: Access of possibly undefined property drawings through a reference with static type flash.display:DisplayObjectContainer.
Anyone have any suggestions
UPDATE:
this is how, on the min time line, the drawings occur.
var drawings:Shape = new Shape;
for (i=0; i<numRecs; i++)
{
recStartX = Number(xmlContent.rec[i].startpoint.#ptx);
recStartY = Number(xmlContent.rec[i].startpoint.#pty);
recWidth = Number(xmlContent.rec[i].dimensions.#w);
recHeight = Number(xmlContent.rec[i].dimensions.#h);
fillColor=int(xmlContent.rec[i].look.fillhex);
lineThick = Number(xmlContent.rec[i].look.strokethick);
lineColor = int(xmlContent.rec[i].look.strokehex);
drawings.graphics.lineStyle(lineThick, lineColor);
drawings.graphics.beginFill(fillColor);
drawings.graphics.drawRect(recStartX,recStartY,recWidth,recHeight);
drawings.graphics.endFill();
}
Create an array and push in each shape/rect.
Then iterate through this and remove..
for(var iteration:int = 0; iteration < rectArray.length; iteration++)
this.removeChild(rectArray[iteration]);
or if you are calling this from a class, use
MovieClip(this.root).removeChild(rectArray[iteration]);
Hopefully this is helpful :)
Z
What's drawings?! If you draw in mcSplash, you should use mcSplash.graphics.clear(). If you draw in a child called drawings, you should first get it as a child (after mcSplash get): var drawings = mcSplash.getChildByName('drawings); drawings.graphics.clear();. You could write checks to see what's going on: if (mcSlpash) { if (drawings) {, etc..

Flex: Move a datapoint from 1 location to another in a plotchart

I have a flex plotchart and I need an animation that would enable me to move datapoints from 1 location to another. The actual movement must also be shown.
I have tried move control but the call to play() does not work.
Any hints would also help greatly..
Thanks in advance
After much effort, I found that one way to move the point from 1 point to another is by making it move along the equation of the line and rendering the intermediate points on the graph after some delay...
I'll share the code...
Place the following line where you want to start the movement:
setTimeout(showLabel,singleDuration,oldLocation,newLocation,
Constants.TOTAL_STEPS,1,oldLocation.x, oldLocation.y, singleDuration);
And this is the function definition:
private function showLabel(oldLoc:Object newLoc: Object, totalSteps: Number,
count:Number, currentX: Number, currentY: Number, singleDuration: Number): void{
tempArrColl = new ArrayCollection();
var tempObj: Object= new Object();
xDelta = 0.25;
yDelta = 0.25;
tempObj.x = currentX + (xDelta * count);
tempObj.y = currentY + (yDelta * count);
if ((tempObj.x >= newLoc.x) || (tempObj.y >= newLoc.y)){
tempObj.x = newLoc.x;
tempObj.y = newLoc.y;
callLater(showPoint,[tempObj]);
tempArrColl = new ArrayCollection();
plotGraphArrayColl.addItem(newLoc);
return;
}
callLater(showPoint,[tempObj]);
count++;
setTimeout(showLabel, singleDuration, oldLoc, newLoc,
totalSteps, count, tempObj.x, tempObj.y, singleDuration);
}
private function showPoint(loc: Object): void {
tempArrColl.addItem(loc);
plotChart.validateNow();
}
Here, tempArrColl will hold the intermediate point along the line equation. Put it as a dataProvider in a series on the graph and then once all the points are moved, remove it. plotGraphArrayColl is the dataProvider that would hold the newly moved points..
There may be better ways possible but it worked for me... Do tell if anyone finds something easier.. Thanks