In our project, it so happened that for our geo-wiki we began to use OSM and not GM. In the course of writing a mobile client for Android, the standard MapView component was used. But, during testing, discrepancies in the coordinates of OSM and GM were revealed, which, in some cases, reached 30 meters. Thus, it was decided to switch from Google maps to OSM for which the corresponding osmdroid library was found. About how to move to this library, I will tell under the cut.
Change the layout of the com.google.android.maps.MapView class to org.osmdroid.views.MapView
The project used the MarkerClusterer library for clustering tags on the map, all the classes com.google.android.maps. * Were replaced by org.osmdroid. * For example, com.google.android.maps.GeoPoint on org.osmdroid.util.GeoPoint . Because of an error in the osmdroid code, as a result of which a call to mapView.getProjection (). ToPixels (...) sometimes gives coordinates not on-screen, but tile coordinates, with the result that the hitTest method of the ClusterMarker class did not work and did not handle the cluster click processing, was written found on stack overflow code that converts tile coordinates to screen coordinates
/** * * @param x view coord relative to left * @param y view coord relative to top * @param vw MapView * @return GeoPoint */public static GeoPoint geoPointFromScreenCoords(int x, int y, MapView vw){ if (x < 0 || y < 0 || x > vw.getWidth() || y > vw.getHeight()){ returnnull; // coord outof bounds } // Get the top left GeoPoint Projection projection = vw.getProjection(); GeoPoint geoPointTopLeft = (GeoPoint) projection.fromPixels(0, 0); Point topLeftPoint = newPoint(); // Get the top left Point (includes osmdroid offsets) projection.toPixels(geoPointTopLeft, topLeftPoint); // get the GeoPoint ofanypointon screen GeoPoint rtnGeoPoint = (GeoPoint) projection.fromPixels(x, y); return rtnGeoPoint; } /** * * @param gp GeoPoint * @param vw Mapview * @return a 'Point' in screen coords relative to top left */public static Point pointFromGeoPoint(GeoPoint gp, MapView vw){ Point rtnPoint = newPoint(); Projection projection = vw.getProjection(); projection.toPixels(gp, rtnPoint); // Get the top left GeoPoint GeoPoint geoPointTopLeft = (GeoPoint) projection.fromPixels(0, 0); Point topLeftPoint = newPoint(); // Get the top left Point (includes osmdroid offsets) projection.toPixels(geoPointTopLeft, topLeftPoint); rtnPoint.x-= topLeftPoint.x; // remove offsets rtnPoint.y-= topLeftPoint.y; if (rtnPoint.x > vw.getWidth() || rtnPoint.y > vw.getHeight() || rtnPoint.x < 0 || rtnPoint.y < 0){ returnnull; // gp must be off the screen } return rtnPoint; }
At one time, a wrapper class was written around the standard MyLocationOverlay, was thrown out as a result of the transition, because osm has its own class for this.
The zoom did not work with a “tweak”, to enable it, add a call to mapView.setMultiTouchControls (true);
The “Mapnik” substrate was selected as a substrate by calling mapView.setTileSource (TileSourceFactory.MAPNIK);
At the moment, the application is undergoing testing, as a result of which some new problems with this library can be identified.
upd:
During testing, it turned out that if you first set the coordinates through setCenter (..), and then zoom in, you didn’t get to the right point (it looks like problems with accuracy). Otherwise everything works fine.