рд╣рдо рд╕реНрдорд╛рд░реНрдЯрдлреЛрди рдкрд░ рдирд╛рд╡рд┐рдХ рд╕реЗ рдСрдирд▓рд╛рдЗрди рдирдХреНрд╢реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВред рднрд╛рдЧ 2 - рд╡реЗрдХреНрдЯрд░ рдХрд╛рд░реНрдб

рд╣рдо рдПрдХ рд╕рд░реНрд╡рд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ рдЬреЛ рдСрдирд▓рд╛рдЗрди рд╡реЗрдХреНрдЯрд░ рдореИрдкреНрд╕ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкреАрдПрдирдЬреА рд░реИрд╕реНрдЯрд░ рдЯрд╛рдЗрд▓реНрд╕ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ред рдорд╛рдирдЪрд┐рддреНрд░ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Puppeteer рдХреЗ рд╕рд╛рде рд╡реЗрдм рд╕реНрдХреНрд░реИрдкрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред


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


1 - рдкрд░рд┐рдЪрдпред рдорд╛рдирдХ рд░реЗрдЦрд╛рдкреБрдВрдЬ рдирдХреНрд╢реЗ
2 - рдирд┐рд░рдВрддрд░рддрд╛ред рд╡реЗрдХреНрдЯрд░ рдирдХреНрд╢реЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рд░реЗрдЦрд╛рдкреБрдВрдЬ рд▓рд┐рдЦрдирд╛
3 - рдПрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓рд╛ред рд╣рдо рдУрд╡рд░рдкрд╛рд╕рдЯрд░реНрдмреЛ рдХрд╛рд░реНрдб рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВ


рд╡рд┐рд╕реНрддрд╛рд░


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


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


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


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


рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░


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


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


рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ "рд░рд┐рдореЛрдЯ рдХрдВрдЯреНрд░реЛрд▓ рдмреНрд░рд╛рдЙрдЬрд╝рд░" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ - рд╣реЗрдбрд▓реЗрд╕ рдХреНрд░реЛрдоред рдЖрдк рдиреЛрдб js рд▓рд╛рдЗрдмреНрд░реЗрд░реА Puppeteer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рдЗрд╕ рд▓реЗрдЦ рд╕реЗ рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ рдЬрд╛рди рд╕рдХрддреЗ рд╣реИрдВред


рдирдорд╕реНрддреЗ рд╡рд┐рд╢реНрд╡! рдпрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ рдФрд░ рдХрд╕реНрдЯрдорд╛рдЗрдЬрд╝ рдХрд░реЗрдВ


рдпрджрд┐ рдЖрдкрдиреЗ рдЕрднреА рддрдХ Node.js рд╕реНрдерд╛рдкрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдЗрд╕ рдпрд╛ рдЗрд╕ рдкреГрд╖реНрда рдкрд░ рдЬрд╛рдПрдВ, рдЕрдкрдиреЗ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ рдФрд░ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╕реНрдерд╛рдкрдирд╛ рдХрд░реЗрдВред


рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдлрд╝реЛрд▓реНрдбрд░ рдмрдирд╛рдПрдВ рдФрд░ рдЗрд╕реЗ рдЯрд░реНрдорд┐рдирд▓ рдореЗрдВ рдЦреЛрд▓реЗрдВред


$ cd /Mapshoter_habr 

рд╣рдо рдПрдХ рдирдИ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рдмрдВрдзрдХ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ


 $ npm init 

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


