简体   繁体   中英

I'm having trouble getting accurate GPS locations from the Google Maps API for use on Android

We are developing an application for people to mark areas (single points, lines, and polygons) on Google Maps using Android phones (2.1 and up). They are given a Google Maps view and enter the points for the lines by centering the screen at the location that they want to create a point and then press a button on the GUI to add the point at that location.

After entering a point, they recenter the screen on the location for the next point and press the create point button again. After all of the points for that shape have been entered, they switch to another view where they enter some descriptive information and send the information to a central database.

Unfortunately, the points shift by a small amount relative to the locations they were supposed to mark. If the user switches from the summary view back to the point editing view, all of the points will have shifted, some by only a foot and some by as much as 10 or 15 feet. The problem appears to be that

GeoPoint point = mapView.getMapCenter();

returns inaccurate GPS coordinates after the view has been panned. When the points are rendered to a fresh view, they are consistently shown at the same position which correlate well with Google maps views on the internet for those same GPS coordinates. We have extensively debugged the software and the coordinates have the wrong map location / GPS coordinates when they are returned from mapView.getMapCenter();

Because we were concerned that the

Point p = new Point();
mapView.getProjection().toPixels(mapView.getMapCenter(), p); 

might not return the screenWidth / 2 , screenHeight / 2 location, we actually show the cross-hair used to place points at the toPixels location and the newly created points match up exactly with the cross-hair when they are originally created. After changing to the summary screen and back, they are re-rendered at their real GPS coordinates.

Also, to be clear, this has nothing to do with the accuracy of the GPS sensor.

If we could refresh / reinitialize the map view after panning, it might be awkward, but it would be an improvement over our current problems. Moving to other map software, meanwhile, would take a lot of time and might have its own problems.

I do something similar and have no trouble with inaccuracy. I suspect it's the way you are placing your crosshairs. I define mine in the main.xml using a Unicode character and pin it to the view centre using this snippet:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#0000ff"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <include
        layout="@layout/googlemap"/>
    <Button
        android:text='\u25ce'
        android:id="@+id/BullseyeButton"
        android:background="@android:color/transparent"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24pt"
        android:typeface="monospace"
        android:textColor="#afffff00"></Button>
    <include
        layout="@layout/infobar"/>
</RelativeLayout>

The centerInParent attribute guarantees that both the crosshairs and the mapview are using the same centre.

The u25ce make a pretty good indicator for me. There are other ones that you might find better.

Update

Well I update my app's info bar once per second with a handler. I added this test method to be called in the handler

protected void backAndForth(MapView mv){
    GeoPoint centreGpt = mv.getMapCenter();
    int inLon = centreGpt.getLongitudeE6();
    int inLat = centreGpt.getLatitudeE6();
    Point p = new Point();
    mv.getProjection().toPixels(centreGpt, p);
    GeoPoint backGpt = mv.getProjection().fromPixels(p.x, p.y);
    int outLat = backGpt.getLatitudeE6();
    int outLon = backGpt.getLongitudeE6();
    String res = "In lat " + inLat + " In lon " + inLon 
                + " Out lat " + outLat + " Out lon " + outLon;
    Log.d("POS_TAG", res);
}

The in and out coordinates match perfectly no matter how I pan and zoom. using the reverse geocoder, jumping from Chicago to London to Berlin, I get output from the test method:

In lat 41878113 In lon -87629798 Out lat 41878113 Out lon -87629798
In lat 41878113 In lon -87629798 Out lat 41878113 Out lon -87629798
In lat 51500152 In lon -126236 Out lat 51500152 Out lon -126236
In lat 51500152 In lon -126236 Out lat 51500152 Out lon -126236
In lat 51500152 In lon -126236 Out lat 51500152 Out lon -126236
In lat 52523405 In lon 13411399 Out lat 52523405 Out lon 13411399
In lat 52523405 In lon 13411399 Out lat 52523405 Out lon 13411399
In lat 52523405 In lon 13411399 Out lat 52523405 Out lon 13411399

I'm afraid you've got me stumped

Update

I changed my application to display 6 places of decimals from its normal 5 and chose an intersection of car park bays in a supermarket near me in London. I did as you suggested and took screen shots at maximum zoom from my emulator at the start and after I'd panned and zoomed and panned back to the original place as close as I could without looking at the displayed Lat/Lon as I did it. These are typical results

Start 开始

End 在此处输入图片说明

1 microdegree is only about 11 centimetres for change in latitude and about 6cm for change in longitude at this latitude, so I reckon this is pretty much within my ability to pan accurately.

Google maps themselves seem to have bigger inherent display errors. For example, the UK's mapping agency (The Ordnance Survey) maintains a number of triangulation points around the country. These are fixed by satellite reference on the WGS84 datum to within sub millimetric accuracy. They are normally quarter inch copper studs set into concrete. One which we can correlate with a Google map view is at

Ham trig point

There's sketch of its location at:

Sketch

and a photo on this site (The bolt is under the dog's front right paw):

Trig point photo

If you look at a screen shot of my app geo fixing to that location

在此处输入图片说明

You can see that Google has the spot as a good 6 feet beyond the edge of the jetty and would be in the water at high tide.

In conclusion, I think that any errors I see in terms of repeatability are swamped by those inherent in Google's interpretation of a coordinate. This is probably to be expected as I know they use a simple spherical projection of the Earth's surface, rather than the more accurate ellipsoidal one on which GPS systems are based.

We eventually replaced Google Maps with Bing Maps in our android application, using the Android SDK from InKnowledge. They are providing accurate GPS coordinates for the center of the map view, which we use to build polygons, polylines, and pushpin shapes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM