diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..f166060d
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,17 @@
+# Editor configuration, see https://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.ts]
+quote_type = single
+ij_typescript_use_double_quotes = false
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..804d3533
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,64 @@
+src/assets/data_allsettlements_anon_156_v20251217.csv
+
+# Angular
+/dist
+/tmp
+/out-tsc
+/bazel-out
+
+# Node.js
+/node_modules
+npm-debug.log
+yarn-error.log
+package-lock.json
+yarn.lock
+
+# IDE
+/.vscode
+/.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+.DS_Store
+
+# Angular CLI
+/.angular
+/.ng
+
+# Environment files
+/src/environments/*.ts
+!/src/environments/environment.ts
+!/src/environments/environment.prod.ts
+
+# Build artifacts
+/dist
+/e2e
+/coverage
+
+# Testing
+/coverage
+/.nyc_output
+
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# OS generated files
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
+
+# Optional
+.idea/
+.vscode/
+*.sublime-*
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..d6c16d7e
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,12 @@
+{
+ "printWidth": 100,
+ "singleQuote": true,
+ "overrides": [
+ {
+ "files": "*.html",
+ "options": {
+ "parser": "angular"
+ }
+ }
+ ]
+}
diff --git a/README.md b/README.md
index 163d41b9..9dce8529 100644
--- a/README.md
+++ b/README.md
@@ -1,61 +1,27 @@
-# Безопасность веб-приложений. Лабораторка №2
+# Прогноз погоды
-## Схема сдачи
-
-1. Получить задание
-2. Сделать форк данного репозитория
-3. Выполнить задание согласно полученному варианту
-4. Сделать PR (pull request) в данный репозиторий
-6. Исправить замечания после code review
-7. Получить approve
-8. Прийти на занятие и защитить работу
-
-Что нужно проявить в работе:
-- умение разработать завершенное целое веб-приложение, с клиентской и серверной частями (допустимы открытые АПИ)
-- навыки верстки на html в объеме 200-300 тегов
-- навыки применения css для лейаута и стилизации, желательно с адаптацией к мобилке
-- использование jQuery или аналогичных JS-фреймворков
-- динамическая подгрузка контента
-- динамическое изменение DOM и CSSOM
-
-Если у вас своя идея по заданию, то расскажите, обсудим и подкорректирую.
-
-## Вариант 1. Расписания
-
-Сделать аналог раздела https://ssau.ru/rasp?groupId=531030143
-
-Какие нужны возможности:
-- справочники групп, табличные данные по расписаниям добывать с настоящего сайта на серверной стороне приложения
-- в клиентскую часть подгружать эти сведения динамически по JSON-API
-- обеспечить возможность смотреть расписания в разрезе группы или препода
-- обеспечить возможность выбора учебной недели (по умолчанию выбирается автоматически)
-
-## Вариант 2. Аналог Прибывалки для электричек
-
-Сделать веб-версию Прибывалки, только для электричек
-
-Какие нужны возможности:
-- находить желаемую ЖД-станцию поиском по названию и по карте
-- отображать расписания всех проходящих поездов через выбранную станцию
-- отображать расписания для поездов между двумя станциями
-- работа через АПИ Яндекс.Расписаний https://yandex.ru/dev/rasp/doc/ru/ (доступ получите сами)
-- хорошая работа в условиях экрана смартфона
-- бонус: функция "любимых остановок"
-
-## Вариант 3. Прогноз погоды
-
-Сделать одностраничный сайт с картой, на которой можно выбрать населенный пункт и получить прогноз погоды на несколько дней по нему.
-
-Какие нужны возможности:
- - увидеть на карте точки с населенными пунктами. Координаты населенных пунктов взять из https://tochno.st/datasets/allsettlements - но все 150 тысяч не нужно, выберите 1 тысячу с самым большим населением.
- - при нажатии на точку получить всплывающее окошко с графиками изменения температуры, осадков, силы ветра. API для прогнозов возьмите с https://projecteol.ru/ru/ с соблюдением правил.
- - графики рисовать каким-нибудь приличным компонентом, например, https://www.chartjs.org/
- - находить населенный пункт по названию
- - можете реализовать с собственным серверным компонентом или придумать, как обойтись без него
+Веб-приложение для просмотра прогноза погоды по городам России. Приложение использует карту с маркерами городов, поиск и модальные окна для отображения детальной информации.
+## Возможности
+- 🗺️ Интерактивная карта с маркерами 1000 крупнейших городов России
+- 🔍 Поиск городов по названию
+- 📊 Детальный прогноз погоды на 7 дней
+- 📈 Графики температуры и осадков
+- 🌡️ Текущая погода: температура, осадки, ветер, влажность
+- 📱 Адаптивный дизайн для мобильных устройств
+## Технологии
+- Angular 17+
+- Leaflet для карт
+- Chart.js для графиков
+- Open-Meteo API для данных о погоде
+## Установка и запуск
+### Клонирование репозитория
+```bash
+npm install
+ng serve
\ No newline at end of file
diff --git a/angular.json b/angular.json
new file mode 100644
index 00000000..0928dba5
--- /dev/null
+++ b/angular.json
@@ -0,0 +1,74 @@
+{
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+ "version": 1,
+ "cli": {
+ "packageManager": "npm"
+ },
+ "newProjectRoot": "projects",
+ "projects": {
+ "weather-app": {
+ "projectType": "application",
+ "schematics": {},
+ "root": "",
+ "sourceRoot": "src",
+ "prefix": "app",
+ "architect": {
+ "build": {
+ "builder": "@angular/build:application",
+ "options": {
+ "browser": "src/main.ts",
+ "tsConfig": "tsconfig.app.json",
+ "assets": [
+ {
+ "glob": "**/*",
+ "input": "src/assets",
+ "output": "/assets"
+ }
+ ],
+ "styles": [
+ "src/styles.css"
+ ]
+ },
+ "configurations": {
+ "production": {
+ "budgets": [
+ {
+ "type": "initial",
+ "maximumWarning": "500kB",
+ "maximumError": "1MB"
+ },
+ {
+ "type": "anyComponentStyle",
+ "maximumWarning": "4kB",
+ "maximumError": "8kB"
+ }
+ ],
+ "outputHashing": "all"
+ },
+ "development": {
+ "optimization": false,
+ "extractLicenses": false,
+ "sourceMap": true
+ }
+ },
+ "defaultConfiguration": "production"
+ },
+ "serve": {
+ "builder": "@angular/build:dev-server",
+ "configurations": {
+ "production": {
+ "buildTarget": "weather-app:build:production"
+ },
+ "development": {
+ "buildTarget": "weather-app:build:development"
+ }
+ },
+ "defaultConfiguration": "development"
+ },
+ "test": {
+ "builder": "@angular/build:unit-test"
+ }
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..1f262340
--- /dev/null
+++ b/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "weather-app",
+ "version": "0.0.0",
+ "scripts": {
+ "ng": "ng",
+ "start": "ng serve",
+ "build": "ng build",
+ "watch": "ng build --watch --configuration development",
+ "test": "ng test"
+ },
+ "private": true,
+ "packageManager": "npm@10.9.2",
+ "dependencies": {
+ "@angular/common": "^21.2.0",
+ "@angular/compiler": "^21.2.0",
+ "@angular/core": "^21.2.0",
+ "@angular/forms": "^21.2.0",
+ "@angular/platform-browser": "^21.2.0",
+ "@angular/router": "^21.2.0",
+ "@types/leaflet": "^1.9.21",
+ "chart.js": "^4.5.1",
+ "leaflet": "^1.9.4",
+ "papaparse": "^5.5.3",
+ "rxjs": "~7.8.0",
+ "tslib": "^2.3.0"
+ },
+ "devDependencies": {
+ "@angular/build": "^21.2.6",
+ "@angular/cli": "^21.2.6",
+ "@angular/compiler-cli": "^21.2.0",
+ "@types/papaparse": "^5.5.2",
+ "jsdom": "^28.0.0",
+ "prettier": "^3.8.1",
+ "typescript": "~5.9.2",
+ "vitest": "^4.0.8"
+ }
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 00000000..57614f9c
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/src/app/app.config.ts b/src/app/app.config.ts
new file mode 100644
index 00000000..b78282f3
--- /dev/null
+++ b/src/app/app.config.ts
@@ -0,0 +1,11 @@
+import { ApplicationConfig } from '@angular/core';
+import { provideRouter } from '@angular/router';
+import { provideHttpClient } from '@angular/common/http';
+import { routes } from './app.routes';
+
+export const appConfig: ApplicationConfig = {
+ providers: [
+ provideRouter(routes),
+ provideHttpClient()
+ ]
+};
\ No newline at end of file
diff --git a/src/app/app.css b/src/app/app.css
new file mode 100644
index 00000000..72051974
--- /dev/null
+++ b/src/app/app.css
@@ -0,0 +1,136 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+:host {
+ display: block;
+ font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
+ background: radial-gradient(circle at 20% 30%, #0a0f1e, #05070f);
+ min-height: 100vh;
+ padding: 24px;
+}
+
+.dashboard {
+ max-width: 1300px;
+ margin: 0 auto;
+ background: rgba(18, 25, 45, 0.55);
+ backdrop-filter: blur(16px);
+ border-radius: 48px;
+ padding: 28px 32px;
+ border: 1px solid rgba(90, 150, 220, 0.25);
+ box-shadow: 0 25px 45px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.05);
+}
+
+.title-section {
+ text-align: center;
+ margin-bottom: 32px;
+}
+
+.gradient-title {
+ font-size: 2.5rem;
+ font-weight: 700;
+ background: linear-gradient(135deg, #b9e6ff, #6c9eff, #a07eff);
+ -webkit-background-clip: text;
+ background-clip: text;
+ color: transparent;
+ display: inline-flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.title-icon {
+ font-size: 2rem;
+ filter: drop-shadow(0 0 6px rgba(108, 158, 255, 0.6));
+}
+
+.footer-note {
+ text-align: center;
+ font-size: 11px;
+ margin-top: 32px;
+ color: #6e7e9e;
+ letter-spacing: 0.5px;
+ border-top: 1px dashed rgba(90, 150, 220, 0.2);
+ padding-top: 20px;
+}
+
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(5, 8, 18, 0.92);
+ backdrop-filter: blur(12px);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 2000;
+ animation: overlayFade 0.25s ease;
+}
+
+.modal-card {
+ max-width: 780px;
+ width: 92%;
+ max-height: 88vh;
+ background: linear-gradient(145deg, #0e1628, #080c1a);
+ border-radius: 48px;
+ padding: 28px;
+ overflow-y: auto;
+ border: 1px solid rgba(80, 140, 220, 0.4);
+ box-shadow: 0 30px 60px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.05);
+ animation: modalRise 0.3s cubic-bezier(0.2, 0.9, 0.4, 1.1);
+ position: relative;
+}
+
+.close-modal {
+ position: absolute;
+ top: 20px;
+ right: 24px;
+ background: rgba(80, 120, 200, 0.2);
+ border: none;
+ color: #b0c8ff;
+ font-size: 28px;
+ cursor: pointer;
+ width: 40px;
+ height: 40px;
+ border-radius: 40px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s;
+ backdrop-filter: blur(4px);
+}
+
+.close-modal:hover {
+ background: rgba(80, 120, 200, 0.5);
+ color: white;
+ transform: rotate(90deg);
+}
+
+@keyframes overlayFade {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+@keyframes modalRise {
+ from {
+ opacity: 0;
+ transform: scale(0.96) translateY(20px);
+ }
+ to {
+ opacity: 1;
+ transform: scale(1) translateY(0);
+ }
+}
+
+@media (max-width: 720px) {
+ :host { padding: 12px; }
+ .dashboard { padding: 18px; }
+ .gradient-title { font-size: 1.8rem; }
+}
+
+@media (max-width: 520px) {
+ .modal-card { padding: 20px; }
+}
\ No newline at end of file
diff --git a/src/app/app.html b/src/app/app.html
new file mode 100644
index 00000000..d80791e5
--- /dev/null
+++ b/src/app/app.html
@@ -0,0 +1,26 @@
+
+
+
+ ⛅
+ Прогнозпогоды
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
new file mode 100644
index 00000000..6f4966f2
--- /dev/null
+++ b/src/app/app.module.ts
@@ -0,0 +1,26 @@
+import { NgModule } from '@angular/core';
+import { BrowserModule } from '@angular/platform-browser';
+import { FormsModule } from '@angular/forms';
+import { HttpClientModule } from '@angular/common/http';
+
+import { AppComponent } from './app';
+import { MapComponent } from './components/map/map.component';
+import { SearchComponent } from './components/search/search.component';
+import { WeatherComponent } from './components/weather/weather.component';
+
+@NgModule({
+ declarations: [
+ AppComponent,
+ MapComponent,
+ SearchComponent,
+ WeatherComponent
+ ],
+ imports: [
+ BrowserModule,
+ FormsModule,
+ HttpClientModule
+ ],
+ providers: [],
+ bootstrap: [AppComponent]
+})
+export class AppModule { }
\ No newline at end of file
diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts
new file mode 100644
index 00000000..9209eb01
--- /dev/null
+++ b/src/app/app.routes.ts
@@ -0,0 +1,7 @@
+import { Routes } from '@angular/router';
+import { AppComponent } from './app';
+
+export const routes: Routes = [
+ { path: '', component: AppComponent },
+ { path: '**', redirectTo: '' }
+];
\ No newline at end of file
diff --git a/src/app/app.ts b/src/app/app.ts
new file mode 100644
index 00000000..d98fc9e6
--- /dev/null
+++ b/src/app/app.ts
@@ -0,0 +1,39 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { CityService } from './services/city.service';
+import { CityItem } from './models/city.models';
+import { MapComponent } from './components/map/map.component';
+import { SearchComponent } from './components/search/search.component';
+import { WeatherComponent } from './components/weather/weather.component';
+
+@Component({
+ selector: 'app-root',
+ standalone: true,
+ imports: [CommonModule, MapComponent, SearchComponent, WeatherComponent],
+ templateUrl: './app.html',
+ styleUrls: ['./app.css']
+})
+export class AppComponent implements OnInit {
+ cityList: CityItem[] = [];
+ selectedCity: CityItem | null = null;
+
+ constructor(private cityService: CityService) {}
+
+ ngOnInit(): void {
+ this.cityService.fetchCityCatalog().subscribe({
+ next: (data) => {
+ this.cityList = data;
+ this.cityService.storeCatalog(data);
+ },
+ error: (err) => console.error('City load error:', err)
+ });
+ }
+
+ onCitySelected(city: CityItem): void {
+ this.selectedCity = city;
+ }
+
+ dismissModal(): void {
+ this.selectedCity = null;
+ }
+}
\ No newline at end of file
diff --git a/src/app/components/map/map.component.css b/src/app/components/map/map.component.css
new file mode 100644
index 00000000..3b7a2182
--- /dev/null
+++ b/src/app/components/map/map.component.css
@@ -0,0 +1,23 @@
+.map-stage {
+ width: 100%;
+ height: 500px;
+ border-radius: 32px;
+ margin-bottom: 24px;
+ overflow: hidden;
+ border: 1px solid rgba(70, 130, 200, 0.4);
+ box-shadow: 0 12px 28px rgba(0, 0, 0, 0.5);
+ transition: all 0.2s;
+ z-index: 1;
+}
+
+.map-stage:hover {
+ border-color: rgba(90, 160, 240, 0.7);
+ box-shadow: 0 16px 32px rgba(0, 0, 0, 0.55);
+}
+
+@media (max-width: 700px) {
+ .map-stage { height: 400px; }
+}
+@media (max-width: 480px) {
+ .map-stage { height: 340px; }
+}
\ No newline at end of file
diff --git a/src/app/components/map/map.component.html b/src/app/components/map/map.component.html
new file mode 100644
index 00000000..3e3d7492
--- /dev/null
+++ b/src/app/components/map/map.component.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/app/components/map/map.component.ts b/src/app/components/map/map.component.ts
new file mode 100644
index 00000000..c668e465
--- /dev/null
+++ b/src/app/components/map/map.component.ts
@@ -0,0 +1,78 @@
+import { Component, AfterViewInit, Input, OnChanges, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import * as L from 'leaflet';
+import { CityItem } from '../../models/city.models';
+
+@Component({
+ selector: 'app-map',
+ standalone: true,
+ imports: [CommonModule],
+ templateUrl: './map.component.html',
+ styleUrls: ['./map.component.css']
+})
+export class MapComponent implements AfterViewInit, OnChanges {
+ @Input() citiesCatalog: CityItem[] = [];
+ @Output() cityPicked = new EventEmitter();
+
+ private mapCore: L.Map | null = null;
+ private markersPool: L.CircleMarker[] = [];
+
+ constructor(private cdr: ChangeDetectorRef) {}
+
+ ngAfterViewInit(): void {
+ this.initMapSystem();
+ }
+
+ ngOnChanges(): void {
+ if (this.mapCore) this.refreshMarkers();
+ }
+
+ private initMapSystem(): void {
+ const container = document.getElementById('globeContainer');
+ if (!container || this.mapCore) return;
+
+ this.mapCore = L.map(container, {
+ center: [61.5, 95.0],
+ zoom: 3.8,
+ zoomControl: true
+ });
+
+ L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
+ attribution: '© CartoDB | OpenStreetMap',
+ subdomains: 'abcd'
+ }).addTo(this.mapCore);
+
+ setTimeout(() => {
+ this.mapCore?.invalidateSize();
+ this.refreshMarkers();
+ }, 120);
+ }
+
+ private refreshMarkers(): void {
+ if (!this.mapCore) return;
+ this.markersPool.forEach(m => m.remove());
+ this.markersPool = [];
+
+ this.citiesCatalog.forEach(city => {
+ const marker = L.circleMarker([city.lat, city.lon], {
+ radius: 5.5,
+ color: '#5f9eff',
+ fillColor: '#2a6eff',
+ fillOpacity: 0.85,
+ weight: 1.2
+ }).addTo(this.mapCore!);
+
+ marker.bindTooltip(city.name, { direction: 'top' });
+ marker.on('click', () => {
+ this.moveMapTo(city.lat, city.lon);
+ this.cityPicked.emit(city);
+ });
+ this.markersPool.push(marker);
+ });
+ this.cdr.detectChanges();
+ }
+
+ moveMapTo(lat: number, lon: number): void {
+ this.mapCore?.setView([lat, lon], 8.5, { animate: true });
+ }
+}
\ No newline at end of file
diff --git a/src/app/components/search/search.component.css b/src/app/components/search/search.component.css
new file mode 100644
index 00000000..2fa5f6ac
--- /dev/null
+++ b/src/app/components/search/search.component.css
@@ -0,0 +1,91 @@
+.search-panel {
+ position: relative;
+ margin-bottom: 28px;
+ z-index: 1000;
+ width: 100%;
+}
+
+.search-input {
+ width: 100%;
+ padding: 16px 22px;
+ font-size: 15px;
+ background: rgba(10, 18, 32, 0.7);
+ border: 1px solid rgba(90, 140, 220, 0.4);
+ border-radius: 60px;
+ color: #eef5ff;
+ backdrop-filter: blur(8px);
+ transition: all 0.2s;
+ box-sizing: border-box;
+}
+
+.search-input:focus {
+ outline: none;
+ border-color: #6c9eff;
+ background: rgba(10, 18, 32, 0.9);
+ box-shadow: 0 0 12px rgba(108, 158, 255, 0.3);
+}
+
+.search-input::placeholder {
+ color: #6e7e9e;
+}
+
+.results-drop {
+ position: absolute;
+ left: 0;
+ right: 0;
+ width: 100%;
+ background: #0f1629e6;
+ backdrop-filter: blur(16px);
+ border-radius: 28px;
+ margin-top: 12px;
+ border: 1px solid #2a406e;
+ max-height: 280px;
+ overflow-y: auto;
+ display: none;
+ z-index: 1001;
+ box-sizing: border-box;
+}
+
+.results-drop.open {
+ display: block;
+}
+
+.results-drop::-webkit-scrollbar {
+ width: 6px;
+}
+
+.results-drop::-webkit-scrollbar-track {
+ background: #0a1020;
+ border-radius: 10px;
+}
+
+.results-drop::-webkit-scrollbar-thumb {
+ background: #3a5a8c;
+ border-radius: 10px;
+}
+
+.results-drop::-webkit-scrollbar-thumb:hover {
+ background: #5a7ab0;
+}
+
+.result-row {
+ padding: 12px 20px;
+ display: flex;
+ justify-content: space-between;
+ cursor: pointer;
+ border-bottom: 1px solid #1f2a44;
+}
+
+.result-row:hover {
+ background: #1e2b4e;
+}
+
+.city-main {
+ font-weight: 500;
+ color: #cae3ff;
+}
+
+.city-pop {
+ font-size: 12px;
+ color: #7d96c0;
+}
\ No newline at end of file
diff --git a/src/app/components/search/search.component.html b/src/app/components/search/search.component.html
new file mode 100644
index 00000000..5ec2d67a
--- /dev/null
+++ b/src/app/components/search/search.component.html
@@ -0,0 +1,20 @@
+
+
+
+
+ {{ item.name }}
+ {{ formatPop(item.population) }}
+
+
+
\ No newline at end of file
diff --git a/src/app/components/search/search.component.ts b/src/app/components/search/search.component.ts
new file mode 100644
index 00000000..32a91f4a
--- /dev/null
+++ b/src/app/components/search/search.component.ts
@@ -0,0 +1,50 @@
+import { Component, Output, EventEmitter, HostListener } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { CityService } from '../../services/city.service';
+import { CityItem } from '../../models/city.models';
+
+@Component({
+ selector: 'app-search',
+ standalone: true,
+ imports: [CommonModule, FormsModule],
+ templateUrl: './search.component.html',
+ styleUrls: ['./search.component.css']
+})
+export class SearchComponent {
+ queryText = '';
+ suggestedCities: CityItem[] = [];
+ showDropdown = false;
+
+ @Output() cityPicked = new EventEmitter();
+
+ constructor(private cityService: CityService) {}
+
+ onSearchInput(): void {
+ if (this.queryText.length < 2) {
+ this.suggestedCities = [];
+ this.showDropdown = false;
+ return;
+ }
+ this.suggestedCities = this.cityService.searchLocal(this.queryText);
+ this.showDropdown = this.suggestedCities.length > 0;
+ }
+
+ selectCity(city: CityItem): void {
+ this.queryText = city.name;
+ this.showDropdown = false;
+ this.cityPicked.emit(city);
+ }
+
+ @HostListener('document:click', ['$event'])
+ closeOnOutside(e: Event): void {
+ const target = e.target as HTMLElement;
+ if (!target.closest('.search-panel')) {
+ this.showDropdown = false;
+ }
+ }
+
+ formatPop(pop: number): string {
+ return this.cityService.formatPop(pop);
+ }
+}
\ No newline at end of file
diff --git a/src/app/components/weather/weather.component.css b/src/app/components/weather/weather.component.css
new file mode 100644
index 00000000..c29e493b
--- /dev/null
+++ b/src/app/components/weather/weather.component.css
@@ -0,0 +1,161 @@
+.weather-pulse {
+ background: transparent;
+}
+
+.current-glass {
+ background: rgba(20, 32, 55, 0.6);
+ border-radius: 44px;
+ padding: 24px;
+ text-align: center;
+ margin-bottom: 24px;
+ border: 1px solid rgba(90, 150, 255, 0.3);
+}
+
+.city-head {
+ font-size: 32px;
+ font-weight: 700;
+ background: linear-gradient(120deg, #fff, #9bc0ff);
+ -webkit-background-clip: text;
+ background-clip: text;
+ color: transparent;
+}
+
+.pop-tag {
+ font-size: 14px;
+ color: #8ba4d9;
+ margin-top: 6px;
+}
+
+.temp-giant {
+ font-size: 68px;
+ font-weight: 800;
+ color: #ffffff;
+ text-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+ margin: 12px 0;
+}
+
+.weather-tag {
+ font-size: 18px;
+ background: #1f2c46;
+ display: inline-block;
+ padding: 6px 20px;
+ border-radius: 60px;
+ margin-bottom: 20px;
+}
+
+.metrics-row {
+ display: flex;
+ justify-content: center;
+ gap: 20px;
+ flex-wrap: wrap;
+}
+
+.metric-badge {
+ background: #0c1325;
+ padding: 8px 18px;
+ border-radius: 60px;
+ text-align: center;
+ min-width: 100px;
+}
+
+.metric-label {
+ font-size: 11px;
+ letter-spacing: 1px;
+ color: #8ba4d9;
+}
+
+.metric-number {
+ font-size: 20px;
+ font-weight: 600;
+}
+
+.toggle-group {
+ display: flex;
+ justify-content: center;
+ gap: 14px;
+ margin: 20px 0;
+}
+
+.toggle-btn {
+ background: #101a2e;
+ border: none;
+ padding: 8px 28px;
+ border-radius: 60px;
+ color: #b8ceff;
+ font-weight: 500;
+ cursor: pointer;
+ transition: 0.2s;
+}
+
+.toggle-btn.active {
+ background: #2f54b0;
+ color: white;
+ box-shadow: 0 0 10px #2f54b0;
+}
+
+.chart-frame {
+ background: #07102180;
+ border-radius: 32px;
+ padding: 16px;
+ margin: 20px 0;
+ border: 1px solid #2f4580;
+}
+
+.week-list {
+ display: flex;
+ overflow-x: auto;
+ gap: 14px;
+ padding: 8px 0;
+}
+
+.day-card {
+ background: #0f182eb3;
+ border-radius: 32px;
+ padding: 14px 18px;
+ min-width: 100px;
+ text-align: center;
+ transition: 0.2s;
+}
+
+.day-card:hover {
+ background: #1a2a4e;
+ transform: translateY(-3px);
+}
+
+.day-icon {
+ font-size: 36px;
+ margin: 8px 0;
+}
+
+.day-temp-high {
+ font-size: 20px;
+ font-weight: 700;
+}
+
+.day-temp-low {
+ font-size: 13px;
+ opacity: 0.7;
+}
+
+.precip-value {
+ font-size: 11px;
+ margin-top: 8px;
+}
+
+.loader-ring {
+ text-align: center;
+ padding: 40px;
+ font-size: 18px;
+ color: #9bbdff;
+}
+
+.error-message {
+ text-align: center;
+ padding: 40px;
+ color: #ffac9e;
+}
+
+.empty-hint {
+ text-align: center;
+ padding: 30px;
+}
\ No newline at end of file
diff --git a/src/app/components/weather/weather.component.html b/src/app/components/weather/weather.component.html
new file mode 100644
index 00000000..8c9bd73a
--- /dev/null
+++ b/src/app/components/weather/weather.component.html
@@ -0,0 +1,60 @@
+
+
+
Загрузка атмосферных данных...
+
+
+
+
Не удалось получить прогноз
+
+
+
+
+
{{ cityData.name }}
+
🏙️ {{ formatPop(cityData.population) }}
+
+
{{ formatTemp(weatherBundle.current.temperature_2m) }}°
+
+ {{ getWeatherPhrase(weatherBundle.current.weathercode) }}
+ {{ getWeatherSymbol(weatherBundle.current.weathercode) }}
+
+
+
+
+
Осадки
+
{{ weatherBundle.current.precipitation?.toFixed(1) || 0 }} мм
+
+
+
Ветер
+
{{ Math.round(weatherBundle.current.wind_speed_10m) }} км/ч
+
+
+
Влажность
+
{{ weatherBundle.current.relative_humidity_2m || '—' }} %
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ getWeatherSymbol(weatherBundle.daily.weathercode[idx]) }}
+
{{ getDayLabel(day, idx === 0) }}
+
{{ formatTemp(weatherBundle.daily.temperature_2m_max[idx]) }}°
+
{{ formatTemp(weatherBundle.daily.temperature_2m_min[idx]) }}°
+
💧 {{ weatherBundle.daily.precipitation_sum[idx]?.toFixed(1) || 0 }} мм
+
+
+
+
+
+
+ Выберите город на карте или через поиск
+
\ No newline at end of file
diff --git a/src/app/components/weather/weather.component.ts b/src/app/components/weather/weather.component.ts
new file mode 100644
index 00000000..7fc27fe8
--- /dev/null
+++ b/src/app/components/weather/weather.component.ts
@@ -0,0 +1,117 @@
+import { Component, Input, OnChanges, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { CityItem, WeatherDataSet } from '../../models/city.models';
+import { WeatherService } from '../../services/weather.service';
+import { CityService } from '../../services/city.service';
+import Chart from 'chart.js/auto';
+
+@Component({
+ selector: 'app-weather',
+ standalone: true,
+ imports: [CommonModule],
+ templateUrl: './weather.component.html',
+ styleUrls: ['./weather.component.css']
+})
+export class WeatherComponent implements OnChanges {
+ @Input() cityData: CityItem | null = null;
+ @ViewChild('weatherCanvas') canvasRef!: ElementRef;
+
+ weatherBundle: WeatherDataSet | null = null;
+ isBusy = false;
+ hasErrorFlag = false;
+ activeMetric: 'temp' | 'rain' = 'temp';
+
+ private chartInstance: Chart | null = null;
+ readonly Math = Math;
+
+ constructor(
+ private weatherApi: WeatherService,
+ private cityUtil: CityService,
+ private cdr: ChangeDetectorRef
+ ) {}
+
+ ngOnChanges(): void {
+ if (this.cityData) this.loadWeatherData();
+ }
+
+ private loadWeatherData(): void {
+ if (!this.cityData) return;
+ this.isBusy = true;
+ this.hasErrorFlag = false;
+ this.weatherBundle = null;
+ this.cdr.detectChanges();
+
+ this.weatherApi.fetchWeather(this.cityData.lat, this.cityData.lon).subscribe({
+ next: (data) => {
+ this.weatherBundle = data;
+ this.isBusy = false;
+ this.cdr.detectChanges();
+ setTimeout(() => this.renderChart(), 80);
+ },
+ error: () => {
+ this.isBusy = false;
+ this.hasErrorFlag = true;
+ this.cdr.detectChanges();
+ }
+ });
+ }
+
+ setMetric(metric: 'temp' | 'rain'): void {
+ this.activeMetric = metric;
+ this.renderChart();
+ }
+
+ private renderChart(): void {
+ if (!this.weatherBundle || !this.canvasRef) return;
+ if (this.chartInstance) {
+ this.chartInstance.destroy();
+ this.chartInstance = null;
+ }
+ const ctx = this.canvasRef.nativeElement.getContext('2d');
+ if (!ctx) return;
+
+ const daily = this.weatherBundle.daily;
+ const isTempMode = this.activeMetric === 'temp';
+ const dataSet = isTempMode ? daily.temperature_2m_max : daily.precipitation_sum;
+ const labelText = isTempMode ? 'Температура (Celsius)' : 'Сумма осадков (mm)';
+ const lineColor = isTempMode ? '#7fb0ff' : '#60d0a0';
+ const fillColor = isTempMode ? 'rgba(127, 176, 255, 0.1)' : 'rgba(96, 208, 160, 0.1)';
+
+ this.chartInstance = new Chart(ctx, {
+ type: 'line',
+ data: {
+ labels: daily.time.map((t, idx) => this.getDayLabel(t, idx === 0)),
+ datasets: [{
+ label: labelText,
+ data: dataSet,
+ borderColor: lineColor,
+ backgroundColor: fillColor,
+ borderWidth: 2.5,
+ pointRadius: 4,
+ pointBackgroundColor: lineColor,
+ pointBorderColor: '#0a1020',
+ tension: 0.25,
+ fill: true
+ }]
+ },
+ options: {
+ responsive: true,
+ maintainAspectRatio: true,
+ plugins: {
+ legend: { labels: { color: '#bfd6ff' } },
+ tooltip: { backgroundColor: '#0e162e', titleColor: '#cae0ff', bodyColor: '#9db9f0' }
+ },
+ scales: {
+ y: { ticks: { color: '#cae0ff' }, grid: { color: '#2a3a6040' } },
+ x: { ticks: { color: '#cae0ff' }, grid: { display: false } }
+ }
+ }
+ });
+ }
+
+ getWeatherSymbol(code: number): string { return this.weatherApi.getWeatherSymbol(code); }
+ getWeatherPhrase(code: number): string { return this.weatherApi.getWeatherPhrase(code); }
+ getDayLabel(date: string, isToday: boolean): string { return this.weatherApi.formatDayLabel(date, isToday); }
+ formatTemp(t: number): string { return Math.round(t).toString(); }
+ formatPop(p: number): string { return this.cityUtil.formatPop(p); }
+}
\ No newline at end of file
diff --git a/src/app/models/city.models.ts b/src/app/models/city.models.ts
new file mode 100644
index 00000000..519774fe
--- /dev/null
+++ b/src/app/models/city.models.ts
@@ -0,0 +1,27 @@
+export interface CityItem {
+ name: string;
+ lat: number;
+ lon: number;
+ population: number;
+}
+
+export interface CurrentWeather {
+ temperature_2m: number;
+ precipitation: number;
+ wind_speed_10m: number;
+ relative_humidity_2m: number;
+ weathercode: number;
+}
+
+export interface DailyForecastSet {
+ time: string[];
+ weathercode: number[];
+ temperature_2m_max: number[];
+ temperature_2m_min: number[];
+ precipitation_sum: number[];
+}
+
+export interface WeatherDataSet {
+ current: CurrentWeather;
+ daily: DailyForecastSet;
+}
\ No newline at end of file
diff --git a/src/app/services/city.service.ts b/src/app/services/city.service.ts
new file mode 100644
index 00000000..22ba0da1
--- /dev/null
+++ b/src/app/services/city.service.ts
@@ -0,0 +1,71 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { Observable, map } from 'rxjs';
+import * as Papa from 'papaparse';
+import { CityItem } from '../models/city.models';
+
+@Injectable({ providedIn: 'root' })
+export class CityService {
+ private catalog: CityItem[] = [];
+
+ constructor(private http: HttpClient) {}
+
+ fetchCityCatalog(): Observable {
+ return this.http.get('/assets/top1000_cities.csv', { responseType: 'text' })
+ .pipe(
+ map(csv => {
+ const parsed = Papa.parse(csv, {
+ header: true,
+ skipEmptyLines: true
+ });
+
+ return parsed.data.map((row: any) => ({
+ name: row.name,
+ lat: parseFloat(row.lat),
+ lon: parseFloat(row.lon),
+ population: parseInt(row.population, 10)
+ }));
+ })
+ );
+ }
+
+ storeCatalog(data: CityItem[]): void {
+ this.catalog = data;
+ }
+
+ getCatalog(): CityItem[] {
+ return this.catalog;
+ }
+
+ searchLocal(query: string): CityItem[] {
+ if (!query || query.length < 2) return [];
+
+ const q = query.toLowerCase();
+
+ return this.catalog
+ .map(c => ({
+ ...c,
+ _rank: this.getMatchScore(c.name.toLowerCase(), q)
+ }))
+ .filter(c => c._rank > 0)
+ .sort((a, b) => b._rank - a._rank)
+ .slice(0, 8);
+ }
+
+ private getMatchScore(name: string, query: string): number {
+ if (name === query) return 4;
+ if (name.startsWith(query)) return 3;
+ if (name.includes(query)) return 2;
+ return 0;
+ }
+
+ formatPop(pop: number): string {
+ if (pop >= 1_000_000) {
+ return (pop / 1_000_000).toFixed(1).replace(/\.0$/, '') + 'M';
+ }
+ if (pop >= 1_000) {
+ return Math.round(pop / 1_000) + 'K';
+ }
+ return String(pop);
+ }
+}
\ No newline at end of file
diff --git a/src/app/services/weather.service.ts b/src/app/services/weather.service.ts
new file mode 100644
index 00000000..9d82c845
--- /dev/null
+++ b/src/app/services/weather.service.ts
@@ -0,0 +1,52 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { Observable, map } from 'rxjs';
+import { WeatherDataSet } from '../models/city.models';
+
+@Injectable({ providedIn: 'root' })
+export class WeatherService {
+ private apiBase = 'https://api.open-meteo.com/v1/forecast';
+
+ constructor(private http: HttpClient) {}
+
+ fetchWeather(lat: number, lon: number): Observable {
+ const url = `${this.apiBase}?latitude=${lat}&longitude=${lon}¤t=temperature_2m,precipitation,wind_speed_10m,relative_humidity_2m,weathercode&daily=weathercode,temperature_2m_max,temperature_2m_min,precipitation_sum&timezone=auto&forecast_days=7`;
+ return this.http.get(url);
+ }
+
+ getWeatherSymbol(code: number): string {
+ const mapping: Record = {
+ 0: '✨', 1: '🌤️', 2: '⛅', 3: '☁️',
+ 45: '🌫️', 48: '❄️🌫️',
+ 51: '💧', 53: '💧💧', 55: '💧💧💧',
+ 56: '🧊', 57: '🧊❄️',
+ 61: '🌦️', 63: '🌧️', 65: '🌧️🌧️',
+ 66: '🌧️❄️', 67: '⛈️❄️',
+ 71: '❄️', 73: '❄️❄️', 75: '❄️❄️❄️',
+ 77: '🌨️',
+ 80: '🌦️', 81: '🌧️', 82: '⛈️',
+ 85: '🌨️', 86: '🌨️🌨️',
+ 95: '⚡🌩️', 96: '⚡🧊', 99: '⚡⚡🧊'
+ };
+ return mapping[code] || '🌡️';
+ }
+
+ getWeatherPhrase(code: number): string {
+ const phrases: Record = {
+ 0: 'Без осадков', 1: 'Солнечно', 2: 'Облачно', 3: 'Пасмурно',
+ 45: 'Туманно', 48: 'Туман с изморозью',
+ 51: 'Морось', 53: 'Умеренная морось', 55: 'Сильная морось',
+ 61: 'Дождь', 63: 'Ливень', 65: 'Сильный ливень',
+ 71: 'Снег', 73: 'Снегопад', 75: 'Метель',
+ 80: 'Кратковременный дождь', 95: 'Грозовые разряды'
+ };
+ return phrases[code] || 'Переменная облачность';
+ }
+
+ formatDayLabel(dateString: string, isNow: boolean = false): string {
+ if (isNow) return 'Сегодня';
+ const week = ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'];
+ const dt = new Date(dateString);
+ return week[dt.getDay()];
+ }
+}
\ No newline at end of file
diff --git a/src/assets/main.py b/src/assets/main.py
new file mode 100644
index 00000000..4b854f56
--- /dev/null
+++ b/src/assets/main.py
@@ -0,0 +1,42 @@
+import csv
+
+INPUT_FILE = "data_allsettlements_anon_156_v20251217.csv"
+OUTPUT_FILE = "top1000_cities.csv"
+
+cities = []
+
+with open(INPUT_FILE, encoding="utf-8") as f:
+ reader = csv.DictReader(f, delimiter=';')
+
+ for row in reader:
+ if row["object_level"] not in ["Населенный пункт", "Город федерального значения"]:
+ continue
+
+ try:
+ name = row["settlement"]
+ lat = float(row["latitude_dadata"])
+ lon = float(row["longitude_dadata"])
+ population = int(row["population"])
+ except (ValueError, TypeError):
+ continue
+
+ if not name:
+ continue
+
+ cities.append({
+ "name": name,
+ "lat": lat,
+ "lon": lon,
+ "population": population
+ })
+
+cities.sort(key=lambda x: x["population"], reverse=True)
+
+top_cities = cities[:1000]
+
+with open(OUTPUT_FILE, "w", newline='', encoding="utf-8") as f:
+ writer = csv.DictWriter(f, fieldnames=["name", "lat", "lon", "population"])
+ writer.writeheader()
+ writer.writerows(top_cities)
+
+print("top1000_cities.csv")
\ No newline at end of file
diff --git a/src/assets/top1000_cities.csv b/src/assets/top1000_cities.csv
new file mode 100644
index 00000000..c643100e
--- /dev/null
+++ b/src/assets/top1000_cities.csv
@@ -0,0 +1,1001 @@
+name,lat,lon,population
+г. Новосибирск,55.030187,82.920426,1633595
+г. Екатеринбург,56.8387061,60.6054943,1544376
+г. Казань,55.7944326,49.1115164,1308660
+г. Нижний Новгород,56.326794,44.006495,1226076
+г. Челябинск,55.1602292,61.4007614,1189525
+г. Красноярск,56.0095312,92.8525234,1187771
+г. Самара,53.1951774,50.1069625,1173299
+г. Уфа,54.734856,55.9577802,1144809
+г. Ростов-на-Дону,47.2180329,39.6902714,1142162
+г. Омск,54.9849581,73.3675684,1125695
+г. Краснодар,45.035453,38.975301,1099344
+г. Воронеж,51.6593943,39.196922,1057681
+г. Пермь,58.0102668,56.2342725,1034002
+г. Волгоград,48.7071653,44.5170212,1028036
+г. Саратов,51.533557,46.034257,901361
+г. Тюмень,57.1531178,65.5343535,847488
+г. Тольятти,53.5205003,49.3895011,684709
+г. Барнаул,53.3479774,83.7798977,630877
+г. Ижевск,56.8528384,53.211509,623472
+г. Махачкала,42.9849039,47.5045541,623254
+г. Хабаровск,48.4648124,135.0598539,617441
+г. Ульяновск,54.3079032,48.3748473,617352
+г. Иркутск,52.2863483,104.2806793,617264
+г. Владивосток,43.1163208,131.8824988,603519
+г. Ярославль,57.6216293,39.8978921,577279
+г. Кемерово,55.3910176,86.0469193,557119
+г. Томск,56.4846736,84.9482929,556478
+г. Набережные Челны,55.6948843,52.3279115,548434
+г. Ставрополь,45.0444563,41.9691349,547443
+г. Оренбург,51.7875335,55.1017803,543654
+г. Новокузнецк,53.7943459,87.2142908,537480
+г. Рязань,54.6255345,39.7359162,528599
+г. Балашиха,55.796991,37.938104,520962
+г. Пенза,53.1753947,45.0347408,501109
+г. Чебоксары,56.125485,47.377328,497807
+г. Липецк,52.6101389,39.5947287,496403
+г. Калининград,54.7074298,20.5073482,490449
+г. Астрахань,46.3656435,48.0559229,475629
+г. Тула,54.1918898,37.6153644,473622
+г. Киров,58.6034972,49.6680445,468212
+г. Сочи,43.5855182,39.7229922,466078
+г. Курск,51.7303825,36.1925546,440052
+г. Улан-Удэ,51.8334492,107.584068,437565
+г. Тверь,56.8586556,35.9118279,416219
+г. Магнитогорск,53.4072599,58.9791822,410594
+г. Сургут,61.2541492,73.396236,396443
+г. Брянск,53.2420053,34.3653002,379152
+г. Иваново,56.9994066,40.9729071,361644
+г. Якутск,62.0280605,129.7324858,355443
+г. Владимир,56.1280444,40.4082983,349951
+г. Симферополь,44.9482789,34.1001275,340540
+г. Белгород,50.5975582,36.5858422,339978
+г. Нижний Тагил,57.9102289,59.9814188,338966
+г. Калуга,54.506025,36.2516145,337058
+г. Чита,52.0338828,113.499487,334427
+г. Грозный,43.3178923,45.6981421,328533
+г. Волжский,48.7979775,44.7462572,321479
+город Смоленск,54.782635,32.045251,316570
+г. Подольск,55.4389616,37.5703052,314934
+г. Саранск,54.1808234,45.1863143,314871
+г. Вологда,59.220501,39.891523,313944
+г. Курган,55.4443683,65.3162142,310911
+г. Череповец,59.1268743,37.9090556,305185
+г. Орёл,52.9671928,36.0695725,303169
+г. Архангельск,64.53939,40.5170011,301199
+г. Владикавказ,43.020552,44.681905,295830
+г. Нижневартовск,60.9397399,76.5695505,283256
+г. Йошкар-Ола,56.6343266,47.8999167,281248
+г. Стерлитамак,53.6302062,55.9317313,277410
+г. Мурманск,68.970663,33.074918,270384
+г. Кострома,57.768,40.927,267481
+г. Новороссийск,44.7234226,37.7686906,262293
+г. Тамбов,52.7211576,41.4522156,261803
+г. Химки,55.8888467,37.430372,257128
+г. Мытищи,55.9104655,37.7363923,255429
+г. Нальчик,43.4846449,43.6070943,247054
+г. Таганрог,47.2096599,38.9352459,245120
+г. Нижнекамск,55.6312304,51.8144719,241479
+г. Благовещенск,50.290659,127.527198,241437
+г. Комсомольск-на-Амуре,50.5525092,136.9895507,238505
+г. Петрозаводск,61.7889739,34.3596538,234897
+г. Королёв,55.9161885,37.854422,228095
+г. Шахты,47.7085649,40.2158665,226452
+г. Энгельс,51.4855068,46.1267008,225428
+г. Великий Новгород,58.5214164,31.2754186,224286
+г. Люберцы,55.676499,37.898125,224195
+г. Братск,56.1514087,101.6341027,224071
+г. Старый Оскол,51.297974,37.833231,221676
+город Ангарск,52.544898,103.8884509,221296
+г. Сыктывкар,61.6687212,50.8356788,220580
+г. Дзержинск,56.2375332,43.4598979,218630
+г. Псков,57.819825,28.3950685,193082
+г. Орск,51.2292952,58.4752502,189195
+г. Красногорск,55.8318647,37.3294489,187634
+г. Армавир,45.0011356,41.1324283,187177
+г. Абакан,53.7223055,91.4436926,184769
+г. Балаково,52.0222817,47.7827796,184466
+г. Бийск,52.5392784,85.213843,183852
+г. Южно-Сахалинск,46.9667029,142.7212958,181587
+г. Одинцово,55.6790296,37.2635177,180530
+г. Уссурийск,43.8048438,131.9367538,180393
+г. Прокопьевск,53.8604228,86.7183302,177819
+г. Рыбинск,58.0484021,38.858475,177295
+г. Норильск,69.3489906,88.2009379,174453
+г. Волгодонск,47.5165757,42.1984573,168048
+г. Сызрань,53.1557162,48.4744217,165725
+г. Петропавловск-Камчатский,53.0370074,158.65595,164900
+г. Каменск-Уральский,56.4148539,61.9188448,164192
+г. Новочеркасск,47.4118469,40.1040646,163674
+г. Альметьевск,54.9014385,52.297123,163512
+г. Златоуст,55.1714213,59.6726478,161774
+г. Северодвинск,64.5625626,39.8182183,157213
+г. Хасавюрт,43.2504341,46.5850867,155144
+г. Керчь,45.3561252,36.4673129,154621
+г. Домодедово,55.436403,37.7666001,152404
+г. Салават,53.362823,55.9154367,148575
+г. Миасс,55.0552642,60.0791765,147995
+г. Копейск,55.1167381,61.6179305,147806
+г. Пятигорск,44.041234,43.0660504,146473
+г. Электросталь,55.784633,38.444699,146403
+г. Майкоп,44.609792,40.1005698,143385
+г. Находка,42.8111483,132.8844502,139931
+г. Березники,59.4079119,56.8039179,138069
+г. Коломна,55.1026926,38.7530213,134850
+г. Щёлково,55.9233436,37.9783923,134211
+г. Серпухов,54.9226176,37.4033624,133793
+г. Ковров,56.3554229,41.3171096,132417
+г. Нефтекамск,56.0883752,54.2482411,131942
+г. Кисловодск,43.9052745,42.7167964,127521
+г. Батайск,47.1382139,39.750662,126988
+г. Рубцовск,51.5012963,81.2078042,126834
+г. Обнинск,55.0944881,36.6121565,125376
+г. Кызыл,51.7190588,94.4376984,125241
+г. Дербент,42.0590354,48.2908599,124953
+г. Нефтеюганск,61.0881688,72.6163369,124732
+г. Назрань,43.2256598,44.7646901,122350
+г. Каспийск,42.8916263,47.6366936,121140
+г. Долгопрудный,55.9385975,37.5100337,120907
+г. Новочебоксарск,56.1095538,47.4791596,120375
+г. Новомосковск,54.010957,38.2915047,119697
+г. Ессентуки,44.0444693,42.8589782,119658
+г. Невинномысск,44.6226742,41.9476424,117562
+г. Октябрьский,54.4814637,53.4654836,115557
+г. Раменское,55.5495378,38.2728835,114537
+г. Первоуральск,56.9080096,59.9429936,114450
+г. Михайловск,45.1297467,42.0287477,114133
+г. Реутов,55.7582708,37.8618288,113871
+г. Черкесск,44.228353,42.048278,113226
+г. Жуковский,55.5999747,38.1224066,111222
+г. Димитровград,54.2168413,49.6262388,110968
+г. Пушкино,56.0104754,37.847161,110868
+г. Артем,43.3501868,132.1595835,109556
+г. Камышин,50.0652955,45.384535,107927
+г. Евпатория,45.190629,33.367634,107877
+г. Муром,55.563153,42.0230298,107497
+г. Ханты-Мансийск,61.0025598,69.0183366,107473
+г. Новый Уренгой,66.0839904,76.6810104,107251
+г. Северск,56.6032343,84.881027,106648
+г. Орехово-Зуево,55.8164825,38.9368137,105745
+г. Арзамас,55.3946343,43.8408135,104908
+г. Ногинск,55.8760353,38.4231801,103891
+г. Новошахтинск,47.7576743,39.9364541,103480
+г. Бердск,54.7582184,83.1071527,102850
+г. Элиста,46.30821,44.2702746,102583
+г. Сергиев Посад,56.3063854,38.1502956,101756
+г. Видное,55.5517857,37.7062236,101490
+г. Ачинск,56.2537315,90.4793969,100621
+г. Тобольск,58.2017257,68.2538473,100352
+г. Ноябрьск,63.1920786,75.4454918,100188
+г. Елец,52.6152577,38.528899,99875
+г. Зеленодольск,55.8465861,48.500966,99137
+г. Новокуйбышевск,53.0994719,49.9477255,98306
+г. Воткинск,57.0518828,53.9874914,97471
+г. Железногорск,52.3379241,35.3517678,97038
+г. Междуреченск,53.6865918,88.0702782,96174
+г. Воскресенск,55.3070155,38.7028385,95495
+г. Гатчина,59.5651362,30.1281234,94377
+г. Серов,59.6047459,60.5752389,94211
+г. Саров,54.922813,43.3447953,93357
+г. Ленинск-Кузнецкий,54.6674801,86.1796673,92244
+г. Сарапул,56.4616582,53.8036826,91115
+г. Магадан,59.5681947,150.8086939,90757
+г. Мичуринск,52.8913406,40.5103713,90451
+г. Соликамск,59.6483298,56.7710196,89473
+г. Мурино,60.0448984,30.4573012,89083
+г. Чехов,55.1506335,37.4532854,89025
+г. Клин,56.3424345,36.7240443,88511
+г. Бузулук,52.7881715,52.2623964,88341
+г. Глазов,58.1359039,52.6634921,87762
+г. Канск,56.2050971,95.7051994,86816
+г. Великие Луки,56.343703,30.515671,86711
+г. Каменск-Шахтинский,48.3204742,40.2689608,86365
+г. Губкин,51.2836227,37.5347995,85225
+г. Киселевск,54.0383268,86.6605444,83431
+г. Ейск,46.7114714,38.2764767,82943
+г. Ивантеевка,55.9741839,37.9208717,82827
+г. Лобня,56.0328978,37.4614808,82764
+г. Железногорск,56.2528775,93.532226,82723
+г. Азов,47.1122112,39.4233596,81924
+г. Анапа,44.8948984,37.3162896,81863
+г. Бугульма,54.5364489,52.7894083,81677
+г. Московский,55.597255,37.359448,81309
+г. Геленджик,44.5631183,38.0791049,80204
+г. Ухта,63.5563841,53.7013827,79899
+г. Юрга,55.7202352,84.8885927,79693
+г. Усть-Илимск,58.0189147,102.6855314,79570
+г. Всеволожск,60.0190286,30.6456654,79038
+г. Новоуральск,57.2472236,60.0955422,78479
+г. Кузнецк,53.1130584,46.6052642,78390
+г. Бор,56.3565886,44.0645547,78372
+г. Кинешма,57.442535,42.1689258,77694
+г. Озерск,55.7632143,60.7076521,76896
+г. Новотроицк,51.1963401,58.3017089,75960
+г. Кропоткин,45.4332835,40.5728945,75858
+г. Чайковский,56.7780683,54.1477844,75837
+г. Черногорск,53.8258374,91.3259463,75745
+г. Усолье-Сибирское,52.7566823,103.6387415,74762
+г. Ялта,44.4952969,34.1663516,74652
+г. Дубна,56.7416155,37.1756531,74183
+г. Балашов,51.5388261,43.1839668,74057
+посёлок Коммунарка,55.570388,37.475469,73735
+г. Елабуга,55.7566788,52.0545017,73630
+г. Новоалтайск,53.4120027,83.9309813,73049
+г. Выборг,60.7129589,28.7328799,72530
+г. Егорьевск,55.3831202,39.0358883,71686
+г. Верхняя Пышма,56.9758868,60.5649684,71335
+г. Наро-Фоминск,55.386185,36.734484,71121
+г. Минеральные Воды,44.2087295,43.1383447,70485
+г. Троицк,54.0843322,61.5587093,70301
+г. Чапаевск,52.929023,49.8673246,70228
+г. Минусинск,53.7104585,91.6871667,70089
+г. Биробиджан,48.7946217,132.9217228,70064
+г. Шадринск,56.0871041,63.6297172,68609
+г. Белово,54.4221568,86.3037406,68542
+г. Туймазы,54.5999395,53.6950191,68349
+г. Сертолово,60.1446697,30.209571,68241
+г. Буйнакск,42.8213541,47.116407,68121
+г. Ишим,56.1104734,69.4797226,67614
+г. Кирово-Чепецк,58.5560037,50.0317344,66651
+г. Анжеро-Судженск,56.0787454,86.0200409,66583
+г. Феодосия,45.0320187,35.382384,66293
+г. Дмитров,56.3476745,37.5266195,65574
+г. Сосновый Бор,59.904224,29.092209,65367
+г. Горно-Алтайск,51.9581885,85.9603499,65342
+г. Лыткарино,55.5778267,37.9034779,65212
+г. Павловский Посад,55.780723,38.6596371,65098
+г. Троицк,55.4844981,37.3067485,65043
+г. Белорецк,53.967626,58.4100433,64525
+г. Ступино,54.886274,38.078228,64412
+г. Гудермес,43.3518339,46.1034832,64376
+г. Ишимбай,53.4545688,56.0440089,64041
+г. Донской,53.9678617,38.3372254,63837
+г. Котельники,55.6599375,37.8631583,63728
+г. Кстово,56.1432079,44.1663972,63646
+г. Урус-Мартан,43.120175,45.539276,63449
+г. Георгиевск,44.14794,43.474254,63221
+г. Клинцы,52.752875,32.2337792,63059
+г. Нягань,62.1454886,65.3945936,63034
+г. Славянск-на-Кубани,45.2604694,38.1259659,62985
+г. Кунгур,57.4284056,56.9438416,62673
+город Сунжа,43.3203629,45.0477848,62078
+г. Туапсе,44.1104007,39.0825379,61571
+г. Когалым,62.2639797,74.482946,61441
+г. Белогорск,50.921219,128.4737866,61440
+г. Лениногорск,54.5966119,52.4433347,60993
+город Россошь,50.1701985,39.6226453,60879
+г. Алексин,54.5084968,37.0478364,60842
+г. Кудрово,59.9076688,30.5119611,60791
+г. Борисоглебск,51.3654207,42.1009542,60687
+г. Фрязино,55.9589291,38.0409827,60580
+г. Гуково,48.0450292,39.9485638,60361
+г. Ревда,56.7987642,59.9071644,60200
+г. Прохладный,43.7590107,44.010051,59938
+г. Березовский,56.9136462,60.7852371,59698
+г. Белебей,54.1034535,54.1112181,59195
+г. Чистополь,55.3699331,50.6285823,58815
+г. Заречный,53.1961885,45.1691136,58510
+г. Будённовск,44.781467,44.164948,58103
+г. Кумертау,52.756471,55.7970469,57949
+г. Сальск,46.475234,41.541039,57937
+г. Дзержинский,55.6241057,37.8441593,57918
+г. Лабинск,44.6354147,40.7244209,57428
+г. Асбест,57.0052534,61.4581769,57317
+г. Искитим,54.626704,83.2949994,57147
+г. Павлово,55.965103,43.064848,57116
+г. Александров,56.3918756,38.7110582,57053
+г. Воркута,67.497434,64.0611813,56985
+г. Щербинка,55.50868,37.5633253,56531
+г. Сибай,52.7204622,58.6663921,56514
+г. Мелеуз,52.9589874,55.9282514,56505
+г. Котлас,61.2528975,46.6332216,56093
+г. Михайловка,50.0708708,43.2401092,56031
+г. Избербаш,42.5652081,47.8710684,55996
+г. Краснотурьинск,59.7638319,60.1935754,55875
+г. Белореченск,44.7652692,39.8781164,55870
+г. Ржев,56.2629154,34.3290948,55757
+г. Лесосибирск,58.2216981,92.503692,55730
+г. Тихорецк,45.8546923,40.1258776,55686
+г. Тихвин,59.644619,33.54193,55415
+г. Шуя,56.8507513,41.3516168,55225
+г. Полевской,56.4958618,60.2366252,55182
+г. Щекино,54.0021718,37.5177177,55109
+г. Шали,43.1487442,45.9010465,55054
+г. Вольск,52.0459603,47.3873,55035
+г. Крымск,44.9343723,37.9854857,54597
+пгт Яблоновский,44.981266,38.936362,54291
+г. Зеленогорск,56.1133542,94.5889359,54279
+г. Лиски,50.9945381,39.5183454,54147
+г. Черемхово,53.1233358,103.1574108,53958
+г. Лысьва,58.0996742,57.8087369,53855
+г. Нерюнгри,56.6599502,124.7201885,53409
+г. Волжск,55.8623164,48.3715777,53013
+г. Мегион,61.0318864,76.102504,52887
+г. Вязьма,55.2116645,34.2952096,51950
+г. Тимашевск,45.6158949,38.9351457,51858
+г. Гусь-Хрустальный,55.6199041,40.6578219,51552
+г. Краснокаменск,50.09868,118.034118,51137
+г. Кириши,59.449699,32.008705,51028
+пгт Нахабино рп,55.840381,37.175899,50916
+г. Снежинск,56.0852853,60.73251,50619
+г. Жигулевск,53.4012735,49.4944877,50466
+г. Кизляр,43.8484072,46.7232534,49999
+г. Кингисепп,59.3741261,28.611223,49716
+г. Апатиты,67.567731,33.4067789,49647
+г. Узловая,53.9731953,38.1764288,49427
+г. Краснокамск,58.0820673,55.7478889,48778
+г. Балахна,56.4950365,43.575846,48569
+г. Свободный,51.3612532,128.122028,48517
+г. Солнечногорск,56.185102,36.977631,48413
+г. Аксай,47.2675888,39.8755792,48372
+г. Лесной,58.6349153,59.7980136,48261
+г. Арсеньев,44.1621626,133.2696658,47937
+г. Салехард,66.5493706,66.6084227,47910
+г. Боровичи,58.3840076,33.9176708,47883
+г. Рассказово,52.6538108,41.8743764,47644
+г. Курганинск,44.8877061,40.5914627,47305
+г. Отрадный,53.380127,51.3440385,46984
+г. Донецк,48.3350869,39.9459603,46623
+г. Надым,65.528146,72.514417,45973
+г. Кашира,54.8532793,38.1904181,45922
+г. Вышний Волочек,57.5684471,34.5404365,45830
+г. Чусовой,58.2975271,57.8193629,45471
+г. Рославль,53.9449217,32.847942,45416
+г. Назарово,56.0115024,90.4169443,45333
+г. Выкса,55.3206313,42.1679983,45240
+г. Саяногорск,53.1007127,91.4122756,44872
+г. Чебаркуль,54.9818594,60.3774264,44693
+г. Канаш,55.5068806,47.4917914,44354
+г. Можга,56.4427514,52.2137584,44345
+г. Бирск,55.4156358,55.5583061,44295
+г. Березовский,55.6693866,86.2745058,44073
+г. Грязи,52.4872943,39.9331152,43908
+г. Краснознаменск,55.5978331,37.039529,43868
+г. Бугуруслан,53.6522761,52.4326104,43593
+г. Радужный,62.1342204,77.458477,43577
+г. Ливны,52.4286428,37.6040201,43549
+г. Североморск,69.07651,33.4178343,43327
+г. Карабулак,43.3055756,44.9095113,43037
+г. Рузаевка,54.0582232,44.949083,42989
+г. Лангепас,61.2537123,75.1806961,42701
+г. Сатка,55.0404006,59.0288229,42597
+г. Шелехов,52.2101358,104.0973332,41998
+г. Куйбышев,55.445949,78.311108,41946
+г. Малоярославец,55.0177696,36.4633694,41836
+г. Кореновск,45.4642106,39.4589751,41826
+г. Большой Камень,43.1111521,132.3479458,41825
+станица Каневская,46.0847521,38.9719273,41721
+г. Аргун,43.2917917,45.8722923,41622
+г. Темрюк,45.2610243,37.4455473,41608
+г. Ярцево,55.0565468,32.6902745,41452
+г. Урай,60.1297244,64.8038858,41315
+г. Заринск,53.7064163,84.93148,41272
+г. Торжок,57.041349,34.9602076,41116
+г. Верхняя Салда,58.0466272,60.5560133,41034
+г. Лянтор,61.6392893,72.1793962,40977
+г. Горячий Ключ,44.6344393,39.1355285,40903
+г. Кимры,56.8732554,37.3557008,40875
+г. Мариинск,56.2128227,87.7454299,40779
+г. Белая Калитва,48.176882,40.8032881,40448
+г. Сосновоборск,56.120075,93.3354461,40442
+г. Осинники,53.598681,87.3371253,40367
+г. Курчатов,51.6605387,35.6571025,40318
+г. Апшеронск,44.4583753,39.7301418,40289
+г. Пыть-Ях,60.7586475,72.8366942,40180
+г. Усть-Лабинск,45.2226625,39.6929278,40158
+г. Пугачев,52.0159472,48.797175,40127
+г. Мыски,53.7126111,87.8056844,40109
+г. Мончегорск,67.9386512,32.9359042,39962
+г. Заинск,55.2988956,52.0063163,39739
+г. Шебекино,50.4004378,36.8878943,39680
+г. Тутаев,57.8674415,39.536868,39643
+г. Баксан,43.6819288,43.5344884,39593
+г. Абинск,44.8679116,38.1617987,39511
+г. Кольчугино,56.3328004,39.391268,39410
+г. Стрежевой,60.7327472,77.6039789,39169
+г. Моршанск,53.4436449,41.8115193,39023
+г. Советск,55.0811102,21.8887115,38910
+г. Ялуторовск,56.6546647,66.3121926,38853
+г. Новозыбков,52.5371414,31.9357361,38680
+г. Изобильный,45.3684383,41.7085873,38614
+г. Амурск,50.2345703,136.8791531,38606
+г. Волхов,59.9004589,32.3520685,38511
+г. Тулун,54.5570223,100.5779905,38440
+г. Луга,58.735207,29.847945,38407
+г. Сафоново,55.1200105,33.233658,38403
+г. Кизилюрт,43.2038278,46.872864,38335
+г. Югорск,61.3124125,63.3364948,38238
+г. Шатура,55.5778265,39.5445373,38230
+г. Ртищево,52.2616938,43.7842747,37850
+г. Переславль-Залесский,56.7360013,38.8543687,37738
+г. Протвино,54.8705841,37.2182922,37735
+г. Южноуральск,54.4490432,61.2581713,37478
+г. Истра,55.9061876,36.8600649,37474
+г. Качканар,58.7050979,59.4839558,37307
+г. Красноуфимск,56.612429,57.7635494,37301
+г. Коркино,54.8903864,61.4032939,37224
+г. Джанкой,45.7092913,34.3883718,37014
+г. Ирбит,57.683808,63.0576929,37009
+пгт Маркова рп,52.211106,104.207909,36971
+г. Мценск,53.2789769,36.5749963,36960
+г. Усть-Кут,56.780878,105.745373,36918
+г. Моздок,43.7472597,44.657072,36784
+г. Заволжье,56.6404919,43.3870929,36763
+г. Кинель,53.2209314,50.6343567,36729
+г. Урюпинск,50.7904909,42.0289034,36669
+г. Реж,57.3716798,61.38338,36585
+г. Алексеевка,50.6299988,38.6881066,36578
+станица Динская,45.2362774,39.2405427,36576
+г. Ефремов,53.137603,38.117673,36545
+г. Малгобек,43.5097018,44.5901112,36480
+г. Елизово,53.1829398,158.3884312,36240
+г. Вязники,56.2977573,42.268676,36203
+г. Алапаевск,57.8476947,61.6695786,36189
+г. Учалы,54.3066963,59.4127255,36175
+г. Черняховск,54.6245018,21.7969164,36128
+г. Кыштым,55.706159,60.5562529,36045
+пгт Горячеводский рп,44.0236208,43.0973777,36032
+г. Беслан,43.1936637,44.533792,35929
+Балаклава,44.501414,33.600037,35919
+г. Людиново,53.8701272,34.4385772,35874
+г. Звенигород,55.7295881,36.8553623,35842
+г. Спасск-Дальний,44.5900901,132.8158275,35732
+г. Светлоград,45.3286594,42.856594,35703
+г. Красный Сулин,47.883196,40.0781926,35697
+г. Фролово,49.7648209,43.6649431,35661
+г. Ахтубинск,48.2753708,46.1905298,35635
+г. Саянск,54.1108195,102.1802309,35561
+станица Ленинградская,46.3449638,39.3907816,35561
+г. Апрелевка,55.527617,37.0650837,35514
+г. Благовещенск,55.0498049,55.9553149,35481
+г. Лесозаводск,45.4780131,133.4185314,35433
+г. Печора,65.1486942,57.2239645,35254
+г. Богородск,56.1020008,43.5135913,35068
+г. Миллерово,48.9259954,40.3982659,34841
+г. Азнакаево,54.8597519,53.0744925,34750
+г. Сокол,59.4757853,40.1114848,34742
+деревня Ватутинки,55.4942411,37.3288668,34697
+г. Сланцы,59.1177053,28.0882334,34628
+г. Коряжма,61.2886248,47.1002365,34523
+г. Тайшет,55.9405482,98.0030449,34491
+г. Ликино-Дулёво,55.7077293,38.9577959,34191
+г. Тосно,59.540686,30.8777641,34066
+г. Мирный,62.5362564,113.9667642,34045
+г. Новокубанск,45.1036986,41.0475442,34000
+г. Нурлат,54.4281036,50.8049432,33990
+г. Шарыпово,55.5391274,89.1801041,33961
+г. Корсаков,46.6324255,142.7994957,33950
+г. Можайск,55.5069403,36.0239829,33880
+г. Партизанск,43.1504279,133.1666126,33832
+г. Дальнегорск,44.5541197,135.566156,33655
+г. Конаково,56.7275398,36.801348,33560
+г. Каменка,53.1855489,44.0468101,33491
+г. Гулькевичи,45.3605339,40.6918433,33357
+г. Новодвинск,64.4136473,40.8206783,33294
+г. Гай,51.4650759,58.4436431,33280
+г. Губкинский,64.4456403,76.4713798,33273
+деревня Рассказовка,55.6317853,37.3132339,33259
+г. Нарткала,43.5578132,43.8576082,33203
+г. Зеленокумск,44.4032361,43.8841172,33187
+пгт Приволжский рп,51.4109503,46.0481131,33096
+г. Валуйки,50.211172,38.0999436,33032
+г. Чернушка,56.515934,56.0764463,32991
+г. Тавда,58.0434995,65.274369,32749
+г. Сухой Лог,56.9074957,62.0357985,32748
+г. Углич,57.522461,38.3018763,32719
+г. Трехгорный,54.8177944,58.4463721,32463
+г. Камень-на-Оби,53.7914749,81.3545962,32385
+г. Алатырь,54.8372699,46.5339898,32265
+г. Кулебаки,55.4296716,42.5124575,32184
+г. Усинск,65.9940586,57.5569288,32182
+г. Острогожск,50.867943,39.0406177,31699
+станица Новотитаровская,45.2376345,38.9765189,31520
+г. Дагестанские Огни,42.1152854,48.193977,31412
+г. Алушта,44.6763996,34.4100439,31364
+г. Тейково,56.8542792,40.5353799,31305
+г. Дюртюли,55.4848147,54.8524883,31185
+село Иглино,54.834468,56.416165,31169
+г. Советский,61.3707009,63.5667177,31138
+г. Усть-Джегута,44.0838556,41.9710356,31137
+г. Приморско-Ахтарск,46.0515858,38.1704382,31087
+Фактория,64.53939,40.5170011,31008
+г. Кохма,56.9325054,41.0931324,30940
+г. Благодарный,45.098943,43.4306154,30827
+село Ачхой-Мартан,43.1872011,45.2863481,30739
+г. Дедовск,55.8704582,37.124447,30731
+г. Вичуга,57.2044884,41.9131422,30694
+город Нововоронеж,51.3091935,39.216289,30658
+г. Зима,53.9336544,102.0498973,30640
+станица Кущевская,46.569894,39.619836,30375
+г. Обь,54.9945378,82.6937661,30369
+станица Староминская,46.5331093,39.0535727,30362
+пгт Томилино рп,55.663107,37.949918,30306
+г. Сердобск,52.4697777,44.2123029,30220
+г. Богданович,56.7764214,62.0462888,30142
+г. Нижнеудинск,54.896942,99.031408,29995
+г. Электрогорск,55.8778372,38.7805887,29982
+г. Луховицы,54.7659596,39.2706433,29889
+г. Вятские Поляны,56.2285162,51.0616058,29742
+г. Фурманов,57.2537548,41.1054731,29715
+г. Борзя,50.3877136,116.5235118,29596
+г. Богородицк,53.7700594,38.1225087,29560
+станица Павловская,46.122016,39.781416,29514
+г. Гусев,54.5915197,22.1942896,29234
+г. Муравленко,63.795443,74.494826,29233
+г. Слободской,58.7312106,50.1669806,29148
+г. Кандалакша,67.1566641,32.4142961,29138
+пгт Краснообск рп,54.921237,82.991197,29086
+пгт Дрожжино рп,55.5277293,37.5937701,29072
+г. Балабаново,55.1774068,36.656839,29029
+г. Лосино-Петровский,55.869566,38.202852,29000
+г. Артемовский,57.3384593,61.8945883,28943
+г. Добрянка,58.542592,56.293958,28782
+г. Маркс,51.7133247,46.7400877,28749
+г. Великий Устюг,60.7602824,46.3053948,28670
+г. Городец,56.644865,43.4722664,28660
+г. Тында,55.1546593,124.7468001,28625
+г. Бахчисарай,44.751299,33.8750748,28609
+г. Сорочинск,52.4266473,53.1541824,28478
+г. Касимов,54.9373071,41.3913313,28443
+г. Кудымкар,59.0168409,54.6573613,28293
+пгт Власиха,55.680815,37.1902369,28240
+пгт Разумное,50.533611,36.689562,28192
+г. Ростов,57.2050397,39.4378513,28122
+г. Заречный,56.8103256,61.3380277,28112
+г. Киров,54.0789799,34.3076309,28097
+город Семилуки,51.6951946,39.0188991,27938
+г. Славгород,52.999413,78.6458451,27900
+г. Аша,54.990582,57.2784381,27890
+пгт Энем,44.9263995,38.9107709,27717
+г. Барабинск,55.3515169,78.3464604,27648
+г. Еманжелинск,54.7554485,61.3243638,27632
+посёлок Придорожный,53.0860041,50.1587223,27515
+пгт Иноземцево кп,44.0970899,43.0894193,27500
+г. Старая Русса,57.9907473,31.355452,27487
+г. Дивногорск,55.9577356,92.380129,27477
+г. Похвистнево,53.6497658,52.1234466,27333
+г. Киржач,56.1486461,38.8635967,27318
+пгт Красково дп,55.65879,37.9885476,27306
+г. Кушва,58.2825138,59.7647615,27306
+г. Мирный,62.764551,40.336094,27262
+г. Кировск,59.875234,30.9815172,27238
+село Экажево,43.2082923,44.8190051,27224
+г. Топки,55.2765207,85.6152094,27158
+г. Камышлов,56.8464908,62.7120309,27117
+г. Карталы,53.0537382,60.6477347,27103
+г. Заводоуковск,56.5028398,66.5513555,27100
+деревня Мисайлово,55.5639995,37.8255811,27093
+деревня Путилково,55.865253,37.392526,27081
+станица Северская,44.8562413,38.6959282,26973
+г. Тара,56.9159295,74.3648797,26878
+село Засечное,53.105904,45.0717034,26878
+г. Шумерля,55.5229338,46.3752894,26873
+г. Балтийск,54.6513858,19.9140642,26796
+г. Новоалександровск,45.4932983,41.2153595,26767
+г. Гурьевск,54.7705454,20.6039948,26760
+г. Котовск,52.5923425,41.5102238,26694
+село Кочубеевское,44.6907487,41.8242914,26645
+г. Майский,43.6283265,44.051839,26632
+г. Кувандык,51.4785827,57.3610986,26596
+г. Гагарин,55.5526733,34.9950319,26500
+г. Красноармейск,56.105426,38.140838,26492
+г. Кимовск,53.9698013,38.538127,26475
+г. Волоколамск,56.0356464,35.958479,26389
+г. Петровск,52.3094724,45.3851898,26319
+г. Соль-Илецк,51.1634754,54.9895396,26149
+г. Ипатово,45.7181195,42.8970759,26122
+г. Костомукша,64.5890912,30.6015362,26048
+пгт Малаховка рп,55.6452616,38.0042385,25989
+г. Удомля,57.8787641,35.0166208,25950
+г. Янаул,56.2649073,54.9297772,25908
+г. Карпинск,59.766559,60.0012125,25879
+г. Кондопога,62.2059903,34.2681816,25851
+г. Коммунар,59.6215741,30.3935534,25793
+г. Отрадное,59.7726485,30.798845,25706
+г. Холмск,47.0408656,142.0416132,25677
+станица Тбилисская,45.3644521,40.2016871,25650
+г. Полысаево,54.6054908,86.2809963,25631
+г. Красноперекопск,45.9536596,33.792071,25569
+г. Киреевск,53.9320407,37.9219941,25560
+пгт Мостовской,44.4144395,40.790292,25548
+г. Лабытнанги,66.6593565,66.3881811,25501
+село Александровское,44.7105748,43.0049484,25479
+город Десногорск,54.1463618,33.2834089,25414
+г. Алейск,52.4922482,82.7795177,25380
+г. Десногорск,54.1463618,33.2834089,25345
+г. Дятьково,53.5958143,34.355106,25255
+г. Скопин,53.8235282,39.5493392,25238
+пгт Калининец рп,55.559738,36.981914,25082
+г. Семенов,56.7890706,44.4902872,25075
+пгт Ильский,44.804549,38.546089,24932
+г. Асино,56.990811,86.1764966,24913
+г. Карасук,53.7343642,78.0422879,24890
+г. Кировск,67.6151587,33.6636568,24857
+станица Ессентукская,44.0267307,42.8764379,24710
+пгт Октябрьский рп,55.6110724,37.9737423,24704
+г. Знаменск,48.5866454,45.7369007,24628
+г. Гусиноозерск,51.2865987,106.5229836,24451
+пгт Пойковский,60.996548,71.902431,24440
+г. Североуральск,60.1533388,59.952553,24428
+г. Бутурлиновка,50.8312775,40.5977424,24397
+г. Озёры,54.8540209,38.5598706,24359
+г. Саки,45.13433,33.6032255,24285
+г. Калач-на-Дону,48.6889101,43.5307585,24277
+г. Унеча,52.8461971,32.6757398,24274
+г. Морозовск,48.351132,41.8307844,24258
+г. Северобайкальск,55.6355591,109.3361645,24233
+г. Советская Гавань,48.9663668,140.2852088,24231
+станица Полтавская,45.3654401,38.2109117,24164
+г. Родники,57.1024811,41.7298234,24101
+г. Зерноград,46.849613,40.3128993,24076
+пгт Северный,50.6774988,36.5607698,24070
+деревня Новое Девяткино,60.0572998,30.4762703,23988
+посёлок Тельмана,59.725444,30.612106,23986
+г. Карачаевск,43.7731804,41.9144084,23867
+станица Елизаветинская,45.0484348,38.7999276,23841
+г. Строитель,50.785172,36.486998,23780
+г. Татарск,55.2144722,75.9740764,23711
+г. Медногорск,51.4038655,57.5831571,23693
+пгт Федоровский,61.6484245,73.488652,23614
+г. Дальнереченск,45.9308807,133.7316844,23613
+пгт Афипский,44.9034044,38.8411512,23592
+г. Уварово,51.983084,42.261,23584
+г. Сегежа,63.7437691,34.3126737,23543
+г Курчалой,43.2045354,46.0889297,23425
+г. Нарьян-Мар,67.6379742,53.0069529,23399
+г. Губаха,58.8370347,57.5544775,23397
+г. Среднеуральск,56.9919113,60.4771159,23344
+г. Кубинка,55.6790296,37.2635177,23146
+г. Нефтекумск,44.7545311,44.9865999,23137
+станица Троицкая,43.3060175,44.9893927,23078
+пгт Свердловский рп,55.9032059,38.1361082,23058
+станица Отрадная,44.39317,41.5156681,23041
+г. Верхний Уфалей,56.0487398,60.2320146,22981
+пгт Городище рп,48.8096322,44.4761656,22905
+г. Старая Купавна,55.810648,38.175624,22898
+г. Менделеевск,55.8951887,52.3143634,22875
+г. Железноводск,44.1320536,43.0304695,22863
+г. Голицыно,55.6189919,36.9856491,22733
+г. Аткарск,51.8737167,45.000324,22709
+пгт Тучково рп,55.6007848,36.4718788,22657
+рп Чишмы,54.5892603,55.3803504,22597
+г. Лермонтов,44.1053341,42.9731493,22444
+посёлок Бугры,60.0700161,30.3997764,22428
+город Павловск,50.4533503,40.1369424,22384
+г. Тайга,56.1723887,85.4268959,22375
+г. Никольское,59.7042138,30.7874065,22355
+г. Верещагино,58.0798499,54.6579923,22239
+г. Сосногорск,63.599118,53.8762442,22189
+г. Гурьевск,54.2859162,85.9477116,22134
+г. Хадыженск,44.412253,39.5320316,22094
+г. Невьянск,57.4912147,60.218324,22061
+г. Тырныауз,43.3981998,42.9214143,22056
+г. Котельниково,47.6310339,43.1330384,22016
+г. Таштагол,52.7594115,87.8476574,21980
+г. Давлеканово,54.222692,55.0311854,21834
+г. Бронницы,55.4254542,38.264161,21831
+г. Вилючинск,52.9302624,158.4057425,21774
+г. Калтан,53.521076,87.2771909,21752
+пгт Медведево,56.6332603,47.8032407,21752
+г. Вихоревка,56.1208112,101.1704184,21719
+г. Семикаракорск,47.517792,40.811485,21719
+г. Лысково,56.0262601,45.0357974,21657
+г. Сасово,54.3508047,41.9117508,21628
+г. Бавлы,54.4063524,53.2458119,21628
+г. Железногорск-Илимский,56.5847582,104.1142358,21621
+г. Вельск,61.0658321,42.1032464,21613
+г. Алдан,58.6095359,125.3817685,21590
+пгт Стройкерамика,53.2766484,50.3870415,21567
+г. Алагир,43.0416623,44.2197807,21550
+пгт Ахтырский,44.8503138,38.2998264,21515
+г. Красноуральск,58.3486753,60.0408929,21507
+г. Бежецк,57.7859527,36.6905192,21466
+г. Усть-Катав,54.9260247,58.1528932,21439
+г. Оленегорск,68.1420962,33.2669298,21438
+г. Рошаль,55.6632087,39.8656345,21401
+г. Ленск,60.7276227,114.9548502,21392
+пгт Излучинск,60.9530651,76.891202,21389
+г. Калачинск,55.059708,74.5655042,21378
+г. Красноармейск,51.0235479,45.6951366,21350
+г. Светлый,54.6773492,20.1356707,21114
+г. Рыбное,54.7256308,39.5135902,21069
+г. Котово,50.3205819,44.803057,21028
+г. Остров,57.3452065,28.3437983,20923
+г. Бобров,51.0902207,40.031849,20871
+пгт Кольцово рп,54.939754,83.189226,20862
+село Дыгулыбгей,43.6605157,43.5399799,20852
+г. Колпашево,58.3114151,82.9027717,20824
+г. Новопавловск,43.957372,43.631908,20781
+г. Тогучин,55.2251228,84.4103609,20766
+г. Чегем,43.567119,43.5866245,20736
+г. Зарайск,54.7624731,38.8851435,20736
+село Карабудахкент,42.7101719,47.5652001,20710
+г. Октябрьск,53.1641278,48.6707034,20703
+г. Армянск,46.1058917,33.6911918,20692
+г. Ряжск,53.7068457,40.0521364,20634
+г. Сысерть,56.5005302,60.8190383,20634
+г. Буй,58.4733865,41.5306164,20564
+пгт Безенчук,52.9844016,49.4332576,20516
+г. Исилькуль,54.9095226,71.2815165,20515
+г. Хотьково,56.2515987,37.9394556,20466
+г. Шарья,58.3760015,45.4060912,20439
+г. Нижний Ломов,53.5301144,43.6730824,20421
+г. Арск,56.0913566,49.8769472,20421
+г. Пикалево,59.5131477,34.1772986,20388
+г. Оха,53.5868177,142.9412704,20357
+пгт Монино рп,55.8393791,38.1953929,20313
+г. Инта,66.0367224,60.1153645,20271
+г. Сергач,55.5200817,45.4813786,20256
+г. Бологое,57.8855456,34.0537078,20234
+г. Котельнич,58.3034526,48.3475879,20144
+г. Лебедянь,53.0155445,39.143535,20049
+станица Зеленчукская,43.8608392,41.5827377,20009
+г. Белоярский,63.7120526,66.6773163,19994
+г. Агрыз,56.5234282,52.9943111,19991
+г. Нерехта,57.4543591,40.5725027,19977
+пгт Боровский рп,57.0437279,65.7219998,19972
+г. Буинск,54.964071,48.2901712,19968
+станица Выселки,45.5801087,39.6553854,19955
+г. Терек,43.4837944,44.140333,19948
+село Новая Усмань (часть 2),51.6440564,39.4129162,19939
+г. Черепаново,54.2206618,83.3724671,19900
+г. Тарко-Сале,64.9117423,77.7610229,19900
+г. Никольск,53.7138244,46.0799725,19873
+г. Куровское,55.5790488,38.920837,19857
+г. Ковылкино,54.0391206,43.9191408,19793
+г. Козьмодемьянск,56.3333702,46.5465866,19731
+г. Данков,53.2576888,39.1456386,19726
+г. Фокино,42.9707585,132.4110104,19711
+пгт Каа-Хем,51.6974519,94.559472,19686
+г. Усмань,52.0444077,39.7263813,19662
+посёлок Строитель,52.6512001,41.4310661,19647
+г. Омутнинск,58.6698906,52.189375,19629
+рп Приютово,53.8951581,53.9369819,19595
+село Чалтырь,47.2826729,39.4992447,19583
+г. Пущино,54.8351813,37.6265045,19578
+г. Дудинка,69.4032072,86.1909075,19556
+поселок Трудовое,43.3002872,132.0632507,19543
+г. Черноголовка,56.0099863,38.3792964,19530
+г. Оса,57.2889708,55.468868,19523
+пгт Кокошкино дп,55.598467,37.167633,19490
+пгт Промышленная,54.916573,85.6376222,19484
+пгт Ленинкент,42.9703441,47.3535191,19438
+поселок Ойсхара,43.2627893,46.2498555,19415
+г. Зея,53.7340347,127.2657094,19414
+станица Суворовская,44.1975139,42.6499527,19378
+г. Зверево,48.0434167,40.1265252,19353
+поселок Игра,57.5401354,53.0861913,19319
+село Гойты,43.1609736,45.6212637,19198
+станица Брюховецкая,45.8020888,38.9971898,19154
+станица Незлобная,44.1168985,43.408563,19068
+пгт Березовка,56.037108,93.1266,19059
+поселок Ува,56.9820545,52.1873031,19057
+г. Арамиль,56.6915504,60.8441135,19013
+г. Пролетарск,46.7038132,41.7276002,18983
+г. Ардон,43.1755904,44.2956828,18956
+г. Лодейное Поле,60.7320844,33.5522164,18905
+посёлок Саракташ,51.7830951,56.3652582,18789
+г. Приозерск,61.03598,30.115586,18777
+станица Холмская,44.848128,38.3892456,18699
+г. Кировград,57.4298874,60.0624019,18698
+село Раевский,54.0650359,54.932837,18698
+г. Николаевск-на-Амуре,53.1461923,140.7110577,18631
+г. Нелидово,56.223391,32.7766208,18603
+пгт Свободы рп,44.0248348,43.0514483,18582
+станица Новопокровская,45.9538509,40.7070143,18559
+село Чигири,50.3391503,127.5076851,18538
+г. Харабали,47.4089236,47.2525264,18514
+г. Няндома,61.6654144,40.2063093,18473
+село Автуры,43.163267,46.0031899,18446
+г. Нижняя Тура,58.6310449,59.8520228,18392
+г. Пласт,54.3691735,60.815252,18379
+г. Новый Оскол,50.764439,37.863064,18359
+пгт Тарки,42.9445024,47.4957949,18233
+г. Суровикино,48.6189098,42.8542126,18227
+г. Боготол,56.2098683,89.5300867,18206
+рп Южный,53.2513304,83.6947313,18098
+г. Ершов,51.35079,48.2763191,18095
+г. Нефтегорск,52.79725,51.1638245,18076
+пгт Тальменка рп,53.8172662,83.5691716,18070
+г. Слюдянка,51.6563035,103.7186495,18058
+село Бабаюрт,43.6011227,46.7793044,18039
+станица Нестеровская,43.2381741,45.0491681,17981
+г. Электроугли,55.7170793,38.219367,17944
+г. Кукмор,56.1860939,50.8971592,17886
+г. Кяхта,50.3466144,106.453365,17877
+пгт Удельная дп,55.6349087,38.049353,17846
+г. Судак,44.8505071,34.9761502,17834
+г. Баймак,52.5913527,58.3111821,17833
+пгт Линево рп,54.4570315,83.3815692,17779
+посёлок завода Мосрентген,55.620947,37.473815,17758
+г. Покров,55.9167157,39.1733602,17747
+село Высокая Гора,55.912126,49.312767,17736
+г. Стародуб,52.5853129,32.7603416,17687
+г. Жуковка,53.5340871,33.7302336,17628
+г. Шахунья,57.6763123,46.6128512,17626
+г. Калач,50.4240228,41.0162465,17624
+г. Суворов,54.122088,36.490348,17598
+посёлок ВНИИССОК,55.6569429,37.2117743,17597
+г. Радужный,55.9960812,40.3322223,17569
+г. Льгов,51.65971,35.261144,17557
+г. Енисейск,58.4485678,92.1650748,17537
+село Белая Глина,46.0736706,40.8713114,17470
+г. Карачев,53.1296862,34.9887384,17449
+г. Белогорск,45.0570816,34.599941,17445
+г. Собинка,55.9938217,40.0178919,17444
+пгт Лучегорск,46.438443,134.289358,17437
+станица Медведовская,45.4491448,39.0101617,17404
+пгт Ванино,49.0909744,140.2563927,17326
+г. Талдом,56.7308601,37.5276018,17317
+пгт Васильево,55.8369276,48.7040265,17286
+г. Юрьев-Польский,56.4936868,39.6680526,17276
+г. Абдулино,53.6778052,53.6473384,17274
+станица Старощербиновская,46.6297567,38.6673969,17251
+г. Константиновск,47.5773447,41.0967357,17207
+село Бачи-Юрт,43.2209854,46.194994,17173
+г. Куса,55.3386556,59.4386134,17136
+пгт Коченево рп,55.019014,82.2060574,17053
+село Осиново,55.8775039,48.8897995,16991
+село Нижнее Казанище,42.760984,47.161627,16984
+г. Онега,63.9162842,38.0805165,16947
+г. Новомичуринск,54.037654,39.7466785,16900
+г. Плавск,53.7095277,37.2862058,16893
+село Майма,52.0037707,85.8962579,16890
+село Цоци-Юрт,43.2426159,46.0018219,16890
+пгт Янино-1,59.945394,30.5611967,16886
+деревня Сапроново,55.529323,37.712318,16817
+деревня Пыхтино,55.6209417,37.3002729,16803
+село Кантышево,43.2281058,44.6484198,16783
+г. Козельск,54.0348045,35.7806829,16759
+село Краснокумское,44.1748104,43.4967116,16702
+г. Нытва,57.9336576,55.3355911,16675
+г. Осташков,57.1457822,33.1116377,16674
+село Кинель-Черкассы,53.4640756,51.5193824,16658
+г. Зеленоградск,54.9599261,20.4752742,16625
+село Новая Усмань (часть 1),51.6440564,39.4129162,16601
+пгт Шушенское,53.333753,91.935624,16573
+г. Туринск,58.0394946,63.6981776,16561
+г. Краснослободск,48.7068501,44.5631832,16545
+пгт Агинское,51.1036078,114.5378536,16511
+г. Нижняя Салда,58.0749078,60.7025219,16505
+г. Шимановск,52.005177,127.7005913,16488
+село Плиево,43.2854671,44.8359413,16440
+станица Гостагаевская,44.8948984,37.3162896,16438
+г. Яровое,52.9252719,78.5729219,16424
+город Поворино,51.195289,42.2473555,16417
+г. Бакал,54.9406707,58.8051112,16345
+г. Инза,53.8549261,46.353359,16293
+г. Шумиха,55.2281331,63.2901783,16264
+пгт Шексна,59.2361104,38.5112653,16246
+г. Бикин,46.8185692,134.2550619,16240
+г. Жуков,55.0302319,36.7393387,16224
+г. Светлогорск,54.9439073,20.1514612,16207
+г. Бокситогорск,59.473579,33.8457452,16185
+г. Кирсанов,52.6506577,42.7284824,16164
+пгт Рощино,60.2408076,29.6288048,16162
+г. Камызяк,46.1106454,48.0732549,16154
+пгт Белый Яр,61.260563,73.252472,16141
+пгт им. Воровского рп,55.7219506,38.3276944,16127
+г. Подпорожье,60.912778,34.1567171,16123
+посёлок Дубовое,50.5303214,36.5682872,16101
+г. Гаврилов-Ям,57.3091517,39.8544895,16084
+село Нартан,43.5054195,43.7016693,16075
+г. Покачи,61.7422837,75.5940895,16040
+г. Поронайск,49.2387506,143.1008839,16026
+г. Руза,55.7015428,36.1959789,16014
+г. Мензелинск,55.7270085,53.1005154,16008
+деревня Куюки,55.7128384,49.3565309,15977
+г. Иланский,56.2375329,96.0673849,15945
+посёлок Орловский,46.874451,42.05931,15942
+село Каякент,42.3862993,47.9054979,15923
+г. Сельцо,53.3739073,34.106007,15906
+станица Раевская,44.836305,37.5496436,15902
+село Учкекен,43.9390432,42.5155851,15849
+г. Райчихинск,49.7941325,129.411213,15797
+г. Ковдор,67.5662699,30.4741763,15770
+деревня Островцы,55.5912674,37.9926244,15752
+село Супсех,44.8948984,37.3162896,15736
+г. Кондрово,54.7959825,35.9275777,15734
+г. Мамадыш,55.7150947,51.4128069,15726
+г. Межгорье,54.2396811,57.9612743,15697
+посёлок Зимовники,47.1453719,42.4676643,15691
+пгт Емельяново,56.1686437,92.6866976,15649
+г. Болотное,55.6692803,84.3906602,15644
+г. Кизел,59.0512352,57.6471132,15619
+пгт Товарково,54.67724,35.942735,15606
+село Поселье,51.8057402,107.5376329,15603
+станица Анапская,44.8948984,37.3162896,15593
+пгт Семендер,42.9911799,47.4021163,15565
+пгт Кратово дп,55.5973949,38.1635172,15565
+г. Жирновск,50.9769212,44.7857873,15555
+посёлок Навля,52.8301087,34.5066338,15536
+пгт Заводской,43.1077853,44.6453692,15508
+г. Дегтярск,56.7048,60.0790826,15497
+г. Свирск,53.0838888,103.3413682,15485
+пгт Сузун рп,53.7891996,82.3161043,15482
+г. Ясный,51.0368874,59.8742748,15471
+село Подстепки,53.5179261,49.1533951,15455
+посёлок Зональная Станция,56.4268771,85.0227819,15421
+станица Варениковская,45.1198484,37.6385129,15385
+г. Касли,55.8869825,60.7422584,15383
+посёлок Усть-Ордынский,52.8052189,104.7536738,15364
+село Гехи,43.1606137,45.4742778,15352
+г. Новоаннинский,50.5295721,42.6666194,15351
+пгт Анна,51.489329,40.4242248,15316
+"посёлок подсобного хозяйства ""Воскресенское""",55.5296175,37.4458356,15293
+г. Нерчинск,51.9594649,116.5853127,15290
+село Ахты,41.4591981,47.7495262,15285
+г. Магас,43.1686871,44.8131101,15271
+г. Ясногорск,54.4794749,37.689663,15269
+г. Новоузенск,50.4551199,48.1411389,15216
+посёлок Знамя Октября,55.47574,37.538359,15199
+село Катар-Юрт,43.1688806,45.370387,15199
+пгт Запрудня рп,56.5609117,37.4336132,15189
+г. Бородино,55.9053464,94.9022323,15174
+пгт Рефтинский,57.0906513,61.6564554,15164
+пгт Софрино рп,56.1354141,37.9260237,15136
+пгт Вырица,59.4172905,30.3469408,15086
+г. Рыльск,51.568137,34.6802211,15069
+г. Купино,54.3661206,77.2973372,15065
+село Хомутово,52.4652523,104.3620353,15064
+пгт Большие Вязёмы рп,55.6291397,37.0053667,15060
+г. Петровск-Забайкальский,51.2748412,108.8468131,15015
+г. Почеп,52.9153976,33.4745131,14991
+г. Палласовка,50.0502023,46.8804085,14966
+г. Калининск,51.4993043,44.4710883,14949
+г. Щигры,51.8785827,36.8911689,14927
+г. Барыш,53.6534032,47.1180501,14924
+пгт Чернянка,50.940917,37.804134,14896
+г. Сортавала,61.7032224,30.6917823,14867
+пгт Грибановский,51.4564459,41.9799021,14830
+станица Васюринская,45.1181463,39.4216389,14829
+г. Талица,57.0123163,63.7320587,14808
+г. Сухиничи,54.0973084,35.344484,14806
+г. Куртамыш,54.9369493,64.4203207,14806
+г. Заполярный,69.4131822,30.7985579,14791
+посёлок Развилка,55.5910519,37.7529499,14788
+г. Дубовка,49.0554351,44.8269342,14779
+пгт Лесной Городок дп,55.636239,37.212612,14765
+г. Белокуриха,51.9961123,84.9839441,14735
+г. Цимлянск,47.6477932,42.092975,14731
+село Кулунда,52.5661304,78.9368917,14708
+пгт Новый Городок,54.3036194,86.2934438,14691
+г. Навашино,55.5438077,42.1887675,14664
+г. Катав-Ивановск,54.7520677,58.1984888,14663
+пгт Ильинский рп,55.6202604,38.1055975,14645
+г. Краснозаводск,56.4409201,38.2320198,14639
+деревня Кондратово,57.9760676,56.1090821,14631
+г. Советск,57.5841376,48.9589455,14626
+станица Егорлыкская,46.553251,40.683235,14602
+село Кулешовка,47.0857816,39.5270717,14568
+пгт Селятино рп,55.5141029,36.9798359,14523
+г. Грязовец,58.875883,40.2485948,14505
+г. Красновишерск,60.3903039,57.0535948,14460
+поселок Балезино,57.983878,53.012307,14459
+станица Гиагинская,44.8847971,40.0577305,14445
+село Алхан-Кала,43.2624396,45.534823,14423
+г. Очер,57.8852534,54.7161526,14385
+город Богучар,49.93528,40.5591512,14370
+г. Волгореченск,57.4424513,41.1592512,14355
+село Донское,45.4672559,41.989783,14338
+г. Приволжск,57.380718,41.2807571,14332
+станица Старовеличковская,45.4329681,38.7244163,14310
+г. Ивдель,60.6945985,60.4245258,14306
+г. Чудово,59.1248174,31.6866267,14302
+г. Красный Кут,50.9597049,46.9711885,14296
+г. Яранск,57.3041231,47.8478976,14284
+село Старые-Атаги,43.1229624,45.7414172,14280
+пгт Средняя Ахтуба рп,48.7136601,44.8600821,14241
+г. Агидель,55.8997421,53.9221357,14219
+посёлок Нижнесортымский,62.4428117,71.7652884,14217
+рп Усть-Абакан,53.8329508,91.3943386,14210
+село Красногвардейское,45.8450489,41.5144643,14200
+село Новый Хушет,42.8993406,47.5613354,14180
+г. Полярные Зори,67.3738152,32.4891688,14146
+посёлок Майский,50.5218213,36.4544411,14143
+г. Ужур,55.3142192,89.8334338,14134
+г. Шлиссельбург,59.9443081,31.0332835,14131
+г. Гвардейск,54.6588822,21.0500744,14122
+станица Калининская,45.4855794,38.6616721,14121
+г. Кашин,57.3600935,37.6118448,14113
diff --git a/src/index.html b/src/index.html
new file mode 100644
index 00000000..83427f8c
--- /dev/null
+++ b/src/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Прогноз погоды
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 00000000..8a288e07
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,9 @@
+import { bootstrapApplication } from '@angular/platform-browser';
+import { provideHttpClient } from '@angular/common/http';
+import { AppComponent } from './app/app';
+
+bootstrapApplication(AppComponent, {
+ providers: [
+ provideHttpClient()
+ ]
+}).catch((err) => console.error(err));
\ No newline at end of file
diff --git a/src/styles.css b/src/styles.css
new file mode 100644
index 00000000..9edf5459
--- /dev/null
+++ b/src/styles.css
@@ -0,0 +1,33 @@
+* {
+ scrollbar-width: thin;
+ scrollbar-color: #3a5a8c #0f1629;
+}
+
+*::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+}
+
+*::-webkit-scrollbar-track {
+ background: #0f1629;
+ border-radius: 10px;
+}
+
+*::-webkit-scrollbar-thumb {
+ background: #3a5a8c;
+ border-radius: 10px;
+}
+
+*::-webkit-scrollbar-thumb:hover {
+ background: #5a7ab0;
+}
+
+*:focus {
+ outline: none;
+ box-shadow: 0 0 0 2px rgba(90, 150, 220, 0.5);
+}
+
+body {
+ background: radial-gradient(circle at 20% 30%, #0a0f1e, #05070f);
+ color: #eef5ff;
+}
\ No newline at end of file
diff --git a/tsconfig.app.json b/tsconfig.app.json
new file mode 100644
index 00000000..5a2cc466
--- /dev/null
+++ b/tsconfig.app.json
@@ -0,0 +1,21 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./out-tsc/app",
+ "types": [],
+ "target": "ES2022",
+ "module": "ES2022",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true,
+ "rootDir": "./src"
+ },
+ "files": [
+ "src/main.ts"
+ ],
+ "include": [
+ "src/**/*.d.ts"
+ ],
+ "exclude": [
+ "src/**/*.spec.ts"
+ ]
+}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 00000000..2ab74427
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,33 @@
+/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
+/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
+{
+ "compileOnSave": false,
+ "compilerOptions": {
+ "strict": true,
+ "noImplicitOverride": true,
+ "noPropertyAccessFromIndexSignature": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true,
+ "skipLibCheck": true,
+ "isolatedModules": true,
+ "experimentalDecorators": true,
+ "importHelpers": true,
+ "target": "ES2022",
+ "module": "preserve"
+ },
+ "angularCompilerOptions": {
+ "enableI18nLegacyMessageIdFormat": false,
+ "strictInjectionParameters": true,
+ "strictInputAccessModifiers": true,
+ "strictTemplates": true
+ },
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.spec.json"
+ }
+ ]
+}
diff --git a/tsconfig.spec.json b/tsconfig.spec.json
new file mode 100644
index 00000000..ef5434c1
--- /dev/null
+++ b/tsconfig.spec.json
@@ -0,0 +1,18 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./out-tsc/spec",
+ "types": [
+ "jasmine"
+ ],
+ "target": "ES2022",
+ "module": "ES2022",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true,
+ "rootDir": "./src"
+ },
+ "include": [
+ "src/**/*.spec.ts",
+ "src/**/*.d.ts"
+ ]
+}
\ No newline at end of file