рдЕрдЧрд▓рд╛, рдХрд╛рдо рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд░реВрдкрд░реЗрдЦрд╛рдПрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВред рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░реНрд╡рд░ рдФрд░ Puppeteer рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡реНрдпрдХреНрдд рдХрд░реЗрдВред


 $ npm install express $ npm i puppeteer 

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


 { "name": "mapshoter_habr", "version": "1.0.0", "description": "", "main": "router.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "nnngrach", "license": "ISC", "dependencies": { "express": "^4.17.1", "puppeteer": "^1.18.1" } } 

рд╣рдо рд╣рдорд╛рд░реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рдЖрд╕рд╛рдиреА рд╕реЗ рд▓реЙрдиреНрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗрдХреНрд╢рди рдореЗрдВ рд╕реНрдЯрд╛рд░реНрдЯ рд▓рд╛рдЗрди рдЬреЛрдбрд╝ рджреЗрдВрдЧреЗред


 "scripts": { "start": "node router.js", "test": "echo \"Error: no test specified\" && exit 1" }, 

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


 //        const express = require( 'express' ) const mapshoter = require( './mapshoter' ) //  ,       const PORT = process.env.PORT || 5000 //     const app = express() app.listen( PORT, () => { console.log( '    ', PORT ) }) //       // http://siteName.com/x/y/z app.get( '/:x/:y/:z', async ( req, res, next ) => { //      const x = req.params.x const y = req.params.y const z = req.params.z //      const screenshot = await mapshoter.makeTile( x, y, z ) //        const imageBuffer = Buffer.from( screenshot, 'base64' ) //    res.writeHead( 200, { 'Content-Type': 'image/png', 'Content-Length': imageBuffer.length }) //    res.end( imageBuffer ) }) 

рдЕрдм рдПрдХ рджреВрд╕рд░реА рдлрд╛рдЗрд▓ рдмрдирд╛рдПрдВред рд╡рд╣ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░реЗрдЧрд╛ рдФрд░ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рд▓реЗрдЧрд╛ред рдореИрдВрдиреЗ рдЗрд╕реЗ mapshoter.js рдХрд╣рд╛ рд╣реИред


 const puppeteer = require( 'puppeteer' ) async function makeTile( x, y, z ) { //   const browser = await puppeteer.launch() //       const page = await browser.newPage() await page.goto( 'https://www.google.ru/' ) //    const screenshot = await page.screenshot() //      await browser.close() return screenshot } module.exports.makeTile = makeTile 

рд╣рдорд╛рд░реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛рдПрдВ рдФрд░ рдЙрд╕рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдВрд╕реЛрд▓ рдореЗрдВ рдЯрд╛рдЗрдк рдХрд░реЗрдВ:


$ npm start


рдПрдХ рд╕рдВрджреЗрд╢ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдХрд╣рддрд╛ рд╣реИ рдХрд┐ "рд╕рд░реНрд╡рд░ 5000 рдкреЛрд░реНрдЯ рдкрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ"ред рдЕрдм рдЕрдкрдиреЗ рдХрдВрдкреНрдпреВрдЯрд░ рдкрд░ рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдЦреЛрд▓реЗрдВ рдФрд░ рд╣рдорд╛рд░реЗ рд╕рд░реНрд╡рд░ рдХреЗ рд╕реНрдерд╛рдиреАрдп рдкрддреЗ рдкрд░ рдЬрд╛рдПрдВред X, y, z рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рдмрдЬрд╛рдп , рдЖрдк рдХрд┐рд╕реА рднреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВрдиреЗ рез, реи, рей рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд┐рдпрд╛ред


http://localhost:5000/1/2/3


рдпрджрд┐ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ Google рд╕рд╛рдЗрдЯ рдХрд╛ рдПрдХ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ред


рдЫрд╡рд┐


рд╣рдорд╛рд░реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдХрдВрд╕реЛрд▓ рдореЗрдВ Ctrl + C рджрдмрд╛рдПрдВред


рдмрдзрд╛рдИ, рд╣рдорд╛рд░реЗ рдЖрд╡реЗрджрди рдХрд╛ рдЖрдзрд╛рд░ рддреИрдпрд╛рд░ рд╣реИ! рд╣рдордиреЗ рдПрдХ рд╕рд░реНрд╡рд░ рдмрдирд╛рдпрд╛ рдЬреЛ рд╣рдорд╛рд░реЗ HTML рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдПрдХ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рд╣рдореЗрдВ рдПрдХ рдЫрд╡рд┐ рджреЗрддрд╛ рд╣реИред рдЕрдм рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред


рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ


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


рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рд╕реАрд░рд┐рдпрд▓ рдирдВрдмрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЯрд╛рдЗрд▓ рдХреЗ рдХреЗрдВрджреНрд░ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореИрдВ рдКрдкрд░реА рдмрд╛рдПрдБ рдХреЛрдиреЗ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд╕реВрддреНрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдРрд╕рд╛ рдХрд░реВрдБрдЧрд╛ред рдореИрдВрдиреЗ рдЗрд╕реЗ getCoordinates () рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдбрд╛рд▓рд╛ред


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


 //   -   function getCoordinates( x, y, z ) { const n = Math.pow( 2, z ) const lon = x / n * 360.0 - 180.0 const lat = 180.0 * ( Math.atan( Math.sinh( Math.PI * ( 1 - 2 * y / n) ) ) ) / Math.PI return { lat: lat, lon: lon } } //          function getCenter( left, rigth, top, bottom ) { let lat = ( left + rigth ) / 2 let lon = ( top + bottom ) / 2 return { lat: lat, lon: lon } } //        function getAllCoordinates( stringX, stringY, stringZ ) { //      const x = Number( stringX ) const y = Number( stringY ) const z = Number( stringZ ) //     //    -  -  const topLeft = getCoordinates( x, y, z ) const bottomRight = getCoordinates( x+1, y+1, z ) //   const center = getCenter( topLeft.lat, bottomRight.lat, topLeft.lon, bottomRight.lon ) //   const bBox = { latMin: bottomRight.lat, lonMin: topLeft.lon, latMax: topLeft.lat, lonMax: bottomRight.lon } return { bBox: bBox, center: center } } module.exports.getAllCoordinates = getAllCoordinates 

рдЕрдм рд╣рдо рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рдкрд░рд┐рджреГрд╢реНрдп 1 - рдПрдкреАрдЖрдИ рдЦреЛрдЬ


рдЖрдЗрдП рд╕рд░рд▓рддрдо рдорд╛рдорд▓реЗ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ, рдЬрдм рдЖрдк рдорд╛рдирдЪрд┐рддреНрд░ рдкреГрд╖реНрда рдХреЗ URL рдореЗрдВ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рджрд░реНрдЬ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣:


https://nakarte.me/#m=5/50.28144/89.30666&l=O/Wp


рдЖрдЗрдП рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджреЗрдЦреЗрдВред рдмрд╕ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ, mapshoter.js рдлрд╝рд╛рдЗрд▓ рдХреА рд╕рдВрдкреВрд░реНрдг рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╣рдЯрд╛ рджреЗрдВ рдФрд░ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХреЛрдб рдХреЛ рдкреЗрд╕реНрдЯ рдХрд░реЗрдВред


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


рдЕрдЧрд▓рд╛, рд╣рдо рд╡рд╛рдВрдЫрд┐рдд рдЯрд╛рдЗрд▓ рдХреЗ рдХреЗрдВрджреНрд░ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдЙрдиреНрд╣реЗрдВ URL рдореЗрдВ рдкреЗрд╕реНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╣реИрдВред рдЯрд╛рдЗрд▓ рдмрд┐рд▓реНрдХреБрд▓ рд╕реНрдХреНрд░реАрди рдХреЗ рдХреЗрдВрджреНрд░ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИред 256x256 рдкрд┐рдХреНрд╕реЗрд▓ рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рдХрд╛рдЯреЗрдВред рдпрд╣ рд╡рд╣ рдЯрд╛рдЗрд▓ рд╣реЛрдЧреА рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдХреЗрд╡рд▓ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИред


рдХреЛрдб рдкрд░ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗ рд╕рднреА рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рд╣рдЯрд╛ рджреА рдЧрдИ рд╣реИред


 const puppeteer = require( 'puppeteer' ) const geoTools = require( './geoTools' ) async function makeTile( x, y, z ) { //    ,    Heroku const herokuDeploymentParams = {'args' : ['--no-sandbox', '--disable-setuid-sandbox']} const browser = await puppeteer.launch( herokuDeploymentParams ) //        //       const page = await browser.newPage() await page.setViewport( { width: 660, height: 400 } ) //         URL const coordinates = geoTools.getAllCoordinates( x, y, z ) const centerCoordinates = `${z}/${coordinates.center.lat}/${coordinates.center.lon}&l=` const pageUrl = 'https://nakarte.me/#m=' + centerCoordinates + "O/Wp" //   URL  ,    await page.goto( pageUrl, { waitUntil: 'networkidle0', timeout: 20000 } ) //    const cropOptions = { fullPage: false, clip: { x: 202, y: 67, width: 256, height: 256 } } const screenshot = await page.screenshot( cropOptions ) //      await browser.close() return screenshot } module.exports.makeTile = makeTile 

рдЕрдм рд╣рдорд╛рд░реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛рдПрдВ рдФрд░ рдЗрд╕ рдЕрдиреБрднрд╛рдЧ рдХреЗ рд▓рд┐рдП рдорд╛рдирдЪрд┐рддреНрд░ рджреЗрдЦреЗрдВред


http://localhost:5000/24/10/5


рдпрджрд┐ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕рд░реНрд╡рд░ рдХреЛ рдРрд╕реА рдЯрд╛рдЗрд▓ рд╡рд╛рдкрд╕ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП:



рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╣рдо рдлрд╕рд▓ рдмрдирд╛рддреЗ рд╕рдордп рдХреБрдЫ рднреА рдирд╣реАрдВ рдорд┐рд▓рд╛рддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реА рдЯрд╛рдЗрд▓ рдХреА рддреБрд▓рдирд╛ OpenStreetMaps.org рдХреЗ рдореВрд▓ рд╕реЗ рдХрд░реЗрдВ



рдкрд░рд┐рджреГрд╢реНрдп 2 - рд╕рд╛рдЗрдЯ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЦреЛрдЬреЗрдВ


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


рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдорддреМрд░ рдкрд░ рдЦреЛрдЬ рдХреЗ рдмрд╛рдж рдЙрд╕реА рдкреИрдорд╛рдиреЗ рдХреЛ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред 15 рд╡реЗрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдПред рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдРрд╕рд╛ рд╣рдореЗрд╢рд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдкреГрд╖реНрда рдкрд░ HTML рддрддреНрд╡реЛрдВ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рд╕реЗ рдЬрд╝реВрдо рд╕реНрддрд░ рдХреЛ рдкрд╣рдЪрд╛рдиреЗрдВрдЧреЗред


рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рднреА, рд╣рдо XPath рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рддрддреНрд╡реЛрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░реЗрдВрдЧреЗред рд▓реЗрдХрд┐рди рдЖрдк рдЙрдиреНрд╣реЗрдВ рдХреИрд╕реЗ рдкрд╣рдЪрд╛рдирддреЗ рд╣реИрдВ?


рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдкреГрд╖реНрда рдЦреЛрд▓реЗрдВ рдФрд░ рдбреЗрд╡рд▓рдкрд░ рдЯреВрд▓рдмрд╛рд░ рдЦреЛрд▓реЗрдВ (Google Chrome рдХреЗ рд▓рд┐рдП Ctll + Alt + I )ред рдЖрдЗрдЯрдо рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдЯрди рджрдмрд╛рдПрдВред рд╣рдо рдЙрд╕ рддрддреНрд╡ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдЖрдк рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ (рдореИрдВ рдЦреЛрдЬ рдХреНрд╖реЗрддреНрд░ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реВрдВ)ред



рдЖрдЗрдЯрдо рдХреА рд╕реВрдЪреА рдЙрд╕ рдкрд░ рд╕реНрдХреНрд░реЙрд▓ рдХрд░рддреА рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдиреЗ рдХреНрд▓рд┐рдХ рдХрд┐рдпрд╛ рдерд╛ рдФрд░ рдЗрд╕реЗ рдиреАрд▓реЗ рд░рдВрдЧ рдореЗрдВ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдирд╛рдо рдХреЗ рдмрд╛рдИрдВ рдУрд░ рддреАрди рдбреЙрдЯреНрд╕ рд╡рд╛рд▓реЗ рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВред


рдкреЙрдк-рдЕрдк рдореЗрдиреВ рд╕реЗ, рдХреЙрдкреА рдЪреБрдиреЗрдВред рдЕрдЧрд▓рд╛, рдпрджрд┐ рдЖрдкрдХреЛ рдПрдХ рдирд┐рдпрдорд┐рдд рдЪрдпрдирдХрд░реНрддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдХреЙрдкреА рдЪрдпрдирдХрд░реНрддрд╛ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ ред рд▓реЗрдХрд┐рди рдЙрд╕реА рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдХреЙрдкреА XPath рдЖрдЗрдЯрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред



рдЕрдм рдЗрд╕ рдХреЛрдб рдХреЗ рд╕рд╛рде mapshoter.js рдлрд╝рд╛рдЗрд▓ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрджрд▓реЗрдВред рдЗрд╕рдореЗрдВ, рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╣реА рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдЪрдпрдирдХрд░реНрддрд╛рдУрдВ рдХреЛ рдПрдХрддреНрд░ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИред


 const puppeteer = require( 'puppeteer' ) const geoTools = require( './geoTools' ) async function makeTile( x, y, z ) { //      const searchFieldXPath = '//*[@id="map"]/div[1]/div[1]/div/input' const zoomPlusXPath = '//*[@id="map"]/div[2]/div[2]/div[4]/div[1]/a[1]' const zoomMinusXPath = '//*[@id="map"]/div[2]/div[2]/div[4]/div[1]/a[2]' const directionButonXPath = '//*[@id="gtm-poi-card-get-directions"]' const deletePinButonXPatch = '//*[@id="map"]/div[1]/div/div/div[1]/div[2]/div/div[4]/div/div[4]' //         () const coordinates = geoTools.getAllCoordinates( x, y, z ) const centerCoordinates = `lat=${coordinates.center.lat} lng=${coordinates.center.lon}` //      const herokuDeploymentParams = {'args' : ['--no-sandbox', '--disable-setuid-sandbox']} const browser = await puppeteer.launch( herokuDeploymentParams ) const page = await browser.newPage() await page.setViewport( { width: 1100, height: 450 } ) //         const pageUrl = 'https://www.waze.com/en/livemap?utm_campaign=waze_website' await page.goto( pageUrl, { waitUntil: 'networkidle2', timeout: 10000 } ) //    ,      await click( searchFieldXPath, page ) //        await page.keyboard.type( centerCoordinates ) //  Enter    page.keyboard.press( 'Enter' ); //  500     await page.waitFor( 500 ) //       //       await click( directionButonXPath, page ) await page.waitFor( 100 ) await click( deletePinButonXPatch, page ) await page.waitFor( 100 ) //       //        while( z > await fetchCurrentZoom( page )) { await click( zoomPlusXPath, page ) await page.waitFor( 300 ) } while( z < await fetchCurrentZoom( page )) { await click( zoomMinusXPath, page ) await page.waitFor( 300 ) } //    const cropOptions = { fullPage: false, clip: { x: 422, y: 97, width: 256, height: 256 } } const screenshot = await page.screenshot( cropOptions ) //   await browser.close() return screenshot } //  : //        async function click( xPathSelector, page ) { await page.waitForXPath( xPathSelector ) const foundedElements = await page.$x( xPathSelector ) if ( foundedElements.length > 0 ) { await foundedElements[0].click() } else { throw new Error( "XPath element not found: ", xPathSelector ) } } //         html  async function fetchCurrentZoom( page ) { const xPathSelector = '//*[@id="map"]/div[2]' await page.waitForXPath( xPathSelector ) const elems = await page.$x(xPathSelector) const elementParams = await page.evaluate((...elems) => { return elems.map(e => e.className); }, ...elems); const zoom = elementParams[0].split('--zoom-').pop() return zoom } module.exports.makeTile = makeTile 

рд╣рдорд╛рд░реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛рдПрдБ рдФрд░ рд▓рд┐рдВрдХ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░реЗрдВред рдпрджрд┐ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЗрд╕ рдЯрд╛рдЗрд▓ рдХреА рддрд░рд╣ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧреАред


http://localhost:5000/1237/640/11



рдЕрдиреБрдХреВрд▓рди


рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рджреЛ рд╡рд┐рдзрд┐рдпрд╛рдВ рд╡реЗрдХреНрдЯрд░ рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рд╕рд╛рде рдХрдИ рд╕рд╛рдЗрдЯреЛрдВ рд╕реЗ рдЬреБрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИрдВред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдкрдХреЛ рдЕрдЪрд╛рдирдХ рдХреБрдЫ рдирдП рдирдХреНрд╢реЗ рддрдХ рдкрд╣реБрдВрдЪ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ mapshoter.js рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдпрд╣реА рд╣реИ, рдЗрд╕ рдкрджреНрдзрддрд┐ рд╕реЗ рдирдП рдХрд╛рд░реНрдб рдЬреЛрдбрд╝рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЗрд╕рдХреЗ рдлрд╛рдпрджреЛрдВ рдореЗрдВ рд╕реЗ рд╣реИред


рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдиреБрдХрд╕рд╛рди рднреА рд╣реИрдВред рдФрд░ рдореБрдЦреНрдп рдПрдХ рдХрд╛рдо рдХреА рдЧрддрд┐ рд╣реИред рдмрд╕ рддреБрд▓рдирд╛ рдХреАрдЬрд┐рдПред рдПрдХ рдирд┐рдпрдорд┐рдд рд░рд╛рд╕реНрдЯрд░ рдЯрд╛рдЗрд▓ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдореЗрдВ рдФрд╕рддрди рд▓рдЧрднрдЧ 0.5 рд╕реЗрдХрдВрдб рдХрд╛ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред рдЗрд╕ рд╕рдордп рд╣рдорд╛рд░реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗ рдПрдХ рдЯрд╛рдЗрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рд▓рдЧрднрдЧ 8 рд╕реЗрдХрдВрдб рд▓рдЧрддреЗ рд╣реИрдВред


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


рдФрд░ рдПрдХ рдмрд╛рддред рдХреБрдЫ рдирд╛рд╡рд┐рдХреЛрдВ рдХрд╛ рд╕рдордп рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ рд╣реИ: рд╡реЗ 30 рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдж рд▓реЛрдб рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджреЗрдВрдЧреЗред рдФрд░ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдХреЗрд╡рд▓ 3-4 рдЯрд╛рдЗрд▓реЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реЛрдЧрд╛ред рдЦреИрд░, рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рд╣рдо рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


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


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


рддреАрд╕рд░рд╛ред рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рд╛рде, рд╣рдо рдХреНрд░реЛрдо рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдореЗрдВ рд╕рдордп рдмрд┐рддрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдкреВрд░рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЕрдм рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдмрдирд╛рдПрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ mapshoter.js рдореЗрдВ рд▓рд┐рдВрдХ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░реЗрдВрдЧреЗред рдирддреАрдЬрддрди, рдЧрддрд┐ рдкрд╣рд▓реЗ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдмрджрд▓реЗрдЧреАред рд▓реЗрдХрд┐рди рдмрд╛рдж рдХреЗ рд╕рднреА рдбрд╛рдЙрдирд▓реЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдЯрд╛рдЗрд▓ рдХреА рдЧрддрд┐ 4 рд╕реЗрдХрдВрдб рддрдХ рдХрдо рд╣реЛ рдЬрд╛рддреА рд╣реИред рдФрд░ 30 рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдж рдкреВрд░реЗ рдирдХреНрд╢реЗ рдореЗрдВ рд▓реЛрдб рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ - рд╕рднреА 24 рдЯрд╛рдЗрд▓реЗрдВ рдЬреЛ рдореЗрд░реА рд╕реНрдХреНрд░реАрди рдкрд░ рд░рдЦреА рдЧрдИ рд╣реИрдВред


рдареАрдХ рд╣реИ, рдпрджрд┐ рдЖрдк рдпрд╣ рд╕рдм рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛рдлреА рд╡реНрдпрд╡рд╣рд╛рд░реНрдп рд╣реЛ рд╕рдХрддреА рд╣реИред рддреЛ рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рд╕рд░рд▓ рдХрд╛рдо рдХреЗ рд▓рд┐рдП, рдореИрдВ рдиреЛрдб-рд╡рд░реНрдХрд░-рдереНрд░реЗрдбреНрд╕-рдкреВрд▓ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ - рдХрд╛рд░реНрдпрдХрд░реНрддрд╛_рдХреНрд░реЗрдбреНрд╕ рдкрд░ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЖрд╡рд░рдгред рдЗрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВред


$ npm install node-worker-threads-pool --save


рд░рд╛рдЙрдЯрд░ рдХреЛ рдареАрдХ рдХрд░реЗрдВред рдЬреЗрдПрд╕ рдлрд╛рдЗрд▓ред рдЗрд╕реЗ рдереНрд░реЗрдб рдкреВрд▓ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред рдзрд╛рдЧреЗ 3 рдЯреБрдХрдбрд╝реЗ рд╣реЛрдВрдЧреЗред рдЙрдирдХрд╛ рдХреЛрдб рдХрд╛рд░реНрдпрдХрд░реНрддрд╛ рдХреА рдЬреЗрдПрд╕ рдлрд╛рдЗрд▓ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд╣рдо рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рджреЗрдЦреЗрдВрдЧреЗред рдЗрд╕ рдмреАрдЪ, рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓реЙрдиреНрдЪ рдХреЛ рд╕реАрдзреЗ рд╣рдЯрд╛ рджреЗрдВред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдереНрд░реЗрдб рдкреВрд▓ рдореЗрдВ рдПрдХ рдирдпрд╛ рдХрд╛рд░реНрдп рдЬреЛрдбрд╝реЗрдВрдЧреЗред рдереНрд░реЗрдбреНрд╕ рдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдХреЛ рдореБрдХреНрдд рдХрд░рдиреЗ рдкрд░ рд╡реЗ рдЗрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдВрдЧреЗред


 const express = require( 'express' ) const PORT = process.env.PORT || 5000 const app = express() app.listen( PORT, () => { console.log( '    ', PORT ) }) //   . const { StaticPool } = require( 'node-worker-threads-pool' ) const worker = "./worker.js" const workersPool = new StaticPool({ size: 3, task: worker, workerData: "no" }) app.get( '/:x/:y/:z', async ( req, res, next ) => { const x = req.params.x const y = req.params.y const z = req.params.z //       //       const screenshot = await workersPool.exec( { x, y, z } ) const imageBuffer = Buffer.from( screenshot, 'base64' ) res.writeHead( 200, { 'Content-Type': 'image/png', 'Content-Length': imageBuffer.length }) res.end( imageBuffer ) }) 

рдЕрдм рдХрд╛рд░реНрдпрдХрд░реНрддрд╛.рдЬреЗрдПрд╕ рдлрд╝рд╛рдЗрд▓ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред рд╣рд░ рдмрд╛рд░ рдПрдХ рдирдпрд╛ рдХрд╛рд░реНрдп рдЖрдиреЗ рдкрд░, parentPort.on () рд╡рд┐рдзрд┐ рд▓реЙрдиреНрдЪ рдХреА рдЬрд╛рдПрдЧреАред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ async / рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓ рдирд╣реАрдВ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рд╣рдо doMyAsyncCode () рд╡рд┐рдзрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдбреЗрдкреНрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред


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


 const { parentPort, workerData } = require( 'worker_threads' ); const puppeteer = require( 'puppeteer' ) const mapshoter = require( './mapshoter' ) //     var browser = "empty" //         //    ,     parentPort.on( "message", ( params ) => { doMyAsyncCode( params ) .then( ( result) => { parentPort.postMessage( result ) }) }) //  ,    async/aswit //     async function doMyAsyncCode( params ) { //      await prepareEnviroment() //     const screenshot = await mapshoter.makeTile( params.x, params.y, params.z, browser ) return screenshot } //  .     ,    async function prepareEnviroment( ) { if ( browser === "empty" ) { const herokuDeploymentParams = {'args' : ['--no-sandbox', '--disable-setuid-sandbox']} browser = await puppeteer.launch( herokuDeploymentParams ) } } 

рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо mapshoter.js рдХреЗ рдкрд╣рд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рд▓реМрдЯрддреЗ рд╣реИрдВ ред рдпрд╣ рдЬреНрдпрд╛рджрд╛ рдирд╣реАрдВ рдмрджрд▓реЗрдЧрд╛ред рдЕрдм рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рдпрд╣ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рд┐рдВрдХ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдЧрд╛, рдФрд░ рдЬрдм рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рдПрдЧреА, рддреЛ рдпрд╣ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдмрдВрдж рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдмрд╕ рдмрдирд╛рдП рдЧрдП рдЯреИрдм рдХреЛ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛ред


 const puppeteer = require( 'puppeteer' ) const geoTools = require( './geoTools' ) async function makeTile( x, y, z, browserLink ) { //      const browser = await browserLink //      const page = await browser.newPage() await page.setViewport( { width: 660, height: 400 } ) const coordinates = geoTools.getAllCoordinates( x, y, z ) const centerCoordinates = `${z}/${coordinates.center.lat}/${coordinates.center.lon}&l=` const pageUrl = 'https://nakarte.me/#m=' + centerCoordinates + "O/Wp" await page.goto( pageUrl, { waitUntil: 'networkidle0', timeout: 20000 } ) const cropOptions = { fullPage: false, clip: { x: 202, y: 67, width: 256, height: 256 } } const screenshot = await page.screenshot( cropOptions ) //   .   . await page.close() return screenshot } module.exports.makeTile = makeTile 

рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдпрд╣ рд╕рдм рд╣реИред рдЕрдм рдЖрдк рд╕рд░реНрд╡рд░ рдХреЛ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдЖрдкрдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЗ рд╕реЗ рдкрд░рд┐рдгрд╛рдо рдЕрдкрд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, docker рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗред рдпрджрд┐ рдЖрдк рд╕рдорд╛рдкреНрдд рдкрд░рд┐рдгрд╛рдо рдХреЛ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕ рд▓рд┐рдВрдХ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рддреБрдо рднреА рдореЗрд░реЗ GitHub рдкрд░ рдкреВрд░реНрдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛрдб рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред


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


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


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


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


рдЦреИрд░, рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдмрд╕ рдЗрд╕рд╕реЗ рдирд┐рдкрдЯреВрдВрдЧрд╛ред рдореИрдВ OverpassTurbo рдЗрдВрдЯрд░реЗрдХреНрдЯрд┐рд╡ рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдПрдХ рддрд░рд╣ рдХреЗ рдПрдкреАрдЖрдИ рдореЗрдВ рдмрджрд▓ рджреВрдВрдЧрд╛ред

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


All Articles