Yandex Map KitまたはAndroidアプリケーションのさまざまなソースのマップを使用しないYandexマップ

こんにちは

この投稿では、Androidアプリケーションでのさまざまなソース(Yandexカードを含む)のカードの使用を検討します。

画像

問題を解決するために、 osmdroidライブラリを使用します。 ライブラリ自体(リンクは最新バージョン用ではありません。このバージョンは、新しいバージョンよりも安定しており、高速です)と、 もう1つ追加する必要があります。 それらをプロジェクトに追加します(Windows版Eclipseを使用)(ビルドパス->ビルパスの構成->ライブラリ->外部JARの追加)。

プロジェクトマニフェストに必要な権限を書き込みます

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      
      





YandexやGoogleなどの新しいマップソースを追加するには(Mapnikは既にライブラリに組み込まれています)、XYTileSourceクラスを展開する必要があります。

MyTileSource
 public class MyTileSource extends XYTileSource { public MyTileSource(String aName, string aResourceId, int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels, String aImageFilenameEnding, String... aBaseUrl) { super(aName, aResourceId, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding, aBaseUrl); } //  getTileURLString,        @Override public String getTileURLString(MapTile aTile) { return String.format(getBaseUrl(), aTile.getX(), aTile.getY(), aTile.getZoomLevel()); } }
      
      







問題は、osmdroidがYandexマップ投影をサポートしていないことです。 したがって、Yandexマップを正しく表示するために、TilesOverlayクラスを拡張します。 座標をタイルに変換し、ネットワークに戻すために、 クラスが見つかりました。 これは少し変更されたクラスです

YandexUtils
 public class YandexUtils { public static double[] geoToMercator(double[] g) { double d = g[0] * Math.PI / 180, m = g[1] * Math.PI / 180, l = 6378137, k = 0.0818191908426, f = k * Math.sin(m); double h = Math.tan(Math.PI / 4 + m / 2), j = Math.pow( Math.tan(Math.PI / 4 + Math.asin(f) / 2), k), i = h / j; // return new DoublePoint(Math.round(l * d), Math.round(l * // Math.log(i))); return new double[] { l * d, l * Math.log(i) }; } public static double[] mercatorToGeo(double[] e) { double j = Math.PI, f = j / 2, i = 6378137, n = 0.003356551468879694, k = 0.00000657187271079536, h = 1.764564338702e-8, m = 5.328478445e-11; double g = f - 2 * Math.atan(1 / Math.exp(e[1] / i)); double l = g + n * Math.sin(2 * g) + k * Math.sin(4 * g) + h * Math.sin(6 * g) + m * Math.sin(8 * g); double d = e[0] / i; return new double[] { d * 180 / Math.PI, l * 180 / Math.PI }; } public static double[] mercatorToTiles(double[] e) { double d = Math.round((20037508.342789 + e[0]) * 53.5865938), f = Math .round((20037508.342789 - e[1]) * 53.5865938); d = boundaryRestrict(d, 0, 2147483647); f = boundaryRestrict(f, 0, 2147483647); return new double[] { d, f }; } public static double[] tileToMercator(long[] d) { return new double[] { Math.round(d[0] / 53.5865938 - 20037508.342789), Math.round(20037508.342789 - d[1] / 53.5865938) }; } public static double[] tileCoordinatesToPixels(double[] i, int h) { double g = Math.pow(2, toScale(h)); return new double[] { (int) i[0] / g, (int) i[1] / g }; } public static double boundaryRestrict(double f, double e, double d) { return Math.max(Math.min(f, d), e); } public static int toScale(int i) { return 23 - i; } public static long[] getTile(double[] h, int i) { long e = 8; long j = toScale(i), g = (long) h[0] >> j, f = (long) h[1] >> j; return new long[] { g >> e, f >> e }; } public static long[] getPxCoordFromTileCoord(double[] h, int i) { long j = toScale(i), g = (long) h[0] >> j, f = (long) h[1] >> j; return new long[] { g, f }; } public static long[] getTileCoordFromPixCoord(long[] h, int i) { long j = toScale(i), g = h[0] << j, f = h[1] << j; return new long[] { g, f }; } public static double[] ReGetTile(double[] h, int i) { long e = 8; long j = toScale(i); long g = (long) h[0] << (int) j; long f = (long) h[1] << (int) j; double ge = g << (int) e; double fe = f << (int) e; long g2 = (long) (h[0] + 1) << (int) j; long f2 = (long) (h[1] + 1) << (int) j; double ge2 = g2 << (int) e; double fe2 = f2 << (int) e; double ad_g = (ge2 - ge) * (h[0] - Math.floor(h[0])); double ad_f = (fe2 - fe) * (h[1] - Math.floor(h[1])); return new double[] { ge + ad_g, fe + ad_f }; } public static double[] ReGetTile(long[] h, int i) { long e = 8; long j = toScale(i); long g = (long) h[0] << (int) j; long f = (long) h[1] << (int) j; return new double[] { g << (int) e, f << (int) e }; } public static double[] getGeoFromTile(int x, int y, int zoom) { double a, c1, c2, c3, c4, g, z, mercX, mercY; a = 6378137; c1 = 0.00335655146887969; c2 = 0.00000657187271079536; c3 = 0.00000001764564338702; c4 = 0.00000000005328478445; mercX = (x * 256 * 2 ^ (23 - zoom)) / 53.5865938 - 20037508.342789; mercY = 20037508.342789 - (y * 256 * 2 ^ (23 - zoom)) / 53.5865938; g = Math.PI / 2 - 2 * Math.atan(1 / Math.exp(mercY / a)); z = g + c1 * Math.sin(2 * g) + c2 * Math.sin(4 * g) + c3 * Math.sin(6 * g) + c4 * Math.sin(8 * g); return new double[] { mercX / a * 180 / Math.PI, z * 180 / Math.PI }; } public static long[] getTileFromGeo(double lat, double lon, int zoom) { double rLon, rLat, a, k, z; rLon = lon * Math.PI / 180; rLat = lat * Math.PI / 180; a = 6378137; k = 0.0818191908426; z = Math.pow( Math.tan(Math.PI / 4 + rLat / 2) / (Math.tan(Math.PI / 4 + Math.asin(k * Math.sin(rLat)) / 2)), k); return new long[] { (int) (((20037508.342789 + a * rLon) * 53.5865938 / Math.pow(2, (23 - zoom))) / 256), (int) (((20037508.342789 - a * Math.log(z)) * 53.5865938 / Math .pow(2, (23 - zoom)))) / 256 }; } public static double tile2lon(int x, int aZoom) { return (x / Math.pow(2.0, aZoom) * 360.0) - 180; } public static double tile2lat(int y, int aZoom) { final double MerkElipsK = 0.0000001; final long sradiusa = 6378137; final long sradiusb = 6356752; final double FExct = (double) Math.sqrt(sradiusa * sradiusa - sradiusb * sradiusb) / sradiusa; final int TilesAtZoom = 1 << aZoom; double result = (y - TilesAtZoom / 2) / -(TilesAtZoom / (2 * Math.PI)); result = (2 * Math.atan(Math.exp(result)) - Math.PI / 2) * 180 / Math.PI; double Zu = result / (180 / Math.PI); double yy = ((y) - TilesAtZoom / 2); double Zum1 = Zu; Zu = Math.asin(1 - ((1 + Math.sin(Zum1)) * Math.pow(1 - FExct * Math.sin(Zum1), FExct)) / (Math.exp((2 * yy) / -(TilesAtZoom / (2 * Math.PI))) * Math .pow(1 + FExct * Math.sin(Zum1), FExct))); while (Math.abs(Zum1 - Zu) >= MerkElipsK) { Zum1 = Zu; Zu = Math .asin(1 - ((1 + Math.sin(Zum1)) * Math.pow( 1 - FExct * Math.sin(Zum1), FExct)) / (Math.exp((2 * yy) / -(TilesAtZoom / (2 * Math.PI))) * Math .pow(1 + FExct * Math.sin(Zum1), FExct))); } result = Zu * 180 / Math.PI; return result; } public static int[] getMapTileFromCoordinates(final double aLat, final double aLon, final int zoom) { final int[] out = new int[2]; final double E2 = (double) aLat * Math.PI / 180; final long sradiusa = 6378137; final long sradiusb = 6356752; final double J2 = (double) Math.sqrt(sradiusa * sradiusa - sradiusb * sradiusb) / sradiusa; final double M2 = (double) Math.log((1 + Math.sin(E2)) / (1 - Math.sin(E2))) / 2 - J2 * Math.log((1 + J2 * Math.sin(E2)) / (1 - J2 * Math.sin(E2))) / 2; final double B2 = (double) (1 << zoom); out[0] = (int) Math.floor(B2 / 2 - M2 * B2 / 2 / Math.PI); out[1] = (int) Math.floor((aLon + 180) / 360 * (1 << zoom)); return out; } }
      
      







座標を変換するための式があるので、TilesOverlayを展開できます

YandexTilesOverlay
 public class YandexTilesOverlay extends TilesOverlay { private final Rect mTileRect = new Rect(); private final Point mTilePos = new Point(); public YandexTilesOverlay(MapTileProviderBase aTileProvider, Context aContext) { super(aTileProvider, aContext); } //  draw   Yandex  @Override protected void draw(Canvas c, MapView osmv, boolean shadow) { //  int zoom = osmv.getZoomLevel(); final Projection pj = osmv.getProjection(); //     BoundingBoxE6 bb = osmv.getBoundingBox(); //        double[] MercatorTL = YandexUtils.geoToMercator(new double[] { bb.getLonWestE6() / 1E6, bb.getLatNorthE6() / 1E6 }); double[] TilesTL = YandexUtils.mercatorToTiles(MercatorTL); long[] TileTL = YandexUtils.getTile(TilesTL, zoom); double[] MercatorRB = YandexUtils.geoToMercator(new double[] { bb.getLonEastE6() / 1E6, bb.getLatSouthE6() / 1E6 }); double[] TilesRB = YandexUtils.mercatorToTiles(MercatorRB); long[] TileRB = YandexUtils.getTile(TilesRB, zoom); mTileProvider .ensureCapacity((int) ((TileRB[1] - TileTL[1] + 1) * (TileRB[0] - TileTL[0] + 1))); //    Yandex double[] reTiles = YandexUtils.ReGetTile(new long[] { TileTL[0], TileTL[1] }, zoom); long xx = (long) reTiles[0]; long yy = (long) reTiles[1]; double[] reMercator = YandexUtils.tileToMercator(new long[] { xx, yy }); double[] tmp = YandexUtils.mercatorToGeo(reMercator); //    Yandex     osmdroid GeoPoint gp = new GeoPoint(tmp[1], tmp[0]); pj.toPixels(gp, mTilePos); //      Yandex for (int y = (int) TileTL[1]; y <= TileRB[1]; y++) { int xcount = 0; for (int x = (int) TileTL[0]; x <= TileRB[0]; x++) { final MapTile tile = new MapTile(zoom, x, y); final Drawable currentMapTile = mTileProvider.getMapTile(tile); if (currentMapTile != null) { mTileRect.set(mTilePos.x, mTilePos.y, mTilePos.x + 256, mTilePos.y + 256); currentMapTile.setBounds(mTileRect); currentMapTile.draw(c); } xcount++; mTilePos.x += 256; } mTilePos.x -= xcount * 256; mTilePos.y += 256; } } }
      
      







フォームにカードを表示するために残ります

BlogOsmYandexActivity
 public class BlogOsmYandexActivity extends Activity { MapView mMap; MapController mMapController; YandexTilesOverlay tilesOverlayYandex; TilesOverlay tilesOverlayGoogle; TilesOverlay tilesOverlayMapnik; MapTileProviderBasic tileProviderYandex; MapTileProviderBasic tileProviderGoogle; MapTileProviderBasic tileProviderMapnik; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // RelativeLayout rl = new RelativeLayout(this); // mMap = new MapView(this, 256); //     mMap.setBuiltInZoomControls(true); //    rl.addView(mMap, new RelativeLayout.LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); setContentView(rl); //       mMapController = mMap.getController(); mMapController.setZoom(15); mMapController.setCenter(new GeoPoint(55.751893, 37.617166)); //   Yandex //    firebug //getTileURLString   %s     ITileSource tileSourceYandex = new MyTileSource( "YandexMap", null, 0, 23, 256, ".png", "http://vec04.maps.yandex.net/tiles?l=map&v=2.28.0&x=%s&y=%s&z=%s&lang=ru-RU", "http://vec03.maps.yandex.net/tiles?l=map&v=2.28.0&x=%s&y=%s&z=%s&lang=ru-RU", "http://vec02.maps.yandex.net/tiles?l=map&v=2.28.0&x=%s&y=%s&z=%s&lang=ru-RU", "http://vec01.maps.yandex.net/tiles?l=map&v=2.28.0&x=%s&y=%s&z=%s&lang=ru-RU"); //   Google ITileSource tileSourceGoogle = new MyTileSource( "Google-Map", null, 0, 23, 256, ".png", "http://mt0.google.com/vt/lyrs=m&hl=ru&x=%s&y=%s&z=%s&s=Galileo", "http://mt1.google.com/vt/lyrs=m&hl=ru&x=%s&y=%s&z=%s&s=Galileo", "http://mt2.google.com/vt/lyrs=m&hl=ru&x=%s&y=%s&z=%s&s=Galileo", "http://mt3.google.com/vt/lyrs=m&hl=ru&x=%s&y=%s&z=%s&s=Galileo"); //         Yandex tileProviderYandex = new MapTileProviderBasic(getApplicationContext()); tileProviderYandex.setTileSource(tileSourceYandex); tileProviderYandex.setTileRequestCompleteHandler(mMap .getTileRequestCompleteHandler()); //  Yandex  tilesOverlayYandex = new YandexTilesOverlay(tileProviderYandex, this.getBaseContext()); //         Google tileProviderGoogle = new MapTileProviderBasic(getApplicationContext()); tileProviderGoogle.setTileRequestCompleteHandler(mMap .getTileRequestCompleteHandler()); tileProviderGoogle.setTileSource(tileSourceGoogle); //  Google  tilesOverlayGoogle = new TilesOverlay(tileProviderGoogle, this.getBaseContext()); //         Mapnik tileProviderMapnik = new MapTileProviderBasic(getApplicationContext()); tileProviderMapnik.setTileRequestCompleteHandler(mMap .getTileRequestCompleteHandler()); tileProviderMapnik.setTileSource(TileSourceFactory.MAPNIK); //  Mapnik  tilesOverlayMapnik = new TilesOverlay(tileProviderMapnik, this.getBaseContext()); // Yandex    mMap.getOverlayManager().setTilesOverlay(tilesOverlayYandex); } //   / @Override public boolean onCreateOptionsMenu(Menu menu) { SubMenu sm = menu.addSubMenu(" "); sm.add(0, 111, Menu.NONE, ""); sm.add(0, 222, Menu.NONE, "Google"); sm.add(0, 333, Menu.NONE, "Mapnik"); return true; } //      / @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case (111): mMap.getOverlayManager().setTilesOverlay(tilesOverlayYandex); mMap.invalidate(); return true; case (222): mMap.getOverlayManager().setTilesOverlay(tilesOverlayGoogle); mMap.invalidate(); return true; case (333): mMap.getOverlayManager().setTilesOverlay(tilesOverlayMapnik); mMap.invalidate(); return true; default: return super.onOptionsItemSelected(item); } } }
      
      







結果

画像







All Articles