Клуб API Карт

Длина единичного отрезка в метрах

Пост в архиве.

Собственно, как расчитывать сабж?

Поясню. Задача такова - загружается план некой территории, ресайзится на три масштаба: оригинальный размер, 256х256 и средний между ними (все размеры вписываются в прозрачные квадраты со стороной, кратной 256). Затем все это нарезается на тайлы.

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


Мне думается, что это из-за неверного значения сабжа.

Вот код:

    <script>
        YMaps.jQuery(function () {
            var myData = new YMaps.TileDataSource("/media/0/floor/tiles/", 1, 1);
            myData.getTileUrl = function (tile, zoom) {
                return this.getTileUrlTemplate() + zoom + "-" + tile.x + "-" + tile.y + ".png";
            };

            myData.getErrorTileUrl = function() {
                return '{{ static('img/empty.png') }}';
            };


            var myLayer = function () {
                return new YMaps.Layer(myData);
            };

            YMaps.Layers.add("level#map", myLayer);

            // Создаем собственный тип карты
            var myType = new YMaps.MapType(["level#map"], "Floor plan");

            var myCoordSystem = new YMaps.CartesianCoordSystem(
                    new YMaps.Point(0, 0),  

                    new YMaps.Point(1024, 1024), 
                    1,
                    2
                );

            var map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0], {
                coordSystem: myCoordSystem
            });


            map.setCenter(new YMaps.Point(512, 512), 2, myType);

            map.addControl(new YMaps.Zoom({ noTips: true }));
            map.enableScrollZoom();

            var Listener = YMaps.Events.observe(map, map.Events.Click, function (map, mEvent) {
                var style = new YMaps.Style("default#greenPoint");
                style.polygonStyle = new YMaps.PolygonStyle();
                style.polygonStyle.fill = 1;
                style.polygonStyle.outline = 1;
                style.polygonStyle.strokeWidth = 4;
                style.polygonStyle.strokeColor = "ffff0088";
                style.polygonStyle.fillColor = "ff000055";
                YMaps.Styles.add("polygon#Example", style);
                var points = mEvent.getGeoPoint();

                var polygon = new YMaps.Polygon([
                        new YMaps.Point(points.x, points.y)
                    ],{style: "polygon#Example"});

                    map.addOverlay(polygon);
                    polygon.startEditing();

                    Listener.cleanup();

                    $('#mb').click(function() {
                        var pts = polygon.getPoints();
                        for (i in pts){
                            $('#room_add_form').append('<input type="hidden" name="room_params[]" value="' + pts[i]['x'] + ',' + pts[i]['y'] + '">');
                        }
                    });
            });
        });
    </script>

Нормальный полигон: http://img360.imageshack.us/img360/7596/99366572.png

Съехал: http://img715.imageshack.us/img715/9471/46774553.png

20 комментариев
ресайзиться должно не просто в оригинал-средний-256 а четко каждый раз уменьшаться в два раза.
Чтобы правило что в одном тайле находиться 4 тайла след зума выполнялось..
Так и есть?
Андрей Синицын
28 января 2016, 07:48
Ага, так и есть. Ну в данном частном случае именно так :) Но с координатами все равно косяк
промазали :)
 только что проверил линейкой
http://img715.imageshack.us/img715/9471/46774553.png - ширина левого блока 4 сантиметра

http://img360.imageshack.us/img360/7596/99366572.png - ширина левого блока 6 сантиметров.
а должны отличатся РОВНО в два раза
Андрей Синицын
28 января 2016, 07:48
Так, подождите :) Может это я где туплю? :)
Алгоритм таков - если исходноре изображение не квадратное, то я его кладу на прозрачный квадрат со стороной, кратной 256. И, затем, провожу манипуляции с ресайзом. В данном случае у меня получилось:
1. 1 тайл 256х256
2. 4 тайла 256х256
3. 16 тайлов 256х256
Т.е. условие в одном тайле - 4 последующих, вроде как, выполняется? И, следовательно, наложенные полигоны должны вести себя нормально?
при выполнении этих условий при каждом зуме у вас линейные размеры карты увеличиваются в два раза по ширине\высоте.
был один тайл, стало два по x и два по y
всего из одного тайла получаем 4..

еще раз, увеличивается картинки или уменьшается, но ровно в два раза
и еще раз - у вас это правило не выполняется - факт
Андрей Синицын
28 января 2016, 07:48
Сделал с полным выполнением этих условий. Ничего не изменилось, наложенный полигон  ведет себя по прежнему
вот мы мне живой пример пощупать...
Андрей Синицын
28 января 2016, 07:48
Ща устроим :)
ЗЫ Спасибо за помощь!
у вас вообще как горит
я сейчас просто пишу супер-пупер-мега-тайлор, который точно работает стабильно.
Андрей Синицын
28 января 2016, 07:48
Все, отбой :) Сам дурак - действительно накосячил с масштабами. Вы были совершенно правы, огромное спасибо!
линейка и пристреленный глазомер творят чудеса
Кирилл Яковлев
28 января 2016, 07:48

у есть меня вопрос как раз по сабжу..

дано:

  • координаты левого нижнего угла: x1,y1;
  • координаты правого верхнего угла: x2,y2;
  • один слой (в данный момент);
  • m тайлов по горизонтали;
  • n - по вертикали;

какими должны быть параметры декартовой системы координат, для правильной координатной сетки?

Кирилл Яковлев
28 января 2016, 07:48
у есть меня вопрос как раз по сабжу..

будь проклята моя невнимательность..

Кирилл Яковлев
28 января 2016, 07:48
кстати координаты у меня в метрах
Sergey Konstantinov
28 января 2016, 07:48
m и n тайлов - это, видимо, на каком-то конкретном масштабе.
Чтобы не реализовывать свою координатную систему, необходимо, чтобы:
а) m = n = 2 в степени k
б) тайлы готовы для всех уровней масштаба от 0 до k (на нулевом масштабе ровно один тайл 256х256).

Тогда декартова система создается совершенно прозрачно:

new YMaps.CartesianCoordSystem(
  new YMaps.Point(x1, y1), // Координаты левого нижнего угла
  new YMaps.Point(x2, y2), // Координаты правого верхнего угла
  1, // Длина единичного отрезка. Раз Ваши координаты и так в метрах, ставим 1
  k // Максимальный уровень масштаба
)
Кирилл Яковлев
28 января 2016, 07:48
у меня m != k: на нулевом масштабе подразумевается 4 x 7 тайлов.
Кирилл Яковлев
28 января 2016, 07:48
конечно можно сделать нумерацию и координаты углов, как если бы это была часть третьего слоя..
Кирилл Яковлев
28 января 2016, 07:48
точнее только координаты.
Sergey Konstantinov
28 января 2016, 07:48
Я могу Вам посоветовать только напилить еще 36 пустых тайлов, чтобы стало 8х8. Иначе интерфейс координатной системы Вам придется реализовать самому.
4х7,
будем считать что 4х8
да этож третий зум?
скажите что у вас тайлы начинаются с третьего зума, а не давайте карты выбираться выше