рдПрдХ рдмрд╛рд░ рдореИрдВрдиреЗ рдЗрд╕
рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдерд╛ рдХрд┐ рдЖрдк рд╡реЗрдм рдкрд░ рдмрд┐рдирд╛ рдиреЗрдЯрд╡рд░реНрдХ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ Google рдорд╛рдирдЪрд┐рддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЙрдкрдпреЛрдЧ рдХреА рд╢рд░реНрддреЛрдВ рдиреЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдордирд╛ рдХрд┐рдпрд╛ рдерд╛, рдФрд░ рдореИрдВрдиреЗ рдЬреЛ рдХреЛрдб рд▓рд┐рдЦрд╛ рдерд╛ рд╡рд╣ рдХреЗрд╡рд▓
localStorage
рд╕рд╛рде рдХрд╛рдо рдХрд┐рдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдмрд▓ рдХреЗ рдЙрдЬреНрдЬреНрд╡рд▓ рдкрдХреНрд╖ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдЬрд╣рд╛рдВ рдХреЛрдб рдЦреБрд▓рд╛, рд╕рд░рд▓ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд╣реИред
рдореБрдЭреЗ рдХреНрдпрд╛ рдЪрд╛рд╣рд┐рдП?
рдореИрдВ рдПрдХ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдмрд┐рдирд╛ рдкреВрд░реНрдг рдХрд╛рдо рдХреЗ рд▓рд┐рдП рдореИрдк рдХреИрд╢рд┐рдВрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдкрд╣рд▓реА рдмрд╛рд░ рдЬрдм рдЖрдк рдореИрдк рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдмреНрдпрд╛рдЬ рдХреА рдЯрд╛рдЗрд▓реЗрдВ рджреЗрдЦреЗрдВ (рдЬреЛ рдХрд┐ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдХреИрд╢ рдХреА рдЬрд╛рдПрдВрдЧреА) рдФрд░ рдЕрдЧрд▓реА рдмрд╛рд░ рджреЗрдЦреЗ рдЧрдП рдЯрд╛рдЗрд▓реЛрдВ рд╡рд╛рд▓рд╛ рдореИрдк рдмрд┐рдирд╛ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реБрд▓рдн рд╣реЛрдЧрд╛ред
рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдордХреНрдЦреА рдкрд░ рдХреИрд╢рд┐рдВрдЧ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЖрдк рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ рд╕реЗ рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдореИрдВ рд╕рд┐рд░реНрдл рджреГрд╖реНрдЯрд┐рдХреЛрдг рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреНрдпрд╛ рд╣реИ?
рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрдзреБрдирд┐рдХ рд╡реЗрдм рдореЗрдВ, рдЖрдк рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ:
рдЖрд╡реЗрджрди рдХреИрд╢ - рд╕реНрдЯреИрдЯрд┐рдХреНрд╕ рдХреЗ рд▓рд┐рдП, рд▓реЗрдХрд┐рди рдЯрд╛рдЗрд▓реНрд╕ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВред
рд▓реЛрдХрд▓ рд╕реНрдЯреЛрд░реЗрдЬ - рдмреЗрд╕ 64 рдбреЗрдЯрд╛ рдпреВрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝ рдХрд░рддреЗ рд╣реБрдП, рд╣рд░ рдЬрдЧрд╣ рд╕рдорд░реНрдерд┐рдд, рд▓реЗрдХрд┐рди рдмрд╣реБрдд рдХрдо рдЬрдЧрд╣ред
рдЕрдиреБрдХреНрд░рдорд┐рдд рдбреАрдмреА - рдмреЗрд╕ 64 рдбреЗрдЯрд╛ рдпреВрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ, рдкреВрд░реНрдг рдФрд░ рдореЛрдмрд╛рдЗрд▓ рдХреНрд░реЛрдо, рдПрдлрдПрдл, рдпрд╛рдиреА 10 рдореЗрдВ рд╕рдорд░реНрдерд┐рдд рд╣реИред
рд╡реЗрдм рдПрд╕рдХреНрдпреВрдПрд▓ - рдмреЗрд╕ 64 рдбреЗрдЯрд╛ рдпреВрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ, рдЪрд┐рд╣реНрдирд┐рдд рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд, рдкреВрд░реНрдг рдФрд░ рдореЛрдмрд╛рдЗрд▓ рдХреНрд░реЛрдо, рд╕рдлрд╛рд░реА, рдУрдкреЗрд░рд╛, рдПрдВрдбреНрд░реЙрдЗрдб рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рд╕рдорд░реНрдерд┐рддред
рдлрд╝рд╛рдЗрд▓ рд▓реЗрдЦрдХ рдХреЗрд╡рд▓ рдХреНрд░реЛрдо рд╣реИред
рдЖрдк рдЯрд╛рдЗрд▓реЛрдВ рдХреЗ рдХрдмреНрдЬреЗ рд╡рд╛рд▓реЗ рд╕реНрдерд╛рди рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
рдмреНрд▓рдмреНрд╕ рдФрд░
рдмреНрд▓реЙрдм рдпреВрд░рд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рднреА рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдХреЗрд╡рд▓
рдЕрдиреБрдХреНрд░рдорд┐рдд рдбреАрдмреА рдХреЗ рд╕рд╛рде рдорд┐рд▓рдХрд░ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдореИрдВ рдЕрдм рдЗрд╕ рдЙрджреНрдпрдо рдХреЛ рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ред
рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдЖрдк
рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╢ ,
рдЕрдиреБрдХреНрд░рдорд┐рдд рдбреАрдмреА рдФрд░
рд╡реЗрдм рдПрд╕рдХреНрдпреВрдПрд▓ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдореЛрдмрд╛рдЗрд▓ рд╕рд╣рд┐рдд рдЖрдзреБрдирд┐рдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдЯрд╛рдЗрд▓реНрд╕ рдХреЗ рднрдВрдбрд╛рд░рдг рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╕рд┐рджреНрдзрд╛рдВрдд
рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рд╣рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
- рдПрдкреАрдЖрдИ рд▓реЗ;
- рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╢ рдореЗрдВ рд╕рднреА рд╕реНрдЯреЗрдЯрд┐рдХреНрд╕ рдЬреЛрдбрд╝реЗрдВ;
- рдЯрд╛рдЗрд▓ рдХреА рдкрд░рдд рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ рддрд╛рдХрд┐ рдпрд╣ рд╣рдорд╛рд░реЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рднрдВрдбрд╛рд░рдг рд╕реЗ рдбреЗрдЯрд╛ рдХреЛ рд▓реЛрдб рдХрд░реЗ;
- рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдЯрд╛рдЗрд▓ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрд░реНрдХ рдЬреЛрдбрд╝реЗрдВред
рдХреЛрд╖
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЗрдВрдбреЗрдХреНрд╕реЗрдб рдбреАрдмреА рдФрд░ рд╡реЗрдм рдПрд╕рдХреНрдпреВрдПрд▓ рдХреЗ рд▓рд┐рдП рдмреБрдирд┐рдпрд╛рджреА рд╕рдВрдЪрд╛рд▓рди рдЬреЛрдбрд╝рдиреЗ, рд╣рдЯрд╛рдиреЗ, рдХреЗ рд╕рд╛рде рдХреБрдВрдЬреА-рдореВрд▓реНрдп рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХрд╛ рдЖрдпреЛрдЬрди рдХрд░рддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдПрдХ рдЬрд╛рджреВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг
emr.fire('storageLoaded', storage);
, рдЬрд┐рд╕реЗ рддрд┐рдЬреЛрд░реА рд╢реБрд░реВ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рддрд╛рдХрд┐ рддрд┐рдЬреЛрд░реА рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рджреМрд░рд╛рди рдХрд╛рд░реНрдб рдЧрд┐рд░ рди рдЬрд╛рдПред
рдЕрдиреБрдХреНрд░рдорд┐рдд рдбреАрдмреА рдХреЗ рд╕рд╛рде рднрдВрдбрд╛рд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ var getIndexedDBStorage = function () { var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; var IndexedDBImpl = function () { var self = this; var db = null; var request = indexedDB.open('TileStorage'); request.onsuccess = function() { db = this.result; emr.fire('storageLoaded', self); }; request.onerror = function (error) { console.log(error); }; request.onupgradeneeded = function () { var store = this.result.createObjectStore('tile', { keyPath: 'key'}); store.createIndex('key', 'key', { unique: true }); }; this.add = function (key, value) { var transaction = db.transaction(['tile'], 'readwrite'); var objectStore = transaction.objectStore('tile'); objectStore.put({key: key, value: value}); }; this.delete = function (key) { var transaction = db.transaction(['tile'], 'readwrite'); var objectStore = transaction.objectStore('tile'); objectStore.delete(key); }; this.get = function (key, successCallback, errorCallback) { var transaction = db.transaction(['tile'], 'readonly'); var objectStore = transaction.objectStore('tile'); var result = objectStore.get(key); result.onsuccess = function () { successCallback(this.result ? this.result.value : undefined); }; result.onerror = errorCallback; }; }; return indexedDB ? new IndexedDBImpl() : null; };
рд╡реЗрдм рдПрд╕рдХреНрдпреВрдПрд▓ рдХреЗ рд╕рд╛рде рднрдВрдбрд╛рд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ var getWebSqlStorage = function () { var openDatabase = window.openDatabase; var WebSqlImpl = function () { var self = this; var db = openDatabase('TileStorage', '1.0', 'Tile Storage', 5 * 1024 * 1024); db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS tile (key TEXT PRIMARY KEY, value TEXT)', [], function () { emr.fire('storageLoaded', self); }); }); this.add = function (key, value) { db.transaction(function (tx) { tx.executeSql('INSERT INTO tile (key, value) VALUES (?, ?)', [key, value]); }); }; this.delete = function (key) { db.transaction(function (tx) { tx.executeSql('DELETE FROM tile WHERE key = ?', [key]); }); }; this.get = function (key, successCallback, errorCallback) { db.transaction(function (tx) { tx.executeSql('SELECT value FROM tile WHERE key = ?', [key], function (tx, result) { successCallback(result.rows.length ? result.rows.item(0).value : undefined); }, errorCallback); }); }; }; return openDatabase ? new WebSqlImpl() : null; };
рднрдВрдбрд╛рд░рдг рд╕реГрдЬрди var storage = getIndexedDBStorage() || getWebSqlStorage() || null; if (!storage) { emr.fire('storageLoaded', null); }
рдореИрдВ рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмрд╣реБрдд рд╣реА рд╕реНрдХреЗрдЪ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдб рдХреЗ рдЖрд░рдВрднреАрдХрд░рдг рдХреЛ рдЕрд╡рд░реБрджреНрдз рдирд╣реАрдВ рдХрд░рдирд╛ рдЬрдмрдХрд┐ рднрдВрдбрд╛рд░рдг рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╣реИ; рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рдПрдкреАрдЖрдИ рдХреЛ рд╕реАрдзреЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдП рдмрд┐рдирд╛ рдХреМрди рд╕реЗ рдЯрд╛рдЗрд▓реЗрдВ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╣реИрдВ; рдбрд┐рд╕реНрдХ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓реЗрдирджреЗрди рдореЗрдВ рдХрдИ рдмрдЪрдд рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ; рдЬрд╣рд╛рдВ рд╡реЗ рд╕рдорд░реНрдерд┐рдд рд╣реИрдВ, рдмреНрд▓рдмреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рд╢рд╛рдпрдж рдкреБрд░рд╛рдиреЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдореЗрдВ рдЕрдиреБрдХреНрд░рдорд┐рдд рдбреАрдмреА рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЧрд┐рд░рд╛рд╡рдЯ рдЖрдПрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рдЙрди рдкрд░
onupgradeneeded
рдШрдЯрдирд╛ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
URI рдФрд░ CORS рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП IMG
рдЯрд╛рдЗрд▓реЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдпреВрдЖрд░рдЖрдИ, рдЕрд░реНрдерд╛рддреН рдПрдХ рдмреЗрд╕ 64 рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдбреЗрдЯрд╛ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХреИрдирд╡рд╛рд╕ рдФрд░ рдЙрд╕рдХреЗ
toDataURL
рдпрд╛
getImageData
рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
_imageToDataUri: function (image) { var canvas = window.document.createElement('canvas'); canvas.width = image.width; canvas.height = image.height; var context = canvas.getContext('2d'); context.drawImage(image, 0, 0); return canvas.toDataURL('image/png'); }
рдЪреВрдВрдХрд┐ html img рддрддреНрд╡ рдХрд┐рд╕реА рднреА рдЙрдкрд▓рдмреНрдз рд╕рдВрд╕рд╛рдзрди рдХреЛ рдЪрд┐рддреНрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЕрдзрд┐рдХреГрдд рд╕реЗрд╡рд╛рдУрдВ рдФрд░ рд╕реНрдерд╛рдиреАрдп рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЗрд╕ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдХрд┐рд╕реА рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЛ рднреЗрдЬрдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдПрдХ рд╕реБрд░рдХреНрд╖рд╛ рдЬреЛрдЦрд┐рдо рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЪрд┐рддреНрд░
Access-Control-Allow-Origing
рд▓рд┐рдП рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВ рдЖрдкрдХрд╛ рдбреЛрдореЗрди рд╕рд╣реЗрдЬрд╛ рдирд╣реАрдВ рдЬрд╛рдПрдЧрд╛ред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, mapnik рдЯрд╛рдЗрд▓реНрд╕ рдпрд╛ рдЯрд╛рдЗрд▓ .openstreetmap.org рдЯрд╛рдЗрд▓реНрд╕ рдореЗрдВ рд╣реЗрдбрд░
Access-Control-Allow-Origing: *
, рд▓реЗрдХрд┐рди рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рд░ рдЪреАрдЬ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ
img.crossOrigin
рдПрд▓рд┐рдореЗрдВрдЯ
img.crossOrigin
рдХреЛ
Anonymous
рдкрд░ рд╕реЗрдЯ рдХрд░рдирд╛
img.crossOrigin
ред
рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдХреЛрд░ рдХрд╛ рдХрд╛рдо рд╕рднреА рдореЛрдмрд╛рдЗрд▓ рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдореЗрдВ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЗ рдбреЛрдореЗрди рдкрд░ рдЖрдкрдХреА рд╕рд╛рдЗрдЯ рдХреЗ рд▓рд┐рдП рдкреНрд░реЙрдХреНрд╕реА рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рд╣реИ рдпрд╛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Phoengap рдЕрдиреБрдпрд╛рдпрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП CORS рдХреА рдЬрд╛рдБрдЪ рдЕрдХреНрд╖рдо рдХрд░реЗрдВред рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ, рдпрд╣ рдХреЛрдб рдПрдВрдбреНрд░реЙрдЗрдб рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдмрдВрдж рдирд╣реАрдВ рд╣реБрдЖ (androin 4.0.4 Sony xperia рд╕рдХреНрд░рд┐рдп), рдФрд░ рдУрдкреЗрд░рд╛ рдореЗрдВ рдХреБрдЫ рдЯрд╛рдЗрд▓реЛрдВ рдХреЛ рдПрдХ рдЕрдЬреАрдм рддрд░реАрдХреЗ рд╕реЗ рдмрдЪрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ (рддреБрд▓рдирд╛
рдХрднреА-рдХрднреА рд╣реЛрддреА рд╣реИ рдФрд░
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП , рд▓реЗрдХрд┐рди рдпрд╣ рдУрдкреЗрд░рд╛ рдмрдЧ рдХреА рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ )ред
рдпрд╣рд╛рдВ рдЖрдк
canvas
рдмрдЬрд╛рдп
WebWorkers
+
AJAX
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдкрддреНрд░рдХ
рддреЛ рд╣рдореЗрдВ рд▓реЛрдХрдкреНрд░рд┐рдп рдУрдкрди рд╕реЛрд░реНрд╕ рдЬреЗрдПрд╕ рдПрдкреАрдЖрдИ рдХрд╛рд░реНрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрдирдореЗрдВ рд╕реЗ рдПрдХ рдЙрдореНрдореАрджрд╡рд╛рд░
рдХреИрдЯ рд╣реИ ред
рд╕реНрд░реЛрдд рдкрд░ рдереЛрдбрд╝рд╛ рджреЗрдЦрдиреЗ рдХреЗ рдмрд╛рдж
, рдЖрдк рдЯрд╛рдЗрд▓ рдкрд░рдд рд╡рд┐рдзрд┐ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╕реАрдзреЗ рдЯрд╛рдЗрд▓реНрд╕ рдХреЗ рд▓рд┐рдП
src
рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ:
_loadTile: function (tile, tilePoint) { tile._layer = this; tile.onload = this._tileOnLoad; tile.onerror = this._tileOnError; tile.src = this.getTileUrl(tilePoint); }
рдпрд╣реА рд╣реИ, рдпрджрд┐ рдЖрдк рдЗрд╕ рд╡рд░реНрдЧ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╕реАрдзреЗ рдбреЗрдЯрд╛ рдХреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╕реЗ
src
рдореЗрдВ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рддрд░реАрдХрд╛ рд╣реИ, рддреЛ рд╣рдо рд╡рд╣реА рдХрд░реЗрдВрдЧреЗ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдПред рдпрджрд┐ рд╣рдо рдиреЗрдЯрд╡рд░реНрдХ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдП рдЧрдП рд╣реИрдВ рдФрд░ рдкреВрд░реНрдг рдХреИрд╢рд┐рдВрдЧ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рддреЛ рд╣рдо рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдбреЗрдЯрд╛ рдХреЗ рдЬреЛрдбрд╝ рдХреЛ рднреА рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред
CAT рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди var StorageTileLayer = L.TileLayer.extend({ _imageToDataUri: function (image) { var canvas = window.document.createElement('canvas'); canvas.width = image.width; canvas.height = image.height; var context = canvas.getContext('2d'); context.drawImage(image, 0, 0); return canvas.toDataURL('image/png'); }, _tileOnLoadWithCache: function () { var storage = this._layer.options.storage; if (storage) { storage.add(this._storageKey, this._layer._imageToDataUri(this)); } L.TileLayer.prototype._tileOnLoad.apply(this, arguments); }, _setUpTile: function (tile, key, value, cache) { tile._layer = this; if (cache) { tile._storageKey = key; tile.onload = this._tileOnLoadWithCache; tile.crossOrigin = 'Anonymous'; } else { tile.onload = this._tileOnLoad; } tile.onerror = this._tileOnError; tile.src = value; }, _loadTile: function (tile, tilePoint) { this._adjustTilePoint(tilePoint); var key = tilePoint.z + ',' + tilePoint.y + ',' + tilePoint.x; var self = this; if (this.options.storage) { this.options.storage.get(key, function (value) { if (value) { self._setUpTile(tile, key, value, false); } else { self._setUpTile(tile, key, self.getTileUrl(tilePoint), true); } }, function () { self._setUpTile(tile, key, self.getTileUrl(tilePoint), true); }); } else { self._setUpTile(tile, key, self.getTileUrl(tilePoint), false); } } });
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реНрд╡рдпрдВ рдХрд╛рд░реНрдб рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдЖрд░рдВрднреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
var map = L.map('map').setView([53.902254, 27.561850], 13); new StorageTileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {storage: storage}).addTo(map);
рд╣рдо рдЕрдкрдиреЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╢ рдореЗрдВ рднреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдХрд╛рд░реНрдб рдХреИрд╢реНрдб рдЯрд╛рдЗрд▓ рд╡рд╛рд▓реЗ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдмрд┐рдирд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХреЗред
рдирд┐рдГрд╢реБрд▓реНрдХ рдХреНрд░реЛрдПрд╢рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЖрд╡реЗрджрди рдХреИрд╢ рдкреНрд░рдХрдЯ CACHE MANIFEST NETWORK: * CACHE: index.html style.css event.js storage.js map.js run.js leaflet.css leaflet.js images/layers.png images/marker-icon.png images/marker-icon@2x.png images/marker-shadow.png
рдЬреАрдердм рдкрд░ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдФрд░
рдЙрд╕рдХрд╛ рдХреЛрдб ред
рдореИрдкрдмреЙрдХреНрд╕ (рдореЛрдбрдореИрдкреНрд╕)
рдЦреБрд▓реЗ рдЬреЗрдПрд╕ рдПрдкреАрдЖрдИ рдирдХреНрд╢реЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдЙрдореНрдореАрджрд╡рд╛рд░
рдореЛрдбрдореИрдк рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдПрдХ рдорд╛рдирдЪрд┐рддреНрд░
рдмреЙрдХреНрд╕ рд╣реИ ред
рдореИрдкрдмреЙрдХреНрд╕ рдХреЗ
рд╕реНрд░реЛрдд рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдЕрдкрдиреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд▓рдЧрд╛, рддреЛ рдЪрд▓рд┐рдП рд╣рдо
рдореЙрдбреЗрд╕реНрдЯрдореИрдк рдХреЗ
рд╕реНрд░реЛрдд рдХреА рдУрд░ рдмрдврд╝рддреЗ рд╣реИрдВ ред рдЖрдЗрдП
TemplatedLayer
рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреНрд░рджрд╛рддрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдирд┐рдпрдорд┐рдд рдорд╛рдирдЪрд┐рддреНрд░ рдкрд░рдд рд╣реИ, рд╣рдореЗрдВ рдЬреЛ рдХреЛрдб рдЪрд╛рд╣рд┐рдП рд╡рд╣ рдкрд░рдд рд╡рд░реНрдЧ рдореЗрдВ рд╣реЛрдЧрд╛:
MM.TemplatedLayer = function(template, subdomains, name) { return new MM.Layer(new MM.Template(template, subdomains), null, name); };
рдореИрдк рд▓реЗрдпрд░ рдореЗрдВ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдкреНрд░реЛрд╡рд╛рдЗрдбрд░ рдХреЗ
рдЙрдкрдпреЛрдЧ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рддреЗ рд╣реБрдП
, рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░рд╛ рдкреНрд░реЛрд╡рд╛рдЗрдбрд░ рдЯрд╛рдЗрд▓ URL рдпрд╛ рд╕рдорд╛рдкреНрдд DOM рдПрд▓рд┐рдореЗрдВрдЯ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ DOM рдПрд▓рд┐рдореЗрдВрдЯ рдХреЛ рддреБрд░рдВрдд рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░
requestManager
URL рдХреЛ
requestManager
рдХреЛ рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ:
if (!this.requestManager.hasRequest(tile_key)) { var tileToRequest = this.provider.getTile(tile_coord); if (typeof tileToRequest == 'string') { this.addTileImage(tile_key, tile_coord, tileToRequest); } else if (tileToRequest) { this.addTileElement(tile_key, tile_coord, tileToRequest); } }
addTileImage: function(key, coord, url) { this.requestManager.requestTile(key, coord, url); }
addTileElement: function(key, coordinate, element) { element.id = key; element.coord = coordinate.copy(); this.positionTile(element); }
requestManager
рдЦреБрдж рдореИрдк рд▓реЗрдпрд░ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рд╣реЛрддрд╛ рд╣реИред
processQueue
рддрддреНрд╡ рдХрд╛ DOM рдмрдирд╛рдирд╛ рдФрд░ рдЙрд╕рдХреЗ
src
рд╕реЗрдЯ рдХрд░рдирд╛,
processQueue
рдореЗрдердб рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдореИрдк рд▓реЗрдпрд░ рд╕реЗ рднреА
processQueue
:
processQueue: function(sortFunc) { if (sortFunc && this.requestQueue.length > 8) { this.requestQueue.sort(sortFunc); } while (this.openRequestCount < this.maxOpenRequests && this.requestQueue.length > 0) { var request = this.requestQueue.pop(); if (request) { this.openRequestCount++; var img = document.createElement('img'); img.id = request.id; img.style.position = 'absolute'; img.coord = request.coord; this.loadingBay.appendChild(img); img.onload = img.onerror = this.getLoadComplete(); img.src = request.url; request = request.id = request.coord = request.url = null; } } }
рдпрд╣реА рд╣реИ, рдЕрдЧрд░ рд╣рдо рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рдкрд░рд┐рдгрд╛рдо рднреА рдорд┐рд▓рддрд╛ рд╣реИред
рдореИрдкрдмреЙрдХреНрд╕ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди (modestmaps) var StorageRequestManager = function (storage) { MM.RequestManager.apply(this, []); this._storage = storage; }; StorageRequestManager.prototype._imageToDataUri = function (image) { var canvas = window.document.createElement('canvas'); canvas.width = image.width; canvas.height = image.height; var context = canvas.getContext('2d'); context.drawImage(image, 0, 0); return canvas.toDataURL('image/png'); }; StorageRequestManager.prototype._createTileImage = function (id, coord, value, cache) { var img = window.document.createElement('img'); img.id = id; img.style.position = 'absolute'; img.coord = coord; this.loadingBay.appendChild(img); if (cache) { img.onload = this.getLoadCompleteWithCache(); img.crossOrigin = 'Anonymous'; } else { img.onload = this.getLoadComplete(); } img.onerror = this.getLoadComplete(); img.src = value; }; StorageRequestManager.prototype._loadTile = function (id, coord, url) { var self = this; if (this._storage) { this._storage.get(id, function (value) { if (value) { self._createTileImage(id, coord, value, false); } else { self._createTileImage(id, coord, url, true); } }, function () { self._createTileImage(id, coord, url, true); }); } else { self._createTileImage(id, coord, url, false); } }; StorageRequestManager.prototype.processQueue = function (sortFunc) { if (sortFunc && this.requestQueue.length > 8) { this.requestQueue.sort(sortFunc); } while (this.openRequestCount < this.maxOpenRequests && this.requestQueue.length > 0) { var request = this.requestQueue.pop(); if (request) { this.openRequestCount++; this._loadTile(request.id, request.coord, request.url); request = request.id = request.coord = request.url = null; } } }; StorageRequestManager.prototype.getLoadCompleteWithCache = function () { if (!this._loadComplete) { var theManager = this; this._loadComplete = function(e) { e = e || window.event; var img = e.srcElement || e.target; img.onload = img.onerror = null; if (theManager._storage) { theManager._storage.add(this.id, theManager._imageToDataUri(this)); } theManager.loadingBay.removeChild(img); theManager.openRequestCount--; delete theManager.requestsById[img.id]; if (e.type === 'load' && (img.complete || (img.readyState && img.readyState === 'complete'))) { theManager.dispatchCallback('requestcomplete', img); } else { theManager.dispatchCallback('requesterror', { element: img, url: ('' + img.src) }); img.src = null; } setTimeout(theManager.getProcessQueue(), 0); }; } return this._loadComplete; }; MM.extend(StorageRequestManager, MM.RequestManager); var StorageLayer = function(provider, parent, name, storage) { this.parent = parent || document.createElement('div'); this.parent.style.cssText = 'position: absolute; top: 0px; left: 0px;' + 'width: 100%; height: 100%; margin: 0; padding: 0; z-index: 0'; this.name = name; this.levels = {}; this.requestManager = new StorageRequestManager(storage); this.requestManager.addCallback('requestcomplete', this.getTileComplete()); this.requestManager.addCallback('requesterror', this.getTileError()); if (provider) { this.setProvider(provider); } }; MM.extend(StorageLayer, MM.Layer); var StorageTemplatedLayer = function(template, subdomains, name, storage) { return new StorageLayer(new MM.Template(template, subdomains), null, name, storage); };
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реНрд╡рдпрдВ рдХрд╛рд░реНрдб рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдЖрд░рдВрднреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
var map = mapbox.map('map'); map.addLayer(new StorageTemplatedLayer('http://{S}.tile.osm.org/{Z}/{X}/{Y}.png', ['a', 'b', 'c'], undefined, storage)); map.ui.zoomer.add(); map.ui.zoombox.add(); map.centerzoom({lat: 53.902254, lon: 27.561850}, 13);
рд╣рдо рдЕрдкрдиреЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╢ рдореЗрдВ рднреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдХрд╛рд░реНрдб рдХреИрд╢реНрдб рдЯрд╛рдЗрд▓ рд╡рд╛рд▓реЗ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдмрд┐рдирд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХреЗред
Mapbox рдХреЗ рд▓рд┐рдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╢ рдкреНрд░рдХрдЯ (modestmaps) CACHE MANIFEST NETWORK: * CACHE: index.html style.css event.js storage.js map.js run.js mapbox.css mapbox.js map-controls.png
рдЬреАрдердм рдкрд░ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдФрд░
рдЙрд╕рдХрд╛ рдХреЛрдб ред
OpenLayers
рдФрд░ рдЦреБрд▓реЗ рдЬреЗрдПрд╕ рдПрдкреАрдЖрдИ рдирдХреНрд╢реЗ рдХреЗ рд▓рд┐рдП рдирд╡реАрдирддрдо рдЙрдореНрдореАрджрд╡рд╛рд░ рдУрдкрди
рд▓реЙрдпрд░реНрд╕ рд╣реИ ред
рдореБрдЭреЗ рдпрд╣ рд╕рдордЭрдиреЗ рдореЗрдВ рдХреБрдЫ рд╕рдордп рд▓рдЧрд╛рдирд╛ рдерд╛ рдХрд┐ рдХрдо рд╕реЗ рдХрдо рджреГрд╢реНрдп рдХреИрд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рдП, рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдореЗрд░реА рдмрд┐рд▓реНрдб рдлрд╝рд╛рдЗрд▓ рдиреЗ рдирд┐рдореНрди рд░реВрдк рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛:
[first] [last] [include] OpenLayers/Map.js OpenLayers/Layer/OSM.js OpenLayers/Control/Zoom.js OpenLayers/Control/Navigation.js OpenLayers/Control/TouchNavigation.js [exclude]
рдореИрдВ
OpenLayers.Layer.OSM
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕рд╕реЗ рдЦреЛрдЬ рд╢реБрд░реВ рдХрд░реВрдВрдЧрд╛:
url: [ 'http://a.tile.openstreetmap.org/${z}/${x}/${y}.png', 'http://b.tile.openstreetmap.org/${z}/${x}/${y}.png', 'http://c.tile.openstreetmap.org/${z}/${x}/${y}.png' ]
OpenLayers.Layer.OSM
рдкреБрдирд░реНрдирд┐рд░реНрдзрд╛рд░рд┐рдд URL рдХреЗ рд╕рд╛рде
OpenLayers.Layer.XYZ
рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд
OpenLayers.Layer.OSM
рдорд┐рд▓рд╛ рд╣реИред
getURL
рд╡рд┐рдзрд┐ рдпрд╣рд╛рдБ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ:
getURL: function (bounds) { var xyz = this.getXYZ(bounds); var url = this.url; if (OpenLayers.Util.isArray(url)) { var s = '' + xyz.x + xyz.y + xyz.z; url = this.selectUrl(s, url); } return OpenLayers.String.format(url, xyz); }
рдпрд╣ рднреА рджрд┐рд▓рдЪрд╕реНрдк
getXYZ
рд╡рд┐рдзрд┐ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдк рдПрдХ рдХреБрдВрдЬреА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
getXYZ: function(bounds) { var res = this.getServerResolution(); var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w)); var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h)); var z = this.getServerZoom(); if (this.wrapDateLine) { var limit = Math.pow(2, z); x = ((x % limit) + limit) % limit; } return {'x': x, 'y': y, 'z': z}; }
OpenLayers.Layer.XYZ
рд╣реА
addTile
рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдПрдХ
addTile
рд╡рд┐рдзрд┐ рд╣реИ рдФрд░ рдЬреЛ
tileClass
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рдЕрдВрджрд░ рдЯрд╛рдЗрд▓ рдмрдирд╛рддрд╛ рд╣реИ, рдЬреЛ
tileClass
рд╣реИ:
addTile: function(bounds, position) { var tile = new this.tileClass( this, position, bounds, null, this.tileSize, this.tileOptions ); this.events.triggerEvent("addtile", {tile: tile}); return tile; }
setImgSrc
src
рдореЗрдВ
setImgSrc
рд╡рд┐рдзрд┐ рд╕реЗрдЯ рдХреА
setImgSrc
рд╣реИ:
setImgSrc: function(url) { var img = this.imgDiv; if (url) { img.style.visibility = 'hidden'; img.style.opacity = 0; if (this.crossOriginKeyword) { if (url.substr(0, 5) !== 'data:') { img.setAttribute("crossorigin", this.crossOriginKeyword); } else { img.removeAttribute("crossorigin"); } } img.src = url; } else { this.stopLoading(); this.imgDiv = null; if (img.parentNode) { img.parentNode.removeChild(img); } } }
рд▓реЗрдХрд┐рди рдпрд╣
onload
рдФрд░
onerror
рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд╡рд┐рдзрд┐ рдЦреБрдж рдХреЛ
initImage
рд╕реЗ
initImage
, рдЬрд╣рд╛рдВ рдпреЗ рд╣реИрдВрдбрд▓рд░ рд▓рдЯрдХрд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ:
initImage: function() { this.events.triggerEvent('beforeload'); this.layer.div.appendChild(this.getTile()); this.events.triggerEvent(this._loadEvent); var img = this.getImage(); if (this.url && img.getAttribute("src") == this.url) { this._loadTimeout = window.setTimeout( OpenLayers.Function.bind(this.onImageLoad, this), 0 ); } else { this.stopLoading(); if (this.crossOriginKeyword) { img.removeAttribute("crossorigin"); } OpenLayers.Event.observe(img, "load", OpenLayers.Function.bind(this.onImageLoad, this) ); OpenLayers.Event.observe(img, "error", OpenLayers.Function.bind(this.onImageError, this) ); this.imageReloadAttempts = 0; this.setImgSrc(this.url); } }
рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐
initImage
рд▓реЗрдпрд░ рдХреНрд▓рд╛рд╕ рд╡рд┐рдзрд┐, рд╕рд╛рде рд╣реА
initImage
, рдХреЛ
initImage
рд╕реЗ рдЦреАрдВрдЪ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
renderTile: function() { if (this.layer.async) { var id = this.asyncRequestId = (this.asyncRequestId || 0) + 1; this.layer.getURLasync(this.bounds, function(url) { if (id == this.asyncRequestId) { this.url = url; this.initImage(); } }, this); } else { this.url = this.layer.getURL(this.bounds); this.initImage(); } }
рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рд╣рдо рдЗрд╕ рд╡рд░реНрдЧ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рдкрд░рд┐рдгрд╛рдо рднреА рдорд┐рд▓реЗрдЧрд╛ред
OpenLayers рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди var StorageImageTile = OpenLayers.Class(OpenLayers.Tile.Image, { _imageToDataUri: function (image) { var canvas = window.document.createElement('canvas'); canvas.width = image.width; canvas.height = image.height; var context = canvas.getContext('2d'); context.drawImage(image, 0, 0); return canvas.toDataURL('image/png'); }, onImageLoadWithCache: function() { if (this.storage) { this.storage.add(this._storageKey, this._imageToDataUri(this.imgDiv)); } this.onImageLoad.apply(this, arguments); }, renderTile: function() { var self = this; var xyz = this.layer.getXYZ(this.bounds); var key = xyz.z + ',' + xyz.y + ',' + xyz.x; var url = this.layer.getURL(this.bounds); if (this.storage) { this.storage.get(key, function (value) { if (value) { self.initImage(key, value, false); } else { self.initImage(key, url, true); } }, function () { self.initImage(key, url, true); }); } else { self.initImage(key, url, false); } }, initImage: function(key, url, cache) { this.events.triggerEvent('beforeload'); this.layer.div.appendChild(this.getTile()); this.events.triggerEvent(this._loadEvent); var img = this.getImage(); this.stopLoading(); if (cache) { OpenLayers.Event.observe(img, 'load', OpenLayers.Function.bind(this.onImageLoadWithCache, this) ); this._storageKey = key; } else { OpenLayers.Event.observe(img, 'load', OpenLayers.Function.bind(this.onImageLoad, this) ); } OpenLayers.Event.observe(img, 'error', OpenLayers.Function.bind(this.onImageError, this) ); this.imageReloadAttempts = 0; this.setImgSrc(url); } }); var StorageOSMLayer = OpenLayers.Class(OpenLayers.Layer.OSM, { async: true, tileClass: StorageImageTile, initialize: function(name, url, options) { OpenLayers.Layer.OSM.prototype.initialize.apply(this, arguments); this.tileOptions = OpenLayers.Util.extend({ storage: options.storage }, this.options && this.options.tileOptions); }, clone: function (obj) { if (obj == null) { obj = new StorageOSMLayer(this.name, this.url, this.getOptions()); } obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]); return obj; } });
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реНрд╡рдпрдВ рдХрд╛рд░реНрдб рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдЖрд░рдВрднреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
var map = new OpenLayers.Map('map'); map.addLayer(new StorageOSMLayer(undefined, undefined, {storage: storage})); var fromProjection = new OpenLayers.Projection('EPSG:4326'); var toProjection = new OpenLayers.Projection('EPSG:900913'); var center = new OpenLayers.LonLat(27.561850, 53.902254).transform(fromProjection, toProjection); map.setCenter(center, 13);
рд╣рдо рдЕрдкрдиреЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╢ рдореЗрдВ рднреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдХрд╛рд░реНрдб рдХреИрд╢реНрдб рдЯрд╛рдЗрд▓ рд╡рд╛рд▓реЗ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдмрд┐рдирд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХреЗред
OpenLayers рдХреЗ рд▓рд┐рдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреИрд╢ рдкреНрд░рдХрдЯ рд╣реЛрддрд╛ рд╣реИ CACHE MANIFEST NETWORK: * CACHE: index.html style.css event.js storage.js map.js run.js theme/default/style.css OpenLayers.js
рдЬреАрдердм рдкрд░ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдФрд░
рдЙрд╕рдХрд╛ рдХреЛрдб ред
рдореБрдЭреЗ
OpenLayers.Control.CacheWrite
рдХреИрд╢ рдХрд╛ рдПрдХ рддреИрдпрд╛рд░-рдирд┐рд░реНрдорд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднреА рдорд┐рд▓рд╛, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓
localStorage
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛, рдЬреЛ рдмрд╣реБрдд рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд╣реИред
рдирд┐рд╖реНрдХрд░реНрд╖
рдЕрд╕рд▓ рдореЗрдВ, рдореБрдЭреЗ рд╡рд╣реА рдорд┐рд▓рд╛ рдЬреЛ рдореИрдВ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдЙрджрд╛рд╣рд░рдг рдХреНрд░реЛрдо рдореЗрдВ рдЪрд╛рд▓рд╛рдХреА рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдпрд╛ рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрд╕рдПрд╕рдбреА рд╣реИ, рддреЛ рдбрд┐рд╕реНрдХ рдХреЛ рд╕рд╣реЗрдЬрддреЗ рд╕рдордп рд▓реЛрдордбрд╝реА рдФрд░ рдУрдкреЗрд░рд╛ рдореЗрдВ рдмреНрд░реЗрдХ рд╣реЛрддреЗ рд╣реИрдВ, рдЧрдзрд╛ рд╣рд╛рде рдореЗрдВ рдирд╣реАрдВ рдерд╛ред рдореЛрдмрд╛рдЗрд▓ рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдореЗрдВ рднреА рдмреНрд░реЗрдХ рд▓рдЧрддреЗ рд╣реИрдВ, рдФрд░ рдкрдврд╝рддреЗ рд╕рдордп рднреА, рдЬреЛ рдореБрдЭреЗ рдереЛрдбрд╝рд╛ рдкрд░реЗрд╢рд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдореЛрдмрд╛рдЗрд▓ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рдХрд╛рд░реНрдп рдЕрдзрд┐рдХ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рд╣реИред
IndexedDB
рдпрд╛
WebSQL
рдХрд╛ рдорд╛рдирдХ рдЖрдХрд╛рд░ рдХрд┐рд╕реА рд╢рд╣рд░ рдпрд╛ рдЙрд╕рд╕реЗ рдЕрдзрд┐рдХ рдХреЛ рдХреИрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рд╣реИ, рдЬреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ
localStorage
рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рдмрдирд╛рддрд╛ рд╣реИред
рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ, рдЖрдк рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╕реНрдЯреЛрд░реЗрдЬ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХ рдЖрд░рд╛рдо рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЕрднреА рднреА рдЙрдирдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдирдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред