Рисунок OSMDroid PathOverlay поврежден при высоком уровне масштабирования - PullRequest
1 голос
/ 14 февраля 2012

Я использую OSMdroid для реализации картографического приложения.

Я реализовал пользовательский MapTileProvider, который использует источник листов, который позволяет увеличивать уровни до 22.

Поставщик MAPNIK по умолчанию разрешает увеличение только до 18 уровня.

Проблема в том, что любые экземпляры PathOverlay отрисовываются отлично до уровня масштабирования 19, но затем не прорисованы должным образом при уровне масштабирования 20-22. похоже, что кто-то стирает дорожку с ластиком на 90% длины пути (см. скриншоты ниже).

Я прошел через метод draw () PathOverlay и exerything кажется, рассчитывается правильно (промежуточные точки кажутся правильными для ZoomLevel 22, а затем проекции XY делятся на 22-ZoomLevel для получить текущие координаты экрана).

Может ли кто-нибудь дать некоторое представление о том, в чем заключается проблема и как ее решить?

То же самое происходит, если я вызываю MapView с использованием небольших плиток Cloudmade, которые позволяют увеличивать изображение до уровня 20 и являются «встроенным» классом поставщиков плиток osmDroid.

    //mMapTileProvider = new HighResMapTileProvider(this);
    mMapTileProvider = new MapTileProviderBasic(this,TileSourceFactory.CLOUDMADESMALLTILES);
    mMapView = new MapView(this, 256, mResourceProxy,mMapTileProvider);

Таким образом, проблема, по-видимому, связана не с источником или поставщиком листов, а с методом рисования на холсте. Любые идеи о том, как решить эту проблему?

На zoomLevel 19 я хорошо вижу свои пути: ZoomLevel 19

Но вот тот же путь на следующем уровне масштабирования: enter image description here

Ответы [ 6 ]

2 голосов
/ 15 февраля 2012

Я нашел обходной путь. Это не идеально, но работает.

Во-первых, если я добавлю canvas.drawCircle (screenPoint1.x, screenPoint1.y, 5, cpaint);

в методе PathOverlay draw () Я вижу это, так что я знаю, что координаты, по крайней мере, вычисляются правильно.

Zoom Level 20

Так что, похоже, проблема связана с основным методом рисования линий в Android.

После некоторых проб и ошибок я обнаружил, что установка STROKE WIDTH на 0.0 для объекта Paint в PathOverlay устраняет проблему, но ширина линии, очевидно, составляет всего 1 пиксель.

Добавление проверки текущего уровня масштабирования в PathOverlay.draw () для установки ширины обводки сохранит текущее поведение для уровней <20 и нарисует линию роста волос для более высоких уровней масштабирования. </p>

Некоторые другие вещи, которые я заметил:

  • Круги становятся квадратами при уровне масштабирования 21 и 22. Это настоятельно предполагает, что есть некоторые проблемы точности с плавающей точкой при передаче очень больших (x, y) координат в Path.lineTo / canvas.drawCircle и т. Д., Например, mPath.lineTo (131000001,38000001)
  • Установка ширины штриха, скажем, 5 видов работы до уровня масштабирования 21, но та же проблема снова возникает на уровне 22 * ​​1021 *
1 голос
/ 03 июля 2012

Обновление: Это было исправлено в osmdroid 3.0.9.

Оригинальный ответ: Эта проблема, кажется, коренится в Android.Я полагаю, что это связано с ошибкой округления, которая возникает при прокрутке представления с большим смещением (возможно, из-за использования SKScalar).Эту ошибку можно изолировать, создав новый проект Android с действием и представлением:

  1. Начните с представления в начале координат без смещения прокрутки.
  2. Нарисуйте круг нахолст: canvas.drawCircle(screenCenterX, screenCenterY, 100, mPaint)
  3. Прокрутите представление до большого числа: mainView.scrollTo(536870912, 536870912)
  4. Нарисуйте круг на холсте: canvas.drawCircle(newScreenCenterX, newScreenCenterY, 100, mPaint)

Первыйкруг рисует нормально, второй рисует искажено.Чтобы получить дополнительные доказательства, попробуйте нарисовать ваш путь около 0 широта / 0 в длину и увеличить масштаб - заметьте, что искажение больше не появляется.

Я обновлю билет osmdroid с некоторыми возможными решениями обходными путями.

1 голос
/ 14 февраля 2012

Я вполне уверен, что это потому, что по умолчанию PathOverlay рисует только линию между точками в представлении.Если точка находится за пределами текущего представления, отрезок линии не рисуется.При более низких уровнях масштабирования вы просто не видите, что часть линии, выходящей из вида, не отображается, так как все секции маленькие.

Я думаю, у вас есть 2 варианта.

Легким, но, возможно, не самым лучшим является поставить больше точек на пути, тогда, по крайней мере, проблема будет менее заметна.Если это хорошая идея или нет, это будет зависеть от того, сколько точек у вас уже есть.

Основным решением будет расширение класса и создание собственного метода рисования, а затем обрезать отрезок линии, который выходит из представления, накрай взгляда.В идеале вы должны внести свой код обратно в источник.

0 голосов
/ 09 августа 2013

Чтобы решить эту проблему, нам нужно реализовать алгоритм отсечения строк. Обрезая область просмотра карты, путь добавляет больше вершин. Таким образом, он будет нарисован правильно при большом уровне масштабирования.

0 голосов
/ 02 марта 2012

Я согласен, что это ошибка, связанная с OSMDROID, потому что я получил ту же рабочую функцию DrawPath (уровень масштабирования 21 и 22), используя Google MapView. Я надеюсь, что они смогут решить эту проблему.

0 голосов
/ 21 февраля 2012

У меня та же проблема, и я разместил ошибку на OSMDroid здесь:

http://code.google.com/p/osmdroid/issues/detail?can=2&start=0&num=100&q=221&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary&groupby=&sort=&id=221

Я не уверен, является ли это проблемой OSMDroid или просто слишком большойcanvas.

Другой обходной путь - рисование на новом меньшем холсте (размер текущего видимого mapView) и использование drawBitmap в верхнем левом углу большого холста.Только помните, что не нужно создавать новые растровые изображения при каждом рисовании - потому что это дорого.

Все фигуры нарисованы отлично, но я борюсь с другой проблемой - не плавным панорамированием на уровнях> 18. Вы можете видеть это, когда вы панорамируете картуон перемещает не каждый пиксель, как на уровнях <18, но он перепрыгивает через несколько пикселей. </p>

...