рдорд╛рдирдЪрд┐рддреНрд░ рдкрд░ рдлрд╝реЛрдЯреЛ рдХрд╛ рдЪрдпрди, рдХреИрд╢рд┐рдВрдЧ рдФрд░ рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВрдиреЗ рдпрд╣ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдХрд┐ рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЦрдВрдб рдкрд░ рддрд╕реНрд╡реАрд░реЛрдВ рдХреЛ рдЪреБрдирдиреЗ рдФрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣рдорд╛рд░реА gfranq.com рдлреЛрдЯреЛ рд╕реЗрд╡рд╛ рдореЗрдВ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХреА рдЧрдИ рдереАред



рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛ рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реА рддрд╕реНрд╡реАрд░реЗрдВ рдереАрдВ рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдкреНрд░рд╢реНрди рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрд╕рд╛рдзрди-рдЧрд╣рди рдерд╛, рдЗрд╕рд▓рд┐рдП рд╣рд░ рдмрд╛рд░ рджреЗрдЦрдиреЗ рдХреА рдЦрд┐рдбрд╝рдХреА рдмрджрд▓ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдирдХреНрд╢реЗ рдХреЛ рдЙрди рдЦрдВрдбреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рддрд░реНрдХрд╕рдВрдЧрдд рдерд╛ рдЬрд╣рд╛рдВ рдкрд╣рд▓реЗ рд╕реЗ рдирд┐рдХрд╛рд▓реЗ рдЧрдП рдбреЗрдЯрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рдПрдЧреАред рд╕реНрдкрд╖реНрдЯ рдХрд╛рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рдЗрди рд╡рд░реНрдЧреЛрдВ рдореЗрдВ рдПрдХ рдЖрдпрддрд╛рдХрд╛рд░ рдЖрдХрд╛рд░ рд╣реЛрддрд╛ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдПрдХ рд╣реЗрдХреНрд╕рд╛рдЧреЛрдирд▓ рдЧреНрд░рд┐рдб рдХреЗ рд╕рд╛рде рд╡рд┐рдХрд▓реНрдк рдкрд░ рднреА рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛)ред рдЪреВрдВрдХрд┐ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдЕрдиреБрднрд╛рдЧ рдЕрдзрд┐рдХ рдЧреЛрд▓рд╛рдХрд╛рд░ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рдЧреЛрд▓рд╛рдХрд╛рд░ рдЬреНрдпрд╛рдорд┐рддрд┐ рдХреЗ рддрддреНрд╡реЛрдВ рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдХрд░рдгреЛрдВ рдкрд░ рднреА рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред


рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореБрджреНрджреЛрдВ рдХреЛ рд╕рдВрдмреЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:



рд╕рд╛рдордЧреНрд░реА



рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб


рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдирдореВрдирд╛ рд▓реЗрдиреЗ рдФрд░ рднрдВрдбрд╛рд░рдг рдХрд░рдиреЗ рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЛрдВ рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:



рдЖрдЧреЗ, рдЗрди рд╡рд┐рдзрд┐рдпреЛрдВ рдкрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреАред


рдПрдВрдмреЗрдбреЗрдб рдЬрд┐рдпреЛрдЯрд╛рдЗрдкреНрд╕


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, SQL Server 2008 рдиреЗ рднреВрдЧреЛрд▓ рдФрд░ рдЬреНрдпрд╛рдорд┐рддрд┐ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдкреЗрд╢ рдХрд┐рдпрд╛, рдЬреЛ рдЖрдкрдХреЛ рднреМрдЧреЛрд▓рд┐рдХ (рдХреНрд╖реЗрддреНрд░ рдкрд░) рдФрд░ рдЬреНрдпрд╛рдорд┐рддреАрдп (рд╡рд┐рдорд╛рди рдкрд░) рдЬрд╛рдирдХрд╛рд░реА, рдЬреИрд╕реЗ рдмрд┐рдВрджреБ, рд░реЗрдЦрд╛, рдмрд╣реБрднреБрдЬ , рдЖрджрд┐ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ ред ред рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ ( lngMin latMin ) рдФрд░ ( latMax lngMax ) рдХреЗ рд╕рд╛рде рдПрдХ рдЖрдпрдд рджреНрд╡рд╛рд░рд╛ рд╕рдВрд▓рдЧреНрди рд╕рднреА рдлрд╝реЛрдЯреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреНрд╡реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 DECLARE @h geography; DECLARE @p geography; SET @rect = geography::STGeomFromText('POLYGON((lngMin latMin, lngMax latMin, lngMax latMax, lngMin latMax, lngMin latMin))', 4326); SELECT TOP @cound id, image75Path, geoTag.Lat as Lat, geoTag.Long as Lng, popularity, width, height FROM Photo WITH (INDEX(IX_Photo_geoTag)) WHERE @rect.STContains(geoTag) = 1 ORDER BY popularity DESC 

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдмрд╣реБрднреБрдЬ рдХреЛ рд╡рд╛рдорд╛рд╡рд░реНрдд рдмрд╛рдпрдкрд╛рд╕ IX_Photo_geoTag рдФрд░ рд╕реНрдерд╛рдирд┐рдХ рд╕реВрдЪрдХрд╛рдВрдХ IX_Photo_geoTag , рдЬреЛ рдХрд┐ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ ( рдмреА-рдкреЗрдбрд╝реЛрдВ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рджреНрд╡рд╛рд░рд╛ рд╕реНрдерд╛рдирд┐рдХ рд╕реВрдЪрдХрд╛рдВрдХ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ) рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдорд┐рдд рд╣реИ ред


рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ Microsoft SQL Server 2008 рдореЗрдВ рд╕реНрдерд╛рдирд┐рдХ рдЗрдВрдбреЗрдХреНрд╕ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдпрджрд┐ рднреВрдЧреЛрд▓ рдХреЗ рд╕рд╛рде рдХреЙрд▓рдо NULL рдорд╛рдиреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╕рдордЧреНрд░ рд╕реВрдЪрдХрд╛рдВрдХ рдореЗрдВ рдЯрд╛рдЗрдк рднреВрдЧреЛрд▓ рдХреЗ рд╕рд╛рде рдПрдХ рдХреЙрд▓рдо рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╕реНрдЯреИрдХрдУрд╡рд░рдлрд╝реНрд▓реЛ рдкрд░ рдпрд╣ рдкреНрд░рд╢реНрди рдЙрдард╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЗрд╕ рд╡рдЬрд╣ рд╕реЗ, рдЗрд╕ рддрд░рд╣ рдХреЗ рдкреНрд░рд╢реНрдиреЛрдВ (рдЗрдВрдбреЗрдХреНрд╕ рдХреЗ рдмрд┐рдирд╛) рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдмрд╣реБрдд рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред


рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рд░реВрдк рдореЗрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:



рднреМрдЧреЛрд▓рд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╡реНрдпрд╛рдкрдХ рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж (рдФрд░ рд╡реЗ рд╣рдореЗрдВ рди рдХреЗрд╡рд▓ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЪрдпрди рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рджреВрд░реА, рд╡рд┐рднрд┐рдиреНрди рдмрд╣реБрднреБрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА), рд╡реЗ рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдП рдЧрдП рдереЗред


рдирд┐рдпрдорд┐рдд рдирдореВрдирд╛


рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ ( lngMin latMin ) рдФрд░ ( latMax lngMax ) рджреНрд╡рд╛рд░рд╛ рд╕реАрдорд┐рдд рдХреНрд╖реЗрддреНрд░ рд╕реЗ рдлрд╝реЛрдЯреЛ рдХрд╛ рдЪрдпрди рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреНрд╡реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ:


 SELECT TOP @Count id, url, ... FROM Photo WHERE latitude > @latMin AND longitude > @lngMin AND latitude < @latMax AND longitude < @lngMax ORDER BY popularity DESC 

рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдк latitude рдФрд░ longitude рдХреНрд╖реЗрддреНрд░реЛрдВ (рдкрд╣рд▓реЗ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╡рд┐рдкрд░реАрдд) рдХреЗ рд▓рд┐рдП рдХреЛрдИ рднреА рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╕рд╛рдорд╛рдиреНрдп рдлреНрд▓реЛрдЯ рдкреНрд░рдХрд╛рд░ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рдирдореВрдиреЗ рдореЗрдВ 4 рддреБрд▓рдирд╛рдПрдВ рд╣реИрдВред


рд╣реИрд╢ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рдХреБрдЫ рдХреНрд╖реЗрддреНрд░реЛрдВ рд╕реЗ рддрд╕реНрд╡реАрд░реЛрдВ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдмрд╕реЗ рдЗрд╖реНрдЯрддрдо рд╕рдорд╛рдзрд╛рди рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд Zooms рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдирд╛ рд╣реИ рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдЬрд╝реВрдо рдХреЗ рд▓рд┐рдП рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рд░рд╛рдЦ рдпреБрдХреНрдд рд░реЗрдЦрд╛рдУрдВ рдХреЛ Zooms рдХрд░рддрд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдиреАрдЪреЗ рджреА рдЧрдИ рдЖрдХреГрддрд┐ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред



SQL рдХреНрд╡реЗрд░реА рдирд┐рдореНрди рдлрд╝реЙрд░реНрдо рдкрд░ рд▓реЗ рдЬрд╛рддреА рд╣реИ ( zn рд╡рд░реНрддрдорд╛рди рдЬрд╝реВрдо рд╕реНрддрд░ рд╣реИ):


 DECLARE @hash float; SET @hash = (@latMin + 90) + (@lngMin + 180) * 180 + (@latMax + 90) * 64800 + (@lngMax + 180) * 11664000; SELECT TOP @Count id, url, ... FROM Photo WHERE id = (SELECT id FROM Zooms WHERE zn = @hash) 

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдиреБрдХрд╕рд╛рди рдпрд╣ рд╣реИ рдХрд┐ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд╛рд▓рд┐рдХрд╛ рдЕрддрд┐рд░рд┐рдХреНрдд рдореЗрдореЛрд░реА рд╕реНрдерд╛рди рд▓реЗрддреА рд╣реИред


