location services deviate about 300m from the current location;
my custom Spatial Reference (wkString)
Spatial Reference: PROJCS["VN-2000",GEOGCS["GCS_VN_2000",DATUM["D_VN_2000",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",107.75],PARAMETER["Scale_Factor",0.9999],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]],VERTCS["Hon_Dau_1992",VDATUM["Hon_Dau_1992"],PARAMETER["Vertical_Shift",0.0],PARAMETER["Direction",1.0],UNIT["Meter",1.0]]
below my code:
map = new ArcGISMap(SpatialReference.create(getResources().getString(R.string.wkString))); // Viewpoint viewPoint1 = new Viewpoint(new Point(433214.603,1211184.161, map.getSpatialReference()), 1000000); // map.setInitialViewpoint(viewPoint1); // map = new ArcGISMap(); map.getBasemap().getBaseLayers().add(usaLayer); map.getBasemap().getBaseLayers().add(usaLayerCached); //map.getBasemap().getBaseLayers().add(FeatureLayerVungCay); mMapView = (MapView) findViewById(R.id.mapView); BackgroundGrid backgroundGrid = new BackgroundGrid(Color.WHITE,Color.WHITE,0,2); mMapView.setBackgroundGrid(backgroundGrid); mMapView.setMap(map); Viewpoint viewPoint = new Viewpoint(new Point(433214.603,1211184.161, map.getSpatialReference()), 1000000); mMapView.setViewpoint(viewPoint); // map.setInitialViewpoint(view); mMapView.setAttributionTextVisible(false);
mLocationDisplay = mMapView.getLocationDisplay(); mLocationDisplay.addDataSourceStatusChangedListener(new LocationDisplay.DataSourceStatusChangedListener() { @Override public void onStatusChanged(LocationDisplay.DataSourceStatusChangedEvent dataSourceStatusChangedEvent) { // If LocationDisplay started OK, then continue. if (dataSourceStatusChangedEvent.isStarted()) return; // No error is reported, then continue. if (dataSourceStatusChangedEvent.getError() == null) return; // If an error is found, handle the failure to start. // Check permissions to see if failure may be due to lack of permissions. boolean permissionCheck1 = ContextCompat.checkSelfPermission(MainActivity.this, reqPermissions[0]) == PackageManager.PERMISSION_GRANTED; boolean permissionCheck2 = ContextCompat.checkSelfPermission(MainActivity.this, reqPermissions[1]) == PackageManager.PERMISSION_GRANTED; if (!(permissionCheck1 && permissionCheck2)) { // If permissions are not already granted, request permission from the user. ActivityCompat.requestPermissions(MainActivity.this, reqPermissions, requestCode); } else { // Report other unknown failure types to the user - for example, location services may not // be enabled on the device. String message = String.format("Error in DataSourceStatusChangedListener: %s", dataSourceStatusChangedEvent .getSource().getLocationDataSource().getError().getMessage()); Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show(); // Update UI to reflect that the location display did not actually start mSpinner.setSelection(0, true); } } }); // Populate the list for the Location display options for the spinner's Adapter ArrayList<ItemData> list = new ArrayList<>(); list.add(new ItemData("", R.mipmap.locationdisplaydisabled)); list.add(new ItemData("", R.mipmap.locationdisplayon)); list.add(new ItemData("", R.mipmap.locationdisplayrecenter)); list.add(new ItemData("", R.mipmap.locationdisplaynavigation)); list.add(new ItemData("", R.mipmap.locationdisplayheading)); SpinnerAdapter adapter = new SpinnerAdapter(this, R.layout.spinner_layout, R.id.txt, list); mSpinner.setAdapter(adapter); mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { switch (position) { case 0: // Stop Location Display if (mLocationDisplay.isStarted()) mLocationDisplay.stop(); break; case 1: // Start Location Display if (!mLocationDisplay.isStarted()) mLocationDisplay.startAsync(); break; case 2: // Re-Center MapView on Location // AutoPanMode - Default: In this mode, the MapView attempts to keep the location symbol on-screen by // re-centering the location symbol when the symbol moves outside a "wander extent". The location symbol // may move freely within the wander extent, but as soon as the symbol exits the wander extent, the MapView // re-centers the map on the symbol. mLocationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.RECENTER); if (!mLocationDisplay.isStarted()) mLocationDisplay.startAsync(); break; case 3: // Start Navigation Mode // This mode is best suited for in-vehicle navigation. mLocationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.NAVIGATION); if (!mLocationDisplay.isStarted()) mLocationDisplay.startAsync(); break; case 4: // Start Compass Mode // This mode is better suited for waypoint navigation when the user is walking. mLocationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.COMPASS_NAVIGATION); if (!mLocationDisplay.isStarted()) mLocationDisplay.startAsync(); break; } } @Override public void onNothingSelected(AdapterView<?> parent) { } });
Your problem is still under investigation, the default location data precision is dependent upon the network provider of your device. Questions : is the usaLayer in the same the spatial reference as the wkString defined?
the usaLayer and usaLayerCached
in the same the spatial reference as the wkString defined. All layer in app same spatial reference
1. Could you try to set your map using the well-know id, like
//https://developers.arcgis.com/rest/services-reference/geographic-coordinate-systems.htm
map = new ArcGISMap(SpatialReference.create(4756));
2. What type of layer the usaLayer is? is it possible to share it?
usaLayer is type TiledLayer(cached layer)
ArcGISTiledLayer usaLayer = new ArcGISTiledLayer(getResources().getString(R.string.mycustom_base_map));
map.getBasemap().getBaseLayers().add(usaLayer);
http://115.79.20.1:6080/arcgis/rest/services/DUAN_NN/Maplocal_NN/MapServer(mycustom_base_map)
Try to repo your issue, could you please provide the coordinates,
1. "correct location", "incorrect location" in the map spatial reference.
2. "incorrect location" from the input, you can use the location changed listener:
mLocationDisplay.addLocationChangedListener(location -> { Point point1 = location.getLocation().getPosition(); Point prjPoint = (Point) GeometryEngine.project(point1, mMap.getSpatialReference()); Log.d(TAG, "location position-->" + point1.toJson()); Log.d(TAG, "Projected point-->" + prjPoint.toJson()); });