Здравствуйте!
Существует много способов отображения различной информации на карте в приложении для платформы Android, например, Google Maps или Яндекс Карты, но, пожалуй, самым быстрым и гибким способом является использование библиотеки osmdroid, т.к. для ее использования не потребуется получения API-ключа, исходный код библиотеки открыт, есть возможность отображать карты из различных источников (например, OpenStreetMap и др.), добавлять новые без существенной доработки исходного кода библиотеки или вовсе без доработки. Загруженные карты сохраняются на карте памяти и доступны без подключения к сети Internet.
В этой заметке, рассмотрим:
Скачаем основную библиотеку и вспомогательную, которая требуется для работы основной и добавим их в наш проект.
В манифест добавим разрешения для нашего приложения
"android.permission.INTERNET"
"android.permission.WRITE_EXTERNAL_STORAGE" "android.permission.ACCESS_COARSE_LOCATION" "android.permission.ACCESS_FINE_LOCATION" "android.permission.ACCESS_NETWORK_STATE"
"android.permission.ACCESS_WIFI_STATE"
2. Размещение карты в разметке
Разметка нашей Activity с картой будет динамической, т.е. создадим ее в процессе выполнения приложения в методе onCreate
Существует много способов отображения различной информации на карте в приложении для платформы Android, например, Google Maps или Яндекс Карты, но, пожалуй, самым быстрым и гибким способом является использование библиотеки osmdroid, т.к. для ее использования не потребуется получения API-ключа, исходный код библиотеки открыт, есть возможность отображать карты из различных источников (например, OpenStreetMap и др.), добавлять новые без существенной доработки исходного кода библиотеки или вовсе без доработки. Загруженные карты сохраняются на карте памяти и доступны без подключения к сети Internet.
В этой заметке, рассмотрим:
- Добавление библиотеки в проект (Eclipse, Windows)
- Размещение карты в разметке
- Добавление нового источника карт
- Переключение между поставщиками карт, изменение масштаба, центра карты
- Вывод информации на карту
Скачаем основную библиотеку и вспомогательную, которая требуется для работы основной и добавим их в наш проект.
"android.permission.INTERNET"
"android.permission.WRITE_EXTERNAL_STORAGE" "android.permission.ACCESS_COARSE_LOCATION" "android.permission.ACCESS_FINE_LOCATION" "android.permission.ACCESS_NETWORK_STATE"
"android.permission.ACCESS_WIFI_STATE"
2. Размещение карты в разметке
Разметка нашей Activity с картой будет динамической, т.е. создадим ее в процессе выполнения приложения в методе onCreate
private MapView mMap;@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final 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); }
3. Добавление нового источника карт
Чтобы добавить новый источник создадим новый класс наследник XYTileSource и добавим в наш пакет.public class myNoYandexTileSource extends XYTileSource{ public myNoYandexTileSource(String aName, string aResourceId, int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels, String aImageFilenameEnding, String... aBaseUrl) { super(aName, aResourceId, aZoomMinLevel, aZoomMaxLevel, aTileSizePixels, aImageFilenameEnding, aBaseUrl); // TODO Auto-generated constructor stub } @Override public String getTileURLString(MapTile aTile) { // TODO Auto-generated method stub return String.format(getBaseUrl(), aTile.getX(), aTile.getY(), aTile.getZoomLevel()); } }И создадим экземпляры этого класса
//Google Maps final ITileSource tileSourceGoogleMap=new myNoYandexTileSource("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"); mTileSources.add(tileSourceGoogleMap); /Google Maps Sat final ITileSource tileSourceGoogleSat=new myNoYandexTileSource("Google-Sat", null, 0, 23, 256, ".png", "http://khm0.google.ru/kh/v=95&x=%s&y=%s&z=%s&s=Galileo", "http://khm1.google.ru/kh/v=95&x=%s&y=%s&z=%s&s=Galileo", "http://khm2.google.ru/kh/v=95&x=%s&y=%s&z=%s&s=Galileo", "http://khm3.google.ru/kh/v=95&x=%s&y=%s&z=%s&s=Galileo");4. Переключение между поставщиками карт, изменение масштаба, центра карты
Отображать Google Maps Карты
mMap.setTileSource(tileSourceGoogleMap);Отображать Google Maps Спутник
mMap.setTileSource(tileSourceGoogleSat);
Отображать OpenStreetMapmMap.setTileSource(TileSourceFactory.MAPNIK);Изменение масштаба
mMap.getController().setZoom(10);
Перемещение центра картыGeoPoint p = new GeoPoint(55.786438, 49.122458);
mMap.getController().animateTo(p);
5. Вывод информации на карту
final ArrayList items = new ArrayList();
items.add(new OverlayItem("Казань", "Татарстан", new GeoPoint(55.786438, 49.122458)));
ItemizedIconOverlay MyLocationOverlay = new ItemizedIconOverlay(this, items, null);
mMap.getOverlays().add(MyLocationOverlay);
Замечу, что Яндекс Карты добавленные описанным способом будут отображаться неверно из-за того, что библиотека не поддерживает нужной проекции. В следующих заметках постараюсь описать, как это исправить без изменения кода библиотеки и доработав код.
Пытаюсь делать всё по инструкции и сталкиваюсь с такой ошибкой: java.lang.NoClassDefFoundError: org.osmdroid.views.MapView
ОтветитьУдалитьЯ понимаю, что не получается найти класс, но библиотеки я добавил, их видно...
если библиотеки добавлены, попробуй сделать Android Tools -> Fix Project Properties
ОтветитьУдалитьну так что там с яндекс картами то?
ОтветитьУдалитьвсе отлично, выводятся
Удалитья про пересчет проекции:
Удалить"Замечу, что Яндекс Карты добавленные описанным способом будут отображаться неверно из-за того, что библиотека не поддерживает нужной проекции. В следующих заметках постараюсь описать, как это исправить без изменения кода библиотеки и доработав код."
схема такая
Удалить1.Расширяешь класс XYTileSource, он будет генерить ссылку на тайл c сервера яндекс
2.Расширяешь класс TilesOverlay, он будет отрисовывать тайлы (пересчет координат в тайлы и обратно для яндекса легко найдешь в сети), пример такого класса есть в исходниках osmdroid(osmdroid-third-party)
3. выводишь все на карту
tileProviderYandex = new MapTileProviderBasic(getApplicationContext());
tileProviderYandex .setTileSource(экземпляр класса созданного на первом шаге);
tilesOverlayYandex = new КлассСозданныйНаВторомШаге(tileProviderYandex, this.getBaseContext());
mMap.getOverlays().add(tilesOverlayYandex);
не могли бы Вы привести код данных классов
Удалитьвот ссылка http://www.geofaq.ru/forum/index.php?action=vthread&forum=2&topic=7&page=5#msg1152
УдалитьЗдравствуйте!
УдалитьПри таком способе возникают проблемы при смене зума. Видны тайлы в неправильной проекции, до того как загрузятся нужные в overlay. Если подсунуть фейковые, пустые тайлы - все равно при зуме проблемы:
1)решетка, вместо масштабируемого изображения предыдущего zoomlevel'a
2)на части экрана снова куски карты, хоть и из нужной области экрана, но явно с неправильным масштабом и позицией.
Не могли бы вы подсказать, есть какой-то альтернативный способ корректировки проекции, чтобы она применялась как tileSource, а не overlay. Или это у Вас все зумится корректно?
наверное, ты где-то ошибся, у меня все работает нормально
Удалитьименно с этим расчетом я и экспериментировал до вопросов Вам, подозреваю что Вы меня попросите показать код, встречный вопрос - Вам какой из ДЕСЯТКОВ вариантов?
ОтветитьУдалитьне угадал ), не попрошу, у меня есть рабочий код )
Удалитьа у тебя все есть, чтобы вывести тайл яндекса, в чем проблема?
проблема в том что тайлы получаю, и вроде как нужные, а показать их в правильном месте не выходит
Удалитьпиши на почтовый адрес, который укащан в профиле
Удалить