рдмрд╛рдж рдХреЗ рддрд░реАрдХреЗ рдХреА рдпреЛрдЧреНрдпрддрд╛ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рд╕рд╛рдорд╛рдиреНрдп рдЪрдпрди рдХреЗ рд╕рд╛рде рджреВрд╕рд░рд╛ рд╡рд┐рдХрд▓реНрдк рд╕рд░реНрд╡рд░ рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рдХрд╛рдлреА рдЕрдЪреНрдЫрд╛ рдкреНрд░рджрд░реНрд╢рди рднреА рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред


рдорд▓реНрдЯреА рдереНрд░реЗрдбреЗрдб рдлреЛрдЯреЛ рдХреИрд╢рд┐рдВрдЧ


рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдПрдХ рдпрд╛ рджреВрд╕рд░реЗ рддрд░реАрдХреЗ рд╕реЗ рдирд┐рдХрд╛рд▓реЗ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдлрд╝реЛрдЯреЛ рдХреЛ рд╕рд░реНрд╡рд░ рдХреИрд╢ рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ:


 private static object SyncObject = new object(); ... List<Photo> photos = (List<Photo>)CachedAreas[hash]; if (photos == null) { //    ,           1 . lock (SyncObject) { photos = (List<Photo>)CachedAreas[hash]; if (photos == null) { photos = PhotoList.GetAllFromRect(latMin, lngMin, latMax, lngMax, count); //          2     . CachedAreas.Add(hash, photos, null, DateTime.Now.AddSeconds(120), Cache.NoSlidingExpiration, CacheItemPriority.High, null); } } } //   CachedAreas[hash] 

рдЗрд╕ рдЦрдВрдб рдореЗрдВ, рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдлрд╝реЛрдЯреЛ рд▓рд╛рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдХреИрд╢ рдореЗрдВ рд╕рд╣реЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЕрдЧрд▓рд╛ рднрд╛рдЧ рдпрд╣ рд╡рд░реНрдгрди рдХрд░реЗрдЧрд╛ рдХрд┐ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рддрд░рдл рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИред


рдЧреНрд░рд╛рд╣рдХ рднрд╛рдЧ


рдЗрд╕ рдкрд░ рдорд╛рдирдЪрд┐рддреНрд░ рдФрд░ рдлрд╝реЛрдЯреЛ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, Google рдорд╛рдирдЪрд┐рддреНрд░ API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдирдХреНрд╢реЗ рдХреЛ рдЙрдирдХреЗ рдЬрд┐рдпреЛрд▓реЛрдХреЗрд╢рди рдХреЗ рдЕрдиреБрд░реВрдк рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЙрдкрдпреБрдХреНрдд рд╕реНрдерд╛рди рдкрд░ рд▓реЗ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред


рдорд╛рдирдЪрд┐рддреНрд░ рдЖрд░рдВрднреАрдХрд░рдг


рдорд╛рдирдЪрд┐рддреНрд░ рдХреЛ рдкреНрд░рд╛рд░рдВрдн рдХрд░рддреЗ рд╕рдордп рд╕реНрдерд╛рди рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рджреЛ рддрд░реАрдХреЗ рд╣реИрдВред рдкрд╣рд▓рд╛ HTML5 рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ рд╕рднреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдкреВрд░реНрд╡-рдЧрдгрдирд╛ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред


HTML5 рдХреЗ рд╕рд╛рде рдкреЛрдЬрд┐рд╢рдирд┐рдВрдЧ


 function detectRegion() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(success); } else { map.setZoom(defaultZoom); map.setCenter(defaultPoint); } } function success(position) { ... map.setZoom(defaultZoom); map.setCenter(new google.maps.LatLng(position.coords.latitude, position.coords.longitude)); } 

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдиреБрдХрд╕рд╛рди рдпрд╣ рд╣реИ рдХрд┐ рд╕рднреА рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдЗрд╕ HTML5 рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдкрдиреЗ рдбрд┐рд╡рд╛рдЗрд╕ рдкрд░ рднреВ-рд╕реВрдЪрдирд╛ рддрдХ рдкрд╣реБрдВрдЪ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗ рд╕рдХрддрд╛ рд╣реИред


рд╕рд░реНрд╡рд░ рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕реНрдерд╛рди


