API на Google Maps v3 ImageMapType

Следвам примера за API на Google Maps v3 ImageMapType тук: https://developers.google.com/maps/documentation/javascript/examples/maptype-image

Но нямам ясно разбиране от документацията как работят плочките/увеличението. Засега просто се опитвам да го накарам да работи с 0 увеличение. След като се справя с това, мога да разбера частта за увеличение.

Изображението ми е 2000px X 2000px. Нарязах го на 8 плочки по 8 плочки по 250px X 250px на плочка.

Правя console.log на getTileUrl. Очаквах да видя всичките си 64 плочки, заредени от 0-0.png до 7-7.png, но виждам, че 0-0.png се опитва да се зареди девет пъти.

Създадох този http://jsfiddle.net/2N2sy/1/ (код по-долу), за симулира моя код.

Помощ за разплитане на плочките/увеличаване ще бъде високо оценена!

function getNormalizedCoord(coord, zoom) {
    var y = coord.y;
    var x = coord.x;

    // tile range in one direction range is dependent on zoom level
    // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc
    var tileRange = 1 << zoom;

    // don't repeat across y-axis (vertically)
    if (y < 0 || y >= tileRange) {
        return null;
    }

    // repeat across x-axis
    if (x < 0 || x >= tileRange) {
        x = (x % tileRange + tileRange) % tileRange;
    }

    return {
        x: x,
        y: y
    };
}

var map;

