I have list of stores and when i click on any one depending on their latitude and longitude values which i get from a web server i show them on the map. some of them show up but some wont...i know this is not a good question....but i am just expecting if someone who might have experienced the same problem might help.
here is the code:
Double Storelat = (FeedListViewActivity.lat);
Double Storelng = (FeedListViewActivity.lng);
storeLocation = new GeoPoint((int) (Storelat * 1E6), (int) (Storelng * 1E6));
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
Point locationPoint1 = new Point();
Projection projection1 = mapView.getProjection();
projection1.toPixels(storeLocation, locationPoint1);
Paint containerPaint = new Paint();
containerPaint.setAntiAlias(true);
int containerX1 = locationPoint1.x;
int containerY1 = locationPoint1.y;
if (shadow) {
containerX1 += CONTAINER_SHADOW_OFFSET;
containerY1 += CONTAINER_SHADOW_OFFSET;
containerPaint.setARGB(90, 0, 0, 0);
canvas.drawCircle(containerX1, containerY1, CONTAINER_RADIUS,
containerPaint);
} else {
containerPaint.setColor(Color.RED);
canvas.drawCircle(containerX1, containerY1, CONTAINER_RADIUS,
containerPaint);
}
}
and these are the values i get from the webserver:
working:
lat = 18.5170002
lng = 73.858078
not working:
lat = 18.618679
lng = 73.8037491
your answer is in your question itself
working:
lat = 18.5170002 lng = 73.858078
not working:
lat = 18.618679 lng = 73.8037491
as per above provided thing you can see the precision difference i have also faced the same problem be 6 months, and i have made that 6 precision to 8 precision and was working well then.
if you pass 18.618679 then it will treat it as 0.18618679 for confirmation try to zoom out up-to level 2 or 3 you will get your point at unexpected place.
Related
I've got a problem with my osm app. I get Set of points from my server side application and than I want to visualise it as some area. So I create a polygon from this points and add it to my mapView object. It works but as the area becomes bigger there occures a problem with scrolling which just lags until I reach the area without my Overlays.
How can I improve map redrawing performance?
I thought about deviding my area polygon into smaller polygons but than they just intersect with each other and the color isn't uniform.
View of my map
Here is part of my code. Normally I call it everytime I get message with new data from the server in AsyncTask and invalidate mapView on postExecute method but it doesn't really matter since the problem is not with just drawing but scrolling, does it?
List<Overlay> mapOverlays = new ArrayList<>();
Drawable icon = getIcon();
Marker marker = new Marker(mapView);
marker.setPosition(new GeoPoint(newPosition));
marker.setTitle(title);
marker.setIcon(icon);
mapOverlays.add(marker);
List<GeoPoint> listWithAreaPoints = new ArrayList<>();
listWithAreaPoints.addAll(setWithAreaPoints);
Polygon searchedArea = new Polygon(activity.getApplicationContext());
searchedArea.setPoints(listWithAreaPoints);
searchedArea.setFillColor(0x12121212);
searchedArea.setStrokeColor(0x12121212);
searchedArea.setStrokeWidth(0);
mapOverlays.add(searchedArea);
mapView.getOverlays().clear();
mapView.getOverlays().addAll(mapOverlays);
mapView.invalidate();
Thanks for any advice.
I've found out what was wrong.
The data which I was receiving from the server contained a lot of points (hundreds maybe thousands) and I was giving them to Polygon object's method setPoints() in chaotic sequence. In consequence the polygon method draw() drew successive lines without any order what can be seen on my printscreen (blank areas). As the number of points increased the number of polygon's "sides" increased also and redrawing performance decreased.
The solution was to sort List of points by distance so it would represent List of successive corners of the polygon and remove repetitions before giving them as argument to method Polygon.setPoints().
Maybe it will help someone in the future so I'll live here my method to sort GeoPoints as successive polygon's points:
private List<GeoPoint> sortGeoPointsListByDistance(List<GeoPoint> searchedArea){
List<GeoPoint> orderedSearchedArea = new ArrayList<>();
orderedSearchedArea.add(searchedArea.remove(0));
while (searchedArea.size() > 0) {
GeoPoint point = orderedSearchedArea.get(orderedSearchedArea.size() - 1);
int nearestPointIndex = findNearestPointIndex(point, searchedArea);
GeoPoint nearestPoint = searchedArea.get(nearestPointIndex);
if(nearesPointIsTheSamePoint(point, nearestPoint)){
searchedArea.remove(nearestPointIndex);
} else {
orderedSearchedArea.add(searchedArea.remove(nearestPointIndex));
}
}
return orderedSearchedArea;
}
private int findNearestPointIndex(GeoPoint point, List<GeoPoint> listToSearch) {
int index =0;
double dist = 0;
for(int i=0;i<listToSearch.size();i++){
GeoPoint currentPoint = listToSearch.get(i);
double currentPointDist = distFrom( point.getLatitude(), point.getLongitude(), currentPoint.getLatitude(), currentPoint.getLongitude());
if(i==0){
index = i;
dist = currentPointDist;
} else if(currentPointDist<dist){
index = i;
dist = currentPointDist;
}
}
return index;
}
private boolean nearesPointIsTheSamePoint(GeoPoint point, GeoPoint nearestPoint){
if(point.getLatitude()==nearestPoint.getLatitude() && point.getLongitude()==nearestPoint.getLongitude()){
return true;
} else{
return false;
}
}
private double distFrom(double lat1, double lng1, double lat2, double lng2) {
double earthRadius = 6371000; //meters
double dLat = Math.toRadians(lat2-lat1);
double dLng = Math.toRadians(lng2-lng1);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng/2) * Math.sin(dLng/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double dist = (earthRadius * c);
return dist;
}
I am trying to show the users current location with the default blue dot in android. In my maps page I also have a layout that shows different points of interest. Im having trouble figuring out what to put for some of the variables and was wondering if someone could help me out.
This is what I'm using so far to show my location.
Location location = locationManager
.getLastKnownLocation(bestProvider);
try {
GeoPoint myPoint2 = new GeoPoint(
(int) (location.getLatitude() * 1E6),
(int) (location.getLongitude() * 1E6));
newoverlay.drawMyLocation(null, mapView, location, myPoint2,
1000);
mapOverlays.add(newoverlay);
} catch (NullPointerException e) {
GeoPoint myPoint2 = new GeoPoint((int) (-1 * 1E6),
(int) (-1 * 1E6));
**newoverlay.drawMyLocation(null, mapView, location, myPoint2,
1000);**
mapOverlays.add(newoverlay);
}
I'm not sure what to put as the Canvas so I placed it with null so that it would compile. I'm using the location from a location Manager and I have my geopoint from the location variable. I'm also unsure what the "when" parameter is supposed to be.
I was also wondering how the blue bubble knows to move with the person, does the picture update every x milliseconds depending on the "when" parameter?
So far the app isn't crashing, but it is also not showing the blue dot at any location.
I'm sure I just need help with finding what the canvas parameter should be.
Thanks
try this way in your map activity
class CurOverlay extends Overlay {
private GeoPoint pointToDraw;
public void setPointToDraw(GeoPoint point) {
pointToDraw = point;
}
public GeoPoint getPointToDraw() {
return pointToDraw;
}
#Override
public boolean draw(Canvas canvas, MapView curmapView, boolean shadow,
long when) {
super.draw(canvas, curmapView, shadow);
// convert point to pixels
Point screenPts = new Point();
curmapView.getProjection().toPixels(pointToDraw, screenPts);
// add marker
Bitmap bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.pinsource);
canvas.drawBitmap(bmp, screenPts.x - 28, screenPts.y - 48, null);
return true;
}
}
i hope this will work for you.
I need your quick assistance for the problem stated below
In my android application I show a marker on specific location.
Here is my code
double latitude = Double.parseDouble(this.latitude);
double longitude = Double.parseDouble(this.longitude);
int latitudeE6 = (int) (latitude * 1e6);
int longitudeE6 = (int) (longitude * 1e6);
Log.i("Latitude","String = "+this.latitude+",Double = "+latitude+", int = "+latitudeE6);
Log.i("Longitude","String = "+this.longitude+",Double = "+longitude+", int = "+longitudeE6);
GeoPoint point = new GeoPoint(latitudeE6, longitudeE6);
Log.i("Point a", ""+point.getLatitudeE6()+","+point.getLongitudeE6());
OverlayItem overlay = new OverlayItem(point, title, detail);
Drawable drawable = mapView.getContext().getResources().getDrawable(
R.drawable.pin);
HelloOverlayItem helloOverLay = new HelloOverlayItem(drawable, this);
Log.i("Point b", ""+point.getLatitudeE6()+","+point.getLongitudeE6());
helloOverLay.addOverlay(overlay);
mapView.getOverlays().add(helloOverLay);
MapController controller = mapView.getController();
Log.i("Point c", ""+point.getLatitudeE6()+","+point.getLongitudeE6());
controller.animateTo(point);
controller.setCenter(point);
controller.setZoom(10);
I can get proper location integers in "Point C" log entry, which is not 0,0 (some where near London) But in map it always show me on 0,0 how can it be possible?? How to get rid of this??
I can't say that it's surely an answer or just a work around until it create some bug. But calling mapView.invalidate() worked. I have added this line exactly after mapView.getOverlays().add(helloOverLay); And it worked.
I'm just trying to make sense of a basic Android navigation-related question, namely "How can I display the current location". I've used a bit of code from articles and tutorials from my long googling sessions. The display of a simple overlay (circle + text message) is works, yet at a wrong on-screen position (on the Equator apparently).
My code setup includes a small inner class that implements LocationListener, and its onLocationChanged event handler calls this method :
protected void createAndShowCustomOverlay(Location newLocation)
{
double lat = newLocation.getLatitude();
double lng = newLocation.getLongitude();
// geoPointFromLatLng is an E6 converter :
// return new GeoPoint((int) (pLat * 1E6), (int) (pLng * 1E6));
GeoPoint geopoint = GeoFunctions.geoPointFromLatLng(lat, lng);
CustomOverlay overlay = new CustomOverlay(geopoint);
mapView.getOverlays().add(overlay);
mapView.getController().animateTo(geopoint);
mapView.postInvalidate();
}
Up to this point, it all looks ok, I've debugged around and the non-transformed lat/lng pair is ok, the E6 variant thereof ok as well. Here is the CustomOverlay class :
public class CustomOverlay extends Overlay
{
private static final int CIRCLERADIUS = 2;
private GeoPoint geopoint;
public CustomOverlay(GeoPoint point)
{
geopoint = point;
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow)
{
// Transfrom geoposition to Point on canvas
Projection projection = mapView.getProjection();
Point point = new Point();
projection.toPixels(geopoint, point);
// background
Paint background = new Paint();
background.setColor(Color.WHITE);
RectF rect = new RectF();
rect.set(point.x + 2 * CIRCLERADIUS, point.y - 4 * CIRCLERADIUS,
point.x + 90, point.y + 12);
// text "My Location"
Paint text = new Paint();
text.setAntiAlias(true);
text.setColor(Color.BLUE);
text.setTextSize(12);
text.setTypeface(Typeface.MONOSPACE);
// the circle to mark the spot
Paint circle = new Paint();
circle.setColor(Color.BLUE);
circle.setAntiAlias(true);
canvas.drawRoundRect(rect, 2, 2, background);
canvas.drawCircle(point.x, point.y, CIRCLERADIUS, circle);
canvas.drawText("My Location", point.x + 3 * CIRCLERADIUS, point.y + 3
* CIRCLERADIUS, text);
}
}
It's most definitely a projection error of sorts, since all my geo fix'd coords end up on the Equator, so there are some 0.0 values getting thrown around.
I can provide other details if needed, I'm running the code on the emulator, Maps API Level 8 (Android 2.2) and I get tiles and the CustomOverlay (circle + text) gets displayed, only at a really false position (coords such as 54.foo and 8.bar are way off).
The codebase could be a bit older, then perhaps a projection such as toPixels isn't required anymore ? No idea.
Thanks in advance !
Solved, turns out the "geo fix" command sent via telnet wants a (Lng, Lat) pair, not a (Lat, Lng) pair. Inconsistency at its best ! Thanks for the input.
If you only want to show current location and keep it updating with a small blinking circule on the screen like Google Maps for Android does, then Android has a default implementation of this feature.
MyLocationOverlay myLocationOverlay = new MyLocationOverlay(context, mapView);
myLocationOverlay.enableMyLocation();
mapView.getOverlays().add(myLocationOverlay);
That's it Android will handle everything.
I am having an issue calculating distance using the Location.distanceTo method.
private class MyLocationOverlay1 extends MyLocationOverlay {
#Override
public void drawMyLocation(Canvas canvas, MapView mapView, Location lastFix, GeoPoint myLocation, long when)
super.drawMyLocation(canvas,mapView,lastFix,myLocation,when);
Location bLocation = new Location("reverseGeocoded");
bLocation.setLatitude(FindList.gpslat); // Value = 3.294391E7
bLocation.setLongitude(FindList.gpslong); // Value = -9.6564615E7
Location aLocation = new Location("reverseGeocoded");
aLocation.setLatitude(myLocation.getLatitudeE6()); // Value = 3.2946164E7
aLocation.setLongitude(myLocation.getLongitudeE6()); // Value = -9.6505141E7
aLocation.set(aLocation); // Don't think I need this
bLocation.set(bLocation); // Don't think I need this either
int distance = (int)aLocation.distanceTo(bLocation); // Value = 12637795 ???
String str = " (" + String.valueOf(distance) + " meters)";
}
}
Can someone tell my why my distance calculation is showing 12,637,795 Meters?
You should Modify lines:
aLocation.setLatitude(myLocation.getLatitudeE6() / 1e6);
aLocation.setLongitude(myLocation.getLongitudeE6() / 1e6);
And remove the lines:
aLocation.set(aLocation);
bLocation.set(bLocation);