рдореИрдк рдХреЛ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ рдЖрд░рдВрднреАрдХреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ bounds рд╕рд░реНрд╡рд░ рджреНрд╡рд╛рд░рд╛ рд▓реМрдЯрд╛рдП рдЧрдП рдХреНрд╖реЗрддреНрд░ (рд╢рд╣рд░, рдХреНрд╖реЗрддреНрд░ рдпрд╛ рджреЗрд╢) рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╣реИрдВред рдЕрдиреБрдорд╛рдирд┐рдд рдЬрд╝реВрдо рд╕реНрддрд░ рдХреА рдЧрдгрдирд╛ getZoomFromBounds рдлрд╝рдВрдХреНрд╢рди ( getZoomFromBounds рд╕реЗ рдЙрдзрд╛рд░ рд▓рд┐рдпрд╛ рдЧрдпрд╛) рдореЗрдВ рджрд┐рдП рдЧрдП рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИред


 var northEast = bounds.getNorthEast(); var southWest = bounds.getSouthWest(); var myOptions = { zoom: getZoomFromBounds(northEast, southWest), center: new google.maps.LatLng((northEast.lat() + southWest.lat()) / 2, (northEast.lng() + southWest.lng()) / 2), mapTypeId: google.maps.MapTypeId.ROADMAP, minZoom: 3, maxZoom: 19 } map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); 

 function getZoomFromBounds(ne, sw) { var GLOBE_WIDTH = 256; // a constant in Google's map projection var west = sw.lng(); var east = ne.lng(); var angle = east - west; if (angle < 0) { angle += 360; } return Math.round(Math.log($('#map_canvas').width() * 360 / angle / GLOBE_WIDTH) / Math.LN2); } 

рд╕рд░реНрд╡рд░ рдкрд░, рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рдЧрдгрдирд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЖрдИрдкреА рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреА рдЬрд╛рддреА рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рд╕рднреА рдмреЙрд░реНрдбрд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рдПрдХрддреНрд░реАрдХрд░рдг рдХреЗ рд▓рд┐рдП, Google рдЬрд┐рдпреЛрдХреЛрдбрд┐рдВрдЧ рдПрдкреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ , рд╣рд╛рд▓рд╛рдВрдХрд┐ рдСрдлрд╝рд▓рд╛рдЗрди рдРрд╕реА рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡реИрдз рдирд╣реАрдВ рд╣реИ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдкреНрд░рддрд┐ рджрд┐рди 2500 рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╕реАрдорд╛ рднреА рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рд╢рд╣рд░, рдХреНрд╖реЗрддреНрд░ рдФрд░ рджреЗрд╢ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдПрдХ рдЕрдиреБрд░реЛрдз рдЙрддреНрдкрдиреНрди рд╣реБрдЖ рдЬреЛ рд╡рд╛рдВрдЫрд┐рдд viewport рдФрд░ рд╕реАрдорд╛рдПрдВ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрддрд╛ рд╣реИред рд╡реЗ рдХреЗрд╡рд▓ рдмрдбрд╝реЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рднрд┐рдиреНрди рд╣реЛрддреЗ рд╣реИрдВ рдЬреЛ рд╡реНрдпреВрдкреЛрд░реНрдЯ рдореЗрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдлрд┐рдЯ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗред рдЙрд╕реА рд╕рдордп, рдпрджрд┐ рдЙрддреНрддрд░ рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рд╡рд╛рдкрд╕ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдЕрдиреНрдп рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬреЛ рдХрд┐ рдХреНрд╖реЗрддреНрд░ рдпрд╛ рдЕрдВрдЧреНрд░реЗрдЬреА рдХреА рдореВрд▓ рднрд╛рд╖рд╛ рдореЗрдВ рд╕рдВрдпреБрдХреНрдд рд▓реЗрдЦрди, рднрд╛рдЧ {рд╕реЗрдЯрд▓рдореЗрдВрдЯ}, рдЖрджрд┐ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред http://maps.googleapis.com/maps/api/geocode/xml?address={},{/},{ }&sensor=false


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣ рдХреЗ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП: http://maps.googleapis.com/maps/api/geocode/xml?address=Russia, рдЗрд╡рд╛рдирд╡рд╛% 20 рдХреНрд╖реЗрддреНрд░, рдЗрд╡рд╛рдиреЛрд╡реЛ рдФрд░ рд╕реЗрдВрд╕рд░ = рдЭреВрдард╛


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдП рдЬрд╛рдПрдВрдЧреЗ (рдЯреБрдХрдбрд╝реЗ)
 ... <location> <lat>56.9951313</lat> <lng>40.9796047</lng> </location> <location_type>APPROXIMATE</location_type> <viewport> <southwest> <lat>56.9420231</lat> <lng>40.8765941</lng> </southwest> <northeast> <lat>57.0703221</lat> <lng>41.0876169</lng> </northeast> </viewport> <bounds> <southwest> <lat>56.9420231</lat> <lng>40.8765941</lng> </southwest> <northeast> <lat>57.0703221</lat> <lng>41.0876169</lng> </northeast> </bounds> ... 

рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рджреГрд╢реНрдпрдорд╛рди рдЖрдпрддрд╛рдХрд╛рд░ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рдЧрдгрдирд╛


рдХреИрд╢ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдЖрдХрд╛рд░ рдХреА рдЧрдгрдирд╛


рдЗрд╕рд▓рд┐рдП, рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рджреЛрдиреЛрдВ рдкрд░ рд╕рднреА рддрд╕реНрд╡реАрд░реЗрдВ рдЖрдпрддрд╛рдХрд╛рд░ рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рдХреИрд╢ рдХреА рдЬрд╛рддреА рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рд╕рдВрджрд░реНрдн рдмрд┐рдВрджреБ рдПрдХ рдордирдорд╛рдирд╛ рдмрд┐рдВрджреБ рд╣реИ (рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ (0, 0) рдХреЗ рд╕рд╛рде рдмрд┐рдВрджреБ), рдФрд░ рдЖрдХрд╛рд░ рдХреА рдЧрдгрдирд╛ рд╡рд░реНрддрдорд╛рди рд╕реНрддрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреА рдЬрд╛рддреА рд╣реИред (рдЬрд╝реВрдо) рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:


 //  ,    initMapSizeLat  initMapSizeLng var initDefaultDimX = 1000, var initDefaultDimY = 800; //     ,     . var currentDefaultDimX = 1080, var currentDefaultDimY = 500; var initMapSizeLat = 0.0003019; var initMapSizeLng = 0.00067055; //  () . var initRatio = 0.75; //               // .. initMapSizeLat  initMapSizeLng   . var initZoomSize = new google.maps.Size( initMapSizeLat / initDefaultDimX * currentDefaultDimX * initRatio, initMapSizeLng / initDefaultDimY * currentDefaultDimY * initRatio); //      ,     (     2,        1,     2 ,   -  4). function initZoomSizes() { zoomSizes = []; var coef = 1; for (var i = 21; i >= 0; i--) { zoomSizes[i] = new google.maps.Size(initZoomSize.width * coef, initZoomSize.height * coef); coef *= 2; } } 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкреНрд░рддреНрдпреЗрдХ рдЬрд╝реВрдо рд╕реНрддрд░ рдкрд░, рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдЖрдпрддрд╛рдХрд╛рд░ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдЖрдХрд╛рд░ рд╡рд░реНрддрдорд╛рди рджреЗрдЦрдиреЗ рд╡рд╛рд▓реА рдЦрд┐рдбрд╝рдХреА рд╕реЗ 0.75^2=0.5625 рд╣реИ рдпрджрд┐ рдЗрд╕рдХреА рдЪреМрдбрд╝рд╛рдИ = 1080px рдФрд░ рдКрдВрдЪрд╛рдИ рдКрдВрдЪрд╛рдИ = 500pxред


рдкреБрди: рд╡рд┐рддрд░рдг рдХрд░рддреЗ рд╕рдордп рджреЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рдЪреВрдВрдХрд┐ рдорд╛рдирдЪрд┐рддреНрд░ рдкрд░ рд╕рднреА рдлрд╝реЛрдЯреЛ рдХреЛ рдкреБрдирдГ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдмрд╣реБрдд рддреЗрдЬрд╝ рд╕рдВрдЪрд╛рд▓рди рдирд╣реАрдВ рд╣реИ (рдЬреИрд╕рд╛ рдХрд┐ рдмрд╛рдж рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛), рдпрд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдирдкреБрдЯ рдХреЗ рдмрд╛рдж рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рджреЗрд░реА рд╕реЗ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:


 google.maps.event.addListener(map, 'bounds_changed', function () { if (boundsChangedInverval != undefined) clearInterval(boundsChangedInverval); var zoom = map.getZoom(); boundsChangedInverval = setTimeout(function () { boundsChanged(); }, prevZoom === zoom ? moveUpdateDelay : zoomUpdateDelay); prevZoom = zoom; }); 

рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рджреГрд╢реНрдпрдорд╛рди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдФрд░ рд╣реИрд╢ рдХреА рдЧрдгрдирд╛


рд╕рднреА рдЖрдпрддреЛрдВ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдФрд░ рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдЬреЛ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ ( latMin , lngMin ) рдХреЗ рд╕рд╛рде рджреГрд╢реНрдпрдорд╛рди рд╡рд┐рдВрдбреЛ рдХреЛ рдУрд╡рд░рд▓реИрдк рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкрд╣рд▓реЗ рд╡рд░реНрдгрд┐рдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЧрдгрдирд╛ рдХрд┐рдП рдЧрдП рдЖрдпрд╛рдо рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИрдВ:



 var s = zoomSizes[zoom]; var beginLat = Math.floor((latMin - initPoint.x) / s.width) * s.width + initPoint.x; var beginLng = Math.floor((lngMin - initPoint.y) / s.height) * s.height + initPoint.y; var lat = beginLat; var lng = beginLng; if (lngMax <= beginLng) beginLng = beginLng - 360; while (lat <= maxlat) { lng = beginLng; while (lng <= maxLng) { //  lat  normalizeLng(lng)    . //    - ,        180     -180. loadIfNeeded(lat, normalizeLng(lng)); lng += s.height; } lat += s.width; } function normalizeLng(lng) { var rtn = lng % 360; if (rtn <= 0) rtn += 360; if (rtn > 180) rtn -= 360; return rtn; } 

рдлрд┐рд░, рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдиреЗ рдкрд░ рд╕рд░реНрд╡рд░ рдХреЛ рдЕрдиреБрд░реЛрдз рднреЗрдЬрддрд╛ рд╣реИред рд╣реИрд╢ рдЧрдгрдирд╛ рд╕реВрддреНрд░ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕рдВрджрд░реНрдн рдмрд┐рдВрджреБ рдФрд░ рдЖрдпрд╛рдо рдирд┐рд╢реНрдЪрд┐рдд рд╣реИрдВред


 function loadIfNeeded(lat, lng) { var hash = calculateHash(lat, lng, zoom); if (!(hash in items)) { //           . } else { //    . } } function calculateHash(lat, lng, zoom) { // lat: [-90..90] // lng: [-180..180] return (lat + 90) + ((lng + 180) * 180) + (zoom * 64800); } 

рдкреНрд░рджрд░реНрд╢рд┐рдд рддрд╕реНрд╡реАрд░реЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рддреИрдпрд╛рд░ рдХрд░рдирд╛


рд╕рднреА рддрд╕реНрд╡реАрд░реЛрдВ рдХреЛ рдХреИрд╢ рд╕реЗ рд▓реЛрдб рдпрд╛ рдирд┐рдХрд╛рд▓реЗ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдХреЛ рдлрд┐рд░ рд╕реЗ рддреИрдпрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рддрд╕реНрд╡реАрд░реЛрдВ рдХреЗ рдПрдХ рдмрдбрд╝реЗ рд╕рдВрдЪрдп рдХреЗ рд╕рд╛рде, рдпрд╛ рдмрд▓реНрдХрд┐ рдорд╛рд░реНрдХрд░, рдПрдХ рдЬрдЧрд╣ рдкрд░, рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдХреЛ рдЫрд┐рдкрд╛рдирд╛ рд╡рд╛рдВрдЫрдиреАрдп рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реЛ рдкрд╛рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рд╕реНрдерд╛рди рдкрд░ рдХрд┐рддрдиреА рддрд╕реНрд╡реАрд░реЗрдВ рд╕реНрдерд┐рдд рд╣реИрдВред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рджреЛ рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рд░реНрдХрд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рдмрдирд╛рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛: рдорд╛рд░реНрдХрд░ рдЬреЛ рдлрд╝реЛрдЯреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдорд╛рд░реНрдХрд░ рдЬреЛ рдмрддрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕ рдЬрдЧрд╣ рдореЗрдВ рдлрд╝реЛрдЯреЛ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рд╕рднреА рдорд╛рд░реНрдХрд░ рд╕реАрдорд╛рдУрдВ рдХреЛ рдмрджрд▓рддреЗ рд╕рдордп рдЫрд┐рдкреЗ рд╣реБрдП рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдлрд┐рд░ рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЭрд┐рд▓рдорд┐рд▓рд╛рд╣рдЯ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реЛрдЧрд╛ред рдЙрдкрд░реЛрдХреНрдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:


  1. рдХреНрд▓рд╛рдЗрдВрдЯ рдХреИрд╢ рд╕реЗ рд╕рднреА рджреГрд╢реНрдпрдорд╛рди рдлрд╝реЛрдЯреЛ рдХреЛ visMarks рд╕рд░рдгреА рдореЗрдВ visMarks ред рддрд╕реНрд╡реАрд░реЛрдВ рдХреЗ рд╕рд╛рде рдЗрди рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рдЧрдгрдирд╛ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдереАред
  2. рд▓реЛрдХрдкреНрд░рд┐рдпрддрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реЙрд░реНрдЯрд░реНрд╕ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдПред
  3. рдорд╛рд░реНрдХрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдУрд╡рд░рд▓реИрдкрд┐рдВрдЧ рдорд╛рд░реНрдХрд░реЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ, smallMarkerSize , minPhotoDistRatio рдФрд░ pixelDistance рдлрд╝рдВрдХреНрд╢рдиред
  4. maxBigVisPhotosCount рдорд╛рд░реНрдХрд░реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде maxBigVisPhotosCount рдХреА рд╕рдВрдЦреНрдпрд╛ рдФрд░ maxSmlVisPhotosCount рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде maxSmlVisPhotosCount ред
  5. рдкреБрд░рд╛рдиреЗ рдорд╛рд░реНрдХрд░ рдХреЛ рдЫреБрдкрд╛рдирд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ smlMarksToHide рдФрд░ bigMarksToHide рдореЗрдВ smlMarksToHide рдФрд░ рдЙрдиреНрд╣реЗрдВ bigMarksToHide рдХрд╛ refreshMarkerArrays ред
  6. рдирдП рдорд╛рд░реНрдХрд░реЛрдВ рдХреЗ рд▓рд┐рдП рджреГрд╢реНрдпрддрд╛ рдФрд░ zIndex рдбреЗрдкреНрде рдЗрдВрдбреЗрдХреНрд╕ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдЬреЛ рдХрд┐ zIndex рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
  7. addPhotoToRibbon рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╢реАрд░реНрд╖ рд░рд┐рдмрди рдкрд░ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд╡рд╛рд▓реА рдлрд╝реЛрдЯреЛ рдЬреЛрдбрд╝рдирд╛ред

рджрд░реНрд╢рдиреАрдп рдорд╛рд░реНрдХрд░ рдкреБрдирд░реНрдЧрдгрдирд╛ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо
 function redraw() { isRedrawing = true; var visMarker; var visMarks = []; var visBigMarks2; var visSmlMarks2; var bigMarksToHide = []; var smlMarksToHide = []; var photo; var i, j; var bounds = map.getBounds(); var northEast = bounds.getNorthEast(); var southWest = bounds.getSouthWest(); var latMin = southWest.lat(); var lngMin = southWest.lng(); var latMax = northEast.lat(); var lngMax = northEast.lng(); var ratio = (latMax - latMin) / $("#map_canvas").height(); var zoom = map.getZoom(); visMarks = []; var k = 0; var s = zoomSizes[zoom]; var beginLat = Math.floor((latMin - initPoint.x) / s.width) * s.width + initPoint.x; var beginLng = Math.floor((lngMin - initPoint.y) / s.height) * s.height + initPoint.y; var lat = beginLat; var lng = beginLng; i = 0; if (lngMax <= beginLng) beginLng = beginLng - 360; //    . while (lat <= latMax) { lng = beginLng; while (lng <= lngMax) { var hash = calcHash(lat, normLng(lng), zoom); if (!(hash in curItems)) { } else { var item = curItems[hash]; for (photo in item.photos) { if (bounds.contains(item.photos[photo].latLng)) { visMarks[i] = item.photos[photo]; visMarks[i].overlapCount = 0; i++; } } } k++; lng += s.height; } lat += s.width; } //    . visMarks.sort(function (a, b) { if (b.priority !== a.priority) { return b.priority - a.priority; } else if (b.popularity !== a.popularity) { return b.popularity - a.popularity; } else { return b.id - a.id; } }); //     ,    . var curInd; var contains; var contains2; var dist; visBigMarks2 = []; visSmlMarks2 = []; for (i = 0; i < visMarks.length; i++) { contains = false; contains2 = false; visMarker = visMarks[i]; for (j = 0; j < visBigMarks2.length; j++) { dist = pixelDistance(visMarker.latLng, visBigMarks2[j].latLng, zoom); if (dist <= markerSize * minPhotoDistRatio) { contains = true; if (contains && contains2) break; } if (dist <= (markerSize + smallMarkerSize) / 2) { contains2 = true; if (contains && contains2) break; } } if (!contains) { if (visBigMarks2.length < maxBigVisPhotosCount) { smlMarksToHide[smlMarksToHide.length] = visMarker; visBigMarks2[visBigMarks2.length] = visMarker; } } else { bigMarksToHide[bigMarksToHide.length] = visMarker; if (!contains2 && visSmlMarks2.length < maxSmlVisPhotosCount) { visSmlMarks2[visSmlMarks2.length] = visMarker; } else { visBigMarks2[j].overlapCount++; } } } //  ,     smlMarksToHide  bigMarksToHide . refreshMarkerArrays(visibleSmallMarkers, visSmlMarks2, smlMarksToHide); refreshMarkerArrays(visibleBigMarkers, visBigMarks2, bigMarksToHide); //         zIndex. var curZInd = maxBigVisPhotosCount + 1; curZInd = updateMarkersVis(visBigMarks2, bigMarksToHide, true, curZInd); curZInd = 0; curZInd = updateMarkersVis(visSmlMarks2, smlMarksToHide, false, curZInd); visibleBigMarkers = visBigMarks2; visibleSmallMarkers = visSmlMarks2; //     . trPhotosOnMap.innerHTML = ''; for (var marker in visBigMarks2) { addPhotoToRibbon(visBigMarks2[marker]); } isRedrawing = false; } function refreshMarkerArrays(oldArr, newArr, toHide) { for (var j = 0; j < oldArr.length; j++) { contains = false; var visMarker = oldArr[j]; for (i = 0; i < newArr.length; i++) { if (newArr[i].id === visMarker.id) { contains = true; break; } } if (!contains) { toHide[toHide.length] = visMarker; } } } function updateMarkersVis(showArr, hideArr, big, curZInd) { var marker; var bounds = map.getBounds(); for (var i = 0; i < showArr.length; i++) { var photo = showArr[i]; if (big) { marker = photo.bigMarker; $('#divOvlpCount' + photo.id).html(photo.overlapCount); } else { marker = photo.smlMarker; } marker.setZIndex(++curZInd); if (marker.getMap() === null) { marker.setMap(map); } } for (i = 0; i < hideArr.length; i++) { marker = big ? hideArr[i].bigMarker : hideArr[i].smlMarker; if (marker.getMap() !== null) { marker.setMap(null); marker.setZIndex(0); if (!bounds.contains(hideArr[i].latLng)) hideArr[i].priority = 0; } } return curZInd; } function addPhotoToRibbon(marker) { var td = createColumn(marker); if (isLatLngValid(marker.latLng)) { trPhotosOnMap.appendChild(td); } else { trPhotosNotOnMap.appendChild(td); if (photoViewMode == 'user') { var img = $("#photo" + marker.id).children()[0]; $('#photo' + marker.id).draggable({ helper: 'clone', appendTo: $('#map_canvas'), stop: function (e) { var mapBoundingRect = document.getElementById("map_canvas").getBoundingClientRect(); var point = new google.maps.Point(e.pageX - mapBoundingRect.left, e.pageY - mapBoundingRect.top); var latLng = overlay.getProjection().fromContainerPixelToLatLng(point); marker.latLng = latLng; marker.priority = ++curPriority; placeMarker(marker); }, containment: 'parent', distance: 5 }); } } } 

рдирдХреНрд╢рд╛ рджреВрд░реА


рдкрд┐рдХреНрд╕реЗрд▓ рдореЗрдВ рдорд╛рдирдЪрд┐рддреНрд░ рдкрд░ рджреЛ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдмреАрдЪ рдХреА рджреВрд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП , рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:


 var Offset = 268435456; var Radius = 85445659.4471; function pixelDistance(latLng1, latLng2, zoom) { var x1 = lonToX(latLng1.lng()); var y1 = latToY(latLng1.lat()); var x2 = lonToX(latLng2.lng()); var y2 = latToY(latLng2.lat()); return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) >> (21 - zoom); } function lonToX(lng) { return Math.round(Offset + Radius * lng * Math.PI / 180); } function latToY(lat) { return Math.round(Offset - Radius * Math.log((1 + Math.sin(lat * Math.PI / 180)) / (1 - Math.sin(lat * Math.PI / 180))) / 2); } 

рдпрд╣ рдХрд╛рд░реНрдп рд╡рд┐рд╢рд╛рд▓ рд╕реНрдЯреИрдХрдУрд╡рд░рдлреНрд▓реЛ рдкрд░ рднреА рдкрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред


рдорд╛рд░реНрдХрд░реЛрдВ рдХреЛ рд╕реНрдЯрд╛рдЗрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрд╛рдХрд┐ рд╡реЗ VKontakte рдЬреИрд╕реЗ рдлрд╝реЛрдЯреЛ рдХреЗ рд╕рд╛рде рдордВрдбрд▓рд┐рдпреЛрдВ рдХреА рддрд░рд╣ рджрд┐рдЦреЗрдВ, RichMarker рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ div рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдПрдХ рдордирдорд╛рдирд╛ рд╢реИрд▓реА рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред


рдирд┐рд╖реНрдХрд░реНрд╖


рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ, рдирдХреНрд╢реЗ рдкрд░ рдлрд╝реЛрдЯреЛ рдХреЛ рдЬрд▓реНрджреА рдФрд░ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХреИрд╢рд┐рдВрдЧ рдФрд░ рдЧреЛрд▓рд╛рдХрд╛рд░ рдЬреНрдпрд╛рдорд┐рддрд┐ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдмрд▓реНрдХрд┐ рджрд┐рд▓рдЪрд╕реНрдк рдФрд░ рдЧреИрд░-рддреБрдЪреНрдЫ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рд╣рдорд╛рд░реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рд╕рдордп рдмрд░реНрдмрд╛рдж рдирд╣реАрдВ рд╣реБрдЖ рдерд╛ рдкреНрд░рд╛рдкреНрдд рдЕрдиреБрднрд╡ рдЕрдиреНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рднреА рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдЗрд╕ рд▓реЗрдЦ рдХреЛ рдкрдврд╝рд╛ рд╣реИ рдФрд░ рдЙрдирдХрд╛ рдЙрджреНрдзрд╛рд░ рдХрд┐рдпрд╛ рд╣реИред



Source: https://habr.com/ru/post/In182532/


All Articles