function initMaps() {

    $.getScript("http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js").done(function (script, textStatus) {

        var customMapTypeOptions = {
            getTileUrl: function (coord, zoom) {
                var normalizedCoord = getNormalizedCoord(coord, zoom);
                if (!normalizedCoord) {
                    return null;
                }
                var bound = Math.pow(2, zoom);
                console.log('http://img.photobucket.com/albums/v229/s15199d/ + normalizedCoord.x + '-' + (bound - normalizedCoord.y - 1) + '.png');
                return 'http://img.photobucket.com/albums/v229/s15199d/ + normalizedCoord.x + '-' + (bound - normalizedCoord.y - 1) + '.png';
            },
            tileSize: new google.maps.Size(250, 250),
            maxZoom: 0,
            minZoom: 0,
            radius: 1738000,
            name: 'custom map'
        };

        var customMapType = new google.maps.ImageMapType(customMapTypeOptions);

        var latlng = new google.maps.LatLng(0, 0), // center point

        mapOptions = {
            zoom: 0,
            center: latlng,
            draggable: true,
            scrollwheel: false,
            mapTypeControl: false,
            panControl: false,
            scaleControl: false,
            zoomControl: true,
            zoomControlOptions: {
                style: google.maps.ZoomControlStyle.LARGE,
                position: google.maps.ControlPosition.RIGHT_TOP
            },
            streetViewControl: false,
            streetViewControlOptions: {
                position: google.maps.ControlPosition.RIGHT_TOP
            },        
            mapTypeControlOptions: {
                mapTypeIds: ['custom map']
            }
        };

        map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

        map.mapTypes.set('custom map', customMapType);
        map.setMapTypeId('custom map');

    });
}

$(function () {
    if (window.google && google.maps) {
        //alert("Map script is already loaded. Initializing");
        initMaps();
    } else {
        //alert("Lazy loading Google map...");
        lazyLoadGoogleMap();
    }

});

function lazyLoadGoogleMap() {
    $.getScript("http://maps.google.com/maps/api/js?sensor=true&callback=initMaps")
    .done(function (script, textStatus) {
        //alert("Google map script loaded successfully");
    })
    .fail(function (jqxhr, settings, ex) {
        //alert("Could not load Google Map script: " + jqxhr);
    });
}

person s15199d    schedule 01.08.2014    source източник
comment
@geocodezip благодаря, че поправи моя jsfiddle! Виждате само 3x от console.log поради ширината на изходния прозорец на jsfiddle. Ако разширите прозореца по-широко, ще видите повече итерации на console.log   -  person s15199d    schedule 04.08.2014
comment
Връзката към Fiddle не е правилна.   -  person MrUpsidown    schedule 06.08.2014
comment
Само с удар и изпитание. тази цигулка връзка работи: jsfiddle.net/2N2sy/1   -  person SSA    schedule 06.08.2014


Отговори (2)


Вие му казвате да го направи. Ако погледнете вашата getNormalizedCoord функция, ще видите, че очаквате tileRange от 1. След това проверявате x координатата спрямо tileRange. Тъй като това е 1, всички стойности над или равни на 1 ще бъдат нормализирани надолу (само една опция под 1 и това е нула).

Ако следвате логиката, той прави следното:

  1. Задайте x на 1 % 1 (това е 0)
  2. Задайте x на 0 + 1 (това е 1)
  3. Задайте x на 1 % 1 (това отново е 0)

Така че при нивото на мащабиране, което сте избрали, функцията с право винаги връща 0. Ако опитате с по-голямо ниво на мащабиране, ще забележите, че зарежда другите ви плочки.

Една от грешките, които допускате (според мен), е, че сте получили нивата на мащабиране наобратно: 0 е напълно намалено, а 9 е напълно увеличено. Примерът, който сте използвали, се основава на едно общо изображение за ниво на мащабиране 0 и по-малки парчета на всяка стъпка се увеличават допълнително. Следователно трябва да очаквате една плочка (0, 0) да бъде заредена при ниво на увеличение 0. За да заредите всичките 64 плочки, ще ви трябва по-високо ниво на увеличение. Множеството извиквания към един и същ URL адрес са просто API, използващ своя кеш за попълване на плочките. Ако погледнете примера, той просто повтаря същото изображение по оста X и там.


За да обобщим какво се обсъжда в коментарите, нивото на мащабиране, при което използваната функция за нормализиране ще зареди всички плочки, е 3. В момента плочките се зареждат с обърната ос y. За да коригирате това, ще трябва да промените следния ред в getTileUrl от (bound - normalizedCoord.y - 1) на (normalizedCoord.y - 1).

Цялата идея за мащабиране в Google Maps се основава на зареждане на изображения с по-високо ниво на детайлност за една и съща мрежа с плочки, което дава идеята за допълнително увеличение. За да постигнете това, ще трябва да създадете допълнителни изображения.

Ако нямате / не се нуждаете от изображения с допълнителни детайли, можете или да изберете да фиксирате нивото на увеличение на 3 (така или иначе никой никога няма да забележи) и да разположите така или да почистите (може би дори да премахнете) кода за нормализиране, за вашите нужди. Понастоящем функцията отговаря за повтарянето на едни и същи изображения по оста X, без изобщо да се повтаря по оста Y. За повторението по оста X се разглежда нивото на мащабиране, за да се определи колко плочки трябва да бъдат заредени, преди да се увие отново до 0.

От въпроса не мога да разбера дали имате нужда от опаковката или просто го взех от примера. Нито мога да кажа дали имате още изображения или не. Поради това не мога да ви дам готов за използване код, защото нямам никакви спецификации, с които да работя.


Ако не се нуждаете от обвиване, накарайте го да обработва координатите X, както го прави с координатите Y:

function getNormalizedCoord(coord, zoom) {
    var y = coord.y;
    var x = coord.x;

    // tile range in one direction range is dependent on zoom level
    // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc
    var tileRange = 1 << zoom;

    // don't repeat across y-axis (vertically)
    if (y < 0 || y >= tileRange) {
        return null;
    }

    // don't repeat across x-axis (horizontally)
    if (x < 0 || x >= tileRange) {
        return null;
    }

    return {
        x: x,
        y: y
    };
}

(Имайте предвид, че тези два оператора if могат да бъдат свити в едно, просто исках да е лесно да забележите какви промени влияят на това поведение)

person gpgekko    schedule 06.08.2014
comment
@SSA Основният проблем е, че никой не може наистина да „поправи“ мащабирането, тъй като нямаме представа кои изображения са налични. В момента просто се пропускат части от цялостното изображение при различни нива на мащабиране. Тъй като той го наряза в 8x8, функцията за нормализиране би предположила, че ниво на увеличение 3 е това, което показва пълната картина. Въпреки това, тъй като оста Y на предоставените изображения е обърната по грешен начин, всичко изглежда странно. - person gpgekko; 06.08.2014
comment
@gpgekko благодаря за това обяснение. Увеличаването на увеличението по подразбиране и минималното/максималното увеличение всъщност зарежда повече от моите плочки, но те не са в правилния ред. Означих моите 64 заглавия от 0-0.png до 7-7.png, където 0-0 е горният ляв ъгъл, а 7-7 е долният десен ъгъл. Какво ми липсва, за да заработя картата си? - person s15199d; 06.08.2014
comment
@gpgekko искаш да кажеш, че моите x/y са обърнати в името на заглавието ми? - person s15199d; 06.08.2014
comment
@s15199d Всъщност (0,0) е в горния ляв ъгъл и (7,7) в долния десен ъгъл. Изображенията обаче изглеждат обърнати с главата надолу. - person gpgekko; 06.08.2014
comment
@s15199d Това всъщност е примерният код, който обръща нещата. Променете реда с (bound - normalizedCoord.y - 1) на (normalizedCoord.y - 1) (също коригирайте увеличението на 3), вече ще изглежда много по-добре (бих публикувал цигулка, но изглежда, че jsfiddle не работи). - person gpgekko; 06.08.2014
comment
@s15199d След като плочките са оправени, единственото нещо, което остава, е увеличението. Нещото, за което не съм сигурен, е какво искате да покажете на другите нива на увеличение. Имате изображения само за едно ниво на детайлност, така че до какво да увеличавате? - person gpgekko; 06.08.2014
comment
Благодаря @gpgekko! Как трябва да се наименува втората плочка от левия ред 0? 0-1.png или 1-0.png? Що се отнася до това, което искам да прави мащабирането... искам да започна от ниво на мащабиране 1 и да дам на потребителя възможността да увеличава/намалява оттам. Знам, че ще ми трябват 0, 1, 2, 3 папки за увеличението. С 64 резена в папка-3. Колко среза трябва да са папки 0, 1 и 2? - person s15199d; 06.08.2014
comment
@s15199d Google предоставя обозначена примерна мрежа в документи. Според това би било 1-0 (така X-Y). Що се отнася до срезовете, ако продължите да използвате функцията за нормализиране, има коментар, описващ броя на плочките в ред за всяко ниво на мащабиране: // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc. Така че ще бъде 1, 4, 16, 64 за нива на мащабиране 0, 1, 2, 3. - person gpgekko; 06.08.2014
comment
Наименувах правилно. Успяхте, като премахнахте bound - @gpgekko, толкова сте полезни, благодаря! Почти го направих. Дано това е последният ми въпрос. Ако изображението ми е 2000px X 2000px при ниво на мащабиране 3. Какви трябва да са размерите на изображението ми при нива на мащабиране 0, 1, 2? - person s15199d; 06.08.2014
comment
@s15199d Зависи от качеството на изображението, но вече ще работи, ако просто запазите текущите размери и го нарежете на по-малки парчета. Това ще позволи на хората да погледнат по-отблизо без артефакти от преоразмеряване. - person gpgekko; 06.08.2014
comment
@s15199d Ех, умнико, това разбира се няма да работи, защото няма да получите плочките 250x250. Което означава, че трябва да направите математиката по обратния начин, така че за нулево ниво на мащабиране ще получите 250x250, едно ще бъде (250x2) 500x500, две ще бъде (250x4) 1000x1000. - person gpgekko; 06.08.2014
comment
Нека продължим тази дискусия в чата. - person s15199d; 06.08.2014
comment
Може да пробутвам късмета си тук @gpgekko, но знаете ли как да го настроя, за да попреча на картата ми да се повтаря хоризонтално? - person s15199d; 06.08.2014
comment
Никога не съм бил сигурен дали получавате известия за чат, когато сте офлайн, така че ето коментар, за да отбележа, че отговорих там и добавих фрагмент към отговора си тук. Надяваме се, че това ще ви помогне да продължите напред. - person gpgekko; 06.08.2014

Изглежда, че имате проблем с нивото на мащабиране. Чрез промяна на minZoom и maxZoom в обекта customMapTypeOptions на '0' и '2' съответно и задаване на началното увеличение на '1' в обекта mapOptions, приложението извика изображения '0-1', '0-0',' 1-1' и '1-0' при натоварване.

След като проучих примера на Google, който посочихте, забелязах, че когато URL адресът за тяхната плочка на картата включва нивото на увеличение в URL адреса. Ето пример за една плочка, извикана при ниво на мащабиране 0:

http://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw/0/0/0.jpg

Обърнете внимание на последните три числа, ".../0/0/0.jpg". След като увеличих мащаба до ниво 1, първите две плочки на картата, извикани беше, имат URL адресите:

http://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw/1/0/1.jpg
http://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw/1/0/0.jpg

Забележете как са се променили последните три числа. Вярвам, че първото число е нивото на мащабиране, при което изображението трябва да се показва, последвано от x & y на позицията на изображенията в мрежата с плочки на картата.

Според коментар в примерния код:

// tile range in one direction range is dependent on zoom level
// 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc
var tileRange = 1 << zoom;

ще използвате един файл с изображение за ниво на мащабиране 0 (поради което 0-0 е единственото ви заредено изображение), 2 изображения за ниво на мащабиране 1, 4 изображения за ниво на мащабиране 2 и т.н.

person Xion Dark    schedule 06.08.2014