From c71253a8fd8b663023b28e2476b0dcf6441017df Mon Sep 17 00:00:00 2001 From: Branko Kokanovic Date: Sun, 18 Apr 2021 00:52:03 +0200 Subject: [PATCH 01/29] Adding Serbian Latin translation for phrases and Telegram It is based on Serbian, but it is transliterated (so, easily obtained by automation). While it was easy to produce and Serbian is 100%, I decided to upload it in same commit. --- .../res/values-b+sr+Latn/strings.xml | 274 ++ OsmAnd/res/values-b+sr+Latn/phrases.xml | 3911 +++++++++++++++++ 2 files changed, 4185 insertions(+) create mode 100644 OsmAnd-telegram/res/values-b+sr+Latn/strings.xml create mode 100644 OsmAnd/res/values-b+sr+Latn/phrases.xml diff --git a/OsmAnd-telegram/res/values-b+sr+Latn/strings.xml b/OsmAnd-telegram/res/values-b+sr+Latn/strings.xml new file mode 100644 index 0000000000..f281e65c4c --- /dev/null +++ b/OsmAnd-telegram/res/values-b+sr+Latn/strings.xml @@ -0,0 +1,274 @@ + + + Označi + Omogući + Nadmorska visina + Traži + U redu + Ažuriraj + Prosečna visina + Prosečna brzina + Karta + Dodaj + Sakrij + Stanje + Onemogući + Sačuvaj + Ime + Sortiraj + Izlaz + Zatvori + Sve + Isključeno + Instaliraj + Deli + Nazad + Nastavi + Otkaži + Postavke + Pozadinski režim + yd + ft + mi + km + m + nmi + min/m + min/km + m/s + km/h + mph + Kilometara na sat + Milja na sat + Metara u sekundi + Minuta po kilometru + Minuta po milji + Milje/stope + Milje/jardi + Kilometri/metri + Nautičke milje + Milje/metri + Primeni + Uključen + Merne jedinice & formatiranja + Promeni jedinice za dužinu. + Jedinice dužine + Izgled + Vremenska linija + Uživo sada + Moja lokacija + OsmAnd Pratioc omogućava vam da delite svoju lokaciju i vidite lokaciju drugih u OsmAndu.

Aplikacija koristi Telegram API, pa vam je potreban Telegram nalog.
+ sek + min + č + Nautičkih milja na sat (čvorovi) + nmi/č + Dobrodošli + Unesite vaš telefonski broj Telegrama u međunarodnom formatu + Autorizacija + Aktivna ćaskanja + Prikažite korisnike na mapi + Instalirajte OsmAnd + Prvo morate instalirati besplatnu ili plaćenu verziju OsmAnda + Logo OsmAnda + Usluga OsmAnd Pratioca + Deljenje lokacije + Deli lokaciju + Rastojanje + OsmAnd Pratioc radi u pozadini sa isključenim ekranom. + Izaberite jednog od dobavljača lokacije da bi deliti vašu lokaciju. + Uključite „Lokaciju“ u sistemskim podešavanjima + Aplikaciji nedostaje dozvola za pristup podacima o lokaciji. + Niste prijavljeni + Uključiti „Lokaciju“\? + Zatvaranje + Odjavljivanje + Pokretanje + Odjaviti se + Prijavite se + Telegram lozinka + Unesite lozinku + Telegram vam je poslao kod za OsmAnd radi prijave na vaš nalog. + Validacioni kod + Unesite kod + Lozinka + Broj telefona u međunarodnom formatu + Broj telefona + OsmAnd Onlajn GPS Pratioc + Prikaži na mapi + Deli lokaciju + Pretražite: Grupu ili kontakt + Izaberite kontakte i grupe sa kojima želite da delite lokaciju. + Podesite vreme + Podesite vreme za koji će izabrani kontakti i grupe videti vašu lokaciju u realnom vremenu. + Vidljivo vreme za sve + %1$ č + %1$ m + %1$ č %2$ m + Podesite vidljivo vreme za sve + Unesite kod za validaciju + Unesite broj telefona + Nemam Telegram nalog + Potreban vam je registrovani Telegram nalog i broj telefona + Tada možete da koristite ovu aplikaciju. + Instalirajte Telegram i otvorite nalog. + Za deljenje lokacije potreban vam je Telegram nalog. + Registracija u Telegramu + Bot + Uživo + Otvori OsmAnd + Isključite deljenje lokacije + Deljenje je uključeno (isključite) + Ističe + Vreme deljenja + Pozicija + Pošalji moju lokaciju + Podesite minimalni interval za deljenje lokacije. + Nepomičan + Poslednji put kada se kontakt pomerio. + Istorija lokacije + Sakrijte kontakte koji se nisu pomerili u datom vremenu. + Osmand veza + Odaberite verziju OsmAnda koju OsmAnd pratioc koristi za prikazivanje pozicija. + u %1$ + Nalog + Povezani nalog + Kako isključiti OsmAnd pratioca iz Telegrama + Kako isključiti OsmAnd pratioca iz Telegrama + Da biste opozvali pristup deljenju lokacije. Otvorite Telegram, idite na Podešavanja → Privatnost i bezbednost → Sesije i prekinete sesiju OsmAnd pratioca. + Povežite se na Internet kako biste se pravilno odjavili iz Telegrama. + Grupa + Poslednji odgovor + pre + Isključi sve + Onemogući svako deljenje + Isključuje deljenje lokacije prema svim izabranim čatovima (%1$). + Izaberite verziju OsmAnda koju želite da koristite + Izaberite verziju OsmAnda gde će se kontakti prikazati na mapi. + Sortiraj po + Po grupi + Po imenu + Po udaljenosti + Odjaviti se sa OsmAnd pratioca\? + Jeste li sigurni da se želite odjaviti sa OsmAnd pratioca tako da ne možete da delite lokaciju ili vidite lokaciju drugih\? + Kontakti i grupe dele lokaciju vama. + Deljenje lokacije kao + Dodajte uređaj + Nema internet konekcije + Nema GPS veze + Deljenje: %1$ + Deljenje statusa + Poslednja dostupna lokacija + Ponovo pošalji lokaciju + Još nije pronađeno + Još nije poslato + Kasnije + Idi na Podešavanja + Deljenje u pozadini + Isključite optimizaciju baterije za OsmAnd pratilac tako da se ne isključi iznenada kad je u pozadini. + Rad u pozadini + Promenite podešavanja za optimizaciju baterije da biste stabilizovali deljenje lokacije. + Povezivanje sa Internetom + Pozicioniranje… + Pokretanje + Lokacija se šalje + Čeka se odgovor iz Telegrama + Nije moguće poslati u Telegram četove: + Uspešno poslato i ažurirano + Poslednja ažurirana lokacija: + Ako želite da povežete više uređaja sa jednim nalogom telegrama, trebate koristiti drugi uređaj da bi delili vašu lokaciju. + Možete da kreirate i vidite ID uređaja u telegram klijentu koristeći %1$ čat bot. %2$ + Ime uređaja + Ime uređaja ne može biti prazno + Ime uređaja predugo + Imenujte vaš novi uređaj sa maksimalno 200 simbola. + Nije moguće dodati novi uređaj + %1$ dodato. + Izaberite ime koje niste već koristili + Poslednje ažuriranje od Telegrama + Mapa i tekst + Tekst + Odaberite kako će izgledati poruke sa vašom lokacijom. + Pošalji lokaciju kao + Početni datum + Krajnji datum + Prikaži u OsmAndu + Vreme kretanja + Praćenje je onemogućeno + Praćenje je omogućeno + Poslato + GPS tačke + Prikupljeno + Datum + %1$ tačaka + poslato (%1$ u baferu) + Ažurirajte OsmAnd da biste videli podatke na mapi + Prikaži količinu prikupljenih i poslatih GPS tačaka. + Pokaži GPS tačke + Primljene GPKS tačke: %1$ + Kako radi + OsmAnd politika privatnosti + Politika privatnosti Telegrama + Prihvati + Klikom na „Nastavi“ prihvatate uslove politike privatnosti Telegrama i OsmAnda. + OsmAnd pratilac je jedan od klijenata koji koriste otvorenu platformu Telegram. Vaši kontakti mogu da koriste bilo koji drugi Telegram klijent. + Telegram (aplikacija za razmenu poruka) koristi se za povezivanje i komunikaciju sa ljudima. + Telegram + OsmAnd pratilac + Omogućite praćenje da biste sačuvali sve lokacije u istoriji. + Snimanje lokacije omogućeno + Onemogućite praćenje + Vremenska linija je funkcija koja je sada dostupna besplatno. + Unesite ime kontakta ili grupe + Pretraga po svim vašim grupama i kontaktima. + Pretraga kontakta + Usmerenje + Preciznost + Smer + Privatnost + Proksi + Podešavanja proksija + Prekinut + Povezan + Tip proksija + Veza + Server + Port + Akreditivi + Korisničko ime + Lozinka + Ključ + GPX podešavanja + Filter: nema zapisivanja ispod odabrane brzine + Minimalna brzina zapisivanja + Filter: Nema zapisa dok se ne dostigne ova tačnost + Minimalna tačnost evidentiranja + Filter: minimalna udaljenost za evidentiranje nove tačke + Minimalna udaljenost evidentiranja + Nema podataka + Nemamo prikupljene podatke za izabrani dan + Početni — Krajnji datum + Izaberite vreme za prikaz + Početak + Kraj + Sačuvane poruke + Jedinica brzine + Definišite jedinicu brzine. + Vremenska zona + Izaberite vremensku zonu koja će se prikazati u porukama lokacije. + Vreme isteka bafera + Maksimalno vreme za skladištenje tačaka u bafer + Status Tragača OsmAnda + Predloženo + Povratak na OsmAnd + Pre %1$ + Poslednji odgovor: pre %1$ + Poslednje ažuriranje iz Telegrama: pre %1$ + Poslednji odgovor: %1$ + Poslednje ažuriranje iz Telegrama: %1$ + Greška + Izvezi + Logcat bafer + Proverite i podelite detaljne zapise aplikacije + Pošalji izveštaj +
diff --git a/OsmAnd/res/values-b+sr+Latn/phrases.xml b/OsmAnd/res/values-b+sr+Latn/phrases.xml new file mode 100644 index 0000000000..311b4a1425 --- /dev/null +++ b/OsmAnd/res/values-b+sr+Latn/phrases.xml @@ -0,0 +1,3911 @@ + + + Vrsta goriva + Način plaćanja + Platežne kartice za gorivo + Dodatno + Vrsta pristupa internetu + Način prodaje + Održavanje bicikala + Vrsta + Vrsta + Vrsta + Položaj + Izvor vode + Način plaćanja + Zvuk + Vrsta + Održavanje + Sadržaj + Dodatno + Kamp izviđača + Tip + Težina staze + Ravnanje staze + Rod + Spoljašnja klupa + Naknada + Pušenje + Dostava + Drajv-in + Za poneti + Kokteli + Mikropivara + Tip + Dozvoljeni otpad + Tip + Kamin + Sezonski + Osobine vode + Podloga + Nudizam + Tip masaže + Šatori + Mašina za pranje veša + Karavani + Medicinski sistem + Kućna poseta + Tip + Ciljna grupa + Vazduh pod pritiskom + Usisivač + Samousluga + Automatizovano + Vrsta + Prekriven + Podzemna stanica + Teret + Vrsta + Prevoz biciklom + Grejanje + Pumpa + Vrsta + Vrsta + TipVrsta + Glavni grad + Specijalizacija + Osobina + Vrsta + Broj zvezdica + Veroispovest + Vrsta + Drajv tru + Jelo + Tip plaćanja (prevoz) + Osobina + Kafić + Tip + Tip motocikla + Dozvoljene životinje + Svrha + Iznajmljivanje čamaca + Prečišćavanje vode + Stil penjanja + Utičnica + Auto servis + Tip glečera + Prevoz + Prepreka na putu + Benzinska stanica + Lični prevoz + Javni prevoz + Vazdušni prevoz + Vodeni prevoz + Prevoz biciklom + Prevoz vazdušnim putem + Rute za pešačenje + Struja + Komunikacije + Odlaganje smeća + Obrazovanje + Administracija + Zdravstvo + Kancelarije + Sport + Turizam + Razgledanje okoline + Pristup internetu + Klub + Hrana + Kafić i restoran + Finansije + Priroda + Pomorska + Vojska + Vikipedija + Korisnički definisano + Pekara + Podrum pića + Prodavnica sira + Prodavnica čokolade + Prodaje kafe + Tržni centar + Prodavnica pića + Mesna pijaca + Stočna prodavnica + Prodavnica morske hrane + Konfekcija + Supermarket + Prodavnica čaja + Prodavnica testenina + Vinski podrum + Knjižara + Prodavnica bickli + Anime prodavnica + Antikvarnica + Prodavnica umetnina + Stvari za bebu + Modni butik + Fotoaparati i sočiva + Prodavnica tepiha + Drogerija + Prodavnica odeće + Prodavnica odeće za decu + Prodavnica cipela + Prodavnica sveža + Prodavnica računara + Fotokopirnica + Prodavnica zavesa + Prodavnica tkanine + Vrata + Seks šop + Modna prodavnica + Cvećara + Prodavnica ramova + Prodavnica poklona + Oprema za lov + Juvelir + Kiosk + Prodavnica kože + Prodavnica mobilnih telefona + Prodavnica motocikala + Muzička radnja + Muzički instrumenti + Novinarnica + Optometrija + Organski proizvod + Prodavnica boja + Prodavnica kućnih ljubimaca + Foto radnja + Prodavnica polovnih stvari + Sportska oprema + Prodaja karata + Prodavnica duvana + Prodavnica igračaka + Prodavnica guma + Prodavnica usisivača + Video klub + Prodavnica elektronike + Auto delovi + Kozmetika + CHAdeMO izlaz + Tip 2 izlaz + Tip 2 kombo izlaz + Tip 3 izlaz + CEE plavi izlaz + Šuko izlaz + Paleontološki lokalitet + Prodavnica tečnog gasa + Slušni aparati + HiFi prodavnica + Prodavnica enterijera + Prodavnica opreme za ronjenje + Prodavnica osušene robe + Sajdžija + Prodavnica opreme za bazene + Igre + Trofeji, nagrade + Video igrice + Pirotehnika + Prodavnica oružja + Parfimerija + Prodavnica začina + Prodavnica meda + Policija + Vatrogasci + Hidrant + Vatrogasno crevo + Ambulanta + SES stanica + Tačka za okupljanje u slučaju nužde + Zaliv + Planinski prolaz + Kapija + Gradske zidine + Kapija lifta + Telefonska govornica + Pasoška kontrola + Ležeći policajac + Jastuče (brzinsko) + Šikana + Saobraćajno ostrvo + Stop svetlo + Popravka kola + Gume + Pregled vozila + Pranje kola + Benzinska pumpa;Pumpa za plin;Stanica za punjenje + Dizel + GTL dizel + HGV dizel + Biodizel + LPG + Oktan 80 + Oktan 91 + Oktan 92 + Oktan 95 + Oktan 98 + Oktan 100 + 1:25 gorivo + 1:50 gorivo + Etanol + Metanol + SVO + E10 + E20 + E85 + Biogas + Tečni vodonik + Struja + Benzinska stanica za letelice + Benzinska stanica za brodove + Vazduh pod pritiskom + Parking + Parking za motocikle + Ulaz u parking + Garaže + Stanica javnog prevoza + Autobuska stanica + Stanica trolejbusa + Autobuska stanica + Tramvajska stanica + Tramvajska stanica + Stanica javnog prevoza + Autobuska stanica + Železnička stanica + Ulaz u podzemnu + Da + Taksi stanica + Aerodrom + Heliodrom + Pista + Vazdušni terminal + Vazdušni gejt + Svetionik + Iznajmljivanje bicikli + Parking za bicikle + Gondola + Sadržaj: usev + Usev: pirinač + Usev: trava + Usev: kukuruz + Usev: žitarice + Usev: šećerna trska + Usev: pšenica + Usev: soja + Usev: ječam + Usev: povrće + Usev: hmelj + Usev: repica + Usev: cvekla + Usev: lavanda + Usev: čaj + Usev: kafa + Usev: živina + Usev: suncokret + Usev: malina + Usev: duvan + Usev: jagoda + Usev: povrće, cveće + Usev: tapioka + Usev: brusnica + Usev: špargla + Usev: cveće + Da + Tuš: da + Tuš: ne + Tuš: vruć + Tuš: spolja + Tuš: hladan + Tuš: unutra + Da + Nekropola + Izlazna snaga + Izlazna snaga tople vode + Izlazna snaga vazduha pod pritiskom + Protivpožarni aparat + CNG + Stanica za punjenje + Rampa za vozila + Trajektni terminus + Žičara + Lift za robu + Uspinjača + Tunel + Most + Radar kamera + Raskrsnica + Odmorište + Bunar sa vodom + Radovi na vodi + Vodeni toranj + Kapija sa zaključavanjem + Brana + Vodenica + Razbijač talasa + Transformator + Elektrana + Strujni generator + Pošta + Poštansko sanduče + Telefon + Komunikacioni toranj + Osmatračnica + Reciklaža + Centar za reciklažu + Kontejner + Staklo + Papir + Odeća + Limenke + Staklene flaše + Plastika + Metalni otpaci + Baterije + Plastične flaše + Zelenilo + Otpad (crne kese) + Plastične ambalaže + Novine + Karton + Kartonske kutije + Časopisi + Papirnate ambalaže + Mali uređaji + Drvo + Knjige + Cipele + Aluminijum + Organsko + Baštenski otpad + Sijalice male snage + Fluorescentne sijalice + Metal + Električne stvari + Ulje za kuvanje + Motorno ulje + Plastične kese + Opasni otpad + Mobilni telefoni + Živa + Računari + Gume + TV, monitori + Tetrapak + Krš + CD-ovi + Otpadno ulje + Flaše + Pluta + Kertridži iz štampača + Boja + Stiroform + Lekovi + Kompost + Novogodišnje jelke + Sijalice + Poliester + Životinjski otpad + Frižideri i zamrzivači + Nameštaj + Pelene + Akumulatori + Automobili + Bicikli + Nuklearni otpad + Odlaganje smeća + Kanta za smeće + Stambena oblast + Industrijska oblast + Železnička oblast + Trgovinsko zemljište + Zemljište namenjeno za maloprodaju + Kamenolom + Vinograd + Voćnjak + Bašte + Seosko dvorište + Livada + Sliv + Kanal + Dok + Nadzor + Opservatorija + Astronomska + Toranj + Jarbol + Radar + Kran + Radovi + Vetrenjača + Rezervoar + Silos + Koledž + Vozačka škola + Vrtić + Škola + Ustanova za vežbanje + Univerzitet + Sud + Zatvor + Ambasada + Tužilac + Penzioni fond + Carina + Država + Grad + Da + Varošica + Selo + Zaseok + Predgrađe + Lokalitet + Farma + Apoteka + Bolnica + Doktori + Klinika + Prva pomoć + Stomatolog + Veterinar + Alternativna medicina + Banka krvi + Optometrist + Fizioterapeut + Psihoterapeut + Rehabilitacija + Medicinska ustanova + Pedijatrija + Kompanija + Osiguranje + Agent za nekretnine + Advokat + NVO + Gradska većnica + IT kancelarija + Marketinška agencija + Obrazovna ustanova + Studio + Prostorije stranke + Notar + Stadion + Sportski centar + Golf teren + Sportska staza + Trkačka staza + Biciklistička staza + Konjska staza + Trkalište + Kuglanje sa 9 čunjeva + Kuglanje sa 10 čunjeva + Streljaštvo + Atletika + Američki fudbal + Australijski fudbal + Bejzbol + Košarka + Odbojka na pesku + Kanadski fudbal + Šah + Gromobran + Telefonska centrala + Kartoni od pića + Bela tehnika + Lim + Folija + Ljudski održavana šuma + Stanica za nadgledanje + Građevina + Šaht + Slana bara + Gaosmetar + Bunker silos + Tank za skladištenje + Socijalna ustanova + Državna uprava + Sudski izvršitelj + Migraciono + Poreska inspekcija + Administracija + Izolovano mesto stanovanja + Četvrt + Komšiluk + Dom za stare + Sanatorijum + Audolog + Babica + BMX + Kanu + Penjanje + Kriket + Kroket + Biciklizam + Ronjenje + Skuba ronjenje + Trke pasa + Hokej na travi + Hokej na ledu + Golf + Gimnastika + Rukomet + Hokej + Trke konja + Skijanje na ledu + Korfbol + Moto trke + Više sportova + Orijentiring + Paraglajding + Pelote + Reket + Roleri + Veslanje + Ragbi unija + Ragbi liga + Jedrenje + Klizanje + Skejtbord + Skijanje + Fudbal + Surfovanje + Plivanje + Stoni tenis + Tenis + Tobogan + Odbojka + Muzej + Memorijalni spomenik + Arheološko nalazište + Istorijski top + Zamak + Gradska kapija + Tvrđava + Fontana + Istorijske ruševine + Brodska olupina + Istorijski brod + Istorijska mina + Spomenik + Zoološki vrt + Akvarijum + Tematski park + Turistička atrakcija + Turistički objekat + Životinja (atrakcija) + Vrteška + Lavirint + Rolerkoster + Spust + Letnji tobogan + Balerina + Voz (atrakcija) + Vodeni spust + Smeštaj + Hotel + Gostinska kuća + Hostel + Motel + Planinska brvnara + Stan + Brvnara u divljini + Hrišćanstvo + Judaizam + Islam + Sikhizam + Budizam + Hinduizam + Šinto + Taoizam + Vudu + Džainizam + Spiritualizam + Bahaizam + Sajentologija + Paganizam + Zoroastrijanizam + Katolicizam + Baptizam + Rimokatolicizam + Pravoslavlje + Suni + Protestantizam + Metodizam + Rusko pravoslavlje + Mormonstvo + Jehovini svedoci + Grčko pravoslavlje + Adventisti sedmog dana + Engleska crkva + Škotska crkva + Armija spasa + Kvaker + Bugarsko pravoslavlje + Adventisti + Srpsko pravoslavlje + Crkva Isusa Hrista + Jermensko pravoslavlje + Rumunsko pravoslavlje + Mahajana + Internet pristup: žični + Internet pristup: javni + Internet pristup: da + Internet pristup: ne + Internet pristup: sa naknadom + Internet pristup: bez naknade + Manastir + Informacije + Sat + Turistički agent + Vidikovac + Mesto za piknik + Sto za piknik + Izvor + Vrelo + Gejzir + Groblje + Grobnica + Sklonište + Podrum vina + Vinarija + Astronomski klub + Kompjuterski klub + Motociklistički klub + Sportski klub + Igrački klub + Auto klub + Šahovski klub + Ribolovački klub + Klub ratnih veterana + Klub linuksaša + Kampiralište + Odmaralište + Klub ljubitelja + Pozorišni klub + Klub istoričara + Muzički klub + Etnički klub + Klub ljubitelja prirode + Klub fotografa + Lovački klub + Streličarski klub + Turistički klub + Masonska loža + Klub jedriličara + Izviđački klub + Staza + Staza nizbrdo + Nordijska staza + Pešačka staza + Snežni park + Staza za igranje + Klizalište + Najam skija + Biblioteka + Bioskop + Kazino + Socijalni centar + Pozorište + Cirkus + Umetnička galerija + Podijum za igru + Noćni klub;Disko klub + Striptiz + Ski omdaralište + Morsko odmaralište + Park za pse + Mesto za pecanje + Luka + Marina + Mini golf + Igralište + Klupa + Bazen za plivanje + Akva park + Park + Teren za rekreaciju + Kafić + Pivska bašta + Restoran + Brza hrana + Bar + Pab + Voda za piće + Roštilj + Korpar + Pivnica + Brodogradioc + Ćilimar + Sajdžija + Električar + Baštovan + Ručni radovi + Grejanje, ventilacija, klima + Izolacija + Optičar + Slikar + Parketar + Fotograf + Vodoinstalater + Mlinar + Skulptor + Obućar + Krojač + Časovničar + Izrada prozora + Upravnik sahrana + Salon lepote + Manikir + Frizer + Salon za masažu + Tetovaže + Pranje veša + Iznajmljivanje kola + Deljenje kola + Deljenje brodova + Dok + Tuš + Sauna + Mrtvačnica + Krematorijum + Internet kafe + Banka + Terminal za plaćanje + Novčane pozajmice + Menjačnica + Računovođa + Bitkoin plaćanje + Ulaz u pećinu + Planinski vrh + Sedlo + Vulkan + Krater + Greben + Glečer + Vrtača + Vodopad + Reka + Potok + Brzaci + Rt + Plaža + Zaliv + Fjord + Greben + Dolina + Voda + Tresetište + Drvo + Stablo + Prirodni rezervat + Moreuz + Ostrvo + Hrid + Instalaciona bova + Bova, izolovana opasnost + Lateralna bova + Bova sigurnih voda + Bova specijalne namene + Suvi dok + Plutajući dok + Lučki bazen + Luka + Vojna oblast + Vojno sklonište + Barake + Opasna zona + Vojne kancelarije + Vojna mornarička baza + Mesto nuklearne eksplozije + Vikipedija + Engleska vikipedija + Arapska vikipedija + Beloruska vikipedija + Bugarska vikipedija + Katalonska vikipedija + Kebuanska vikipedija + Češka vikipedija + Danska vikipedija + Nemačka vikipedija + Grčka vikipedija + Estonska vikipedija + Španska vikipedija + Finska vikipedija + Francuska vikipedija + Galicijska vikipedija + Jevrejska vikipedija + Hindi vikipedija + Hrvatska vikipedija + Haićanska vikipedija + Mađarska vikipedija + Indonežanska vikipedija + Italijanska vikipedija + Japanska vikipedija + Korejska vikipedija + Litvanska vikipedija + Latvijska vikipedija + Majalska vikipedija + Holandska vikipedija + Novonorveška vikipedija + Norveška vikipedija + Poljska vikipedija + Portugalska vikipedija + Rumunska vikipedija + Ruska vikipedija + Slovačka vikipedija + Slovenačka vikipedija + Srpska vikipedija + Švedska vikipedija + Svahili vikipedija + Telugu vikipedija + Tai vikipedija + Turska vikipedija + Ukrajinska vikipedija + Vijetnamska vikipedija + Volapička vikipedija + Kineska vikipedija + Afrikanska vikipedija + Azerbejdžanska vikipedija + Bengalska vikipedija + Bretonska vikipedija + Bošnjačka vikipedija + Velška vikipedija + Esperanto vikipedija + Baskijska vikipedija + Irska vikipedija + Armenijska vikipedija + Islandska vikipedija + Gruzijska vikipedija + Kurdska vikipedija + Latinska vikipedija + Luksemburgška vikipedija + Makedonska vikipedija + Marati vikipedija + Navaho vikipedija + Osetska vikipedija + Sardinijska vikipedija + Srpko-hrvatska vikipedija + Albanska vikipedija + Tamilska vikipedija + Filipinska vikipedija + Uzbekistanska vikipedija + Čečenska vikipedija + Urdu vikipedija + Oksitanska vikipedija + Tatarska vikipedija + Kirgistanska vikipedija + Pandžabi vikipedija + Aragonska vikipedija + Nepalska vikipedija + Sicilijanska vikipedija + Bavarska vikipedija + Mongolska vikipedija + Napolitanska vikipedija + Blok + Ograda za stoku + Ograničavač visine + Prolaz u zidu ili ogradi + Glavni ulaz + Ulaz + Izlaz + Prelaz ulice + Vreme rada + Opis + Telefon + Veb sajt + E-pošta + Faks + Fejsbuk + Tviter + Skajp + YouTube + Instagram + VKontakte + Google+ + Mobilni + Uslužno vreme + Maksimalna visina + Maksimalna težina + Visina + Visina iznad nivoa mora + Napušteno + Napušteni objekat + Ne koristi se + Operator + Robna marka + Da + Ne + Da + Ne + Nadgledano + Nenadgledano + Da + Ne + Sušna sezona + Vlažna sezona + Proleće + Leto + Jesen + Zima + Sa stop svetlima + Nekontrolisan + Neobeležen + Početni datum + Pristup invalidskim kolicima + Da + Ne + Ograničen + Market prodaja + Privatni posed + Bez pristupa + Odredišni pristup + Pristup za korisnike + Pristup za dostavu + Pristup za poljoprivredu + Sadržaj: voda + Sadržaj: ulje + Sadržaj: gorivo + Sadržaj: vino + Sadržaj: kanalizacija + Sadržaj: gas + Sadržaj: biomasa + Sadržaj: otpadna voda + Sadržaj: pivo + Sadržaj: so + Dozvoljen + Zabranjen + Obavezan + Ograničen + Naseljenost + Podzemni + Na više nivoa + Neformalan + Širokolisno + Maslina + Jabuka + Palmino ulje + Narandže + Badem + Banana + Lešnik + Kokos + Persimon + Trešnja + Orah + Šljiva + Breskva + Čaj + Koka + Kivi + Voćnjak + Nektarina + Mango + Kaučuk + Datula + Drvo kafe + Nar + Urbano + Ruralno + Na snazi: semafor + Na snazi: maks. brzina + Na snazi: maks. visina + Na snazi: putarina + Sklonište za životinje + Psi + Mačke + Psi, mačke + Ptice + Divlje životinje + Konj + Sisari + Ribe + Sedišta + Naslon: da + Naslon: ne + Zgrada + Izvor energije: ugalj + Izvor energije: gas + Izvor energije: nuklearni + Izvor energije: solarni + Izvor energije: hidro + Izvor energije: vetar + Izvor energije: geotermalni + Izvor energije: ulje + Izvor energije: dizel + Međunarodno ime + Nacionalno ime + Regionalni naziv + Lokalni naziv + Stari naziv + Alternativni naziv + Ručno + Na struju + Bez pumpe + Da + Mineralna + Blato + Sumporna + Karta + Kancelarija + Terminal + Karta planinarenja + Priroda + Istorija + Znak + Audio vodič + Biciklistička karta + Taktilni model + Taktilna karta + Biljke + Geologija + Javni prevoz + Tehnologija + Astronomija + Da + Da + Ne + Zabranjeno + Samo napolju + Dozvoljeno + U posebnoj prostoriji + U izolovanoj sobi + Da + Da + Zvuk : ne + Samo kada je dozvoljeno hodanje + Stanica za spašavanje + Mini kružni tok + Prelaz pruge + Mesto za posmatranje ptica + Jahanje konja + Bašta + Trava + Pesak + Štandovi + Specijalna zgrada + Šupa + Mešano + Vrste + Rod + Takson + Povremeno + Tabla + Markacija na drvetu + Marker puta + Oglasna tabla + Nema ognjišta + Za pušače + Putarina + Bez putarine + Mrtvo drvo + Nivo + Laka + Srednja + Napredna + Početnička + Ekspertska + Slobodna vožnja + Klasično + Klasično+klizanje + Skuterom + Klizanje + Ne + Mogul + Tip bašte: stambena + Tip bašte: javna + Tip bašte: privatna + Tip bašte: botanička + Tip bašte: kuhinjska + Tip bašte: rozarijum + Tip bašte: francuski + Tip bašte: engleski + Tip bašte: japanski + Kapacitet + Da + Nema posebnih mesta za osobe sa invaliditetom + Posebna mesta za osobe sa invaliditetom + Posebna mesta za žene + Nema posebnih mesta za žene + Posebna mesta za žene + Posebna mesta za učenike + Posebna mesta za nastavnike + Posebna mesta za roditelje + Bez posebnih mesta za roditelje + Posebna mesta za roditelje + Kapacitet na sat + Prosečno vreme putovanja, u minutima + Balon + Bez balona + Da + Bez grejanja + Dozvoljene + Bicikle: nedozvoljene + Dozvoljene samo leti + Samo ulaz + Samo izlaz + Ulaz i izlaz + Letnji pristup: samo ulaz + Letnji pristup: samo izlaz + Letnji pristup: ulaz i izlaz + Sobe + Ljubavni hotel + Kovanice + Kovanice se ne prihvataju + $0.5 kovanice + 50c, 1€ i 2€ kovanice + Telefonske kartice + Telefonske kartice se ne prihvataju + Kreditne kartice + Kreditne kartice se ne prihvataju + Novčanice + Novčanice se ne prihvataju + Elektronske tašne + Elektronske tašne se ne prihvataju + Keš + Keš se ne prihvata + Debitne kartice + Debitne kartice se ne prihvataju + Bitkoin + Bitkoin se ne prihvata + Visa kartice + Visa kartice se ne prihvataju + MasterCard kartice + MasterCard kartice se ne prihvataju + Maestro kartice + Maestro kartice se ne prihvataju + Kapacitet kabine/klupe/kola + 1 (turistički) + 1S (turistički superior) + 2 (standard) + 2S (standard superior) + 3 (komfort) + 3S (komfort superior) + 4 (prva klasa) + 4S (prva klasa superior) + 5 (luksuz) + 5S (luksuz superior) + Kartice naloga + Kartice naloga se ne prihvataju + American Express (AMEX) kartice + American Express (AMEX) kartice se ne prihvataju + Diners Club kartice + Diners Club kartice se ne prihvataju + DKV kartice + DKV kartice se ne prihvataju + UTA kartice + UTA kartice se ne prihvataju + Efectivo kartice + Efectivo kartice se ne prihvataju + Girocard kartice se ne prihvataju + Discover Card kartice + Discover Card kartice se ne prihvataju + Visa Electron kartice + Visa Electron kartice se ne prihvataju + Lajtkoin + Lajtkoin se ne prihvata + Čekovi + Čekovi se ne prihvataju + PIKEPASS + IC Stored Fare kartice se ne prihvataju + Pripejd tiketi + JCB kartice + JCB kartice se ne prihvataju + Laser kartice + Laser kartice se ne prihvataju + Quick kartice + Quick kartice se ne prihvataju + Eurowag kartice + Eurowag kartice se ne prihvataju + E‑ZPass kartice + E‑ZPass kartice se ne prihvataju + Euroshell kartice + Euroshell kartice za gorivo se ne prihvataju + KITCard kartice + KITCard kartice se ne prihvataju + Westfalen kartice + Westfalen kartice se ne prihvataju + V PAY kartice + V PAY kartice se ne prihvataju + Dodžkoin + Dogecoin se ne prihvata + Cibus kartice + Cibus kartice se ne prihvataju + Keš kartice (Geldkarte) + Keš kartice (Geldkarte) se ne prihvataju + Proton + Proton kartice se ne prihvataju + AvantCard kartice + AvantCard kartice se ne prihvataju + MEP kartice + MEP kartice se ne prihvataju + Minipay kartice + Minipay kartice se ne prihvataju + MiniCash + MiniCash se ne prihvata + Moneo + Moneo se ne prihvata + Monedero 4B + Monedero 4B se ne prihvata + Monedero + Monedero se ne prihvata + BankAxess + BankAxess se ne prihvata + Coinkite + Coinkite se ne prihvata + Roadrunner kartice + Roadrunner kartice se ne prihvataju + SVG + SVG se ne prihvata + Plaćanje SMS-om + Plaćanje SMS-om se ne prihvata + OV-Chipkaart + OV-Chipkaart se ne prihvata + Oyster kartice + Oyster kartice se ne prihvataju + SUBE kartice + SUBE kartice se ne prihvataju + Via Verde + Via Verde se ne prihvata + Vaučeri za jelo + Vaučeri za jelo se ne prihvataju + Pejpal + Pejpal se ne prihvata + U-Key + U-Key se ne prihvata + Žetoni + Žetoni se ne prihvataju + Poklon vaučeri + Poklon vaučeri se ne prihvataju + Golden Crown kartice + Golden Crown kartice se ne prihvataju + PRO100 kartice + PRO100 kartice se ne prihvataju + Union Card kartice + Union Card kartice se ne prihvataju + MTS-Money + MTS-Money se ne prihvata + Yandex.Money + Yandex.Money se ne prihvata + Opis plaćanja + Vegeterijanska + Vegeterijanska (pomalo) + Isključivo vegeterijanska + Vegeterijanska + Vegeterijanska ishrana: ne + Veganska + Isključivo veganska + Veganska + Veganska ishrana: ne + Bezglutenska + Isključivo bezglutenska + Bezglutenska + Bezglutenska ishrana: ne + Košer + Isključivo košer + Košer + Oslonac za prepovijanje pelena + Sto za prepovijanje pelena + Nema stola za prepovijanje pelena + Soba za prepovijanje pelena + Ograničeno vreme parkiranja + Karte za parkiranje + Cigarete + Kese za izmet ljubimaca + Karte za javni prevoz + Piće + Slatkiši + Kondomi + Markice + Hrana + Piće i hrana + Gorivo + Mleko + Izduženi novčići + Hleb + Žvakaće gume + Karte za parkiranje; karte za javni prevoz + Kafe aparat + Automat za putarinu + Automat za karte + Automat za vodu + Telefonski vaučeri + Hrana za životinje + Mapa javnog prevoza + Piće i slatkiši + Vaučeri + DVD-ovi + Sveće + Igračke + Sladoled + SIM kartice + Grana + Ratna spomenica + Spomen-ploča + Statua + Kamen + Stela + Bista + Košinto + Krstolik + Vozilo + Kamen spoticanja + Obelisk + Stub + Stupa + Prasat + Fasadni ukras + Natpis + Istorijski kamenolom + Mešavina + Antimon + Azbest + Barit + Bazalt + Boksit + Beril + Bizmut + Hromit + Glina + Ugalj + Bakar + Dijamant + Dolomit + Gas + Zlato + Grafit + Šljunak + Gips + Ruda gvožđa + Olovo + Lignit + Krečnjak + Mermer + Živa + Tinjci + Mineralno ulje + Nikl + Ulje + Opal + Treset + Platina + Radijum + Rubin + Rutil + So + Pesak + Peščar + Silicijum + Srebro + Argilošist; ruda gvožđa; bakar + Argilošist + Kamen + Kalaj + Tuf + Uranijum + Vanadijum + Voda + Cink + Cirkon + Vlažna livada + Tresava + Močvara + Mangrove + Blato + Pesak + Staroverci + Spiritisti + Jermenski apostoli + Holandski reformisti + Apostolska crkva + Reformisti + Vrsta goriva (avia) + Vođice za slabovide + Bez četkica + Odredište + Apoteka (na recept) + Veroispovest + Zabit + Usluga + Hrana + Zdravstvene usluge + Izvor napajanja + Usluge + Radno stanje + Tip dostave vode + Mesto pristupa vodi + Tip kontrolnog mesta + Prodavnica + Prodavnica potrebština i samousluga + Hitna pomoć + Služba hitne pomoći + Pešački/biciklistički mrežni čvorovi + Ograničenje saobraćaja + Napravljeno ručno + Saobraćajna konstrukcija + Dostava vode + Korišćenje zemljišta + Smeštaj + Zabavno + Usluga + Radionica + Prodavnica potrebština + Prodavnica delikatesa + Prodavnica zelenila + Prostor sa sladoledom + Prodavnica peciva + Mlekara + Automat prodaje + Prodavnica torbi + Nameštaj za kupatilo + Prodavnica kreveta + Prodavnica priloga + Ronilačka oprema + Prodavnica za kućno unapređenje + Oprema za pecanje + Prodavnica stvari slobodnog letenja + Prodavnica nameštaja + Baštenski centar + Prodavnica baštenskog nameštaja + Opšta prodavnica + Staklara + Gvožđara + Prodavnica bilja + Prodavnica kućnih potrebština + Kuhinjski nameštaj + Medicinska dostava + Prodavnica spoljnje opreme + Radiotehnička prodavnica + Brodska oprema + Prodavnica kancelarijske opreme + Prodavnica pribora za jelo + Trgovački terminal + Prodavnica mešane robe + Prodavnica prozorskih zastora + Robna kuća + Energetsko odeljenje + Prodavnica auta + Prodavnica točkaša + Drakstor + Umanjeni modeli + Prodavnica zanatskih rekvizita + Religiozna dobra + Hitan telefon + Protivpožarna metla + Protivpožarni bazen + Sanduk soli + Pešački kameni most + Ispupčenje (brzinsko) + Traka neravnine + Usporivački prelaz + Potiskivač + Stop pozicija javnog prevoza + Peron pruge + Pružni prelaz + Pružni predzaustavljač + Brodogradilišna pruga + Stanica žičare + Sedišta žičare + Sedišta sa t-prečkom + Sedišta sa j-prečkom + Prevozna prečka žičare + Žičara sa gondolama i sedištima + Vučna žičara + Žičara sa vučnim konopcem + Stub žičare + Kružni kraj puta + Autoputna raskrsnica + Hidrant + Brodski suvi dok + Fabrika otpadnih voda + Vodeni prelaz + Niska brana + Sedimentna brana + Podstanica + Odeljenje kablovskog razvoda + Električni toranj + Električni stub + Telefonski toranj + Rashladni toranj + Zidarski šut + Iverica + Suvi malter + Deponija + Pretgrađevinski teren + Novograđevinski teren + Podzemni ulaz + Izvor nafte + Nadzorna tačka + Kriket mreže + Kancelarija za građane + Parcelna grupa + Prihvatilište beba + Terapeut profesija + Ortoped donjih ekstremiteta + Logoped + Telekomunikaciona kancelarija + Kancelarija biroa rada + Istraživačka kancelarija + Novinarska kancelarija + Kancelarija arhitekta + Kladionica + Kancelarija za religije + Kancelarija udruženja + Finansijska kancelarija + Osnivačka kancelarija + Kancelarija poreskog savetnika + Klizalište + Sportski teren + Skakanje + Boćanje + Kuglanje + Konjički + Kuglanje na ledu + Mali tenis + Streljaštvo + Umetnost + Vojni poligon + Granični kamen + Runski kamen + Zabavna vožnja + Točak ringišpil + Izdvojena kabina + Koliba + Otvorena koliba + Lovačka koliba + Pokloničko mesto + Unitarni univerzalizam + Više-verski + Tenrikio + Luterizam + Anglikanizam + Prezbiterijanizam + Evangelizam + Pentakostalizam + Reformizam + Novo-apostolizam + Episkopalizam + Šia islam + Unitarizam + Grčki katolicizam + Tibetanizam + Reformisan unitarizam + Crkva Hristos + Ujedinjenje + Menonitizam + Božji sabori + Nedenominacijski + Nazarećani + Unitarni metodisti + Kongregacionalizam + Sveci kasnijeg dana + Ujedinjena Crkva Hristova + Naučna religija + Etiopsko Tevahedo pravoslavlje + Unitarci + Koptsko pravoslavlje + Veslejani + Šaktizam + Šingon Šu + Maroniti + Internet pristup: VLAN + Internet pristup: terminal + Internet pristup: servis + Religiozna oblast + Krst sputa + Hram sputa + Karavan lokacija + Groblje + Tranvaj usponski + Hanami + Umetnički klub + Klub igara za stolom + Kinematografski klub + Donatorski klub + Skijaška staza + Staza za kočije + Staza za sanke + Umetnički centar + Saborni centar + Lovačka čeka + Centar sela + Konjička stanica + Samoposlužna kuhinja + Poljoprivredne mašine + Pčelar + Kovač + Štampar + Postavljač tepiha + Pripremač jela + Krojač + Staklorezač + Zlatar + Kovač + Ključar + Metalorezac + Foto-tamna soba + Moler + Keramičar + Konopčar + Konstruktor krovova + Sedlar + Jedrar + Konstruktor skela + Konstruktor štandova + Kamenorezaz + Konstruktor suncobrana + Čistač + Parketar + Kovač posuđa + Tapetar + Tehničar računara + Hemijsko čišćenje + Prosek + Zahod;Toaleti + Javna kuća + Pušački deo + Zalagaoničar + Mesto kamena + Sidrište + Sidrišna bova + Svetionik + Navigacioni svetionik + Lateralni svetionik + Svetionik bezbednih voda + Svetionik posebne namene + Dok + Nautička zgrada + Nautički most + Navigaciona bova + Dnevna oznaka + Oznaka udanjenosti + Nasip + Signal magle + Oznaka zemlje + Svetlo, nautika + Glavno svetlo, nautika + Sporedno svetlo, nautika + Plutajuće svetlo, nautika + Svetlo plovila, nautika + Usidrenje + Vodena rampa + Obaveštenje, nautički + Sidrišni ankor + Radarski transponder, nautički + Radio stanica, nautički + Signalna stanica, saobraćaj + Signalna stanica, upozorenje + Prostor za manja plovila + Oznaka na vrhu, nautički + Stena, nautički + Olupina, nautički + Prolazna visina + Prolazna visina (zatvorena) + Prolazna visina (otvorena) + Prolazna širina + Vojni aerodrom + Vojno strelište + Nevarska vikipedija + Alzašanska vikipedija + Bišnuprijska vikipedija + Farsanska vikipedija + Frisk vikipedija + Malajalamska vikipedija + Nisko Saksonska vikipedija + Pidmonteska vikipedija + Varajska vikipedija + Minangkabuska vikipedija + Kazaška vikipedija + Južno Minska vikipedija + Malagasijska vikipedija + Javanska vikipedija + Kantonska vikipedija + Astur-Leoneze vikipedija + Tadžička vikipedija + Baškirska vikipedija + Škotska vikipedija + Čuvaška vikipedija + Lombardska vikipedija + Brumanska vikipedija + Jorubska vikipedija + Gudžaratska vikipedija + Saobraćajni stub + Biciklistička barijera + Motociklička barijera + Bus traka + Obrtna vrata pune visine + Bamp prolaz + Opšta barijera + Niska ograda + Rekonstrukcijski šut + Ulični blokovi + Konjski prolaz + Kapija sa rampom + Kapija na utvrđenju + Rotaciona kapija + Obrtna vrata + Kapija za kočije + Međunarodni biciklistički mrežni čvor + Nacionalni biciklistički mrežni čvor + Regionalni biciklistički mrežni čvor + Lokalni biciklistički mrežni čvor + Međunarodni planinarski mrežni čvor + Nacionalni planinarski mrežni čvor + Regionalni planinarski mrežni čvor + Lokalni planinarski mrežni čvor + Međunarodna planinarska ruta + Nacionalna planinarska ruta + Regionalna planinarska ruta + Lokalna planinarska ruta + Referenca planinarske rute + Kolekcioni periodi + Dozvoljen pristup + Sadržaj: silosni + Sadržaj: balegna zemlja + Sadržaj: balega + Sadržaj: stočna hrana + Sadržaj: zob + Uobičajeno + Građevinska roba + Vodovodna roba + Drvena roba + Poljoprivredna roba + Roba pločica + Sidrište za bicikle + Juniciklno sidrište + Okvirno sidrište + Okasto sidrište + Igličasto + Bezlisno + Na snazi: međurastojanje + Na snazi: kontrola + Na snazi: pravo pristupa + Slepa ulica + Javna česma + Putokaz + HGV putarina + Bez površne obloge + Uslužni prostor + Pružni prelaz u nivou + Zajednički prostor odmora + Vres + Travnata zemlja + Žbun + Zemlja farme + Seča drveta + Opalo voće + Prolazno mesto + RTSA skala + Ruralni deo + Girokartica + PIKEPASS se ne prihvata + PIKEPASS (namenjeno) + Viza debitne kartice + Viza debitne kartice se ne prihvataju + Kriptovalute se ne prihvataju + Drugi metodi + Drugi metodi plaćanja se ne prihvataju + Routex da + Routex krtice goriva se ne prihvataju + Bancomat da + Bancomat se ne prihvata + IC Stored Fare - da + Vajer transferi + Vajer transferi se ne prihvataju + Mesta događaja + Košer ishrana: ne + Halal + Halal samo + Halal + Halal ishrana: ne + Bez laktoze + Bez laktoze samo + Bez laktoze + Bez laktoze ishrana: ne + Peskoterijan + Da + Ulazak kolima: ne + Da + Prolazak kroz: ne + Ime pivare + Da + Ne mikropivara + Da + Za poneti + Ne za poneti + Samo za poneti + Da + Dostava + Bez dostave + Samo dostava + Da + Sedenje napolju: da + Bez sedenja napolju + Sedenje napolju: tarasa + Sedenje napolju: trotoar + Sedenje napolju: pešačka zona + Sedenje napolju: bašta + Sedenje napolju: interno dvorište + Da + Sekond hend roba + Bez sekond hend robe + Samo sekond hend roba + Delovi + Diler + Popravka + Bez popravke + Popravka električnih vozila + Popravka motora + Da + Ne + Da + Ne automatski + Puna usluga + Da + Bez četkica: ne + Ne + Javno kupatilo + Muškarci + Zabranjeno za muškarce + Žene + Zabranjeno za žene + Unutar + Spolja + Da + Bez toaleta + Pristup toaletu za invalidska kolica: da + Pristup toaletu za invalidska kolica: ne + Pristup toaletu: kupci + Pristup toaletu: dopušten + Pristup toaletu: zajednički + Pristup toaletu: javni + Preuzimanje paketa i dopremanje pošte + Bicikl ventili + Preuzimanje paketa + Poštanska dostava paketa + Plavi memorijal + Džizo + Dimenzioni kamen + Pribor za prvu pomoć + Javne vage + Auto zaustavno mesto + Otvorena nešumovita močvara + Zatvorena nešumovita močvara + Solana + Plimski deo + Plimska močvara + Prugasta močvara + Močvarna poljana + Palsa močvara + Kameniti nasip + Kamenita + Dimnjak + Palma + Čempres + Stub zastave + Da + Bez klupe + Sa korpom + Bez korpe + Javni prevoz + Piknik + Vreme + Nadstrešnica + Prosta koliba + Zgrada + Posmatračka koliba + Kamenito sklonište + Sklonište od sunca + Poljsko sklonište + Tip skloništa: šator + Tip skloništa: napušteno + Vaj-Faj + Terminal + Kablovski + Tip pristupa internetu: javni + Tip pristupa internetu: uslužni + Bez pristupa internetu + Sa pristupom internetu + Maksimalna širina + IATA kod + ICAO kod + FAA kod + Tip dela: skulptura + Tip dela: statua + Tip dela: mural + Tip dela: arihitektura + Tip dela: slika + Tip dela: kameno + Tip dela: bista + Tip dela: instalacia + Tip dela: mozaik + Tip dela: reljef + Tip dela: grafiti + Tip dela: spomenik + Tip dela: fontana + Širina + Arhitekta + Arhitektura: moderna + Arhitektura: staljinistički neoklasicizam + Arhitektura: eklektična + Arhitektura: nova objektivnost + Arhitektura: savremena + Arhitektura: konstruktivizam + Arhitektura: okolna + Arhitektura: okvirna drvetom + Arhitektura: nova umetnost + Arhitektura: neoklasicizam + Arhitektura: viktorijanska + Arhitektura: brutalizam + Arhitektura: klasicizam + Arhitektura: gotska + Arhitektura: staroruska + Arhitektura: barokna + Arhitektura: postkonstruktivizam + Arhitektura: vilhelminski stil + Arhitektura: renesansna + Arhitektura: romanska + Vodeni tunel + Tunel putnički + Pešački tunel + Tunel železnički + Most putnički + Most za pešake + Most biciklistički + Most železnički + Most vodenog puta + Struktura mosta: pravi + Struktura mosta: prosta suspenzija + Struktura mosta: suspenzija + Struktura mosta: lučni + Struktura mosta: vezana + Struktura mosta: plutajuća + Struktura mosta: grbava + Struktura mosta: kablo-stojeći + Struktura mosta: šetačka + Struktura mosta: prosto drvena + Struktura mosta: vijadukt + Struktura mosta: akvadukt + Struktura mosta: brvnasta + Tip mosta: pokretan + Tip pokretnog mosta: baskul + Tip pokretnog mosta: okretni + Tip pokretnog mosta: vertikalni + Tip pokretnog mosta: lančani + Tip pokretnog mosta: potopljujući + Tip pokretnog mosta: transporter + Tip pokretnog mosta: uvučeći + Osvetljena: da + Osvetljena: ne + Površina: nepopločana + Površina: popločana + Površina: asfalt + Površina: betonska + Površina: razređena kaldrma + Površina: okrugla kaldrma + Površina: obrađena kocka + Površina: okrugla rizla + Površina: kamena + Površina: metalna + Površina: drvena + Površina: rizlana + Površina: fino rizlana + Površina: kompaktovana + Površina: pesak + Površina: trava + Površina: šuplja kaldrma + Površina: opšta + Površina: zemlja + Površina: blato + Površina: led + Površina: so + Površina: sneg + Autobus + Deljeni taksi + Trolejbus + Tramvaj + Voz + Laka pruga + Monopruga + Uspenska železnica + Trajekt + Metro + Ruta pruge + Istorijski objekat + Nadzor: da + Sa prodavnicom + Maloprodaja + Maloprodaja bicikla: ne + Popravka + Popravka bicikla: ne + Iznajmljivanje + Iznajmljivanje bicikla: ne + Pumpa + Bicikl pumpa: ne + Alati za samopopravku + Alati za samopopravku bicikla: ne + Čišćenje + Čišćenje bicikla: ne + Alat lanca + Alat lanca za bicikl: ne + Maloprodaja polovnih bicikla + Maloprodaja polovnih bicikla: ne + Naplata: da + Naplata: ne + Stanica za popravku bicikala;Stanica za samo-popravku bicikala + Mesto pogleda divljeg sveta + Trening: jezik + Trening: muzika + Trening: igranje + Trening: sport + Trening: umetnost + Trening: kuvanje + Trening: računar + Trening: joga + Trening: borilačke veštine + Trening: avijacija + Trening: šišanje + Monumentalni objekat + Tip: naftna industrija + Tip: mesto izvora + Tip: fabrika + Tip: industrija gasa + Tip: drvnoprerađivačka + Tip: rafinerija + Tip: skladište + Tip: auto otpad + Tip: poljoprivreda + Tip: pivara + Tip: ciglana + Tip: međumodalni teretni terminal + Tip: pilana + Tip: prečišćenje vode + Tip: luka + Tip: depo + Beleška + Voda za životinje + Hotel za životinje + Tip hotela za životinje: pas + Tip hotela za životinje: mačka + Tip hotela za životinje: pas, mačka + Tip hotela za životinje: konj + Istorijski avion + Sa liftom + Bez lifta + Tehnički spomenik + Kamp kancelarija + Model aerodroma + Kancelarija vodiča + KANVO + Savetodavna kancelarija + Kooperativna kancelarija + Šumarska kancelarija + Kancelarija logistike + Parohijska kancelarija + Izdavačka kancelarija + 91UL gorivo + 100LL gorivo + Autogas + Avionsko A-1 gorivo + Aditiv dizel gasova + Gorivo: drvo + Gorivo: ćumur + Gorivo: ugalj + Ulična lampa + Zaustavna traka + Nadzor: unutrašnji + Nadzor: spoljašnji + Nadzor: javni + Žene + Donji veš + Muškarci + Venčanice + Sportovi + Bebe + Teksas + Radna odela + Šeširi + Krzno + Koža + Kostimi + Tradicionalno + Odela + Porodiljska + Staromodna + Veći brojevi + Školska + Plivačka + Čarape + Košulje + Plesačka + Vojna + Istorijska prekretnica + Dečja + Ženska + Sportska + Muška + Ortopedska + Istorijski posed + Tip dvorca: izražajan + Tip dvorca: odbranbeni + Tip dvorca: tvrđava + Tip dvorca: palata + Tip dvorca: kremlj + Tip dvorca: odbranbeni, izražajan + Tip dvorca: utvrđenje + Tip dvorca: širo + Tajlandska + Seksualna + Kineska + Terapeutska + Usluge masaže + Usluge saune + Usluge solarijuma + Dopušteno + Šatori nisu dozvoljeni + Otvorena vatra dozvoljena + Otvorena vatra nedozvoljena + Da + Ne + Da + Izviđački kamp: ne + Grupno samo: da + Grupno samo: ne + Da + Veš mašina: ne + Da + Karavani: ne + Improvizovano: da + Improvizovano: ne + Sanitarna otpadna stanica: da + Sanitarna otpadna stanica: ne + Izvor napajanja: ne + Izvor napajanja (utičnica): CEE 17 plava + Izvor napajanja (utičnica): CEE 7/4 + Izvor napajanja (utičnica): CEE 7/5 + Izvor napajanja (utičnica): NEMA 5-15 + Maksimalni broj šatora + Maksimalni broj karavana + Dozvoljeno za pse + Nije dozvoljeno za pse + Objekti za izbeglice + Izbeglice: ne + Grupno mesto + Usluga zbrinjavanja + Nerezidentno zbrinjavanje + Javna kuhinja + Sklonište + Ambulantna pomoć + Radionica + Dnevna nega + Starije osobe + Deca + Siročad + Osobe sa invaliditetom + Mentalno bolesni pacijenti + Maloletnici + Beskućnici + Migranti + Maloprivilegovani + Narkozavisnici + Nezaposleni + Bolesni + Mlađi maloletnici + Filharmonija + Muzikal + Drama + Opera + Kabare + Lutkarstvo + Komedija + Kamerna muzika + Marionetski + Balet + Predstava senki + Poligonalna bina + Zatvoreni lonac + Proizvod: cigla + Proizvod: negašen kreč + Proizvod: koža + Proizvod: kreč + Proizvod: pivo + Proizvod: ćumur + Proizvod: meso + Opis za korisnike invalidskih kolica + Opis za slepe + Opis za gluve + Stepenice + Rukohvat: da + Rukohvat: ne + Rampa: da + Rampa: ne + Rampa za invalidska kolica: da + Rampa za invalidska kolica: ne + Rampa (sa stepenicama): da + Rampa (sa stepenicama): ne + Rampa za bicikle: da + Rampa za bicikle: ne + Rampa za prtljag: da + Rampa za prtljag: ne + Broj stepenika + Stanje stepenika: isto + Stanje stepenika: različito + Stanje stepenika: grubo + Gomila kamenja + Defibrilator + Defibrilator: da + Tip: ratno groblje + Tip: humka + Tip: u steni + Tip: podzemna + Tip: komora + Tip: kolumbarijum + Tip: mauzolej + Tip: sarkofag + Tip: kripta + Tip: piramida + Civilizacija: starorimska (753.g. pre.H - 284.g. posl.H) + Civilizacija: nuragska (18. v.pre.H - 2. v.posl.H) + Civilizacija: etrurska (12. v. - 6. v.posl.H) + Civilizacija: praistorijska + Civilizacija: starogrčka + Civilizacija: rimska + Civilizacija: vizantijska (285.g. posl.H - 1453.g. posl.H) + Civilizacija: imperijalnokineska (221.g. pre.H - 1911.g. posl.H) + Civilizacija: staroegipadska (do 332.g. pre.H) + Civilizacija: keltska + Civilizacija: zapadnorimska (285.g. posl.H - 476.g. posl.H) + Civilizacija: mikenska + Civilizacija: dačanska + Civilizacija: hernička + Civilizacija: grčko egipadska (332.g. pre.H - 30.g. pre.H) + Civilizacija: rimsko i vizantijsko egipadska + Civilizacija: eladska + Civilizacija: cikladska + Civilizacija: minonska + Civilizacija: tiahunakotska + Trening životinja + Pas + Konj + Dozvoljeno konjima + Nedozvoljeno konjima + Dozvoljeno životinjama + Nedozvoljeno životinjama + Istorijski period: nuragski + Istorijski period: kameno doba / bronzano doba (neodređeno) + Istorijski period: bronzano doba + Istorijski period: principat (27.g. pre.H - 284.g. posl.H) + Istorijski period: klasično grčki (5.v. - 4.v. pre.H) + Istorijski period: arhaično grčki + Istorijski period: gvozdeno doba + Istorijski period: Rimska republika (508.g. pre.H - 27.g. pre.H) + Istorijski period: helensko grčki + Istorijski period: novo carstvo (1550 - 1069 pre.H) + Istorijski period: srednje carstvo (2055 - 1650 pre.H) + Istorijski period: predinastijsko egipadski + Istorijski period: rano dinastijski period (3100 - 2686 pre.H) + Istorijski period: staro carstvo (2686 - 2181 pre.H) + Istorijski period: prvi međuperiod (2181 - 2055 pre.H) + Istorijski period: drugi međuperiod (1650 - 1550 pre.H) + Istorijski period: treći međuperiod (1069 - 664 pre.H) + Istorijski period: prvi persijski period + Istorijski period: kasni period (664 - 332 pre.H) + Istorijski period: drugi persijski period + Istorijski period: Aleksandra Velikog + Istorijski period: ptolomejsko egipadski (305 pre.H - 30 pre.H) + Istorijski period: hrišćansko egipadski + Istorijski period: vizantijsko egipadski (30 pre.H - 641 posl.H) + Istorijski period: persijska okupacija + Istorijski period: Grčki Srednji Vek (1100 - 800 pre.H) + Istorijski period: Rimsko Grčki (146 pre.H - 330 posl.H) + Istorijski period: Rimsko carstvo (753.g. pre.H - 509.g. pre.H) + Istorijski period: dominirajući (285.g. posl.H - 476.g. posl.H) + Istorijski period: seljački (epoha 1., 2., 1580 pre.H - 133 posl.H) + Istorijski period: urbanski (epoha 3., 133 posl.H - 374 posl.H) + Istorijski period: klasični (epoha 4., 374 posl.H - 900 posl.H) + Istorijski period: iperijalni (epoha 5., 900 posl.H - 1200 posl.H) + Istorijska epoha: paleolitska (2,6 miliona god. - 10000 BP) + Istorijska epoha: mezolitska + Istorijska epoha: neolitska + Istorijska epoha: bakarno doba (4. - 3. milenijum pre.H) + Istorijski kamen + Tip: krst pomirenja + Tip: grb + ATM + Materijal: drvo + Materijal: metal + Materijal: ojačani beton + Materijal: beton + Materijal: čelik + Materijal: kamen + Materijal: zidarski + Materijal: cigla + Materijal: plastika + Materijal: kameni pesak + Materijal: granitni kamen + Materijal: metal, drvo + Materijal: staklo + Materijal: bronza + Materijal: zemlja + Materijal: kompozit + Materijal: krečnjak + Materijal: mermer + Materijal: aluminijum + Megalit + Humka + Utvrđenje + Naselje + Velegrad + Krug kućišta + Petroglif + Zemljana barijera + Vojni aerodrom + Vojni/civilni + Teretana na otvorenom + Biohemija + Teretana + Fitnes + Da + Tip kuhinje + Pice + Pljeskavice + Kafa + Sendviči + Kebab + Doner kebab (šavurma) + Piletina + Sladoled + Suši + Plodovi mora + Roštilj + Nudle + Krofne + Ramen + Palačinke + Doručak + Šnicle + Tapas + Kari + Gril + Večera + Kobasice + Torte + Američke palačinke + Testenine + Brza hrana + Sokovi + Čaj + Prodavnica čaja + Supe + Pite + Hotdog + Salate + Pržena hrana + Bistro + Pekara + Kuskus + Pržena piletina + Dezerti + Takosi + Falafel + Smuti + Suvlaki + Jogurt + Giros + Palačinke + Jakiniku + Suki + Udon + Jakotori + Meso + Krilca + Vafle + Čokolada + Vino + Krompir + Branč + Pita + Fandu + Bageti + Buritosi + Terijaki + Šavurma + Regionalna + Italijanska + Kineska + Meksička + Japanska + Nemačka + Indijska + Američka + Azijska + Francuska + Grčka + Tajlandska + Internacionalna + Turska + Španska + Vijetnamska + Korejska + Mediteranska + Bavarska + Libanska + Ruska + Filipinska + Portugalska + Gruzijska + Poljska + Brazilska + Arapska + Danska + Indonežanska + Afrička + Karipska + Argentinska + Balkanska + Peruanska + Hrvatska + Bolivijska + Malagaška + Persijska + Marokanska + Austrijska + Malezijska + Irska + Etiopijska + Mađarska + Laoska + Evropska + Uzbekistanska + Češka + Kubanska + Britanska + Latinoamerička + Nepalska + Mongolska + Bliskoistočna + Ukrajinska + Avganistanska + Belgijska + Baskijska + Švajcarska + Švedska + Jamajčanska + Jermenska + Havajska + Engleska + Pakistanska + Tajvanska + Teks-meks + Holandska + Sirijska + Australijanska + Kadžun + Egipatska + Senegalska + Jevrejska + Bugarska + Tibetanska + Barometar + Barometar: ne + Roštilj: da + Prodavnica na veliko + Knjige + Park i vožnja + Da + Pristup vozilima za sneg + Komunalni + Porodični + Za više porodica + Tip + Pristup autobusu + Pristup karavanu + Pristup prikolici + Pristup motociklima + Pristup mopedu + HGV pristup + Pristup vozilima za laku robu + Pristup za osobe sa invaliditetom + Pristup vozilom: da + Pristup vozilom: privatni + Pristup vozilom: ne + Pristup vozilom: samo do odredišta + Pristup vozilom: odobren + Pristup vozilom: za mušterije + Pristup vozilom: vojni + Pristup vozilom: dostava + Pristup vozilom: šumski saobraćaj + Pristup motornim autom: da + Pristup motornim autom: privatni + Pristup motornim autom: ne + Pristup motornim autom: samo do odredišta + Pristup motornim autom: odobren + Pristup motornim autom: za mušterije + Pristup motornim autom: šumski saobraćaj + Pristup motornim vozilom: da + Pristup motornim vozilom: privatni + Pristup motornim vozilom: ne + Pristup motornim vozilom: samo do odredišta + Pristup motornim vozilom: odobren + Pristup motornim vozilom: za mušterije + Pristup motornim vozilom: vojni + Pristup motornim vozilom: dostava + Pristup motornim vozilom: šumski saobraćaj + Pristup motornim vozilom: poljoprivredni + HGV pristup: privatni + HGV pristup: ne + HGV pristup: poljoprivredni + HGV pristup: nepreporučen + HGV pristup: nepogodno + Pristup za laka dostavna vozila: ne + Pristup za motocikle: privatni + Pristup za motocikle: ne + Pristup za mopede: ne + Pristup za bicikle: privatni + Pristup za bicikle: samo uz guranje bicikle + Pristup za bicikle: samo do odredišta + Pristup za bicikle: odobren + Pristup za bicikle: za mušterije + Pristup konjem: privatni + Pristup konjem: samo do odredišta + Pristup konjem: odobren + Pristup konjem: šumski + Pristup za pešake: da + Pristup za pešake: privatni + Pristup za pešake: ne + Pristup za pešake: samo do odredišta + Pristup za pešake: odobren + Pristup za pešake: za mušterije + Pristup za karavan: ne + Pristup za prikolice: ne + Pristup za autobuse: ne + Pristup za turističke autobuse: da + Pristup za turističke autobuse: namenjen + Pristup za turističke autobuse: ne + Ski pristup: da + Ski pristup: ne + Pristup za snoumobil: privatni + Pristup za snoumobil: ne + Pristup za poljoprivredna vozila: da + Pristup za poljoprivredna vozila: ne + Pristup za taksi: da + Pristup za taksi: namenjen + Pristup za taksi: ne + Pristup za invalide: ne + Tip megalita: menhir + Tip megalita: dolmen + Tip megalita: nuragi + Tip megalita: kameni krugovi + Tip megalita: koridorna grobnica + Tip utvrđenja: gradina + Tip utvrđenja: limes + Tip utvrđenja: šanac + Tip utvrđenja: ukopani kružni šanac + Pa (maorska utvrđena naseobina) + Istorijsko imanje + Istorijska železnička stanica + Istorijsko gumno + Istorijska vešala + Istorijske šine + Trg + Umetnik + Vajar + Tip zgrade: crkva + Tip zgrade: kapela + Tip zgrade: džamija + Tip zgrade: hram + Tip zgrade: katedrala + Tip zgrade: manastir + Tip zgrade: bazilika + Tip zgrade: sinagoga + Tip zgrade: svetilište + Krst + Krst na vrhu: da + Bivši zatvorenički logor + Tip: koncentracioni logor + Tip: zarobljenički logor + Tip: radni logor + Tip: nacistički + Tip: gulag + Temperatura + Kupanje: da + Kupanje: ne + Skladište za brodove + Pokretno: da + Putnici + Vozila + Bicikli + Kontejneri + HGV + Hakerski prostor + Servis za elektroniku + Prodavnica vatrometa + Dužina + Opšta praksa + Oftamologija + Ginekologija + Interno + Ortopedija + Otorinolaringologija + Pedijatrija + Medicinska specijalizacija: pedijatrija: ne + Dermatologija + Urologija + Opšta hirurgija + Radiologija + Psihijatrija + Neurologija + Kardiologija + Traumatologija + Klinička biologija + Osteopatija + Anesteziologija + Pulmologija + Zubna, oralna i maksilofacijalna hirurgija + Porodiljsko + Urgentna medicina + Medicinska specijalizacija: urgentna medicina: ne + Plastična hirurgija + Fizioterapija + Okupaciona terapija + Dečija psihijatrija + Fizikalna medicina i rehabilitacija + Maksilofacijalna hirurgija + Medicinsko snimanje + Gastroenterologija + Stomatologija + Nefrologija (renalne bolesti) + Neurohirurgija + Neuropsihijatrija + Endokrinologija + Nuklearna medicija + Patologija + Onkologija + Tropska medicina + Medicinska specijalizacija: tropska medicina: ne + Akušerstvo (postnatalno) + Medicinska specijalizacija: akušerstvo (postnatalno): ne + Akušerstvo (prenatalno) + Medicinska specijalizacija: akušerstvo (prenatalno): ne + Društvena pedijatrija + Medicinska specijalizacija: društvena pedijatrija: ne + Akušerstvo (carski rez) + Medicinska specijalizacija: akušerstvo (carski rez): ne + Lečenje bolesti zavisnosti + Optometrija + Klinička patologija + Logoped + Sportska masaža + Sportska medicina + Akupunktura + Homeopatija + Tradicionalna kineska medicina + Reiki + Travarstvo + Kiropraktičar + Naturopatija + Dubinska psihologija + Bihejvioralna terapija + Palijativna medicina + Tip zgrade: piramida + Bilijar + Mikrotalasna: da + Mikrotalasna: ne + Grejač za vodu: da + Grejač za vodu: ne + Tip: podloga + Garaže + Natkrivena + Dodžo + Galske igre + Trčanje + Karting + Badmington + Džudo + Futsal + Trkanje kolima na daljinsko upravljanje + Skvoš + Lakros + Boks + Zvanično ime + Dajk + Delfin + Denotacija + Kategorija težine + Radioterapija + Reddit + Istorijski rezervoar + Izvor energije: biomasa + Podizanje novca + Tip + Na otvorenom + Poljoprivredna radnja + Tip: poljoprivredno + Pritisak + Video + SMS + Status + Tip + Tip eksplozije: kraterska rasprskavanja (tik ispod površine) + Kratko ime (engl.) + Niz eksplozija + Vreme eksplozije (UTC) + Tip eksplozije: podvodna + Tip eksplozije: svemir (preko 80km nadmorske visine) + Tip eksplozije: u atmosferi, raketa ili projektil + Tip eksplozije: podzemna + Tip eksplozije: u atmosferi, vodena podloga, barža + Tip eksplozije: u atmosferi, podloga + Tip eksplozije: u atmosferi, balon + Tip eksplozije: u atmosferi, podloga, toranj + Tip eksplozije: u atmosferi, kapljice + Tip eksplozije: u atmosferi + Tip eksplozije: podzemna, tunel + Tip eksplozije: podzemna, jama + Eksplozija: mesto + Eksplozija: država + Objekat pod zaštitom: voda + Objekat pod zaštitom: naselje + Objekat pod zaštitom: priroda + Objekat pod zaštitom: istorijski + Naslov zaštite + Zaštićena oblast + Mesto za vatru + U izgradnji + Ref. + Ref. tunela + Ref. mosta + Akademske + Dečije + Religijske + Antikvarnica + Strip + Sveska + Tip: polica + Jačina udarnog talasa + Nulti nivo nadmorske visine + Visina vatrene lopte + Krater eksplozije + Snaga eksplozije + Vreme eksplozije (UTC) + Svrha eksplozije: industrijska primena, pomeranje zemlje + Svrha eksplozije: industrijska primjena + Svrha eksplozije: industrijska primena, stimulacija nafte + Svrha eksplozije: industrijska primena, seizmičko ozvučavanje + Svrha eksplozije: industrijska primena, iskopavanje šupljina + Svrha eksplozije: fundamentalna nauka + Svrha eksplozije: istraživanje za mirnodopske primene + Svrha eksplozije: bezbednosni eksperiment + Svrha eksplozije: efekti oružja + Svrha eksplozije: povezano sa nuklearnim oružijem + Bendi + Samo proizvodi sajamske trgovine + Sajamska trgovina: ne + Sajamska trgovina: da + Ulični orman + ATM: ne + ATM: da + Natpis:NE + Natpis:E + Natpis:SE + Natpis:S + Natpis:SW + Natpis:W + Natpis:NW + Natpis:N + Pokazivač: šumarsko odeljenje + Pokazivač: šumarsko odeljenje + Disk golf + Psihijatrija za odrasle + Podologija + Ortodonija + Dermato-venereologija + Strelica + Vibracija + Mofa pristup + Pristup motociklima + Stena penjanja + Savetovanje (bračno): ne + Savetovanje (bračno): da + Savetovanje (imigrant): ne + Savetovanje (imigrant): da + Savetovanje (beskućno): ne + Savetovanje (beskućno): da + Savetovanje (porodično): ne + Savetovanje (porodično): da + Savetovanje (obrazovanje): ne + Savetovanje (obrazovanje): da + Savetovanje (oko droga): ne + Savetovanje (oko droga): da + Savetovanje (krizno): ne + Savetovanje (krizno): da + Savetovanje (za parove): ne + Savetovanje (za parove): da + Savetovanje (smernice za dete): ne + Savetovanje (smernice za dete): da + Savetovanje (prenatalno): ne + Savetovanje (prenatalno): da + Savetovanje (zavisnost): ne + Savetovanje (zavisnost): da + Uloga zdravstvenog radnika: veštak + Uloga zdravstvenog radnika: tehničar + Uloga zdravstvenog radnika: pomoćnik lekara + Uloga zdravstvenog radnika: terapeut + Uloga zdravstvenog radnika: psiholog + Uloga zdravstvenog radnika: podolog + Uloga zdravstvenog radnika: lekar + Uloga zdravstvenog radnika: bolničar + Uloga zdravstvenog radnika: medicinska sestra + Uloga zdravstvenog radnika: babica + Uloga zdravstvenog radnika: iscelitelj + Uloga zdravstvenog radnika: asistent + Zid + Pond + Suvo bure + Stub + Podzemni + Tačka usisavanja + Tip zdravstvene ustanove: dom grupe za podršku + Tip zdravstvene ustanove: starački dom + Tip zdravstvene ustanove: prva pomoć + Tip zdravstvene ustanove: ambulanta + Tip zdravstvene ustanove: odeljenje + Tip zdravstvene ustanove: terapija + Tip zdravstvene ustanove: laboratorija + Tip zdravstvene ustanove: savetovalište + Tip zdravstvene ustanove: terenska bolnica + Medicinska kancelarija + Zdravstvena usluga: test: ne + Zdravstvena služba: test: da + Zdravstvena služba: podrška: ne + Zdravstvena služba: podrška: da + Zdravstvena služba: vakcinacija: ne + Zdravstvena služba: vakcinacija: da + Zdravstvena služba: prevencija: ne + Zdravstvena služba: prevencija: da + Zdravstvena usluga: dečje odeljenje: ne + Zdravstvena usluga: dečje odeljenje: da + Zdravstvena služba: pregled: ne + Zdravstvena služba: pregled: da + Zdravstvena služba: savetovanje: ne + Zdravstvena služba: savetovanje: da + Zdravstvena služba: porodilište: ne + Zdravstvena služba: porodilište: da + Unani + Sida + Tradicionalno Tibetanski + Tradicionalno mongolski + Kampo + Ajurveda + Tradicionalno Kineski + Zapadni + Sanitarna otpadna stanica + Solarijum + Smernice za goste: ne + Smernice za goste: da + Orijentacija mesta slobodnog letenja: Z + Orijentacija mesta slobodnog letenja: JZ + Nema vreme leta (slobodno letenje) + Orijentacija mesta slobodnog letenja: SZ + Orijentacija mesta slobodnog letenja: J + Orijentacija mesta slobodnog letenja: JI + Orijentacija mesta slobodnog letenja: I + Orijentacija mesta slobodnog letenja: SI + Orijentacija mesta slobodnog letenja: S + Slobodno letenje kruto: ne + Kruta + Zmajarstvo: ne + Zmajarstvo + Paraglajding: ne + Paraglajding + Zvanično: ne + Zvanično: da + Obuka + Vuča + Sletanje na vrhu + Sletanje + Poletanje + Upravljano dugmetom: ne + Upravljano dugmetom: da + Slavina za vodu + Slobodno letenje (sport) + Usisivač + Usisavač: ne + Da + Komprimovani vazduh: ne + Da + Rasadnik biljaka + Ime kuće + Eksplozija: uređaj + Eksplozija: bojeva glava + Eksplozija: prečnik kratera + Plotun eksplozija: druga ili kasnija detonacija plotun testa + Plotun eksplozija: prva detonacija plotun testa + Kuglanje + Mreža + Prodaja: polovna + Prodaja: da, polovna + Prodaja: ne + Prodaja + Štandovi + Reptili + Sokolarnik + Ptičnik + Ptice + Safari park + Kućište + Park divljih životinja + Zoološki vrt sa maženjem životinja + Životni prsten + Škola stranih jezika + Muzička škola + Dečiji kamp + Popravka elektronike: TV + Popravka elektronike: telefon + Popravka elektronike: aparati + Popravka elektronike: računari + Kancelarija snabdevača energije + Vino: servirano + Vino: maloprodaja + Vino: da + Da + Zajednički radni prostor + Teretna stanica + Konstrukcija: skrivena + Konstrukcija: kupola + Konstrukcija: tanjir + Konstrukcija: samostojeća + Konstrukcija: rešetka + Tip: otvorena štala + Bušenšank + Zatvoreno + Otvoreno + Vidljivost: područje + Vidljivost: ulica + Vidljivost: kuća + Lokacija: ulaz + Lokacija: zid + Lokacija: most + Lokacija: platforma + Lokacija: unutar + Lokacija: napolju + Lokacija: vrh krova + Lokacija: krov + Lokacija: iznad glave + Lokacija: nadzemlje + Lokacija: podvodna + Lokacija: podzemna + Metalna mreža + Dekotrava + Veštačka trava + Tartan + Glina + Planinsko područje + Kuluar + Klisura + VHF kanal + Zakonodavna institucija + Transportna institucija + Blagajna + Socijalne usluge + Socijalno osiguranje + Javni servis + Ministarstvo + Arhiva + Mreža + Kanu: ne + Kanu: da + Kajaci: ne + Kajaci: da + Gumenjak: ne + Gumenjak: da + Jedrenjaci: ne + Jedrenjaci: da + Džetski: ne + Džetski: da + Brodovi na veslanje: ne + Brodovi na veslanje: da + Kućni brodovi: ne + Kućni brodovi: da + Motorni brodovi: ne + Motorni brodovi: da + Tip: ograđen deo + Čuvanje životinja: ovca + Čuvanje životinja: konj + Čuvanje životinja + Litica + Foto studio + Dodaci ishrani + Lokomotiva + Prodavnica elektronskih cigareta + Bingo + Klađenje + Slot mašine + Pacinko + Lutrija + Vrsta + Mesto kockanja + Loto srećke + Oprema za rasvetu + Bravarska prodavnica + Elektro prodavnica + Namirnice za zabavu + Mesto za ishranu životinja + Kantonska + Pastel + Sub + Sagardotegia + Čaj sa mehurićima + Braseri + Empanada + Predjelo + Piadina + Kantina + Slane palačinke + Zamrznuti jogurt + Delikatesi + Fina jela + Soba + Bagel + Heuriger + Gastropub + Giudon + Riba i pomfrit + Tip: metalni orman + Tip: drveni ormar + Tip: kutija za čitanje + Tip: telefonska kutija + Javna polica za knjige + Božić: vebsajt + Božić: lokacija + Božić: radno vreme + Božić: beleška + Božić: period događaja + Jelka + Prodavnica drveća + Božićna radnja + Božićna piramida + Božićno tržište + Božićni događaj + Božić + Vikipedija + Dužina + Odlaganje toaleta: kantom + Odlaganje toaleta: hemijsko + Odlaganje toaleta: pitlatrine + Odlaganje toaleta: ispiranje + Rezervoar za vodu + Protivpožarni operator + Visoka komisija + Rezidencija ambasadora + Delegacija + Stalna misija + Počasni konzulat + Generalni konzulat + Konzulat + Saobraćajno ogledalo + Jedino + Ne + Da + Minimalna starost + Glavni distribucioni okvir + Akvakultura: dagnje + Akvakultura: riba + Akvakultura: škampi + Akvakultura + Prikaz informacija putnicima: ne + Prikaz informacija putnicima: da + Podrška: kula + Podrška: krov + Podrška: noseće + Podrška: plafon + Podrška: bilbord + Podrška: zemlja + Podrška: postolje + Podrška: drvo + Podrška: zid + Podrška: stub + Prikaz datuma: ne + Prikaz datuma + Higrometar: ne + Kapacitet (kreveta) + HigrometarHygrometer + Termometar: ne + Termometar + Sunčani sat + Digitalni ekran + Analogni ekran + Pumpna stanica + Ekran: ne + Ekran: da + Izlaz: biogas + Izlazna snaga biogasa + Izlaz: vakuum + Izlaz: komprimovani vazduh + Izlaz: hladna voda + Izlaz: vruć vazduh + Izlaz: para + Izlaz: topla voda + Izlaz (struja): ne + Izlaz: struja + Napon + Staklenička hortikultura + Gravitaciona + Meteorološka + Upotreba: špijunaža + Upotreba: istraživanje + Upotreba: špijunaža + Upotreba: obrazovanje + Spektar + Prečnik + Gama + Radio + Optički + Teleskop + Kartica \"Trojka\" se ne prihvata + Trojka + Status pumpe: zaključana + Status pumpe: polomljena + Status pumpe: u redu + Stil pumpe: istorijski + Stil pumpe: moderan + Tip pumpe: gravitaciona + Tip pumpe: Indija Mk II ili III> + Tip pumpe: pumpa snopa + Ventilacioni otvor + Balka + Privatni + Javni + Regionalni + Međunarodni + Isporuka: ne + Da + Nadzor prelaza: kamera + Nadzor prelaza: polaznik + Nadzor prelaza: ne + Nadzor prelaza + Prelazni saltir: ne + Prelazni saltir + Prelaz na zahtev: ne + Prelaz na zahtev + Prelazno svetlo: ne + Prelazno svetlo + Prelazno zvono: ne + Prelazno zvono + Prelazna barijera: duplo polovična + Prelazna barijera: polovična + Prelazna barijera: puna + Prelazna barijera + Prelazna barijera: ne + Aktiviranje prelaza: daljinsko + Aktiviranje prelaza: lokalno + Aktiviranje prelaza: automatsko + Rekreacioni centar + Letnji kamp + Pokvarena gomila + Određeno + So: ne + So + Dubina + Ulično postolje + Bicikl drvo + Ormarići + Vojni kontrolni punkt + Tip kabineta: ulična rasveta + Tip kabineta: vodovodni + Tip kabineta: otpadi + Tip kabineta: poštanski + Tip kabineta: gasni + Tip kabineta: kablovska televizija + Tip kabineta: telekomski + Tip kabineta: energetski + U upotrebi: da + Tok + Pond + Glavni + Stil hidranta: wsh + Podzemni + Ulica + Parking + Traka + Zelena + Trotoar + Kapacitet protoka hidranta + Broj hidranta + Pritisak hidranta + Prečnik hidranta + Kancelarija babice + Usluga nege + Kancelarija psihologa + Kancelarija iscelitelja + Kancelarija podologa + Kancelarija terapeuta + Lekarska ordinacija + SIDA: ne + SIDA: da + Autizam: ne + Autizam: da + Ebola: ne + Ebola: da + Malarija: ne + Malarija: da + Kućna poseta: ne + Da + Hitna: ne + Hitna: da + Savetovanje: ne + Savetovanje: da + Bolničke usluge: samo + Bolničke usluge: ne + Bolničke usluge: da + Predviđeno za dečake: ne + Predviđeno za dečake: da + Predviđeno za muškarce: ne + Predviđeno za muškarce: da + Predviđeno za devojke: ne + Predviđeno za devojke: da + Predviđeno za starije osobe: ne + Predviđeno za starije osobe: da + Predviđeno za žene: ne + Predviđeno za žene: da + Predviđeno za odrasle: ne + Predviđeno za odrasle: da + Predviđeno za decu: ne + Predviđeno za decu: da + Predviđeno za mališane: ne + Predviđeno za mališane: da + Predviđeno za novorođenčad: ne + Predviđeno za novorođenčad: da + Savetovanje (nasilje): ne + Savetovanje (nasilje): da + Savetovanje (žrtve): ne + Savetovanje (žrtve): da + Savetovanje (seksualno zlostavljanje): ne + Savetovanje (seksualno zlostavljanje): da + Savetovanje (seksualno): ne + Savetovanje (seksualno): da + Savetovanje (rehabilitacija): ne + Savetovanje (rehabilitacija): da + Savetovanje (ishrana): ne + Savetovanje (ishrana): da + Koralna obala + Donacija krvi + Medicinska laboratorija + Veleprodaja + Proizvodnja konditorskih proizvoda + Terensko prikupljanje + Uređaj inspekcije + Ventilski grupna + Ventilska + Merna + Kompresiona + Kompenzaciona + Pretvaračka + Vučna + Prelazna + Industrijska + Manja distribuciona + Distribuciona + Prenosna + Cevovodna podstanica + Jedino + Da + Popravka obuće + Brdo + Licencni časovi + Ruševine + Minsko polje + Opasnost od poplave + Klizav put + Opasnost od lavine + Opasnost od erozije + Nuklearna opasnost + Opasnost + Beskontaktno ne prihvata se + Beskontaktno + Izranjajuća stena + Prodavnica aparata + Krajnji datum + Stena + Kurs + Elektronski + Injektor + Kod + Tačka ureza + Pešačka kontrolna tačka + Prosečan nagib + Najniža tačka + Najviša tačka + Ledeni jezik + Ostatak + Plato + Stena + Ledopad + Viseći + Planinski + Plimski + Izlazni + Dolina + Plato + Ledeno polje + Ledena kapa + Težina + Broj kabla + Zaštićena ruta + Avantura penjanja + Zip linija + Gume + Osiguranje + Motor + Popravka transmisije + Reglaža + Prigušivač + Popravka kamiona + Staklo + Točkovi + Elektrika + Popravka karoserije + Klima uređaj + Baterije + Auto delovi + Dijagnostika + Prodaja novih automobila + Kočnice + Prodaja polovnih automobila + Promena ulja + Auto servis + Igrački centar za odrasle + Zabavna arkadna igra + Kancelarija za vodosnabdevanje + Mesto isporuke prodavnice + Ime rečnih brzaka + Keramika + Prodavnica podova + Nizak + Srednji + Visok + Nizak + Srednji + Visok + Nizak + Srednji + Visok + Nizak + Srednji + Visok + Nizak + Srednji + Visok + Nizak + Srednji + Visok + AS / NZS 3112 + BS 1363 + Šuko + NEMA 14-30 + NEMA 14-30 + NEMA 5-20 + NEMA 5-15R + Tesla Roudster + Tesla Superpunjač + Tesla standard + CHAdeMO + Tip 3 + Tip 2 kombo + Tip 2 + Tip 1 kombo + Tip 1 + CEE crvena 125A + CEE crvena 64A + CEE crvena 32A + CEE crvena 16A + CEE plava + Prodavnica kanabisa + Prodavnica čamaca + Prodavnica kamina + Zamrznuta hrana + Tip: pašnjak + Tip: trajna + Tip: prelazna + Prečnik krune + Obim + Penjačke rute + Brvno vrha penjanja: ne + Brvno vrha penjanja: da + Orijentacija zida: SZ + Orijentacija zida: Z + Orijentacija zida: JZ + Orijentacija zida: J + Orijentacija zida: JI + Orijentacija zida: I + Orijentacija zida: SI + Orijentacija zida: S + Fiksna sidra: ne + Fiksna sidra: da + Kvalitet penjanja: krh + Kvalitet penjanja: čvrst + Stena za penjanje: porfir + Stena za penjanje: gnais + Stena za penjanje: kvarcit + Stena za penjanje: peščenjak + Penjanje na kamen: granit + Stena za penjanje: krečnjak + Maksimalna dužina penjanja + Minimalna dužina penjanja + Dužina penjanja + Solo u dubljim vodama: ne + Solo u dubljim vodama: da + Mešovito: ne + Mešovito: da + Led: ne + Led: da + Rute na više tačaka: ne + Rute sa više tačaka: da + Tradicionalno: ne + Tradicionalno: da + Gornje uže: ne + Gornje uže: da + Balvaniranje: ne + Balvaniranje: da + Sport: ne + Sport: da + Poštanski broj + Transfer novca + Centar plaćanja + Stan + Kućni broj + Ulica + Kutija pisma + Depo + Stanica punjenje + Veličina mape: regija + Veličina mape: grad + Veličina mape: sajt + Tip mape: toposkopska + Tip mape: šema + Vrsta mape: ulična + Vrsta mape: topo + Izlaz stanice punjenja + Amperaža + Cena parkiranja + Cena parkiranja: ne + Cena parkiranja: da + Kamion: ne + Kamion: da + Skuter: ne + Skuter: da + Bicikl: ne + Bicikl: da + Automobil: ne + Automobil: da + Utičnica: AS / NZS 3112: izlaz + Utičnica: AS / NZS 3112: struja + Utičnica: AS / NZS 3112 + Utičnica: BS 1363: izlaz + Utičnica: BS 1363: struja + Utičnica: BS 1363 + Utičnica: Šuko: izlaz + Utičnica: Šuko: struja + Utičnica: Šuko + Utičnica: NEMA 14-50: izlaz + Utičnica: NEMA 14-50: struja + Utičnica: NEMA 14-50 + Utičnica: NEMA 14-30: izlaz + Utičnica: NEMA 14-30: struja + Utičnica: NEMA 14-30 + Utičnica: NEMA 5-20: izlaz + Utičnica: NEMA 5-20: struja + Utičnica: NEMA 5-20 + Utičnica: NEMA 5-15R: izlaz + Utičnica: NEMA 5-15R: struja + Utičnica: NEMA 5-15R + Utičnica: Tesla Roudster: izlaz + Utičnica: Tesla Roudster: struja + Utičnica: Tesla Roudster + Utičnica: Tesla superpunjač: izlaz + Utičnica: Tesla superpunjač: struja + Utičnica: Tesla superpunjač + Utičnica: Tesla standard: izlaz + Utičnica: Tesla standard: struja + Utičnica: Tesla standard + Utičnica: CHAdeMO: izlaz + Utičnica: CHAdeMO: struja + Utičnica: CHAdeMO + Utičnica: Tip 3: izlaz + Utičnica: Tip 3: struja + Utičnica: Tip 3 + Utičnica: Tip 2 kombo: izlaz + Utičnica: Tip 2 kombo: struja + Utičnica: Tip 2 kombo + Utičnica: Tip 2: izlaz + Utičnica: Tip 2: struja + Utičnica: Tip 2 + Utičnica: Tip 1 kombo: izlaz + Utičnica: Tip 1 kombo: struja + Utičnica: Tip 1 kombo + Socket: Tip 1: izlaz + Utičnica: Tip 1: struja + Utičnica: Tip 1 + Utičnica: CEE crvena 125A: izlaz + Utičnica: CEE crvena 125A: struja + Utičnica: CEE crvena 125A + Utičnica: CEE crvena 64A: izlaz + Utičnica: CEE crvena 64A: struja + Utičnica: CEE crvena 64A + Utičnica: CEE crvena 32A: izlaz + Utičnica: CEE crvena 32A: struja + Utičnica: CEE crvena 32A + Utičnica: CEE crvena 16A: izlaz + Utičnica: CEE crvena 16A: struja + Utičnica: CEE crvena 16A + Utičnica: CEE plava: izlaz + Utičnica: CEE plava: struja + Utičnica: CEE plava + Flaširana voda + Rezervoar za vodu + Prevoz vode + Bušotina + Pumpa + Tekuća voda + Cevovod + Bunar + Akvatablete + Obrnuta osmoza + Hlor + Nema + Trajnost vodenog mesta: hitno + Trajnost vodenog mesta: izdržljiva + Potrebno održavanje + Prekinuto + Ograničen + Lokacija: kiosk + Iznajmljivanje čamaca + Kreveti + Rezervacija: samo članovi + Rezervacija: ne + Rezervacija: da + Rezervacije: preporučuje se + Rezervacija: obavezna + Zimska soba: ne + Zimska soba: da + Pravac: svi + Pravac: izlaz + Pravac: ulaz + Pravac: nadole + Pravac: nagore + Pravac: suprotno od kazaljke na satu + Pravac: u smeru kazaljke na satu + Pravac: unazad + Pravac: napred + Pravac: sever-severozapad + Pravac: severozapad + Pravac: zapad-severozapad + Pravac: zapad + Pravac: zapad-jugozapad + Pravac: jugozapad + Pravac: jug-jugozapad + Pravac: jug + Pravac: jug-jugoistok + Pravac: jugoistok + Pravac: istok-jugoistok + Pravac: istok + Pravac: istok-severoistok + Pravac: severoistok + Pravac: sever-severoistok + Pravac: sever + Svemirska luka + Puštanje: ne + Puštanje: da + Usvajanje: ne + Usvajanje: da + Vlasnik + Standardni + Dualsport + Van puta + Čoper + Sportski motorcikl + Skuter + Moto odeća: ne + Moto odeća + Gume: ne + Gume + Delovi: ne + Delovi + Popravaka: ne + Popravka + Iznajmljivanje: ne + Iznajmljivanje + Da + Oznaka zemlje + Prirodni spomenik + Briga o deci + Putarina + Štit + Stratovulkan + Šljaka + URL + Parking mesto + Grob + Pol zajednice: mešoviti + Pol zajednice: muški + Pol zajednice: ženski + Turistički kamp + Tip manastira: regularno službeni + Tip manastira: otšelnički + Tip manastira: kanonski + Tip manastira: muški + Tip manastira: ženski + Ne + Da + Kupatilo za stopala + Jezero + Reka + Termalno + Tursko kupatilo + Onsen + Topli izvor + Poštanska banka + Žirokartica + Migros banka + Postfinansijska kartica + Podizanje gotovine: strane kartice + Podizanje gotovine: minimalna kupovina + Naknada za podizanje gotovine: ne + Naknada za podizanje gotovine: da + Podizanje gotovine: kupovina nije neophodna + Podizanje gotovine: kupovina neophodna + Valuta za podizanje gotovine + Limit za podizanje gotovine + Tip podizanja gotovine: samoplaćanje + Tip podizanja gotovine: kasa + Operator podizanja gotovine + Podizanje gotovine + Podizanje gotovine: da + Šišanje ljubimaca + Punjenje + Stolar ormana + Pekara + Parketar + Stolar + Destilerija + Zidar + Zdrava hrana + Ulaz u podrum + Određeno + Da + Određeno + Da + Isporuka + Određeno + Dopušteno + Odredište + Da + Određeno + Da + Određeno + Da + Određeno + Odredište + Dopušteno + Da + Određeno + Da + Određeno + Da + Određeno + Da + Određeno + Da + Dopušteno + Određeno + Da + Pristup treneru: ne + Pristup autobusu: da + VJS pristup: ne + PSV pristup: određen + VJS pristup: da + Pristup motornim kućama: ne + Mofa pristup: ne + Taksi kancelarija + Salon sa nargilom + Gomila uglja + Naknada promene stola: ne + Naknada promene stola: da + Broj promena stola + Lokacija promene stola: uniseks toalet + Lokacija promene stola: ženski toalet + Lokacija promene stola: muški toalet + Lokacija promene stola: soba + Promena stola: ograničena + Promena stola: ne + Promena stola: da + Lokacija + Opasnost: kontaminacija + Opasnost: minsko polje + Opasnost: lavina + Opasnost: poplava + Opasnost: nuklearna + Opasnost: odron stena + Opasnost: erozija + Spasilačka kutija + Izbrisani objekt + Gasna baklja;Gomila baklji + 3B* + 3B + 3A* + 3A + 2B* + 2B + 2A* + 2A + 1B* + 1B + 1A* + 1A + n/k* + n/k + Trajekt + Tramvaj + VOV + Metro + Autobus + Voz + Gradski blok + Gradić + Poklon kutija + Da + Da + Vibracija: ne + Status pumpe: nedostaje snop + Usisni + Pod pritiskom + Podzemna voda + Cev + Mreža za ponovno dolivanje pitke vode + Dolivanje vode za piće: ne + Da + Opstrukcija + Nivo vode: ispod srednjeg nivoa + Nivo vode: iznad srednjeg nivoa + Nivo vode: plutajući + Nivo vode: poplave + Nivo vode: na nivou + Nivo vode: prekrivači + Nivo vode: suv + Nivo vode: potopljen + Nivo vode: delimično potopljen + Neispravano + Primitivno + Kontrastno + Dozvoljeno je samo pri hodanju + Pristup internetu: kupci + Ne + Da + Tip kabine + Kabina + Ne + Da + Ronilački centar + Lovačka baza + Referentni broj staze + Centar za kuglanje + Prodavnica bezbednosti + Planinska spasilačka + Paintbol + Bicikl duh + Broj erupcija + Neaktivan + Aktivan + Latentan + Izumreo + Poslednja erupcija + Blato + Kupola lave + Kaldera + Mar + Strelica: ne + Tabla odlaska: ne + Ne + Da + Ne + Da + Ne + Da + Podnacionalni + Predstavništvo + Kancelarija + Počasni konzulat + Generalni konzulat + Konzularna kancelarija + Konzularna agencija + Na čelu sa konzulom + Rezidencija + Nuncijatura + Misija + Interesni + Visoka komisija + Delegacija + Podružnica + Na čelu sa ambasadorom + Posrednik + Ambasada + Radarski toranj + Parking + Parking + Tavan + GPKS tačka + LNG + Prodavnica oraha + Košnica + Raspored + Stvarno vreme + Kašnjenje + Da + Lift + Mali električni uređaji + Usluge za građane + Imigrantske vize + Neimigrantske vize + Posrednik + Konzulat + Ambasada + Tabla + Dolivanje vode za piće + Baza spasioca + Sirena + Medicinska sestra + Mobilni agent za novac + Jezero + Reka + Cepljenje: Kovid 19 + Cepljenje + Društveni klub + Plato + Diplomatsko predstavništvo + Kik-boks + Mačevanje + Kurling + Krosfit + Tuča petlova + Borba sa bikovima + Bob + Biatlon + Aikido + Vodeno skijanje + Vaterpolo + Rvanje + Dizanje tegova + Vejkbording + Ultimat + Taekvondo + Futsal + Sumo + Snuker + Stanje staze: otvorena + Obilažena: ne + Obilažena: da + Ime staze + Ski skok + Tunel za slepe miševe + Most za slepe miševe + Prelaz za divljač + Deo za plivanje + Pojilo + Stanica za prenos otpada + Kolska vaga + Šumarska stanica + Cevni bunar + Bunar + Električna pumpa + Tank sa vodom + Česma + Tip zaliva + From 43564125ce411acb0663252a394194b9e144c757 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 21 Apr 2021 13:57:53 +0300 Subject: [PATCH 02/29] "Split interval:" not translated https://github.com/osmandapp/OsmAnd/issues/11444 --- .../dialog_list_item_with_compound_button.xml | 3 ++- OsmAnd/res/layout/drawer_list_radius_ex.xml | 17 ++++++------- OsmAnd/res/layout/open_bug.xml | 13 +++++----- OsmAnd/res/layout/search_poi_filter.xml | 13 +++++----- OsmAnd/res/layout/split_segments_layout.xml | 2 +- OsmAnd/res/layout/subscription_fragment.xml | 3 ++- OsmAnd/res/layout/switch_select_list_item.xml | 24 +++++++++---------- OsmAnd/res/layout/test_backup_layout.xml | 2 +- OsmAnd/res/layout/undo_popup.xml | 13 +++++----- .../myplaces/SplitSegmentDialogFragment.java | 2 ++ 10 files changed, 50 insertions(+), 42 deletions(-) diff --git a/OsmAnd/res/layout/dialog_list_item_with_compound_button.xml b/OsmAnd/res/layout/dialog_list_item_with_compound_button.xml index 53ca8d39a7..809d19fabc 100644 --- a/OsmAnd/res/layout/dialog_list_item_with_compound_button.xml +++ b/OsmAnd/res/layout/dialog_list_item_with_compound_button.xml @@ -2,6 +2,7 @@ + tools:text="Item title"/> diff --git a/OsmAnd/res/layout/drawer_list_radius_ex.xml b/OsmAnd/res/layout/drawer_list_radius_ex.xml index 4c84dacfd3..de6fb3fd54 100644 --- a/OsmAnd/res/layout/drawer_list_radius_ex.xml +++ b/OsmAnd/res/layout/drawer_list_radius_ex.xml @@ -1,13 +1,14 @@ @@ -69,7 +70,7 @@ android:textColor="@color/color_myloc_distance" android:layout_gravity="center_vertical" android:layout_marginTop="2dp" - android:text="Cinema" + tools:text="Cinema" android:layout_marginRight="16dp" android:layout_marginEnd="16dp" /> diff --git a/OsmAnd/res/layout/open_bug.xml b/OsmAnd/res/layout/open_bug.xml index 1a69405a48..94c2a40798 100644 --- a/OsmAnd/res/layout/open_bug.xml +++ b/OsmAnd/res/layout/open_bug.xml @@ -1,10 +1,11 @@ @@ -32,7 +33,7 @@ android:id="@+id/user_name_field" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:text="NoName"/> + tools:text="NoName"/> + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:osmand="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:orientation="vertical"> diff --git a/OsmAnd/res/layout/split_segments_layout.xml b/OsmAnd/res/layout/split_segments_layout.xml index c4a5d809d9..84f36602fc 100644 --- a/OsmAnd/res/layout/split_segments_layout.xml +++ b/OsmAnd/res/layout/split_segments_layout.xml @@ -94,7 +94,7 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:background="@null" - android:text="Split interval:" + tools:text="Split interval:" android:textColor="?android:attr/textColorPrimary" android:textSize="@dimen/default_desc_text_size" osmand:typeface="@string/font_roboto_medium" /> diff --git a/OsmAnd/res/layout/subscription_fragment.xml b/OsmAnd/res/layout/subscription_fragment.xml index ad308e6be1..5deb8207c2 100644 --- a/OsmAnd/res/layout/subscription_fragment.xml +++ b/OsmAnd/res/layout/subscription_fragment.xml @@ -2,6 +2,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:tools="http://schemas.android.com/tools" android:background="?attr/spinnerListBackground" android:orientation="vertical"> @@ -212,7 +213,7 @@ android:paddingLeft="2dp" android:paddingEnd="0dp" android:paddingRight="0dp" - android:text="Ukraine" + tools:text="Ukraine" app:drawableEndCompat="@drawable/ic_action_arrow_drop_down" app:drawableRightCompat="@drawable/ic_action_arrow_drop_down" /> diff --git a/OsmAnd/res/layout/switch_select_list_item.xml b/OsmAnd/res/layout/switch_select_list_item.xml index d362ff05f2..7c76fc5dec 100644 --- a/OsmAnd/res/layout/switch_select_list_item.xml +++ b/OsmAnd/res/layout/switch_select_list_item.xml @@ -1,14 +1,14 @@ - @@ -36,7 +36,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" - android:text="Avoid selected roads" + tools:text="Avoid selected roads" android:textSize="@dimen/default_list_text_size"/> diff --git a/OsmAnd/res/layout/test_backup_layout.xml b/OsmAnd/res/layout/test_backup_layout.xml index 216820a9bf..384b549ebb 100644 --- a/OsmAnd/res/layout/test_backup_layout.xml +++ b/OsmAnd/res/layout/test_backup_layout.xml @@ -117,7 +117,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/content_padding" - android:text="Actions" + tools:text="Actions" android:textColor="?android:textColorPrimary" android:textSize="@dimen/default_list_text_size" /> diff --git a/OsmAnd/res/layout/undo_popup.xml b/OsmAnd/res/layout/undo_popup.xml index 3a4b81702f..c427c95346 100644 --- a/OsmAnd/res/layout/undo_popup.xml +++ b/OsmAnd/res/layout/undo_popup.xml @@ -1,10 +1,11 @@ + android:layout_width="fill_parent" + android:layout_height="fill_parent" + xmlns:tools="http://schemas.android.com/tools" + android:background="@drawable/popup_bg" + android:gravity="center" + android:orientation="horizontal"> \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/myplaces/SplitSegmentDialogFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/SplitSegmentDialogFragment.java index c981610015..5ec7077718 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/SplitSegmentDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/SplitSegmentDialogFragment.java @@ -287,6 +287,8 @@ public class SplitSegmentDialogFragment extends DialogFragment { } int color = app.getResources().getColor(colorId); title.setTextColor(color); + String titleText = getString(R.string.gpx_split_interval); + title.setText(getString(R.string.ltr_or_rtl_combine_via_colon, titleText, "")); text.setTextColor(color); img.setImageDrawable(ic.getIcon(R.drawable.ic_action_arrow_drop_down, colorId)); } From b5a27d99b8f28922261c31e2395bc13028d16379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Wed, 21 Apr 2021 09:10:23 +0000 Subject: [PATCH 03/29] Translated using Weblate (Hungarian) Currently translated at 99.9% (3720 of 3721 strings) --- OsmAnd/res/values-hu/strings.xml | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index ced108288e..ec3dea7ece 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -13,8 +13,8 @@ Súgó Akadálymentes mód Bekapcsolja a fogyatékkal élőknek szóló funkciókat. - Be - Kikapcsolás + Bekapcsolva + Kikapcsolva Android rendszerbeállítások szerint Vissza a menübe Kicsinyít @@ -1318,7 +1318,7 @@ Bővebben… Célpont Egy meglévő elem adatainak megtekintéséhez koppintson rá, inaktiváláshoz vagy törléshez nyomja meg hosszan. Jelenlegi adatok az eszközön (%1$s szabad): - Sebességkorlátozás-tolerancia + Sebességkorlátozás túllépésének tűréshatára Válassza ki a sebességkorlátozás tűréshatárát, amely fölött hangos figyelmeztetést fog kapni. A Kedvenc hely át lett nevezve erre: %1$s, hogy a hangulatjeleket tartalmazó szöveget fájlba lehessen menteni. Útvonal nyomtatása @@ -1470,7 +1470,7 @@ Megjelent napos Térképek letöltése - Néhány országban (Németország, Franciaország, Olaszország és még néhány) tilos a traffipax figyelmeztetés használata! Az OsmAnd nem vállal felelősséget a szabályok megsértéséért. Koppints az Igen gombra, ha jogosult vagy a funkció használatára. + Néhány országban (Németország, Franciaország, Olaszország stb.) tilos traffipax-riasztást használni! Az OsmAnd nem vállal felelősséget a szabályok megsértéséért. Koppintson az Igen gombra, ha jogosult a funkció használatára. A jelzőtáblák és szabályok helyes értelmezéséhez jelölje ki a vezetési régiót: Az OsmAnd lehetővé teszi a térképek és a navigáció offline használatát az egész világon. Jelenlegi útvonal @@ -3583,7 +3583,7 @@ Traffipaxok eltávolítása Jogi Traffipax POI-k - Bizonyos országokban és régiókban a traffipaxra figyelmeztető alkalmazások törvényileg tiltottak. + Bizonyos országokban és régiókban jogszabály tilgja a traffipaxra figyelmeztető alkalmazások használatát. \n \nDöntsön az ön országának törvényei alapján. \n @@ -3592,14 +3592,14 @@ \nVálassza az %2$s lehetőséget, hogy az összes traffipax-szal kapcsolatos adat: riasztások, értesítések, POI-k törlésre kerüljenek az OsmAnd teljes újratelepítéséig. Maradjanak Eltávolít - Bizonyos országokban a traffipax riasztások törvényileg tiltottak. + Bizonyos országokban a törvény tiltja a traffipaxriasztást. Tájolás %1$s törölve A traffipaxadatok végleges törléséhez indítsa újra az alkalmazást. Eltávolítás és Újraindítás Adja meg az útvonalakon a járművekre vonatkozó hosszkorlátozást. Hosszkorlátozás - Az eszköz nem tartalmaz traffipax adatokat. + Az eszköz nem tartalmaz traffipaxadatokat. Az jelenlegi elemek lecserélésre kerülnek a fájlban lévőkre Az importált elemek előtaggal lesznek hozzáadva Az OsmAnd már tartalmaz az importálttal megegyező nevű elemeket. @@ -4044,7 +4044,11 @@ Minden nem mentett adat törlődni fog. Kezdő párbeszéd megjelenítése Ha le van tiltva, akkor a felvétel közvetlenül a widget vagy a menüelem megérintése után elindul, kihagyva a megerősítő párbeszédpanelt. - • Az OsmAnd Live frissítések átköltöztek a „Letöltések> Frissítések” helyre + • Új lehetőség: szinvonalak letöltése (méter mellett) lábban +\n +\n• Útvonaltervezési környezet: hozzáadott fülek a pontok és grafikonok közötti váltáshoz +\n +\n• Az OsmAnd Live frissítések átköltöztek a „Letöltések> Frissítések” helyre \n \n• A nyomvonalak színezhetők magasság, sebesség vagy lejtés szerint. \n @@ -4078,4 +4082,8 @@ Értesítés túllépéskor Felhasználói pontok Teljesítmény + Kérjük, válassza ki a kívánt mértékegységet. A mértékegység módosításához újra le kell töltenie a fájlt. + Az OsmAnd méterben és lábban adja meg a szintvonalak magasságát. A mértékegység módosításához újra le kell töltenie a fájlt. + láb + Szintvonalak mértékegysége \ No newline at end of file From d9de7ba4b08d2020aeec30abf6b886d0e77dcd91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Morais?= Date: Wed, 21 Apr 2021 10:15:39 +0000 Subject: [PATCH 04/29] Translated using Weblate (Portuguese) Currently translated at 100.0% (3721 of 3721 strings) --- OsmAnd/res/values-pt/strings.xml | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/OsmAnd/res/values-pt/strings.xml b/OsmAnd/res/values-pt/strings.xml index f6e6b35339..9665801ba0 100644 --- a/OsmAnd/res/values-pt/strings.xml +++ b/OsmAnd/res/values-pt/strings.xml @@ -678,9 +678,9 @@ A carregar compilações OsmAnd… Selecionar a compilação OsmAnd a instalar Instalar versão - DDD.DDDDD - DDD MM.MMM - DDD MM SS.S + GGG.GGGGG + GGG MM.MMM + GGG MM SS.S Tornar transparentes todas as características do terreno no mapa. Polígonos Modo de visualização @@ -1021,7 +1021,7 @@ Focar infinito Focagem macro (close-up) A câmara tenta focar continuadamente - Reproduzir o som do obturador da câmara + Reproduzir som ao tirar fotografias Definir som ou silêncio ao fotografar. Canadá Versão: @@ -3440,7 +3440,7 @@ Altere a ordenação da lista e oculte categorias. Pode importar ou exportar todas as alterações com perfis. Reorganizar categorias Autorização bem sucedida - Som do obturador da câmara + Som ao tirar fotografias Usar aplicação do sistema Dividir gravações Repor configurações originais da extensão @@ -3960,13 +3960,17 @@ Bicicleta elétrica As atualizações ao mapa serão verificadas a todas as horas. Próxima %1$s em %2$s. Tem a certeza que quer eliminar todas as %s atualizações OsmAnd Live\? - • Atualizações OsmAnd Live movidas para \"Descarregamentos > Atualizações\" + • Adicionada opção para descarregar curvas de nível em pés. +\n +\n• Planear rota: adicionadas abas para alternar entre pontos ou gráficos. +\n +\n• Atualizações OsmAnd Live movidas para \"Descarregamentos > Atualizações\" \n \n• Os trilhos podem ser agora coloridos conforme a altitude, velocidade e declive. \n -\n• Adicionada opção para alterar a aparência da linha de rota de navegação +\n• Adicionada opção para alterar a aparência da linha de rota de navegação. \n -\n• Janela de diálogo \"Gravação do trilho\" atualizada +\n• Janela de diálogo \"Gravação do trilho\" atualizada. \n \n O roteamento pode evitar subidas íngremes. @@ -4089,4 +4093,8 @@ Anunciar quando ultrapassado Pontos do utilizador Saída + pés + O OsmAnd fornece dados de curvas de nível em metros e pés. Terá de descarregar novamente o ficheiro para alterar o formato. + Formato de unidades de curvas de nível + Selecione o formato necessário. Terá de descarregar novamente o ficheiro para alterar o formato. \ No newline at end of file From 0ca18e6d5f6e8cba5904f026e8e79fda2210ea22 Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Tue, 20 Apr 2021 23:45:38 +0000 Subject: [PATCH 05/29] Translated using Weblate (French) Currently translated at 99.9% (3720 of 3721 strings) --- OsmAnd/res/values-fr/strings.xml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index d0249d93b8..466f9571b7 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -3275,7 +3275,7 @@ Ajouter le profil \'%1$s\' \? Inclure la direction Inclure la direction de chaque point lors de l\'enregistrement d\'une trace. - Afficher le réseau de nœuds de pistes cyclables + Afficher les itinéraires cyclables du réseau de nœuds Nœuds de transport Personnel %1$s • %2$s @@ -4040,9 +4040,13 @@ Toutes les données non enregistrées seront perdues. Afficher la boîte de dialogue de démarrage Si désactivé, l\'enregistrement débutera dès appui sur le gadget ou dans le menu (sans demande de confirmation). - - Les mises à jour d\'OsmAnd Live ont été déplacées vers \"Téléchargements > Mises à jour\" + - Ajout d\'une option pour télécharger les Courbes de niveau en pieds \n -\n - Les traces peuvent maintenant être colorées par altitude, vitesse ou pente. +\n- Planification d\'itinéraires en paysage : ajout d’onglets pour basculer entre Points et Graphs +\n +\n- Les mises à jour d\'OsmAnd Live ont été déplacées vers \"Téléchargements > Mises à jour\" +\n +\n - Les traces peuvent maintenant être colorées par altitude, vitesse ou pente \n \n - Ajout d\'une option pour modifier l\'apparence de la ligne d\'itinéraire en navigation \n @@ -4075,4 +4079,8 @@ Numéro de sortie Annoncer en cas de dépassement Sortie + OsmAnd fournit des données sur les courbes de niveau en mètres et en pieds. Vous devrez à nouveau télécharger le fichier pour modifier le format. + Veuillez sélectionner le format souhaité. Vous devrez à nouveau télécharger le fichier pour modifier le format. + Format d\'unité pour les courbes de niveau + pieds \ No newline at end of file From 8c992bb4a9914f923c45ec21a7d2a5a1d91fbcd6 Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 21 Apr 2021 05:21:24 +0000 Subject: [PATCH 06/29] Translated using Weblate (German) Currently translated at 99.9% (3720 of 3721 strings) --- OsmAnd/res/values-de/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 4a199996b5..c9c4092d52 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -4057,7 +4057,11 @@ Routenlinie anpassen Routenlinie Legen Sie die Farbe für den Kartenmodus fest: %1$s. - • OsmAnd Live-Updates nach \"Downloads > Updates\" verschoben + • Option zum Herunterladen von Höhenlinien in Fuß zugefügt +\n +\n• Routenplanung im Querformat: Registerkarten zum Umschalten zwischen Punkten oder Diagrammen hinzugefügt +\n +\n• OsmAnd Live-Updates nach \"Downloads > Updates\" verschoben \n \n• Tracks können nun nach Höhe, Geschwindigkeit oder Steigung eingefärbt werden. \n @@ -4089,4 +4093,8 @@ Meldung bei Überschreitung Anwenderpunkte Leistung + Fuß + Einheit der Höhenlinien + OsmAnd liefert Höhenlinien-Daten in Metern und Fuß. Sie müssen die Datei erneut herunterladen, um das Format zu ändern. + Bitte wählen Sie das gewünschte Format. Sie müssen die Datei erneut herunterladen, um das Format zu ändern. \ No newline at end of file From da89e737ec10e7229bdbe0e783ff45407391e9d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Ersen?= Date: Tue, 20 Apr 2021 22:51:58 +0000 Subject: [PATCH 07/29] Translated using Weblate (Turkish) Currently translated at 100.0% (3721 of 3721 strings) --- OsmAnd/res/values-tr/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-tr/strings.xml b/OsmAnd/res/values-tr/strings.xml index ca24c81192..473ad3ed09 100644 --- a/OsmAnd/res/values-tr/strings.xml +++ b/OsmAnd/res/values-tr/strings.xml @@ -4072,7 +4072,11 @@ Ek süre içinde Beklemede Süresi doldu - • OsmAnd Live güncellemeleri \"İndirmeler> Güncellemeler\" bölümüne taşındı + • Eş yükselti eğrilerini fit cinsinden indirme seçeneği eklendi +\n +\n • Güzergah Planla görünümü: noktalar veya grafikler arasında geçiş yapmak için sekmeler eklendi +\n +\n • OsmAnd Live güncellemeleri \"İndirmeler > Güncellemeler\" bölümüne taşındı \n \n • Yollar artık rakım, hız veya eğime göre renklendirilebilir \n @@ -4087,4 +4091,8 @@ Kullanıcı puanları Çıkış %1$s → … + fit + Eş yükselti eğrileri birimi biçimi + OsmAnd, metre ve fit cinsinden eş yükselti eğrileri verileri sağlar. Biçimi değiştirmek için dosyayı yeniden indirmeniz gerekecek. + Lütfen gerekli biçimi seçin. Biçimi değiştirmek için dosyayı yeniden indirmeniz gerekecek. \ No newline at end of file From 81687551e7f16c5d9c443a7632ac39cb18e81a24 Mon Sep 17 00:00:00 2001 From: Athoss Date: Wed, 21 Apr 2021 11:14:57 +0000 Subject: [PATCH 08/29] Translated using Weblate (Hungarian) Currently translated at 99.9% (3720 of 3721 strings) --- OsmAnd/res/values-hu/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index ec3dea7ece..c7cdd9ca08 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -3583,7 +3583,7 @@ Traffipaxok eltávolítása Jogi Traffipax POI-k - Bizonyos országokban és régiókban jogszabály tilgja a traffipaxra figyelmeztető alkalmazások használatát. + Bizonyos országokban és régiókban jogszabály tiltja a traffipaxra figyelmeztető alkalmazások használatát. \n \nDöntsön az ön országának törvényei alapján. \n From 6948315605676577194ec9d7e041a72684b16862 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 20 Apr 2021 23:43:27 +0000 Subject: [PATCH 09/29] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3721 of 3721 strings) --- OsmAnd/res/values-uk/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 4fe37da2e3..cb45c0658b 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -4053,7 +4053,11 @@ Лінія маршруту Лінія маршруту застосовуватиме %1$s, вказаний у вибраному стилі мапи: %2$s. Вкажіть колір для режиму мапи: %1$s. - • Оновлення OsmAnd Live переміщено до «Завантаження >Оновлення» + • Додана можливість завантаження контурних ліній у футах +\n +\n• Ландшафтне планування маршруту: додані вкладки для перемикання між точками або графіками +\n +\n• Оновлення OsmAnd Live переміщено до «Завантаження >Оновлення» \n \n• Тепер треки можуть бути забарвлені за висотою, швидкістю або нахилом. \n @@ -4084,4 +4088,8 @@ Повідомляти про перевищення Користувацькі точки Вивід + OsmAnd надає дані горизонталей в метрах і футах. Щоб змінити формат, потрібно повторно завантажити файл. + Формат одиниць вимірювання горизонталей + фути + Виберіть потрібний формат. Щоб змінити формат, потрібно повторно завантажувати файл. \ No newline at end of file From b1d1007cb6ad492988e5f557e1661fcc5fc96663 Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Wed, 21 Apr 2021 05:52:22 +0000 Subject: [PATCH 10/29] Translated using Weblate (Hebrew) Currently translated at 99.9% (3719 of 3721 strings) --- OsmAnd/res/values-iw/strings.xml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index 8fee045082..6a625e3b66 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -4056,13 +4056,17 @@ להתאים קו מסלול אישית קו מסלול לציין צבע למצב מפה: %1$s. - • העדכונים החיים של OsmAnd הועברו אל „הורדות > עדכונים” + • נוספה אפשרות להוריד קווי מתאר ברגל \n -\n • אפשר לצבוע מסלולים לפי גובה, מהירות או שיפוע. +\n• תכנון מסלול אופקית: נוספו לשוניות למעבר בין נקודות לתרשימים \n -\n • נוספה אפשרות לשנות את מראה קו מסלול הניווט +\n• העדכונים החיים של OsmAnd הועברו אל „הורדות > עדכונים” \n -\n • החלונית „הקלטת מסלול” עודכנה +\n• אפשר לצבוע מסלולים לפי גובה, מהירות או שיפוע. +\n +\n• נוספה אפשרות לשנות את מראה קו מסלול הניווט +\n +\n• החלונית „הקלטת מסלול” עודכנה \n \n OsmAnd חי @@ -4087,4 +4091,8 @@ להכריז בחריגה נקודות משתמש פלט + רגל + תצורת יחידת קווי מתאר + OsmAnd מספק נתוני קווי מתאר במטרים וברגל. יהיה עליך להוריד את הקובץ מחדש כדי לשנות את התצורה. + נא לבחור את התצורה הרצויה. יהיה עליך להוריד את הקובץ מחדש כדי לשנות את התצורה. \ No newline at end of file From 5f9e9314826fc4bfaee23633d769fa5ed4c78cc3 Mon Sep 17 00:00:00 2001 From: Softmap Date: Wed, 21 Apr 2021 01:20:55 +0000 Subject: [PATCH 11/29] Translated using Weblate (Arabic) Currently translated at 100.0% (3721 of 3721 strings) --- OsmAnd/res/values-ar/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index e920c24f05..5f81b828e0 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -4123,7 +4123,11 @@ خط المسار سيستخدم خط الطريق %1$s المحدد في نمط الخريطة المحدد: %2$s. حدد لونًا لوضع الخريطة: %1$s. - • تم نقل تحديثات OsmAnd Live إلى \"التنزيلات> التحديثات\" + • خيار مضاف لتنزيل خطوط الكنتور بالقدم +\n +\n• مخطط الطريق الأفقي: علامات تبويب tabs مضافة للتبديل بين النقاط أو الرسوم البيانية +\n +\n• تم نقل تحديثات OsmAnd Live إلى \"التنزيلات> التحديثات\" \n \n • يمكن تلوين المسارات الآن حسب الارتفاع، السرعة أو المنحدر. \n @@ -4154,4 +4158,8 @@ الإعلان عند التجاوز نقاط المستخدم الإخراج + تنسيق وحدة خطوط الكنتور + OsmAnd يوفر بيانات الخطوط الكنتورية بالأمتار والقدم. ستحتاج إلى إعادة تنزيل الملف لتغيير التنسيق. + الرجاء تحديد التنسيق المطلوب. ستحتاج إلى إعادة تنزيل الملف لتغيير التنسيق. + قدم \ No newline at end of file From 3ff1d1a39a6e647b9ebf8f86721bbc0831a1be2f Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Tue, 20 Apr 2021 23:36:52 +0000 Subject: [PATCH 12/29] Translated using Weblate (French) Currently translated at 100.0% (3927 of 3927 strings) --- OsmAnd/res/values-fr/phrases.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OsmAnd/res/values-fr/phrases.xml b/OsmAnd/res/values-fr/phrases.xml index 0164a38387..d73665cdf6 100644 --- a/OsmAnd/res/values-fr/phrases.xml +++ b/OsmAnd/res/values-fr/phrases.xml @@ -3915,4 +3915,17 @@ Pilates Ju-jitsu Karaté + Gymnase Zurkhaneh + Plongeon du haut d\'une falaise + Anneaux + Club social + Plateau + Voie express + Satisfait : oui + Emplacement de camping + Arrêt pour la bibliothèque mobile + Bureau diplomatique + Fers à cheval + Polo-vélo + Type de baie \ No newline at end of file From 83885c373c0247e8a0b5984582128336782be536 Mon Sep 17 00:00:00 2001 From: Verdulo Date: Wed, 21 Apr 2021 11:01:33 +0000 Subject: [PATCH 13/29] Translated using Weblate (Esperanto) Currently translated at 100.0% (3721 of 3721 strings) --- OsmAnd/res/values-eo/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index fa137e6afc..d8d6c27220 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -4054,7 +4054,11 @@ Alĝustigi linion de kurso Linio de kurso Por la linio de kurso estos uzata %1$s difinita por la map‑stilo: %2$s. - • ĝisdatigoj OsmAnd Live movitaj al “elŝutoj” → “ĝisdatigoj” + • eblo elŝuti nivelkurbojn en futoj +\n +\n• horizontala vido por “plani kurson”: aldonitaj langetoj por baskuli inter punktoj kaj diagramoj +\n +\n• ĝisdatigoj OsmAnd Live movitaj al “elŝutoj” → “ĝisdatigoj” \n \n• eblo kolorigi spurojn laŭ altitudo, rapido aŭ dekliveco \n @@ -4085,4 +4089,8 @@ Numero de elirejo Poentoj de uzanto Eligo + futoj + Unuo por nivelkurboj + OsmAnd liveras nivelkurbojn en metroj kaj en futoj. Ve devos reelŝuti la dosieron por ŝanĝi la formon. + Elektu la deziratan formon. Vi devos reelŝuti la dosieron por ŝanĝi la formon. \ No newline at end of file From 0d26b83435c57cd354a3ebf205e3f769aa3c0910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sveinn=20=C3=AD=20Felli?= Date: Wed, 21 Apr 2021 09:28:39 +0000 Subject: [PATCH 14/29] Translated using Weblate (Icelandic) Currently translated at 100.0% (3721 of 3721 strings) --- OsmAnd/res/values-is/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-is/strings.xml b/OsmAnd/res/values-is/strings.xml index 8b0b8e87a5..4621b9ab38 100644 --- a/OsmAnd/res/values-is/strings.xml +++ b/OsmAnd/res/values-is/strings.xml @@ -4052,7 +4052,11 @@ Mörk náttúru Millibil skráninga stillir tímabilið milli þess sem OsmAnd biður um staðsetningargögn. Ef þetta er óvirkt, mun upptaka hefjast strax eftir að ýtt er á hnappinn eða valmyndarfærsluna og staðfestingarglugga er þá sleppt. - • Uppfærslur OsmAnd Live færðar í \"Sótt gögn > Uppfærslur\" + • Bætt við möguleika á að sækja hæðarlínur í fetum +\n +\n• Landslag í leiðaskipulagi: bætt við flipum til að skipta á milli punkta eða grafs +\n +\n• Uppfærslur OsmAnd Live færðar í \"Sótt gögn > Uppfærslur\" \n \n • Ferla er nú hægt að lita eftir hæð, hraða eða halla. \n @@ -4091,4 +4095,8 @@ Tilkynna þegar farið er yfir Punktar notanda %1$s → … + fet + Snið eininga hæðarlína + OsmAnd býður upp á hæðalínugögn í metrum og fetum. Þú þarft að sækja skrána aftur til að breyta sniðinu. + Veldu rétt snið eininga. Þú þarft að sækja skrána aftur til að breyta sniðinu. \ No newline at end of file From d0d60e9d2e596a93084f33704151dbb4b68e1465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sveinn=20=C3=AD=20Felli?= Date: Wed, 21 Apr 2021 09:26:02 +0000 Subject: [PATCH 15/29] Translated using Weblate (Icelandic) Currently translated at 100.0% (3927 of 3927 strings) --- OsmAnd/res/values-is/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-is/phrases.xml b/OsmAnd/res/values-is/phrases.xml index b5b20c54b7..25a7bc3d25 100644 --- a/OsmAnd/res/values-is/phrases.xml +++ b/OsmAnd/res/values-is/phrases.xml @@ -3927,4 +3927,5 @@ Sendiskrifstofa Gerð flóa Háslétta + Félagsstarf \ No newline at end of file From dd1195b0604dc6d606768f63e361768a922d34fc Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Wed, 21 Apr 2021 02:07:44 +0000 Subject: [PATCH 16/29] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3721 of 3721 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index 358a89a8ec..1db440ac46 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -4047,7 +4047,11 @@ 路線 路線將會使用 %1$s 在選定的地圖樣式上指定的:%2$s。 指定地圖模式的顏色:%1$s。 - • OsmAnd Live 更新移動至「下載 > 更新」 + • 新增以英呎為單位下載等高線 +\n +\n • 規劃路線樣式:新增切換點與圖形的分頁 +\n +\n • OsmAnd Live 更新移動至「下載 > 更新」 \n \n • 軌跡現在可以使用海拔、速度或坡度來填色 \n @@ -4079,4 +4083,8 @@ 使用者點 輸出 %1$s → … + 英呎 + 等高線單位格式 + OsmAnd 提供以公尺與英呎為單位的等高線資料。您將必須重新下載檔案以變更格式。 + 請選取需要格式。您將必須重新下載檔案以變更格式。 \ No newline at end of file From 5670680d1ea524454e523080a3d51dbc9ae70c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Wed, 21 Apr 2021 08:58:37 +0000 Subject: [PATCH 17/29] Translated using Weblate (Hungarian) Currently translated at 100.0% (271 of 271 strings) Translation: OsmAnd/Telegram Translate-URL: https://hosted.weblate.org/projects/osmand/telegram/hu/ --- OsmAnd-telegram/res/values-hu/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-telegram/res/values-hu/strings.xml b/OsmAnd-telegram/res/values-hu/strings.xml index 95d655b5cb..01544a2b89 100644 --- a/OsmAnd-telegram/res/values-hu/strings.xml +++ b/OsmAnd-telegram/res/values-hu/strings.xml @@ -109,7 +109,7 @@ Kérjük, telepítse a Telegramot és hozzon létre egy fiókot. Utána használhatja ezt az alkalmazást. Minden - Kikapcsolás + Kikapcsolva %1$d óra %2$d perc %1$d perc Telepítés From cb18d45e43c68ebb67f60761d1020a1786030e58 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 21 Apr 2021 15:05:31 +0300 Subject: [PATCH 18/29] Revert "Move markerGroups to ItineraryHelper" This reverts commit a40f802a --- .../src/net/osmand/plus/AppInitializer.java | 2 +- .../net/osmand/plus/FavouritesDbHelper.java | 9 +- .../net/osmand/plus/GpxSelectionHelper.java | 6 +- .../EditFavoriteGroupDialogFragment.java | 6 +- .../activities/FavoritesTreeFragment.java | 2 +- .../net/osmand/plus/helpers/IntentHelper.java | 4 +- .../plus/itinerary/ItineraryHelper.java | 296 +------------ .../editors/WptPtEditorFragment.java | 4 +- .../editors/WptPtEditorFragmentNew.java | 4 +- ...ouritesGroupBottomSheetDialogFragment.java | 2 +- ...dTracksGroupBottomSheetDialogFragment.java | 2 +- .../plus/mapmarkers/CategoriesSubHeader.java | 8 +- .../CoordinateInputDialogFragment.java | 10 +- .../osmand/plus/mapmarkers/GroupHeader.java | 8 +- .../net/osmand/plus/mapmarkers/MapMarker.java | 5 +- .../plus/mapmarkers/MapMarkersDbHelper.java | 13 +- .../MapMarkersGroup.java} | 12 +- .../plus/mapmarkers/MapMarkersHelper.java | 393 +++++++++++++++--- ...ptCategoriesBottomSheetDialogFragment.java | 12 +- .../adapters/MapMarkersActiveAdapter.java | 6 +- .../adapters/MapMarkersGroupsAdapter.java | 35 +- .../plus/myplaces/DeletePointsTask.java | 4 +- .../EditTrackGroupDialogFragment.java | 12 +- .../plus/myplaces/TrackPointFragment.java | 15 +- .../backup/HistoryMarkersSettingsItem.java | 8 +- .../backend/backup/MarkersSettingsItem.java | 8 +- .../backend/backup/SettingsHelper.java | 31 +- .../fragments/ExportItemsBottomSheet.java | 6 +- .../fragments/ExportSettingsAdapter.java | 6 +- .../plus/views/layers/FavouritesLayer.java | 2 +- .../osmand/plus/views/layers/GPXLayer.java | 5 +- 31 files changed, 459 insertions(+), 477 deletions(-) rename OsmAnd/src/net/osmand/plus/{itinerary/ItineraryGroup.java => mapmarkers/MapMarkersGroup.java} (91%) diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index d5afd31937..cfcdc737b2 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -687,7 +687,7 @@ public class AppInitializer implements IProgress { // restore backuped favorites to normal file restoreBackupForFavoritesFiles(); notifyEvent(InitEvents.RESTORE_BACKUPS); - app.itineraryHelper.syncAllGroupsAsync(); + app.mapMarkersHelper.syncAllGroupsAsync(); app.searchUICore.initSearchUICore(); checkLiveUpdatesAlerts(); diff --git a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java index be36c5197d..ca52169e10 100644 --- a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java @@ -17,7 +17,7 @@ import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; import net.osmand.plus.GeocodingLookupService.AddressLookupRequest; import net.osmand.plus.mapmarkers.MapMarkersHelper; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; import net.osmand.plus.api.SQLiteAPI.SQLiteCursor; import net.osmand.util.Algorithms; @@ -280,7 +280,7 @@ public class FavouritesDbHelper { } private void runSyncWithMarkers(FavoriteGroup favGroup) { - ItineraryGroup group = context.getItineraryHelper().getMarkersGroup(favGroup); + MapMarkersGroup group = context.getMapMarkersHelper().getMarkersGroup(favGroup); if (group != null) { context.getItineraryHelper().runSynchronization(group); } @@ -288,7 +288,7 @@ public class FavouritesDbHelper { private boolean removeFromMarkers(FavoriteGroup favGroup) { MapMarkersHelper helper = context.getMapMarkersHelper(); - ItineraryGroup group = context.getItineraryHelper().getMarkersGroup(favGroup); + MapMarkersGroup group = helper.getMarkersGroup(favGroup); if (group != null) { helper.removeMarkersGroup(group); return true; @@ -297,7 +297,8 @@ public class FavouritesDbHelper { } private void addToMarkers(FavoriteGroup favGroup) { - context.getItineraryHelper().addOrEnableGroup(favGroup); + MapMarkersHelper helper = context.getMapMarkersHelper(); + helper.addOrEnableGroup(favGroup); } private File getInternalFile() { diff --git a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java index 5ec4f28736..77bcb5e0e7 100644 --- a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java +++ b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java @@ -30,7 +30,7 @@ import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.helpers.enums.MetricsConstants; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder; import net.osmand.plus.track.GpxSplitType; import net.osmand.util.Algorithms; @@ -797,7 +797,7 @@ public class GpxSelectionHelper { boolean addToHistory) { GpxDataItem dataItem = app.getGpxDbHelper().getItem(new File(gpx.path)); if (canAddToMarkers && show && dataItem != null && dataItem.isShowAsMarkers()) { - app.getItineraryHelper().addOrEnableGroup(gpx); + app.getMapMarkersHelper().addOrEnableGroup(gpx); } return selectGpxFile(gpx, dataItem, show, notShowNavigationDialog, syncGroup, selectedByUser, addToHistory); } @@ -824,7 +824,7 @@ public class GpxSelectionHelper { } private void syncGpxWithMarkers(GPXFile gpxFile) { - ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile); + MapMarkersGroup group = app.getMapMarkersHelper().getMarkersGroup(gpxFile); if (group != null) { app.getItineraryHelper().runSynchronization(group); } diff --git a/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java b/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java index e625212ee7..001868e7b4 100644 --- a/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/activities/EditFavoriteGroupDialogFragment.java @@ -28,7 +28,7 @@ import net.osmand.AndroidUtils; import net.osmand.plus.FavouritesDbHelper; import net.osmand.plus.FavouritesDbHelper.FavoriteGroup; import net.osmand.plus.mapmarkers.MapMarkersHelper; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -179,7 +179,7 @@ public class EditFavoriteGroupDialogFragment extends MenuBottomSheetDialogFragme final MapMarkersHelper markersHelper = app.getMapMarkersHelper(); final FavoriteGroup favGroup = this.group; - final ItineraryGroup markersGr = app.getItineraryHelper().getMarkersGroup(this.group); + final MapMarkersGroup markersGr = markersHelper.getMarkersGroup(this.group); final boolean synced = markersGr != null; BaseBottomSheetItem markersGroupItem = new SimpleBottomSheetItem.Builder() @@ -192,7 +192,7 @@ public class EditFavoriteGroupDialogFragment extends MenuBottomSheetDialogFragme if (synced) { markersHelper.removeMarkersGroup(markersGr); } else { - app.getItineraryHelper().addOrEnableGroup(favGroup); + markersHelper.addOrEnableGroup(favGroup); } dismiss(); MapActivity.launchMapActivityMoveToTop(getActivity()); diff --git a/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java b/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java index 98304247a4..a24859fa30 100644 --- a/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java +++ b/OsmAnd/src/net/osmand/plus/activities/FavoritesTreeFragment.java @@ -526,7 +526,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen for (Map.Entry> entry : favoritesSelected.entrySet()) { FavoriteGroup group = helper.getGroup(entry.getKey()); if (group != null && entry.getValue().size() == group.getPoints().size()) { - getMyApplication().getItineraryHelper().addOrEnableGroup(group); + markersHelper.addOrEnableGroup(group); } else { for (FavouritePoint fp : entry.getValue()) { points.add(new LatLon(fp.getLatitude(), fp.getLongitude())); diff --git a/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java b/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java index 6fce7b78a6..5d540d5170 100644 --- a/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java +++ b/OsmAnd/src/net/osmand/plus/helpers/IntentHelper.java @@ -18,8 +18,8 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.PluginsFragment; import net.osmand.plus.dashboard.DashboardOnMap.DashboardType; -import net.osmand.plus.itinerary.ItineraryGroup; import net.osmand.plus.mapmarkers.MapMarkersDialogFragment; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapsource.EditMapSourceDialogFragment; import net.osmand.plus.openplacereviews.OPRConstants; import net.osmand.plus.openplacereviews.OprAuthHelper.OprAuthorizationListener; @@ -219,7 +219,7 @@ public class IntentHelper { if (intent.hasExtra(MapMarkersDialogFragment.OPEN_MAP_MARKERS_GROUPS)) { Bundle openMapMarkersGroupsExtra = intent.getBundleExtra(MapMarkersDialogFragment.OPEN_MAP_MARKERS_GROUPS); if (openMapMarkersGroupsExtra != null) { - MapMarkersDialogFragment.showInstance(mapActivity, openMapMarkersGroupsExtra.getString(ItineraryGroup.MARKERS_SYNC_GROUP_ID)); + MapMarkersDialogFragment.showInstance(mapActivity, openMapMarkersGroupsExtra.getString(MapMarkersGroup.MARKERS_SYNC_GROUP_ID)); } mapActivity.setIntent(null); } diff --git a/OsmAnd/src/net/osmand/plus/itinerary/ItineraryHelper.java b/OsmAnd/src/net/osmand/plus/itinerary/ItineraryHelper.java index f89d05c1f9..8e3c96a08a 100644 --- a/OsmAnd/src/net/osmand/plus/itinerary/ItineraryHelper.java +++ b/OsmAnd/src/net/osmand/plus/itinerary/ItineraryHelper.java @@ -3,44 +3,31 @@ package net.osmand.plus.itinerary; import android.os.AsyncTask; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import net.osmand.GPXUtilities.GPXFile; import net.osmand.GPXUtilities.WptPt; -import net.osmand.IndexConstants; import net.osmand.PlatformUtil; import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; import net.osmand.plus.FavouritesDbHelper.FavoriteGroup; -import net.osmand.plus.GPXDatabase; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmandApplication; import net.osmand.plus.mapmarkers.MapMarker; -import net.osmand.plus.mapmarkers.MapMarkersDbHelper; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper.OnGroupSyncedListener; -import net.osmand.plus.wikivoyage.data.TravelArticle; -import net.osmand.plus.wikivoyage.data.TravelHelper; -import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; import java.io.File; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.HashSet; -import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import static net.osmand.plus.mapmarkers.MapMarkersHelper.BY_DATE_ADDED_DESC; - public class ItineraryHelper { private static final Log LOG = PlatformUtil.getLog(ItineraryHelper.class); @@ -48,150 +35,14 @@ public class ItineraryHelper { private OsmandApplication app; private MapMarkersHelper markersHelper; - private MapMarkersDbHelper markersDbHelper; private ExecutorService executorService = Executors.newSingleThreadExecutor(); - private List itineraryGroups = new ArrayList<>(); private Set syncListeners = new HashSet<>(); public ItineraryHelper(@NonNull OsmandApplication app) { this.app = app; markersHelper = app.getMapMarkersHelper(); - markersDbHelper = app.getMapMarkersDbHelper(); - loadGroups(); - } - - public List getItineraryGroups() { - return itineraryGroups; - } - - public void syncAllGroupsAsync() { - for (ItineraryGroup group : itineraryGroups) { - if (group.getId() != null && group.getName() != null) { - runSynchronization(group); - } - } - } - - public void updateGroupWptCategories(@NonNull ItineraryGroup group, Set wptCategories) { - String id = group.getId(); - if (id != null) { - group.setWptCategories(wptCategories); - if (wptCategories != null) { - markersDbHelper.updateGroupCategories(id, group.getWptCategoriesString()); - } - } - } - - public void enableGroup(@NonNull ItineraryGroup gr) { - // check if group doesn't exist internally - if (!itineraryGroups.contains(gr)) { - addGroupInternally(gr); - } - if (gr.isDisabled()) { - updateGroupDisabled(gr, false); - } - runSynchronization(gr); - } - - public void updateGroups() { - for (ItineraryGroup group : itineraryGroups) { - markersHelper.updateGroup(group); - } - } - - public void updateGroupDisabled(@NonNull ItineraryGroup group, boolean disabled) { - String id = group.getId(); - if (id != null) { - markersDbHelper.updateGroupDisabled(id, disabled); - group.setDisabled(disabled); - } - } - - public List getMapMarkersFromDefaultGroups(boolean history) { - List mapMarkers = new ArrayList<>(); - for (ItineraryGroup group : itineraryGroups) { - if (group.getType() == ItineraryGroup.ANY_TYPE) { - for (MapMarker marker : group.getMarkers()) { - if (history && marker.history || !history && !marker.history) { - mapMarkers.add(marker); - } - } - } - } - return mapMarkers; - } - - private void loadGroups() { - Map groupsMap = markersDbHelper.getAllGroupsMap(); - List allMarkers = new ArrayList<>(markersHelper.getMapMarkers()); - allMarkers.addAll(markersHelper.getMapMarkersHistory()); - - Iterator> iterator = groupsMap.entrySet().iterator(); - while (iterator.hasNext()) { - ItineraryGroup group = iterator.next().getValue(); - if (group.getType() == ItineraryGroup.GPX_TYPE && !new File(group.getId()).exists()) { - markersDbHelper.removeMarkersGroup(group.getId()); - iterator.remove(); - } - } - - ItineraryGroup noGroup = null; - - for (MapMarker marker : allMarkers) { - ItineraryGroup group = groupsMap.get(marker.groupKey); - if (group == null) { - if (noGroup == null) { - noGroup = new ItineraryGroup(); - noGroup.setCreationDate(Long.MAX_VALUE); - } - noGroup.getMarkers().add(marker); - } else { - if (marker.creationDate < group.getCreationDate()) { - group.setCreationDate(marker.creationDate); - } - group.getMarkers().add(marker); - } - } - - itineraryGroups = new ArrayList<>(groupsMap.values()); - if (noGroup != null) { - markersHelper.sortMarkers(noGroup.getMarkers(), false, BY_DATE_ADDED_DESC); - addToGroupsList(noGroup); - } - - sortGroups(); - - for (ItineraryGroup group : itineraryGroups) { - markersHelper.updateGroup(group); - } - } - - public void addGroupInternally(ItineraryGroup gr) { - markersDbHelper.addGroup(gr); - markersHelper.addHistoryMarkersToGroup(gr); - addToGroupsList(gr); - } - - public void updateGpxShowAsMarkers(File file) { - GPXDatabase.GpxDataItem dataItem = app.getGpxDbHelper().getItem(file); - if (dataItem != null) { - app.getGpxDbHelper().updateShowAsMarkers(dataItem, true); - dataItem.setShowAsMarkers(true); - } - } - - public void addToGroupsList(ItineraryGroup group) { - List copyList = new ArrayList<>(itineraryGroups); - copyList.add(group); - itineraryGroups = copyList; - } - - public void removeFromGroupsList(ItineraryGroup group) { - List copyList = new ArrayList<>(itineraryGroups); - copyList.remove(group); - itineraryGroups = copyList; } public void addSyncListener(OnGroupSyncedListener listener) { @@ -202,7 +53,7 @@ public class ItineraryHelper { syncListeners.remove(listener); } - public void runSynchronization(final @NonNull ItineraryGroup group) { + public void runSynchronization(final @NonNull MapMarkersGroup group) { app.runInUIThread(new Runnable() { @Override public void run() { @@ -211,146 +62,11 @@ public class ItineraryHelper { }); } - public ItineraryGroup getMarkersGroup(GPXFile gpx) { - if (gpx == null || gpx.path == null) { - return null; - } - return getMapMarkerGroupById(getMarkerGroupId(new File(gpx.path)), ItineraryGroup.GPX_TYPE); - } - - public ItineraryGroup getMarkersGroup(FavoriteGroup favGroup) { - return getMapMarkerGroupById(getMarkerGroupId(favGroup), ItineraryGroup.FAVORITES_TYPE); - } - - public ItineraryGroup addOrEnableGpxGroup(@NonNull File file) { - updateGpxShowAsMarkers(file); - ItineraryGroup gr = getMapMarkerGroupById(getMarkerGroupId(file), ItineraryGroup.GPX_TYPE); - if (gr == null) { - gr = createGPXMarkerGroup(file); - addGroupInternally(gr); - } - enableGroup(gr); - return gr; - } - - public ItineraryGroup addOrEnableGroup(@NonNull GPXFile file) { - updateGpxShowAsMarkers(new File(file.path)); - ItineraryGroup gr = getMarkersGroup(file); - if (gr == null) { - gr = createGPXMarkerGroup(new File(file.path)); - addGroupInternally(gr); - } - enableGroup(gr); - return gr; - } - - public ItineraryGroup addOrEnableGroup(@NonNull FavoriteGroup group) { - ItineraryGroup gr = getMarkersGroup(group); - if (gr == null) { - gr = createFavMarkerGroup(group); - addGroupInternally(gr); - } - enableGroup(gr); - return gr; - } - - private ItineraryGroup createGPXMarkerGroup(File fl) { - return new ItineraryGroup(getMarkerGroupId(fl), - Algorithms.getFileNameWithoutExtension(fl.getName()), - ItineraryGroup.GPX_TYPE); - } - - private ItineraryGroup createFavMarkerGroup(FavoriteGroup favGroup) { - return new ItineraryGroup(favGroup.getName(), favGroup.getName(), ItineraryGroup.FAVORITES_TYPE); - } - - private String getMarkerGroupId(File gpx) { - return gpx.getAbsolutePath(); - } - - private String getMarkerGroupId(FavoriteGroup group) { - return group.getName(); - } - - - public void removeMarkerFromGroup(MapMarker marker) { - if (marker != null) { - ItineraryGroup itineraryGroup = getMapMarkerGroupById(marker.groupKey, marker.getType()); - if (itineraryGroup != null) { - itineraryGroup.getMarkers().remove(marker); - markersHelper.updateGroup(itineraryGroup); - } - } - } - - public void sortGroups() { - if (itineraryGroups.size() > 0) { - Collections.sort(itineraryGroups, new Comparator() { - @Override - public int compare(ItineraryGroup group1, ItineraryGroup group2) { - long t1 = group1.getCreationDate(); - long t2 = group2.getCreationDate(); - return (t1 > t2) ? -1 : ((t1 == t2) ? 0 : 1); - } - }); - } - } - - @Nullable - public ItineraryGroup getMapMarkerGroupById(String id, int type) { - for (ItineraryGroup group : itineraryGroups) { - if ((id == null && group.getId() == null) - || (group.getId() != null && group.getId().equals(id))) { - if (type == ItineraryGroup.ANY_TYPE || type == group.getType()) { - return group; - } - } - } - return null; - } - - @NonNull - public List getGroupsForDisplayedGpx() { - List res = new ArrayList<>(); - List selectedGpxFiles = app.getSelectedGpxHelper().getSelectedGPXFiles(); - for (SelectedGpxFile selected : selectedGpxFiles) { - ItineraryGroup search = getMarkersGroup(selected.getGpxFile()); - if (search == null && selected.getGpxFile() != null && selected.getGpxFile().path != null) { - ItineraryGroup group = createGPXMarkerGroup(new File(selected.getGpxFile().path)); - group.setDisabled(true); - markersHelper.createHeadersInGroup(group); - res.add(group); - } - } - return res; - } - - @NonNull - public List getGroupsForSavedArticlesTravelBook() { - List res = new ArrayList<>(); - TravelHelper travelHelper = app.getTravelHelper(); - if (travelHelper.isAnyTravelBookPresent()) { - List savedArticles = travelHelper.getBookmarksHelper().getSavedArticles(); - for (TravelArticle art : savedArticles) { - String gpxName = travelHelper.getGPXName(art); - File path = app.getAppPath(IndexConstants.GPX_TRAVEL_DIR + gpxName); - ItineraryGroup search = getMapMarkerGroupById(getMarkerGroupId(path), ItineraryGroup.GPX_TYPE); - if (search == null) { - ItineraryGroup group = createGPXMarkerGroup(path); - group.setDisabled(true); - markersHelper.createHeadersInGroup(group); - res.add(group); - } - } - } - return res; - } - private class SyncGroupTask extends AsyncTask { - private ItineraryGroup group; + private MapMarkersGroup group; - SyncGroupTask(ItineraryGroup group) { + SyncGroupTask(MapMarkersGroup group) { this.group = group; } @@ -377,7 +93,7 @@ public class ItineraryHelper { // TODO extract method from Asynctask to Helper directly private void runGroupSynchronization() { List groupMarkers = new ArrayList<>(group.getMarkers()); - if (group.getType() == ItineraryGroup.FAVORITES_TYPE) { + if (group.getType() == MapMarkersGroup.FAVORITES_TYPE) { FavoriteGroup favGroup = app.getFavorites().getGroup(group.getName()); if (favGroup == null) { return; @@ -391,7 +107,7 @@ public class ItineraryHelper { for (FavouritePoint fp : points) { markersHelper.addNewMarkerIfNeeded(group, groupMarkers, new LatLon(fp.getLatitude(), fp.getLongitude()), fp.getName(), fp, null); } - } else if (group.getType() == ItineraryGroup.GPX_TYPE) { + } else if (group.getType() == MapMarkersGroup.GPX_TYPE) { GpxSelectionHelper gpxHelper = app.getSelectedGpxHelper(); File file = new File(group.getId()); if (!file.exists()) { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java index 713b13a177..e1c1ac3d61 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java @@ -24,7 +24,7 @@ import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.base.PointImageDrawable; import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.editors.WptPtEditor.OnDismissListener; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.util.Algorithms; @@ -219,7 +219,7 @@ public class WptPtEditorFragment extends PointEditorFragment { private void syncGpx(GPXFile gpxFile) { OsmandApplication app = getMyApplication(); if (app != null) { - ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile); + MapMarkersGroup group = app.getMapMarkersHelper().getMarkersGroup(gpxFile); if (group != null) { app.getItineraryHelper().runSynchronization(group); } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java index 827151a691..4dea53b0bd 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java @@ -27,9 +27,9 @@ import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.base.PointImageDrawable; -import net.osmand.plus.itinerary.ItineraryGroup; import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.editors.WptPtEditor.OnDismissListener; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.util.Algorithms; @@ -237,7 +237,7 @@ public class WptPtEditorFragmentNew extends PointEditorFragmentNew { private void syncGpx(GPXFile gpxFile) { OsmandApplication app = getMyApplication(); if (app != null) { - ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile); + MapMarkersGroup group = app.getMapMarkersHelper().getMarkersGroup(gpxFile); if (group != null) { app.getItineraryHelper().runSynchronization(group); } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java index 52f85bf0e7..0e6b31f4f4 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddFavouritesGroupBottomSheetDialogFragment.java @@ -56,7 +56,7 @@ public class AddFavouritesGroupBottomSheetDialogFragment extends AddGroupBottomS if (!group.isVisible()) { favouritesDbHelper.editFavouriteGroup(group, group.getName(), group.getColor(), true); } - getMyApplication().getItineraryHelper().addOrEnableGroup(group); + getMyApplication().getMapMarkersHelper().addOrEnableGroup(group); dismiss(); } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java index 32dfd58172..b01548be00 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/AddTracksGroupBottomSheetDialogFragment.java @@ -108,7 +108,7 @@ public class AddTracksGroupBottomSheetDialogFragment extends AddGroupBottomSheet GPXFile res = GPXUtilities.loadGPXFile(gpx); selectionHelper.selectGpxFile(res, true, false, false, false, false); } - app.getItineraryHelper().addOrEnableGpxGroup(gpx); + app.getMapMarkersHelper().addOrEnableGpxGroup(gpx); } } dismiss(); diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/CategoriesSubHeader.java b/OsmAnd/src/net/osmand/plus/mapmarkers/CategoriesSubHeader.java index 52ea71617b..aef2f28afd 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/CategoriesSubHeader.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/CategoriesSubHeader.java @@ -2,15 +2,13 @@ package net.osmand.plus.mapmarkers; import androidx.annotation.DrawableRes; -import net.osmand.plus.itinerary.ItineraryGroup; - public class CategoriesSubHeader { @DrawableRes private int iconRes; - private ItineraryGroup group; + private MapMarkersGroup group; - public CategoriesSubHeader(int iconRes, ItineraryGroup group) { + public CategoriesSubHeader(int iconRes, MapMarkersGroup group) { this.iconRes = iconRes; this.group = group; } @@ -20,7 +18,7 @@ public class CategoriesSubHeader { return iconRes; } - public ItineraryGroup getGroup() { + public MapMarkersGroup getGroup() { return group; } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java index 138109f126..31e477fbf1 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java @@ -71,8 +71,6 @@ import net.osmand.plus.Version; import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.activities.TrackActivity; import net.osmand.plus.helpers.AndroidUiHelper; -import net.osmand.plus.itinerary.ItineraryGroup; -import net.osmand.plus.itinerary.ItineraryHelper; import net.osmand.plus.mapmarkers.CoordinateInputBottomSheetDialogFragment.CoordinateInputFormatChangeListener; import net.osmand.plus.mapmarkers.CoordinateInputFormats.DDM; import net.osmand.plus.mapmarkers.CoordinateInputFormats.DMS; @@ -170,10 +168,10 @@ public class CoordinateInputDialogFragment extends DialogFragment implements Osm } private void syncGpx(GPXFile gpxFile) { - ItineraryHelper helper = getMyApplication().getItineraryHelper(); - ItineraryGroup group = helper.getMarkersGroup(gpxFile); + MapMarkersHelper helper = getMyApplication().getMapMarkersHelper(); + MapMarkersGroup group = helper.getMarkersGroup(gpxFile); if (group != null) { - helper.runSynchronization(group); + getMyApplication().getItineraryHelper().runSynchronization(group); } } @@ -1091,7 +1089,7 @@ public class CoordinateInputDialogFragment extends DialogFragment implements Osm public void saveGpx(final String fileName) { new SaveGpxAsyncTask(app, getGpx(),fileName, false).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); hasUnsavedChanges = false; - app.getItineraryHelper().addOrEnableGroup(getGpx()); + app.getMapMarkersHelper().addOrEnableGroup(getGpx()); if (listener != null) { listener.onPointsSaved(); } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/GroupHeader.java b/OsmAnd/src/net/osmand/plus/mapmarkers/GroupHeader.java index c760b08dee..c5c97a1c2e 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/GroupHeader.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/GroupHeader.java @@ -2,15 +2,13 @@ package net.osmand.plus.mapmarkers; import androidx.annotation.DrawableRes; -import net.osmand.plus.itinerary.ItineraryGroup; - public class GroupHeader { @DrawableRes private int iconRes; - private ItineraryGroup group; + private MapMarkersGroup group; - public GroupHeader(int iconRes, ItineraryGroup group) { + public GroupHeader(int iconRes, MapMarkersGroup group) { this.iconRes = iconRes; this.group = group; } @@ -20,7 +18,7 @@ public class GroupHeader { return iconRes; } - public ItineraryGroup getGroup() { + public MapMarkersGroup getGroup() { return group; } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarker.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarker.java index e1f2c413f1..498c36f93c 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarker.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarker.java @@ -11,7 +11,6 @@ import net.osmand.data.LatLon; import net.osmand.data.LocationPoint; import net.osmand.data.PointDescription; import net.osmand.plus.R; -import net.osmand.plus.itinerary.ItineraryGroup; import net.osmand.util.Algorithms; import static net.osmand.data.PointDescription.POINT_TYPE_MAP_MARKER; @@ -47,8 +46,8 @@ public class MapMarker implements LocationPoint { public int getType() { return favouritePoint == null ? - (wptPt == null ? ItineraryGroup.ANY_TYPE : ItineraryGroup.GPX_TYPE) : - ItineraryGroup.FAVORITES_TYPE; + (wptPt == null ? MapMarkersGroup.ANY_TYPE : MapMarkersGroup.GPX_TYPE) : + MapMarkersGroup.FAVORITES_TYPE; } public PointDescription getPointDescription(Context ctx) { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java index 4fe3debbb5..0b2ba5ab0c 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDbHelper.java @@ -8,7 +8,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.api.SQLiteAPI.SQLiteConnection; import net.osmand.plus.api.SQLiteAPI.SQLiteCursor; import net.osmand.plus.helpers.SearchHistoryHelper; -import net.osmand.plus.itinerary.ItineraryGroup; import net.osmand.util.Algorithms; import java.util.ArrayList; @@ -162,7 +161,7 @@ public class MapMarkersDbHelper { } } - public void addGroup(ItineraryGroup group) { + public void addGroup(MapMarkersGroup group) { SQLiteConnection db = openConnection(false); if (db != null) { try { @@ -174,15 +173,15 @@ public class MapMarkersDbHelper { } } - public Map getAllGroupsMap() { - Map res = new LinkedHashMap<>(); + public Map getAllGroupsMap() { + Map res = new LinkedHashMap<>(); SQLiteConnection db = openConnection(true); if (db != null) { try { SQLiteCursor query = db.rawQuery(GROUPS_TABLE_SELECT, null); if (query != null && query.moveToFirst()) { do { - ItineraryGroup group = readGroup(query); + MapMarkersGroup group = readGroup(query); res.put(group.getId(), group); } while (query.moveToNext()); } @@ -196,14 +195,14 @@ public class MapMarkersDbHelper { return res; } - private ItineraryGroup readGroup(SQLiteCursor query) { + private MapMarkersGroup readGroup(SQLiteCursor query) { String id = query.getString(0); String name = query.getString(1); int type = query.getInt(2); boolean disabled = query.getInt(3) == 1; String categories = query.getString(4); - ItineraryGroup res = new ItineraryGroup(id, name, type); + MapMarkersGroup res = new MapMarkersGroup(id, name, type); res.setDisabled(disabled); res.setWptCategories(categories == null ? null : Algorithms.decodeStringSet(categories)); diff --git a/OsmAnd/src/net/osmand/plus/itinerary/ItineraryGroup.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroup.java similarity index 91% rename from OsmAnd/src/net/osmand/plus/itinerary/ItineraryGroup.java rename to OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroup.java index 595315a028..2a97af91c8 100644 --- a/OsmAnd/src/net/osmand/plus/itinerary/ItineraryGroup.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroup.java @@ -1,12 +1,8 @@ -package net.osmand.plus.itinerary; +package net.osmand.plus.mapmarkers; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.osmand.plus.mapmarkers.CategoriesSubHeader; -import net.osmand.plus.mapmarkers.GroupHeader; -import net.osmand.plus.mapmarkers.MapMarker; -import net.osmand.plus.mapmarkers.ShowHideHistoryButton; import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.util.Algorithms; @@ -14,7 +10,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; -public class ItineraryGroup { +public class MapMarkersGroup { public static final int ANY_TYPE = -1; public static final int FAVORITES_TYPE = 0; @@ -38,11 +34,11 @@ public class ItineraryGroup { private CategoriesSubHeader categoriesSubHeader; private ShowHideHistoryButton showHideHistoryButton; - public ItineraryGroup() { + public MapMarkersGroup() { } - public ItineraryGroup(@NonNull String id, @NonNull String name, int type) { + public MapMarkersGroup(@NonNull String id, @NonNull String name, int type) { this.id = id; this.name = name; this.type = type; diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java index 1f2233b7c0..b8bcddbc5c 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java @@ -14,12 +14,16 @@ import net.osmand.PlatformUtil; import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; +import net.osmand.plus.FavouritesDbHelper.FavoriteGroup; +import net.osmand.plus.GPXDatabase; import net.osmand.plus.GeocodingLookupService; import net.osmand.plus.GeocodingLookupService.AddressLookupRequest; +import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.Version; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.wikivoyage.data.TravelArticle; +import net.osmand.plus.wikivoyage.data.TravelHelper; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; @@ -37,6 +41,8 @@ import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Map; +import java.util.Set; import java.util.TimeZone; import static net.osmand.GPXUtilities.GPX_TIME_FORMAT; @@ -63,11 +69,12 @@ public class MapMarkersHelper { public @interface MapMarkersSortByDef { } - private OsmandApplication app; + private OsmandApplication ctx; private MapMarkersDbHelper markersDbHelper; private List mapMarkers = new ArrayList<>(); private List mapMarkersHistory = new ArrayList<>(); + private List mapMarkersGroups = new ArrayList<>(); private List listeners = new ArrayList<>(); @@ -81,24 +88,29 @@ public class MapMarkersHelper { return mapMarkersHistory; } + public List getMapMarkersGroups() { + return mapMarkersGroups; + } + public boolean isStartFromMyLocation() { - return app.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.get(); + return ctx.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.get(); } public void setStartFromMyLocation(boolean startFromMyLocation) { - app.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.set(startFromMyLocation); + ctx.getSettings().ROUTE_MAP_MARKERS_START_MY_LOC.set(startFromMyLocation); } public MarkersPlanRouteContext getPlanRouteContext() { return planRouteContext; } - public MapMarkersHelper(OsmandApplication app) { - this.app = app; - markersDbHelper = app.getMapMarkersDbHelper(); - planRouteContext = new MarkersPlanRouteContext(app); + public MapMarkersHelper(OsmandApplication ctx) { + this.ctx = ctx; + markersDbHelper = ctx.getMapMarkersDbHelper(); + planRouteContext = new MarkersPlanRouteContext(ctx); markersDbHelper.removeDisabledGroups(); loadMarkers(); + loadGroups(); } private void loadMarkers() { @@ -112,11 +124,63 @@ public class MapMarkersHelper { sortMarkers(markersHistory, true, BY_DATE_ADDED_DESC); addToMapMarkersHistoryList(markersHistory); - if (!app.isApplicationInitializing()) { + if (!ctx.isApplicationInitializing()) { lookupAddressAll(); } } + private void loadGroups() { + Map groupsMap = markersDbHelper.getAllGroupsMap(); + List allMarkers = new ArrayList<>(mapMarkers); + allMarkers.addAll(mapMarkersHistory); + + Iterator> iterator = groupsMap.entrySet().iterator(); + while (iterator.hasNext()) { + MapMarkersGroup group = iterator.next().getValue(); + if (group.getType() == MapMarkersGroup.GPX_TYPE && !new File(group.getId()).exists()) { + markersDbHelper.removeMarkersGroup(group.getId()); + iterator.remove(); + } + } + + MapMarkersGroup noGroup = null; + + for (MapMarker marker : allMarkers) { + MapMarkersGroup group = groupsMap.get(marker.groupKey); + if (group == null) { + if (noGroup == null) { + noGroup = new MapMarkersGroup(); + noGroup.setCreationDate(Long.MAX_VALUE); + } + noGroup.getMarkers().add(marker); + } else { + if (marker.creationDate < group.getCreationDate()) { + group.setCreationDate(marker.creationDate); + } + group.getMarkers().add(marker); + } + } + + mapMarkersGroups = new ArrayList<>(groupsMap.values()); + if (noGroup != null) { + sortMarkers(noGroup.getMarkers(), false, BY_DATE_ADDED_DESC); + addToGroupsList(noGroup); + } + + sortGroups(); + + for (MapMarkersGroup group : mapMarkersGroups) { + updateGroup(group); + } + } + + public void syncAllGroupsAsync() { + for (MapMarkersGroup gr : mapMarkersGroups) { + if (gr.getId() != null && gr.getName() != null) { + ctx.getItineraryHelper().runSynchronization(gr); + } + } + } public void lookupAddressAll() { for (MapMarker mapMarker : mapMarkers) { @@ -128,7 +192,7 @@ public class MapMarkersHelper { } private void lookupAddress(final MapMarker mapMarker) { - if (mapMarker != null && mapMarker.getOriginalPointDescription().isSearchingAddress(app)) { + if (mapMarker != null && mapMarker.getOriginalPointDescription().isSearchingAddress(ctx)) { cancelPointAddressRequests(mapMarker.point); AddressLookupRequest lookupRequest = new AddressLookupRequest(mapMarker.point, new GeocodingLookupService.OnAddressLookupResult() { @@ -136,7 +200,7 @@ public class MapMarkersHelper { public void geocodingDone(String address) { PointDescription pointDescription = mapMarker.getOriginalPointDescription(); if (Algorithms.isEmpty(address)) { - pointDescription.setName(PointDescription.getAddressNotFoundStr(app)); + pointDescription.setName(PointDescription.getAddressNotFoundStr(ctx)); } else { pointDescription.setName(address); } @@ -144,7 +208,7 @@ public class MapMarkersHelper { refreshMarker(mapMarker); } }, null); - app.getGeocodingLookupService().lookupAddress(lookupRequest); + ctx.getGeocodingLookupService().lookupAddress(lookupRequest); } } @@ -161,7 +225,7 @@ public class MapMarkersHelper { private void cancelPointAddressRequests(LatLon latLon) { if (latLon != null) { - app.getGeocodingLookupService().cancel(latLon); + ctx.getGeocodingLookupService().cancel(latLon); } } @@ -190,7 +254,7 @@ public class MapMarkersHelper { reorderActiveMarkersIfNeeded(); } - public void sortMarkers(List markers, final boolean visited, final @MapMarkersSortByDef int sortByMode) { + private void sortMarkers(List markers, final boolean visited, final @MapMarkersSortByDef int sortByMode) { sortMarkers(markers, visited, sortByMode, null); } @@ -222,15 +286,83 @@ public class MapMarkersHelper { return sortByMode == BY_DISTANCE_DESC ? 1 : -1; } } else { - String n1 = mapMarker1.getName(app); - String n2 = mapMarker2.getName(app); + String n1 = mapMarker1.getName(ctx); + String n2 = mapMarker2.getName(ctx); return n1.compareToIgnoreCase(n2); } } }); } - public void addHistoryMarkersToGroup(@NonNull ItineraryGroup group) { + public MapMarkersGroup getMarkersGroup(GPXFile gpx) { + if (gpx == null || gpx.path == null) { + return null; + } + return getMapMarkerGroupById(getMarkerGroupId(new File(gpx.path)), MapMarkersGroup.GPX_TYPE); + } + + public MapMarkersGroup getMarkersGroup(FavoriteGroup favGroup) { + return getMapMarkerGroupById(getMarkerGroupId(favGroup), MapMarkersGroup.FAVORITES_TYPE); + } + + public MapMarkersGroup addOrEnableGpxGroup(@NonNull File file) { + updateGpxShowAsMarkers(file); + MapMarkersGroup gr = getMapMarkerGroupById(getMarkerGroupId(file), MapMarkersGroup.GPX_TYPE); + if (gr == null) { + gr = createGPXMarkerGroup(file); + addGroupInternally(gr); + } + enableGroup(gr); + return gr; + } + + public MapMarkersGroup addOrEnableGroup(@NonNull GPXFile file) { + updateGpxShowAsMarkers(new File(file.path)); + MapMarkersGroup gr = getMarkersGroup(file); + if (gr == null) { + gr = createGPXMarkerGroup(new File(file.path)); + addGroupInternally(gr); + } + enableGroup(gr); + return gr; + } + + public MapMarkersGroup addOrEnableGroup(@NonNull FavoriteGroup group) { + MapMarkersGroup gr = getMarkersGroup(group); + if (gr == null) { + gr = createFavMarkerGroup(group); + addGroupInternally(gr); + } + enableGroup(gr); + return gr; + } + + public void enableGroup(@NonNull MapMarkersGroup gr) { + // check if group doesn't exist internally + if (!mapMarkersGroups.contains(gr)) { + addGroupInternally(gr); + } + if (gr.isDisabled()) { + updateGroupDisabled(gr, false); + } + ctx.getItineraryHelper().runSynchronization(gr); + } + + private void addGroupInternally(MapMarkersGroup gr) { + markersDbHelper.addGroup(gr); + addHistoryMarkersToGroup(gr); + addToGroupsList(gr); + } + + private void updateGpxShowAsMarkers(File file) { + GPXDatabase.GpxDataItem dataItem = ctx.getGpxDbHelper().getItem(file); + if (dataItem != null) { + ctx.getGpxDbHelper().updateShowAsMarkers(dataItem, true); + dataItem.setShowAsMarkers(true); + } + } + + private void addHistoryMarkersToGroup(@NonNull MapMarkersGroup group) { List historyMarkers = new ArrayList<>(mapMarkersHistory); for (MapMarker m : historyMarkers) { if (m.groupKey != null && group.getId() != null && m.groupKey.equals(group.getId())) { @@ -239,15 +371,33 @@ public class MapMarkersHelper { } } - public void removeMarkersGroup(ItineraryGroup group) { + public void removeMarkersGroup(MapMarkersGroup group) { if (group != null) { markersDbHelper.removeMarkersGroup(group.getId()); removeGroupActiveMarkers(group, false); - app.getItineraryHelper().removeFromGroupsList(group); + removeFromGroupsList(group); } } - public void removeGroupActiveMarkers(ItineraryGroup group, boolean updateGroup) { + public void updateGroupDisabled(@NonNull MapMarkersGroup group, boolean disabled) { + String id = group.getId(); + if (id != null) { + markersDbHelper.updateGroupDisabled(id, disabled); + group.setDisabled(disabled); + } + } + + public void updateGroupWptCategories(@NonNull MapMarkersGroup group, Set wptCategories) { + String id = group.getId(); + if (id != null) { + group.setWptCategories(wptCategories); + if (wptCategories != null) { + markersDbHelper.updateGroupCategories(id, group.getWptCategoriesString()); + } + } + } + + public void removeGroupActiveMarkers(MapMarkersGroup group, boolean updateGroup) { if (group != null) { markersDbHelper.removeActiveMarkersFromGroup(group.getId()); removeFromMapMarkersList(group.getActiveMarkers()); @@ -260,21 +410,27 @@ public class MapMarkersHelper { } } - public void updateGroup(ItineraryGroup itineraryGroup) { - if (itineraryGroup.getId() == null || itineraryGroup.getName() == null) { + public void updateGroups() { + for (MapMarkersGroup group : mapMarkersGroups) { + updateGroup(group); + } + } + + public void updateGroup(MapMarkersGroup mapMarkersGroup) { + if (mapMarkersGroup.getId() == null || mapMarkersGroup.getName() == null) { return; } - createHeadersInGroup(itineraryGroup); - int historyMarkersCount = itineraryGroup.getHistoryMarkers().size(); - ShowHideHistoryButton showHideHistoryButton = itineraryGroup.getShowHideHistoryButton(); + createHeadersInGroup(mapMarkersGroup); + int historyMarkersCount = mapMarkersGroup.getHistoryMarkers().size(); + ShowHideHistoryButton showHideHistoryButton = mapMarkersGroup.getShowHideHistoryButton(); if (showHideHistoryButton != null) { if (historyMarkersCount == 0) { - itineraryGroup.setShowHideHistoryButton(null); + mapMarkersGroup.setShowHideHistoryButton(null); } } else if (historyMarkersCount > 0) { showHideHistoryButton = new ShowHideHistoryButton(); showHideHistoryButton.showHistory = false; - itineraryGroup.setShowHideHistoryButton(showHideHistoryButton); + mapMarkersGroup.setShowHideHistoryButton(showHideHistoryButton); } } @@ -286,30 +442,30 @@ public class MapMarkersHelper { private void addMarkerToGroup(MapMarker marker) { if (marker != null) { - ItineraryGroup itineraryGroup = app.getItineraryHelper().getMapMarkerGroupById(marker.groupKey, marker.getType()); - if (itineraryGroup != null) { - itineraryGroup.getMarkers().add(marker); - updateGroup(itineraryGroup); - if (itineraryGroup.getName() == null) { - sortMarkers(itineraryGroup.getMarkers(), false, BY_DATE_ADDED_DESC); + MapMarkersGroup mapMarkersGroup = getMapMarkerGroupById(marker.groupKey, marker.getType()); + if (mapMarkersGroup != null) { + mapMarkersGroup.getMarkers().add(marker); + updateGroup(mapMarkersGroup); + if (mapMarkersGroup.getName() == null) { + sortMarkers(mapMarkersGroup.getMarkers(), false, BY_DATE_ADDED_DESC); } } else { - itineraryGroup = new ItineraryGroup(marker.groupKey, marker.groupName, ItineraryGroup.ANY_TYPE); - itineraryGroup.setCreationDate(Long.MAX_VALUE); - itineraryGroup.getMarkers().add(marker); - app.getItineraryHelper().addToGroupsList(itineraryGroup); - app.getItineraryHelper().sortGroups(); - updateGroup(itineraryGroup); + mapMarkersGroup = new MapMarkersGroup(marker.groupKey, marker.groupName, MapMarkersGroup.ANY_TYPE); + mapMarkersGroup.setCreationDate(Long.MAX_VALUE); + mapMarkersGroup.getMarkers().add(marker); + addToGroupsList(mapMarkersGroup); + sortGroups(); + updateGroup(mapMarkersGroup); } } } - public void createHeadersInGroup(@NonNull ItineraryGroup group) { + private void createHeadersInGroup(@NonNull MapMarkersGroup group) { int type = group.getType(); int headerIconId = 0; int subHeaderIconId = 0; if (type != -1) { - headerIconId = type == ItineraryGroup.FAVORITES_TYPE + headerIconId = type == MapMarkersGroup.FAVORITES_TYPE ? R.drawable.ic_action_favorite : R.drawable.ic_action_polygom_dark; subHeaderIconId = R.drawable.ic_action_filter; } @@ -320,6 +476,97 @@ public class MapMarkersHelper { group.setCategoriesSubHeader(categoriesSubHeader); } + private void removeMarkerFromGroup(MapMarker marker) { + if (marker != null) { + MapMarkersGroup mapMarkersGroup = getMapMarkerGroupById(marker.groupKey, marker.getType()); + if (mapMarkersGroup != null) { + mapMarkersGroup.getMarkers().remove(marker); + updateGroup(mapMarkersGroup); + } + } + } + + private void sortGroups() { + if (mapMarkersGroups.size() > 0) { + Collections.sort(mapMarkersGroups, new Comparator() { + @Override + public int compare(MapMarkersGroup group1, MapMarkersGroup group2) { + long t1 = group1.getCreationDate(); + long t2 = group2.getCreationDate(); + return (t1 > t2) ? -1 : ((t1 == t2) ? 0 : 1); + } + }); + } + } + + @Nullable + public MapMarkersGroup getMapMarkerGroupById(String id, int type) { + for (MapMarkersGroup group : mapMarkersGroups) { + if ((id == null && group.getId() == null) + || (group.getId() != null && group.getId().equals(id))) { + if (type == MapMarkersGroup.ANY_TYPE || type == group.getType()) { + return group; + } + } + } + return null; + } + + private MapMarkersGroup createGPXMarkerGroup(File fl) { + return new MapMarkersGroup(getMarkerGroupId(fl), + Algorithms.getFileNameWithoutExtension(fl.getName()), + MapMarkersGroup.GPX_TYPE); + } + + private MapMarkersGroup createFavMarkerGroup(FavoriteGroup favGroup) { + return new MapMarkersGroup(favGroup.getName(), favGroup.getName(), MapMarkersGroup.FAVORITES_TYPE); + } + + private String getMarkerGroupId(File gpx) { + return gpx.getAbsolutePath(); + } + + private String getMarkerGroupId(FavoriteGroup group) { + return group.getName(); + } + + @NonNull + public List getGroupsForDisplayedGpx() { + List res = new ArrayList<>(); + List selectedGpxFiles = ctx.getSelectedGpxHelper().getSelectedGPXFiles(); + for (SelectedGpxFile selected : selectedGpxFiles) { + MapMarkersGroup search = getMarkersGroup(selected.getGpxFile()); + if (search == null && selected.getGpxFile() != null && selected.getGpxFile().path != null) { + MapMarkersGroup group = createGPXMarkerGroup(new File(selected.getGpxFile().path)); + group.setDisabled(true); + createHeadersInGroup(group); + res.add(group); + } + } + return res; + } + + @NonNull + public List getGroupsForSavedArticlesTravelBook() { + List res = new ArrayList<>(); + TravelHelper travelHelper = ctx.getTravelHelper(); + if (travelHelper.isAnyTravelBookPresent()) { + List savedArticles = travelHelper.getBookmarksHelper().getSavedArticles(); + for (TravelArticle art : savedArticles) { + String gpxName = travelHelper.getGPXName(art); + File path = ctx.getAppPath(IndexConstants.GPX_TRAVEL_DIR + gpxName); + MapMarkersGroup search = getMapMarkerGroupById(getMarkerGroupId(path), MapMarkersGroup.GPX_TYPE); + if (search == null) { + MapMarkersGroup group = createGPXMarkerGroup(path); + group.setDisabled(true); + createHeadersInGroup(group); + res.add(group); + } + } + } + return res; + } + @Nullable public MapMarker getMapMarker(WptPt wptPt) { for (MapMarker marker : getMarkers()) { @@ -352,7 +599,7 @@ public class MapMarkersHelper { private List getMarkers() { List res = new ArrayList<>(mapMarkers); - if (app.getSettings().KEEP_PASSED_MARKERS_ON_MAP.get()) { + if (ctx.getSettings().KEEP_PASSED_MARKERS_ON_MAP.get()) { res.addAll(mapMarkersHistory); } return res; @@ -371,7 +618,7 @@ public class MapMarkersHelper { return null; } - public void addNewMarkerIfNeeded(@NonNull ItineraryGroup group, + public void addNewMarkerIfNeeded(@NonNull MapMarkersGroup group, @NonNull List groupMarkers, @NonNull LatLon latLon, @NonNull String name, @@ -473,7 +720,7 @@ public class MapMarkersHelper { addToMapMarkersList(markers); reorderActiveMarkersIfNeeded(); sortMarkers(mapMarkersHistory, true, BY_DATE_ADDED_DESC); - app.getItineraryHelper().updateGroups(); + updateGroups(); refresh(); } } @@ -490,7 +737,7 @@ public class MapMarkersHelper { } else { removeFromMapMarkersList(marker); } - app.getItineraryHelper().removeMarkerFromGroup(marker); + removeMarkerFromGroup(marker); if (refresh) { refresh(); } @@ -587,7 +834,7 @@ public class MapMarkersHelper { addToMapMarkersHistoryList(mapMarkers); mapMarkers = new ArrayList<>(); sortMarkers(mapMarkersHistory, true, BY_DATE_ADDED_DESC); - app.getItineraryHelper().updateGroups(); + updateGroups(); refresh(); } @@ -608,18 +855,18 @@ public class MapMarkersHelper { public void addMapMarkers(@NonNull List points, @NonNull List historyNames, - @Nullable ItineraryGroup group) { + @Nullable MapMarkersGroup group) { addMarkers(points, historyNames, group, null, null, null); } private void addMarkers(@NonNull List points, @NonNull List historyNames, - @Nullable ItineraryGroup group, + @Nullable MapMarkersGroup group, @Nullable List favouritePoints, @Nullable List wptPts, @Nullable List mapObjNames) { if (points.size() > 0) { - app.getSettings().SHOW_MAP_MARKERS.set(true); + ctx.getSettings().SHOW_MAP_MARKERS.set(true); int colorIndex = -1; List addedMarkers = new ArrayList<>(); for (int i = 0; i < points.size(); i++) { @@ -635,7 +882,7 @@ public class MapMarkersHelper { pointDescription = historyName; } if (pointDescription.isLocation() && Algorithms.isEmpty(pointDescription.getName())) { - pointDescription.setName(PointDescription.getSearchAddressStr(app)); + pointDescription.setName(PointDescription.getSearchAddressStr(ctx)); } if (colorIndex == -1) { if (mapMarkers.size() > 0) { @@ -649,7 +896,7 @@ public class MapMarkersHelper { MapMarker marker = new MapMarker(point, pointDescription, colorIndex, false, 0); if (group != null) { - marker.id = group.getId() + marker.getName(app) + MapUtils.createShortLinkString(marker.point.getLatitude(), marker.point.getLongitude(), 15); + marker.id = group.getId() + marker.getName(ctx) + MapUtils.createShortLinkString(marker.point.getLatitude(), marker.point.getLongitude(), 15); if (markersDbHelper.getMarker(marker.id) != null) { continue; } @@ -716,7 +963,7 @@ public class MapMarkersHelper { } private void refreshMarker(final MapMarker marker) { - app.runInUIThread(new Runnable() { + ctx.runInUIThread(new Runnable() { @Override public void run() { for (MapMarkerChangedListener l : listeners) { @@ -727,7 +974,7 @@ public class MapMarkersHelper { } private void refresh() { - app.runInUIThread(new Runnable() { + ctx.runInUIThread(new Runnable() { @Override public void run() { for (MapMarkerChangedListener l : listeners) { @@ -737,14 +984,28 @@ public class MapMarkersHelper { }); } + public List getMapMarkersFromDefaultGroups(boolean history) { + List mapMarkers = new ArrayList<>(); + for (MapMarkersGroup group : mapMarkersGroups) { + if (group.getType() == MapMarkersGroup.ANY_TYPE) { + for (MapMarker marker : group.getMarkers()) { + if (history && marker.history || !history && !marker.history) { + mapMarkers.add(marker); + } + } + } + } + return mapMarkers; + } + public String saveMarkersToFile(String fileName) { GPXFile gpxFile = generateGpx(); String dirName = IndexConstants.GPX_INDEX_DIR + IndexConstants.MAP_MARKERS_INDEX_DIR; - File dir = app.getAppPath(dirName); + File dir = ctx.getAppPath(dirName); if (!dir.exists()) { dir.mkdirs(); } - String uniqueFileName = FileUtils.createUniqueFileName(app, fileName, dirName, IndexConstants.GPX_FILE_EXT); + String uniqueFileName = FileUtils.createUniqueFileName(ctx, fileName, dirName, IndexConstants.GPX_FILE_EXT); File fout = new File(dir, uniqueFileName + IndexConstants.GPX_FILE_EXT); GPXUtilities.writeGpxFile(fout, gpxFile); @@ -759,13 +1020,13 @@ public class MapMarkersHelper { SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT, Locale.US); format.setTimeZone(TimeZone.getTimeZone("UTC")); - GPXFile gpxFile = new GPXFile(Version.getFullVersion(app)); + GPXFile gpxFile = new GPXFile(Version.getFullVersion(ctx)); for (MapMarker marker : markers) { WptPt wpt = new WptPt(); wpt.lat = marker.getLatitude(); wpt.lon = marker.getLongitude(); wpt.name = marker.getOnlyName(); - wpt.setColor(ContextCompat.getColor(app, MapMarker.getColorId(marker.colorIndex))); + wpt.setColor(ContextCompat.getColor(ctx, MapMarker.getColorId(marker.colorIndex))); if (completeBackup) { if (marker.creationDate != 0) { wpt.getExtensionsToWrite().put(CREATION_DATE, format.format(new Date(marker.creationDate))); @@ -786,7 +1047,7 @@ public class MapMarkersHelper { List mapMarkers = new ArrayList<>(); for (WptPt point : gpxFile.getPoints()) { LatLon latLon = new LatLon(point.lat, point.lon); - int colorIndex = MapMarker.getColorIndex(app, point.getColor()); + int colorIndex = MapMarker.getColorIndex(ctx, point.getColor()); PointDescription name = new PointDescription(PointDescription.POINT_TYPE_LOCATION, point.name); MapMarker marker = new MapMarker(latLon, name, colorIndex, false, 0); @@ -877,6 +1138,22 @@ public class MapMarkersHelper { mapMarkersHistory = copyList; } + // accessors to markers groups: + + private void addToGroupsList(MapMarkersGroup group) { + List copyList = new ArrayList<>(mapMarkersGroups); + copyList.add(group); + mapMarkersGroups = copyList; + } + + private void removeFromGroupsList(MapMarkersGroup group) { + List copyList = new ArrayList<>(mapMarkersGroups); + copyList.remove(group); + mapMarkersGroups = copyList; + } + + // --------------------------------------------------------------------------------------------- + // classes and interfaces: public interface MapMarkerChangedListener { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/SelectWptCategoriesBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/SelectWptCategoriesBottomSheetDialogFragment.java index 2cabb6f804..1f86a94a1d 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/SelectWptCategoriesBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/SelectWptCategoriesBottomSheetDialogFragment.java @@ -20,8 +20,6 @@ import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; -import net.osmand.plus.itinerary.ItineraryGroup; -import net.osmand.plus.itinerary.ItineraryHelper; import java.io.File; import java.util.ArrayList; @@ -138,18 +136,18 @@ public class SelectWptCategoriesBottomSheetDialogFragment extends MenuBottomShee private void updateAddOrEnableGroupWptCategories() { OsmandApplication app = getMyApplication(); GpxSelectionHelper gpxSelectionHelper = app.getSelectedGpxHelper(); - ItineraryHelper helper = app.getItineraryHelper(); + MapMarkersHelper mapMarkersHelper = app.getMapMarkersHelper(); SelectedGpxFile selectedGpxFile = gpxSelectionHelper.getSelectedFileByPath(gpxFile.path); if (selectedGpxFile == null) { gpxSelectionHelper.selectGpxFile(gpxFile, true, false, false, false, false); } - ItineraryGroup group = helper.getMarkersGroup(gpxFile); + MapMarkersGroup group = mapMarkersHelper.getMarkersGroup(gpxFile); if (group == null) { - group = helper.addOrEnableGroup(gpxFile); + group = mapMarkersHelper.addOrEnableGroup(gpxFile); } - helper.updateGroupWptCategories(group, selectedCategories); - helper.runSynchronization(group); + mapMarkersHelper.updateGroupWptCategories(group, selectedCategories); + app.getItineraryHelper().runSynchronization(group); } private boolean isAllChecked() { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java index 4dfe175720..2fa206d08f 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersActiveAdapter.java @@ -14,7 +14,7 @@ import com.google.android.material.snackbar.Snackbar; import net.osmand.data.LatLon; import net.osmand.plus.mapmarkers.MapMarker; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -214,8 +214,8 @@ public class MapMarkersActiveAdapter extends RecyclerView.Adapter(); - ItineraryHelper helper = app.getItineraryHelper(); + MapMarkersHelper helper = app.getMapMarkersHelper(); helper.updateGroups(); - List groups = new ArrayList<>(helper.getItineraryGroups()); + List groups = new ArrayList<>(helper.getMapMarkersGroups()); groups.addAll(helper.getGroupsForDisplayedGpx()); groups.addAll(helper.getGroupsForSavedArticlesTravelBook()); for (int i = 0; i < groups.size(); i++) { - ItineraryGroup group = groups.get(i); + MapMarkersGroup group = groups.get(i); if (!group.isVisible()) { continue; } @@ -177,7 +176,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter categories = group.getWptCategories(); if (categories != null && !categories.isEmpty()) { diff --git a/OsmAnd/src/net/osmand/plus/myplaces/DeletePointsTask.java b/OsmAnd/src/net/osmand/plus/myplaces/DeletePointsTask.java index c7179f1091..c9d9d4c423 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/DeletePointsTask.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/DeletePointsTask.java @@ -8,7 +8,7 @@ import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItemType; import net.osmand.plus.OsmandApplication; import net.osmand.plus.activities.SavingTrackHelper; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import java.io.File; import java.lang.ref.WeakReference; @@ -64,7 +64,7 @@ public class DeletePointsTask extends AsyncTask { } private void syncGpx(GPXFile gpxFile) { - ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile); + MapMarkersGroup group = app.getMapMarkersHelper().getMarkersGroup(gpxFile); if (group != null) { app.getItineraryHelper().runSynchronization(group); } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java index 352e7ecc3b..b3ff9b91bd 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java @@ -49,7 +49,7 @@ import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.FontCache; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.measurementtool.OptionsDividerItem; import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener; @@ -192,7 +192,7 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment } private BaseBottomSheetItem createCopyToMarkersItem(final GPXFile gpxFile) { - ItineraryGroup markersGroup = app.getItineraryHelper().getMarkersGroup(gpxFile); + MapMarkersGroup markersGroup = mapMarkersHelper.getMarkersGroup(gpxFile); final boolean synced = markersGroup != null && (Algorithms.isEmpty(markersGroup.getWptCategories()) || markersGroup.getWptCategories().contains(group.getName())); @@ -216,10 +216,10 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment selectedGpxHelper.selectGpxFile(gpxFile, true, false, false, false, false); } boolean groupCreated = false; - ItineraryGroup markersGroup = app.getItineraryHelper().getMarkersGroup(gpxFile); + MapMarkersGroup markersGroup = mapMarkersHelper.getMarkersGroup(gpxFile); if (markersGroup == null) { groupCreated = true; - markersGroup = app.getItineraryHelper().addOrEnableGroup(gpxFile); + markersGroup = mapMarkersHelper.addOrEnableGroup(gpxFile); } Set categories = markersGroup.getWptCategories(); Set selectedCategories = new HashSet<>(); @@ -234,7 +234,7 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment if (Algorithms.isEmpty(selectedCategories)) { mapMarkersHelper.removeMarkersGroup(markersGroup); } else { - app.getItineraryHelper().updateGroupWptCategories(markersGroup, selectedCategories); + mapMarkersHelper.updateGroupWptCategories(markersGroup, selectedCategories); if (!groupCreated) { app.getItineraryHelper().runSynchronization(markersGroup); } @@ -524,7 +524,7 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment } private void syncGpx(GPXFile gpxFile) { - ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile); + MapMarkersGroup group = app.getMapMarkersHelper().getMarkersGroup(gpxFile); if (group != null) { app.getItineraryHelper().runSynchronization(group); } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java index 2641fe986f..59be8cc533 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/TrackPointFragment.java @@ -63,7 +63,7 @@ import net.osmand.plus.base.OsmandExpandableListFragment; import net.osmand.plus.base.PointImageDrawable; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.mapmarkers.CoordinateInputDialogFragment; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.myplaces.DeletePointsTask.OnPointsDeleteListener; import net.osmand.plus.myplaces.TrackBitmapDrawer.TrackBitmapDrawerListener; @@ -399,7 +399,8 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements createMenuItem(menu, SHARE_ID, R.string.shared_string_share, R.drawable.ic_action_gshare_dark, MenuItem.SHOW_AS_ACTION_NEVER, true); GPXFile gpxFile = getGpx(); if (gpxFile != null && gpxFile.path != null) { - final boolean synced = app.getItineraryHelper().getMarkersGroup(getGpx()) != null; + final MapMarkersHelper markersHelper = app.getMapMarkersHelper(); + final boolean synced = markersHelper.getMarkersGroup(getGpx()) != null; createMenuItem(menu, SELECT_MAP_MARKERS_ID, synced ? R.string.remove_from_map_markers : R.string.shared_string_add_to_map_markers, R.drawable.ic_action_flag, MenuItem.SHOW_AS_ACTION_NEVER); } @@ -500,15 +501,15 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements return; } final GPXFile gpxFile = getGpx(); - ItineraryGroup markersSearch = app.getItineraryHelper().getMarkersGroup(gpxFile); - final ItineraryGroup markersGr; + MapMarkersGroup markersSearch = markersHelper.getMarkersGroup(gpxFile); + final MapMarkersGroup markersGr; final boolean markersRemoved; if (markersSearch != null) { markersGr = markersSearch; markersHelper.removeMarkersGroup(markersGr); markersRemoved = true; } else if (gpxFile != null) { - markersGr = app.getItineraryHelper().addOrEnableGroup(gpxFile); + markersGr = markersHelper.addOrEnableGroup(gpxFile); markersRemoved = false; } else { markersRemoved = false; @@ -534,10 +535,10 @@ public class TrackPointFragment extends OsmandExpandableListFragment implements if (trackActivity != null) { if (markersRemoved) { if (gpxFile != null) { - app.getItineraryHelper().addOrEnableGroup(gpxFile); + markersHelper.addOrEnableGroup(gpxFile); } } else { - ItineraryGroup group = app.getItineraryHelper().getMarkersGroup(gpxFile); + MapMarkersGroup group = markersHelper.getMarkersGroup(gpxFile); if (group != null) { markersHelper.removeMarkersGroup(group); } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/HistoryMarkersSettingsItem.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/HistoryMarkersSettingsItem.java index 9cbb536177..ba0c3d7dc0 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/HistoryMarkersSettingsItem.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/HistoryMarkersSettingsItem.java @@ -12,7 +12,7 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarkersDbHelper; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.util.Algorithms; @@ -46,7 +46,7 @@ public class HistoryMarkersSettingsItem extends CollectionSettingsItem(app.getItineraryHelper().getMapMarkersFromDefaultGroups(true)); + existingItems = new ArrayList<>(markersHelper.getMapMarkersFromDefaultGroups(true)); } @NonNull @@ -122,10 +122,10 @@ public class HistoryMarkersSettingsItem extends CollectionSettingsItem { protected void init() { super.init(); markersHelper = app.getMapMarkersHelper(); - existingItems = new ArrayList<>(app.getItineraryHelper().getMapMarkersFromDefaultGroups(false)); + existingItems = new ArrayList<>(markersHelper.getMapMarkersFromDefaultGroups(false)); } @NonNull @@ -122,10 +122,10 @@ public class MarkersSettingsItem extends CollectionSettingsItem { } } - public ItineraryGroup getMarkersGroup() { + public MapMarkersGroup getMarkersGroup() { String name = app.getString(R.string.map_markers); String groupId = ExportSettingsType.ACTIVE_MARKERS.name(); - ItineraryGroup markersGroup = new ItineraryGroup(groupId, name, ItineraryGroup.ANY_TYPE); + MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE); markersGroup.setMarkers(items); return markersGroup; } diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java index 61a429f05f..61cfd43cc1 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/backup/SettingsHelper.java @@ -30,10 +30,11 @@ import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.FileNameTranslationHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; +import net.osmand.plus.helpers.LocaleHelper; import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; import net.osmand.plus.mapmarkers.MapMarker; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.osmedit.OpenstreetmapPoint; import net.osmand.plus.osmedit.OsmEditingPlugin; @@ -605,19 +606,19 @@ public class SettingsHelper { myPlacesItems.put(ExportSettingsType.MULTIMEDIA_NOTES, files); } } - List mapMarkers = app.getItineraryHelper().getMapMarkersFromDefaultGroups(false); + List mapMarkers = app.getMapMarkersHelper().getMapMarkersFromDefaultGroups(false); if (!mapMarkers.isEmpty()) { String name = app.getString(R.string.map_markers); String groupId = ExportSettingsType.ACTIVE_MARKERS.name(); - ItineraryGroup markersGroup = new ItineraryGroup(groupId, name, ItineraryGroup.ANY_TYPE); + MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE); markersGroup.setMarkers(mapMarkers); myPlacesItems.put(ExportSettingsType.ACTIVE_MARKERS, Collections.singletonList(markersGroup)); } - List markersHistory = app.getItineraryHelper().getMapMarkersFromDefaultGroups(true); + List markersHistory = app.getMapMarkersHelper().getMapMarkersFromDefaultGroups(true); if (!markersHistory.isEmpty()) { String name = app.getString(R.string.shared_string_history); String groupId = ExportSettingsType.HISTORY_MARKERS.name(); - ItineraryGroup markersGroup = new ItineraryGroup(groupId, name, ItineraryGroup.ANY_TYPE); + MapMarkersGroup markersGroup = new MapMarkersGroup(groupId, name, MapMarkersGroup.ANY_TYPE); markersGroup.setMarkers(markersHistory); myPlacesItems.put(ExportSettingsType.HISTORY_MARKERS, Collections.singletonList(markersGroup)); } @@ -720,8 +721,8 @@ public class SettingsHelper { List favoriteGroups = new ArrayList<>(); List osmNotesPointList = new ArrayList<>(); List osmEditsPointList = new ArrayList<>(); - List markersGroups = new ArrayList<>(); - List markersHistoryGroups = new ArrayList<>(); + List markersGroups = new ArrayList<>(); + List markersHistoryGroups = new ArrayList<>(); List historyEntries = new ArrayList<>(); List onlineRoutingEngines = new ArrayList<>(); @@ -755,12 +756,12 @@ public class SettingsHelper { osmEditsPointList.add((OpenstreetmapPoint) object); } else if (object instanceof FavoriteGroup) { favoriteGroups.add((FavoriteGroup) object); - } else if (object instanceof ItineraryGroup) { - ItineraryGroup markersGroup = (ItineraryGroup) object; + } else if (object instanceof MapMarkersGroup) { + MapMarkersGroup markersGroup = (MapMarkersGroup) object; if (ExportSettingsType.ACTIVE_MARKERS.name().equals(markersGroup.getId())) { - markersGroups.add((ItineraryGroup) object); + markersGroups.add((MapMarkersGroup) object); } else if (ExportSettingsType.HISTORY_MARKERS.name().equals(markersGroup.getId())) { - markersHistoryGroups.add((ItineraryGroup) object); + markersHistoryGroups.add((MapMarkersGroup) object); } } else if (object instanceof HistoryEntry) { historyEntries.add((HistoryEntry) object); @@ -812,7 +813,7 @@ public class SettingsHelper { } if (!markersGroups.isEmpty()) { List mapMarkers = new ArrayList<>(); - for (ItineraryGroup group : markersGroups) { + for (MapMarkersGroup group : markersGroups) { mapMarkers.addAll(group.getMarkers()); } MarkersSettingsItem baseItem = getBaseItem(SettingsItemType.ACTIVE_MARKERS, MarkersSettingsItem.class, settingsItems); @@ -820,7 +821,7 @@ public class SettingsHelper { } if (!markersHistoryGroups.isEmpty()) { List mapMarkers = new ArrayList<>(); - for (ItineraryGroup group : markersHistoryGroups) { + for (MapMarkersGroup group : markersHistoryGroups) { mapMarkers.addAll(group.getMarkers()); } HistoryMarkersSettingsItem baseItem = getBaseItem(SettingsItemType.HISTORY_MARKERS, HistoryMarkersSettingsItem.class, settingsItems); @@ -910,8 +911,8 @@ public class SettingsHelper { List notesPointList = new ArrayList<>(); List editsPointList = new ArrayList<>(); List favoriteGroups = new ArrayList<>(); - List markersGroups = new ArrayList<>(); - List markersHistoryGroups = new ArrayList<>(); + List markersGroups = new ArrayList<>(); + List markersHistoryGroups = new ArrayList<>(); List historyEntries = new ArrayList<>(); List onlineRoutingEngines = new ArrayList<>(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportItemsBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportItemsBottomSheet.java index 6357eb94bf..c3b74af4fd 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportItemsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportItemsBottomSheet.java @@ -41,7 +41,7 @@ import net.osmand.plus.helpers.AvoidSpecificRoads.AvoidRoadInfo; import net.osmand.plus.helpers.FileNameTranslationHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.osmedit.OpenstreetmapPoint; import net.osmand.plus.osmedit.OsmEditingPlugin; @@ -377,8 +377,8 @@ public class ExportItemsBottomSheet extends MenuBottomSheetDialogFragment { GlobalSettingsItem globalSettingsItem = (GlobalSettingsItem) object; item.setTitle(globalSettingsItem.getPublicName(app)); item.setIcon(uiUtilities.getIcon(R.drawable.ic_action_settings, getItemIconColor(object))); - } else if (object instanceof ItineraryGroup) { - ItineraryGroup markersGroup = (ItineraryGroup) object; + } else if (object instanceof MapMarkersGroup) { + MapMarkersGroup markersGroup = (MapMarkersGroup) object; if (ExportSettingsType.ACTIVE_MARKERS.name().equals(markersGroup.getId())) { item.setTitle(getString(R.string.map_markers)); item.setIcon(uiUtilities.getIcon(R.drawable.ic_action_flag, getItemIconColor(object))); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsAdapter.java b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsAdapter.java index 360f786b77..6b6a85035d 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/ExportSettingsAdapter.java @@ -18,7 +18,7 @@ import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.FontCache; -import net.osmand.plus.itinerary.ItineraryGroup; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.settings.backend.ExportSettingsCategory; import net.osmand.plus.settings.backend.ExportSettingsType; import net.osmand.plus.settings.backend.backup.FileSettingsItem; @@ -311,8 +311,8 @@ public class ExportSettingsAdapter extends OsmandBaseExpandableListAdapter { itemsSize += ((FileSettingsItem) object).getSize(); } else if (object instanceof File) { itemsSize += ((File) object).length(); - } else if (object instanceof ItineraryGroup) { - int selectedMarkers = ((ItineraryGroup) object).getMarkers().size(); + } else if (object instanceof MapMarkersGroup) { + int selectedMarkers = ((MapMarkersGroup) object).getMarkers().size(); String itemsDescr = app.getString(R.string.shared_string_items); return app.getString(R.string.ltr_or_rtl_combine_via_colon, itemsDescr, selectedMarkers); } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/FavouritesLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/FavouritesLayer.java index 656568b425..04c4ac320a 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/FavouritesLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/FavouritesLayer.java @@ -106,7 +106,7 @@ public class FavouritesLayer extends OsmandMapLayer implements IContextMenuProvi List smallObjectsLatLon = new ArrayList<>(); for (FavoriteGroup group : favouritesDbHelper.getFavoriteGroups()) { List> fullObjects = new ArrayList<>(); - boolean synced = view.getApplication().getItineraryHelper().getMarkersGroup(group) != null; + boolean synced = mapMarkersHelper.getMarkersGroup(group) != null; for (FavouritePoint favoritePoint : group.getPoints()) { double lat = favoritePoint.getLatitude(); double lon = favoritePoint.getLongitude(); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index db26c11019..99d4d41c81 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -48,6 +48,7 @@ import net.osmand.plus.itinerary.ItineraryGroup; import net.osmand.plus.mapcontextmenu.controllers.SelectedGpxMenuController.SelectedGpxPoint; import net.osmand.plus.mapcontextmenu.other.TrackChartPoints; import net.osmand.plus.mapmarkers.MapMarker; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.render.OsmandRenderer; import net.osmand.plus.render.OsmandRenderer.RenderingContext; @@ -543,7 +544,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM for (SelectedGpxFile g : selectedGPXFiles) { List> fullObjects = new ArrayList<>(); int fileColor = getFileColor(g); - boolean synced = view.getApplication().getItineraryHelper().getMarkersGroup(g.getGpxFile()) != null; + boolean synced = mapMarkersHelper.getMarkersGroup(g.getGpxFile()) != null; for (WptPt wpt : getListStarPoints(g)) { if (wpt.lat >= latLonBounds.bottom && wpt.lat <= latLonBounds.top && wpt.lon >= latLonBounds.left && wpt.lon <= latLonBounds.right @@ -1226,7 +1227,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM } private void syncGpx(GPXFile gpxFile) { - ItineraryGroup group = view.getApplication().getItineraryHelper().getMarkersGroup(gpxFile); + MapMarkersGroup group = view.getApplication().getMapMarkersHelper().getMarkersGroup(gpxFile); if (group != null) { view.getApplication().getItineraryHelper().runSynchronization(group); } From eefe1a00ac229ee39c10ab3becaa33eeb0e520db Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 21 Apr 2021 15:07:18 +0300 Subject: [PATCH 19/29] Revert "Create ItineraryHelper" This reverts commit 7218e7d4 --- .../src/net/osmand/plus/AppInitializer.java | 2 - .../net/osmand/plus/FavouritesDbHelper.java | 5 +- .../net/osmand/plus/GpxSelectionHelper.java | 6 +- .../net/osmand/plus/OsmandApplication.java | 10 -- .../plus/itinerary/ItineraryHelper.java | 152 ------------------ .../editors/WptPtEditorFragment.java | 8 +- .../editors/WptPtEditorFragmentNew.java | 8 +- .../CoordinateInputDialogFragment.java | 2 +- .../mapmarkers/MapMarkersDialogFragment.java | 4 +- .../plus/mapmarkers/MapMarkersHelper.java | 135 ++++++++++++++-- ...ptCategoriesBottomSheetDialogFragment.java | 2 +- .../adapters/MapMarkersGroupsAdapter.java | 2 +- .../plus/myplaces/DeletePointsTask.java | 6 +- .../EditTrackGroupDialogFragment.java | 7 +- .../osmand/plus/views/layers/GPXLayer.java | 2 +- 15 files changed, 156 insertions(+), 195 deletions(-) delete mode 100644 OsmAnd/src/net/osmand/plus/itinerary/ItineraryHelper.java diff --git a/OsmAnd/src/net/osmand/plus/AppInitializer.java b/OsmAnd/src/net/osmand/plus/AppInitializer.java index cfcdc737b2..07bb9084e8 100644 --- a/OsmAnd/src/net/osmand/plus/AppInitializer.java +++ b/OsmAnd/src/net/osmand/plus/AppInitializer.java @@ -40,7 +40,6 @@ import net.osmand.plus.helpers.DayNightHelper; import net.osmand.plus.helpers.LockHelper; import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.inapp.InAppPurchaseHelperImpl; -import net.osmand.plus.itinerary.ItineraryHelper; import net.osmand.plus.liveupdates.LiveUpdatesHelper; import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper; @@ -473,7 +472,6 @@ public class AppInitializer implements IProgress { app.osmOAuthHelper = startupInit(new OsmOAuthHelper(app), OsmOAuthHelper.class); app.oprAuthHelper = startupInit(new OprAuthHelper(app), OprAuthHelper.class); app.onlineRoutingHelper = startupInit(new OnlineRoutingHelper(app), OnlineRoutingHelper.class); - app.itineraryHelper = startupInit(new ItineraryHelper(app), ItineraryHelper.class); app.backupHelper = startupInit(new BackupHelper(app), BackupHelper.class); initOpeningHoursParser(); diff --git a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java index ca52169e10..42cf1c0d2e 100644 --- a/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/FavouritesDbHelper.java @@ -280,9 +280,10 @@ public class FavouritesDbHelper { } private void runSyncWithMarkers(FavoriteGroup favGroup) { - MapMarkersGroup group = context.getMapMarkersHelper().getMarkersGroup(favGroup); + MapMarkersHelper helper = context.getMapMarkersHelper(); + MapMarkersGroup group = helper.getMarkersGroup(favGroup); if (group != null) { - context.getItineraryHelper().runSynchronization(group); + helper.runSynchronization(group); } } diff --git a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java index 77bcb5e0e7..0eba1b2b1a 100644 --- a/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java +++ b/OsmAnd/src/net/osmand/plus/GpxSelectionHelper.java @@ -31,6 +31,7 @@ import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; import net.osmand.plus.helpers.SearchHistoryHelper; import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.mapmarkers.MapMarkersGroup; +import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder; import net.osmand.plus.track.GpxSplitType; import net.osmand.util.Algorithms; @@ -824,9 +825,10 @@ public class GpxSelectionHelper { } private void syncGpxWithMarkers(GPXFile gpxFile) { - MapMarkersGroup group = app.getMapMarkersHelper().getMarkersGroup(gpxFile); + MapMarkersHelper mapMarkersHelper = app.getMapMarkersHelper(); + MapMarkersGroup group = mapMarkersHelper.getMarkersGroup(gpxFile); if (group != null) { - app.getItineraryHelper().runSynchronization(group); + mapMarkersHelper.runSynchronization(group); } } diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index ddbbd7087e..e6e6539bcb 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -67,7 +67,6 @@ import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.helpers.enums.DrivingRegion; import net.osmand.plus.helpers.enums.MetricsConstants; import net.osmand.plus.inapp.InAppPurchaseHelper; -import net.osmand.plus.itinerary.ItineraryHelper; import net.osmand.plus.mapmarkers.MapMarkersDbHelper; import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.measurementtool.MeasurementEditingContext; @@ -169,7 +168,6 @@ public class OsmandApplication extends MultiDexApplication { OprAuthHelper oprAuthHelper; MeasurementEditingContext measurementEditingContext; OnlineRoutingHelper onlineRoutingHelper; - ItineraryHelper itineraryHelper; BackupHelper backupHelper; private Map customRoutingConfigs = new ConcurrentHashMap<>(); @@ -472,14 +470,6 @@ public class OsmandApplication extends MultiDexApplication { return onlineRoutingHelper; } - public ItineraryHelper getItineraryHelper() { - return itineraryHelper; - } - - public BackupHelper getBackupHelper() { - return backupHelper; - } - public TransportRoutingHelper getTransportRoutingHelper() { return transportRoutingHelper; } diff --git a/OsmAnd/src/net/osmand/plus/itinerary/ItineraryHelper.java b/OsmAnd/src/net/osmand/plus/itinerary/ItineraryHelper.java deleted file mode 100644 index 8e3c96a08a..0000000000 --- a/OsmAnd/src/net/osmand/plus/itinerary/ItineraryHelper.java +++ /dev/null @@ -1,152 +0,0 @@ -package net.osmand.plus.itinerary; - -import android.os.AsyncTask; - -import androidx.annotation.NonNull; - -import net.osmand.GPXUtilities.GPXFile; -import net.osmand.GPXUtilities.WptPt; -import net.osmand.PlatformUtil; -import net.osmand.data.FavouritePoint; -import net.osmand.data.LatLon; -import net.osmand.plus.FavouritesDbHelper.FavoriteGroup; -import net.osmand.plus.GpxSelectionHelper; -import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.mapmarkers.MapMarker; -import net.osmand.plus.mapmarkers.MapMarkersGroup; -import net.osmand.plus.mapmarkers.MapMarkersHelper; -import net.osmand.plus.mapmarkers.MapMarkersHelper.OnGroupSyncedListener; - -import org.apache.commons.logging.Log; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class ItineraryHelper { - - private static final Log LOG = PlatformUtil.getLog(ItineraryHelper.class); - - private OsmandApplication app; - - private MapMarkersHelper markersHelper; - - private ExecutorService executorService = Executors.newSingleThreadExecutor(); - - private Set syncListeners = new HashSet<>(); - - public ItineraryHelper(@NonNull OsmandApplication app) { - this.app = app; - markersHelper = app.getMapMarkersHelper(); - } - - public void addSyncListener(OnGroupSyncedListener listener) { - syncListeners.add(listener); - } - - public void removeSyncListener(OnGroupSyncedListener listener) { - syncListeners.remove(listener); - } - - public void runSynchronization(final @NonNull MapMarkersGroup group) { - app.runInUIThread(new Runnable() { - @Override - public void run() { - new SyncGroupTask(group).executeOnExecutor(executorService); - } - }); - } - - private class SyncGroupTask extends AsyncTask { - - private MapMarkersGroup group; - - SyncGroupTask(MapMarkersGroup group) { - this.group = group; - } - - @Override - protected void onPreExecute() { - if (!syncListeners.isEmpty()) { - app.runInUIThread(new Runnable() { - @Override - public void run() { - for (OnGroupSyncedListener listener : syncListeners) { - listener.onSyncStarted(); - } - } - }); - } - } - - @Override - protected Void doInBackground(Void... voids) { - runGroupSynchronization(); - return null; - } - - // TODO extract method from Asynctask to Helper directly - private void runGroupSynchronization() { - List groupMarkers = new ArrayList<>(group.getMarkers()); - if (group.getType() == MapMarkersGroup.FAVORITES_TYPE) { - FavoriteGroup favGroup = app.getFavorites().getGroup(group.getName()); - if (favGroup == null) { - return; - } - group.setVisible(favGroup.isVisible()); - if (!group.isVisible() || group.isDisabled()) { - markersHelper.removeGroupActiveMarkers(group, true); - return; - } - List points = new ArrayList<>(favGroup.getPoints()); - for (FavouritePoint fp : points) { - markersHelper.addNewMarkerIfNeeded(group, groupMarkers, new LatLon(fp.getLatitude(), fp.getLongitude()), fp.getName(), fp, null); - } - } else if (group.getType() == MapMarkersGroup.GPX_TYPE) { - GpxSelectionHelper gpxHelper = app.getSelectedGpxHelper(); - File file = new File(group.getId()); - if (!file.exists()) { - return; - } - - String gpxPath = group.getId(); - SelectedGpxFile selectedGpxFile = gpxHelper.getSelectedFileByPath(gpxPath); - GPXFile gpx = selectedGpxFile == null ? null : selectedGpxFile.getGpxFile(); - group.setVisible(gpx != null || group.isVisibleUntilRestart()); - if (gpx == null || group.isDisabled()) { - markersHelper.removeGroupActiveMarkers(group, true); - return; - } - - boolean addAll = group.getWptCategories() == null || group.getWptCategories().isEmpty(); - List gpxPoints = new ArrayList<>(gpx.getPoints()); - for (WptPt pt : gpxPoints) { - if (addAll || group.getWptCategories().contains(pt.category) - || (pt.category == null && group.getWptCategories().contains(""))) { - markersHelper.addNewMarkerIfNeeded(group, groupMarkers, new LatLon(pt.lat, pt.lon), pt.name, null, pt); - } - } - } - markersHelper.removeOldMarkersIfPresent(groupMarkers); - } - - @Override - protected void onPostExecute(Void aVoid) { - if (!syncListeners.isEmpty()) { - app.runInUIThread(new Runnable() { - @Override - public void run() { - for (OnGroupSyncedListener listener : syncListeners) { - listener.onSyncDone(); - } - } - }); - } - } - } -} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java index e1c1ac3d61..2d0654301b 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragment.java @@ -17,6 +17,8 @@ import net.osmand.GPXUtilities.WptPt; import net.osmand.data.LatLon; import net.osmand.data.WptLocationPoint; import net.osmand.plus.GpxSelectionHelper; +import net.osmand.plus.mapmarkers.MapMarkersHelper; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; @@ -24,7 +26,6 @@ import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.base.PointImageDrawable; import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.editors.WptPtEditor.OnDismissListener; -import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.util.Algorithms; @@ -219,9 +220,10 @@ public class WptPtEditorFragment extends PointEditorFragment { private void syncGpx(GPXFile gpxFile) { OsmandApplication app = getMyApplication(); if (app != null) { - MapMarkersGroup group = app.getMapMarkersHelper().getMarkersGroup(gpxFile); + MapMarkersHelper helper = app.getMapMarkersHelper(); + MapMarkersGroup group = helper.getMarkersGroup(gpxFile); if (group != null) { - app.getItineraryHelper().runSynchronization(group); + helper.runSynchronization(group); } } } diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java index 4dea53b0bd..7ecd61565f 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/WptPtEditorFragmentNew.java @@ -20,6 +20,8 @@ import net.osmand.data.FavouritePoint.BackgroundType; import net.osmand.data.LatLon; import net.osmand.data.WptLocationPoint; import net.osmand.plus.GpxSelectionHelper; +import net.osmand.plus.mapmarkers.MapMarkersHelper; +import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -29,7 +31,6 @@ import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.base.PointImageDrawable; import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.editors.WptPtEditor.OnDismissListener; -import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.track.SaveGpxAsyncTask; import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.util.Algorithms; @@ -237,9 +238,10 @@ public class WptPtEditorFragmentNew extends PointEditorFragmentNew { private void syncGpx(GPXFile gpxFile) { OsmandApplication app = getMyApplication(); if (app != null) { - MapMarkersGroup group = app.getMapMarkersHelper().getMarkersGroup(gpxFile); + MapMarkersHelper helper = app.getMapMarkersHelper(); + MapMarkersGroup group = helper.getMarkersGroup(gpxFile); if (group != null) { - app.getItineraryHelper().runSynchronization(group); + helper.runSynchronization(group); } } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java index 31e477fbf1..96d6f9a8f4 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/CoordinateInputDialogFragment.java @@ -171,7 +171,7 @@ public class CoordinateInputDialogFragment extends DialogFragment implements Osm MapMarkersHelper helper = getMyApplication().getMapMarkersHelper(); MapMarkersGroup group = helper.getMarkersGroup(gpxFile); if (group != null) { - getMyApplication().getItineraryHelper().runSynchronization(group); + helper.runSynchronization(group); } } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java index ad453d5fe5..f0b226dd1e 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersDialogFragment.java @@ -218,13 +218,13 @@ public class MapMarkersDialogFragment extends DialogFragment implements OnGroupS @Override public void onResume() { super.onResume(); - getMyApplication().getItineraryHelper().addSyncListener(this); + getMyApplication().getMapMarkersHelper().addSyncListener(this); } @Override public void onPause() { super.onPause(); - getMyApplication().getItineraryHelper().removeSyncListener(this); + getMyApplication().getMapMarkersHelper().removeSyncListener(this); } @Override diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java index b8bcddbc5c..51911e8779 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java @@ -1,5 +1,7 @@ package net.osmand.plus.mapmarkers; +import android.os.AsyncTask; + import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -18,6 +20,7 @@ import net.osmand.plus.FavouritesDbHelper.FavoriteGroup; import net.osmand.plus.GPXDatabase; import net.osmand.plus.GeocodingLookupService; import net.osmand.plus.GeocodingLookupService.AddressLookupRequest; +import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -38,12 +41,15 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TimeZone; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import static net.osmand.GPXUtilities.GPX_TIME_FORMAT; import static net.osmand.data.PointDescription.POINT_TYPE_MAP_MARKER; @@ -72,11 +78,14 @@ public class MapMarkersHelper { private OsmandApplication ctx; private MapMarkersDbHelper markersDbHelper; + private ExecutorService executorService = Executors.newSingleThreadExecutor(); + private List mapMarkers = new ArrayList<>(); private List mapMarkersHistory = new ArrayList<>(); private List mapMarkersGroups = new ArrayList<>(); private List listeners = new ArrayList<>(); + private Set syncListeners = new HashSet<>(); private MarkersPlanRouteContext planRouteContext; @@ -177,7 +186,7 @@ public class MapMarkersHelper { public void syncAllGroupsAsync() { for (MapMarkersGroup gr : mapMarkersGroups) { if (gr.getId() != null && gr.getName() != null) { - ctx.getItineraryHelper().runSynchronization(gr); + runSynchronization(gr); } } } @@ -294,6 +303,15 @@ public class MapMarkersHelper { }); } + public void runSynchronization(final @NonNull MapMarkersGroup group) { + ctx.runInUIThread(new Runnable() { + @Override + public void run() { + new SyncGroupTask(group).executeOnExecutor(executorService); + } + }); + } + public MapMarkersGroup getMarkersGroup(GPXFile gpx) { if (gpx == null || gpx.path == null) { return null; @@ -345,7 +363,7 @@ public class MapMarkersHelper { if (gr.isDisabled()) { updateGroupDisabled(gr, false); } - ctx.getItineraryHelper().runSynchronization(gr); + runSynchronization(gr); } private void addGroupInternally(MapMarkersGroup gr) { @@ -397,7 +415,7 @@ public class MapMarkersHelper { } } - public void removeGroupActiveMarkers(MapMarkersGroup group, boolean updateGroup) { + private void removeGroupActiveMarkers(MapMarkersGroup group, boolean updateGroup) { if (group != null) { markersDbHelper.removeActiveMarkersFromGroup(group.getId()); removeFromMapMarkersList(group.getActiveMarkers()); @@ -618,12 +636,12 @@ public class MapMarkersHelper { return null; } - public void addNewMarkerIfNeeded(@NonNull MapMarkersGroup group, - @NonNull List groupMarkers, - @NonNull LatLon latLon, - @NonNull String name, - @Nullable FavouritePoint favouritePoint, - @Nullable WptPt wptPt) { + private void addNewMarkerIfNeeded(@NonNull MapMarkersGroup group, + @NonNull List groupMarkers, + @NonNull LatLon latLon, + @NonNull String name, + @Nullable FavouritePoint favouritePoint, + @Nullable WptPt wptPt) { boolean exists = false; Iterator iterator = groupMarkers.iterator(); @@ -653,7 +671,7 @@ public class MapMarkersHelper { } } - public void removeOldMarkersIfPresent(List markers) { + private void removeOldMarkersIfPresent(List markers) { if (!markers.isEmpty()) { boolean needRefresh = false; for (MapMarker marker : markers) { @@ -952,6 +970,14 @@ public class MapMarkersHelper { } } + public void addSyncListener(OnGroupSyncedListener listener) { + syncListeners.add(listener); + } + + public void removeSyncListener(OnGroupSyncedListener listener) { + syncListeners.remove(listener); + } + public void addListener(MapMarkerChangedListener l) { if (!listeners.contains(l)) { listeners.add(l); @@ -1168,4 +1194,93 @@ public class MapMarkersHelper { void onSyncDone(); } + + private class SyncGroupTask extends AsyncTask { + + private MapMarkersGroup group; + + SyncGroupTask(MapMarkersGroup group) { + this.group = group; + } + + @Override + protected void onPreExecute() { + if (!syncListeners.isEmpty()) { + ctx.runInUIThread(new Runnable() { + @Override + public void run() { + for (OnGroupSyncedListener listener : syncListeners) { + listener.onSyncStarted(); + } + } + }); + } + } + + @Override + protected Void doInBackground(Void... voids) { + runGroupSynchronization(); + return null; + } + + // TODO extract method from Asynctask to Helper directly + private void runGroupSynchronization() { + List groupMarkers = new ArrayList<>(group.getMarkers()); + if (group.getType() == MapMarkersGroup.FAVORITES_TYPE) { + FavoriteGroup favGroup = ctx.getFavorites().getGroup(group.getName()); + if (favGroup == null) { + return; + } + group.setVisible(favGroup.isVisible()); + if (!group.isVisible() || group.isDisabled()) { + removeGroupActiveMarkers(group, true); + return; + } + List points = new ArrayList<>(favGroup.getPoints()); + for (FavouritePoint fp : points) { + addNewMarkerIfNeeded(group, groupMarkers, new LatLon(fp.getLatitude(), fp.getLongitude()), fp.getName(), fp, null); + } + } else if (group.getType() == MapMarkersGroup.GPX_TYPE) { + GpxSelectionHelper gpxHelper = ctx.getSelectedGpxHelper(); + File file = new File(group.getId()); + if (!file.exists()) { + return; + } + + String gpxPath = group.getId(); + SelectedGpxFile selectedGpxFile = gpxHelper.getSelectedFileByPath(gpxPath); + GPXFile gpx = selectedGpxFile == null ? null : selectedGpxFile.getGpxFile(); + group.setVisible(gpx != null || group.isVisibleUntilRestart()); + if (gpx == null || group.isDisabled()) { + removeGroupActiveMarkers(group, true); + return; + } + + boolean addAll = group.getWptCategories() == null || group.getWptCategories().isEmpty(); + List gpxPoints = new ArrayList<>(gpx.getPoints()); + for (WptPt pt : gpxPoints) { + if (addAll || group.getWptCategories().contains(pt.category) + || (pt.category == null && group.getWptCategories().contains(""))) { + addNewMarkerIfNeeded(group, groupMarkers, new LatLon(pt.lat, pt.lon), pt.name, null, pt); + } + } + } + + removeOldMarkersIfPresent(groupMarkers); + } + + @Override + protected void onPostExecute(Void aVoid) { + if (!syncListeners.isEmpty()) { + ctx.runInUIThread(new Runnable() { + @Override + public void run() { + for (OnGroupSyncedListener listener : syncListeners) { + listener.onSyncDone(); + } + } + }); + } + } + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/SelectWptCategoriesBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/mapmarkers/SelectWptCategoriesBottomSheetDialogFragment.java index 1f86a94a1d..08db4d40fc 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/SelectWptCategoriesBottomSheetDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/SelectWptCategoriesBottomSheetDialogFragment.java @@ -147,7 +147,7 @@ public class SelectWptCategoriesBottomSheetDialogFragment extends MenuBottomShee group = mapMarkersHelper.addOrEnableGroup(gpxFile); } mapMarkersHelper.updateGroupWptCategories(group, selectedCategories); - app.getItineraryHelper().runSynchronization(group); + mapMarkersHelper.runSynchronization(group); } private boolean isAllChecked() { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java index 4992ee88be..fb74956b16 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java @@ -478,7 +478,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter { } private void syncGpx(GPXFile gpxFile) { - MapMarkersGroup group = app.getMapMarkersHelper().getMarkersGroup(gpxFile); + MapMarkersHelper helper = app.getMapMarkersHelper(); + MapMarkersGroup group = helper.getMarkersGroup(gpxFile); if (group != null) { - app.getItineraryHelper().runSynchronization(group); + helper.runSynchronization(group); } } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java index b3ff9b91bd..674ee76042 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/EditTrackGroupDialogFragment.java @@ -236,7 +236,7 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment } else { mapMarkersHelper.updateGroupWptCategories(markersGroup, selectedCategories); if (!groupCreated) { - app.getItineraryHelper().runSynchronization(markersGroup); + mapMarkersHelper.runSynchronization(markersGroup); } } } @@ -524,9 +524,10 @@ public class EditTrackGroupDialogFragment extends MenuBottomSheetDialogFragment } private void syncGpx(GPXFile gpxFile) { - MapMarkersGroup group = app.getMapMarkersHelper().getMarkersGroup(gpxFile); + MapMarkersHelper markersHelper = app.getMapMarkersHelper(); + MapMarkersGroup group = markersHelper.getMarkersGroup(gpxFile); if (group != null) { - app.getItineraryHelper().runSynchronization(group); + markersHelper.runSynchronization(group); } } } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index 99d4d41c81..b26940ff7b 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -1229,7 +1229,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM private void syncGpx(GPXFile gpxFile) { MapMarkersGroup group = view.getApplication().getMapMarkersHelper().getMarkersGroup(gpxFile); if (group != null) { - view.getApplication().getItineraryHelper().runSynchronization(group); + mapMarkersHelper.runSynchronization(group); } } From 7f795a4e439f2ceaa635b6efbfdec3d572d7fec1 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Wed, 21 Apr 2021 15:11:31 +0300 Subject: [PATCH 20/29] Fix compilation --- OsmAnd/src/net/osmand/plus/OsmandApplication.java | 4 ++++ OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index e6e6539bcb..cd3fa4b5ad 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -470,6 +470,10 @@ public class OsmandApplication extends MultiDexApplication { return onlineRoutingHelper; } + public BackupHelper getBackupHelper() { + return backupHelper; + } + public TransportRoutingHelper getTransportRoutingHelper() { return transportRoutingHelper; } diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index b26940ff7b..84a1483834 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -44,7 +44,6 @@ import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.PointImageDrawable; -import net.osmand.plus.itinerary.ItineraryGroup; import net.osmand.plus.mapcontextmenu.controllers.SelectedGpxMenuController.SelectedGpxPoint; import net.osmand.plus.mapcontextmenu.other.TrackChartPoints; import net.osmand.plus.mapmarkers.MapMarker; From c40eb96bd751dd2b4513c512f13804218b289191 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 19 Apr 2021 13:46:14 +0200 Subject: [PATCH 21/29] Remove CategoriesSubHeader --- .../plus/mapmarkers/CategoriesSubHeader.java | 20 ------------------- .../plus/mapmarkers/MapMarkersGroup.java | 9 --------- .../plus/mapmarkers/MapMarkersHelper.java | 5 ----- .../adapters/MapMarkersGroupsAdapter.java | 17 ++++++++++++++-- 4 files changed, 15 insertions(+), 36 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/CategoriesSubHeader.java b/OsmAnd/src/net/osmand/plus/mapmarkers/CategoriesSubHeader.java index aef2f28afd..47353e409f 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/CategoriesSubHeader.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/CategoriesSubHeader.java @@ -2,23 +2,3 @@ package net.osmand.plus.mapmarkers; import androidx.annotation.DrawableRes; -public class CategoriesSubHeader { - - @DrawableRes - private int iconRes; - private MapMarkersGroup group; - - public CategoriesSubHeader(int iconRes, MapMarkersGroup group) { - this.iconRes = iconRes; - this.group = group; - } - - @DrawableRes - public int getIconRes() { - return iconRes; - } - - public MapMarkersGroup getGroup() { - return group; - } -} diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroup.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroup.java index 2a97af91c8..35a4585501 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroup.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersGroup.java @@ -31,7 +31,6 @@ public class MapMarkersGroup { private TravelArticle wikivoyageArticle; // TODO should be removed from this class: private GroupHeader header; - private CategoriesSubHeader categoriesSubHeader; private ShowHideHistoryButton showHideHistoryButton; public MapMarkersGroup() { @@ -76,10 +75,6 @@ public class MapMarkersGroup { this.header = header; } - public void setCategoriesSubHeader(CategoriesSubHeader categoriesSubHeader) { - this.categoriesSubHeader = categoriesSubHeader; - } - public void setShowHideHistoryButton(ShowHideHistoryButton showHideHistoryButton) { this.showHideHistoryButton = showHideHistoryButton; } @@ -144,10 +139,6 @@ public class MapMarkersGroup { return header; } - public CategoriesSubHeader getCategoriesSubHeader() { - return categoriesSubHeader; - } - public ShowHideHistoryButton getShowHideHistoryButton() { return showHideHistoryButton; } diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java index 51911e8779..729a7f3cfd 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/MapMarkersHelper.java @@ -481,17 +481,12 @@ public class MapMarkersHelper { private void createHeadersInGroup(@NonNull MapMarkersGroup group) { int type = group.getType(); int headerIconId = 0; - int subHeaderIconId = 0; if (type != -1) { headerIconId = type == MapMarkersGroup.FAVORITES_TYPE ? R.drawable.ic_action_favorite : R.drawable.ic_action_polygom_dark; - subHeaderIconId = R.drawable.ic_action_filter; } GroupHeader header = new GroupHeader(headerIconId, group); - CategoriesSubHeader categoriesSubHeader = new CategoriesSubHeader(subHeaderIconId, group); - group.setHeader(header); - group.setCategoriesSubHeader(categoriesSubHeader); } private void removeMarkerFromGroup(MapMarker marker) { diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java index fb74956b16..5cb3078e8e 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java @@ -21,7 +21,6 @@ import net.osmand.IndexConstants; import net.osmand.data.LatLon; import net.osmand.plus.GpxSelectionHelper; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; -import net.osmand.plus.mapmarkers.CategoriesSubHeader; import net.osmand.plus.mapmarkers.MapMarkersHelper; import net.osmand.plus.mapmarkers.GroupHeader; import net.osmand.plus.mapmarkers.MapMarker; @@ -160,7 +159,7 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter Date: Mon, 19 Apr 2021 14:45:45 +0200 Subject: [PATCH 22/29] Refactor group markers --- .../adapters/MapMarkersGroupsAdapter.java | 156 +++++++++++------- 1 file changed, 96 insertions(+), 60 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java index 5cb3078e8e..2f4928e5d5 100644 --- a/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java +++ b/OsmAnd/src/net/osmand/plus/mapmarkers/adapters/MapMarkersGroupsAdapter.java @@ -7,8 +7,10 @@ import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.ImageView; +import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; @@ -36,6 +38,7 @@ import net.osmand.plus.mapmarkers.SelectWptCategoriesBottomSheetDialogFragment; import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment; import net.osmand.plus.wikivoyage.data.TravelArticle; import net.osmand.plus.wikivoyage.data.TravelHelper; +import net.osmand.util.Algorithms; import java.io.File; import java.text.SimpleDateFormat; @@ -54,10 +57,6 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter groups = new ArrayList<>(helper.getMapMarkersGroups()); groups.addAll(helper.getGroupsForDisplayedGpx()); groups.addAll(helper.getGroupsForSavedArticlesTravelBook()); + + // evaluate time constants + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + long currentTimeMillis = System.currentTimeMillis(); + Calendar currentDateCalendar = Calendar.getInstance(); + currentDateCalendar.setTimeInMillis(currentTimeMillis); + // evaluate today, yesterday, last 7 days + String today = dateFormat.format(currentDateCalendar.getTime()); + currentDateCalendar.add(Calendar.DAY_OF_YEAR, -1); + String yesterday = dateFormat.format(currentDateCalendar.getTime()); + currentDateCalendar.set(Calendar.HOUR_OF_DAY, 0); + currentDateCalendar.set(Calendar.MINUTE, 0); + currentDateCalendar.add(Calendar.DAY_OF_YEAR, -6); + long last7Days = currentDateCalendar.getTimeInMillis(); + // evaluate this year & last 3 months + currentDateCalendar.setTimeInMillis(currentTimeMillis); + String thisYear = dateFormat.format(currentDateCalendar.getTime()).substring(0, 5); + currentDateCalendar.add(Calendar.MONTH, -1); + String monthMinus1 = dateFormat.format(currentDateCalendar.getTime()).substring(0, 8); + currentDateCalendar.add(Calendar.MONTH, -1); + String monthMinus2 = dateFormat.format(currentDateCalendar.getTime()).substring(0, 8); + currentDateCalendar.add(Calendar.MONTH, -1); + String monthMinus3 = dateFormat.format(currentDateCalendar.getTime()).substring(0, 8); + + + Calendar markerCalendar = Calendar.getInstance(); + for (int i = 0; i < groups.size(); i++) { MapMarkersGroup group = groups.get(i); if (!group.isVisible()) { continue; } String markerGroupName = group.getName(); - if (markerGroupName == null) { - int previousDateHeader = -1; - int monthsDisplayed = 0; - Calendar currentDateCalendar = Calendar.getInstance(); - currentDateCalendar.setTimeInMillis(System.currentTimeMillis()); - int currentDay = currentDateCalendar.get(Calendar.DAY_OF_YEAR); - int currentMonth = currentDateCalendar.get(Calendar.MONTH); - int currentYear = currentDateCalendar.get(Calendar.YEAR); - Calendar markerCalendar = Calendar.getInstance(); + if (markerGroupName == null) { + int previousGroupDateId = 0; + int monthsDisplayed = 0; List groupMarkers = group.getActiveMarkers(); for (int j = 0; j < groupMarkers.size(); j++) { MapMarker marker = groupMarkers.get(j); - markerCalendar.setTimeInMillis(marker.creationDate); - int markerDay = markerCalendar.get(Calendar.DAY_OF_YEAR); - int markerMonth = markerCalendar.get(Calendar.MONTH); - int markerYear = markerCalendar.get(Calendar.YEAR); - if (markerYear == currentYear) { - if (markerDay == currentDay && previousDateHeader != TODAY_HEADER) { - items.add(TODAY_HEADER); - previousDateHeader = TODAY_HEADER; - } else if (markerDay == currentDay - 1 && previousDateHeader != YESTERDAY_HEADER) { - items.add(YESTERDAY_HEADER); - previousDateHeader = YESTERDAY_HEADER; - } else if (currentDay - markerDay >= 2 && currentDay - markerDay <= 8 && previousDateHeader != LAST_SEVEN_DAYS_HEADER) { - items.add(LAST_SEVEN_DAYS_HEADER); - previousDateHeader = LAST_SEVEN_DAYS_HEADER; - } else if (currentDay - markerDay > 8 && monthsDisplayed < 3 && previousDateHeader != markerMonth) { - items.add(markerMonth); - previousDateHeader = markerMonth; - monthsDisplayed += 1; - } else if (currentMonth - markerMonth >= 4 && previousDateHeader != markerMonth && previousDateHeader != THIS_YEAR_HEADER) { - items.add(THIS_YEAR_HEADER); - previousDateHeader = THIS_YEAR_HEADER; + String markerDate = dateFormat.format(new Date(marker.creationDate)); + int currentGroupDateId; + MarkerGroupItem currentGroupItem = null ; + if (marker.creationDate >= currentTimeMillis || (today.equals(markerDate))) { + currentGroupDateId = -1; + currentGroupItem = MarkerGroupItem.TODAY_HEADER; + } else if (yesterday.equals(markerDate)) { + currentGroupDateId = -2; + currentGroupItem = MarkerGroupItem.YESTERDAY_HEADER; + } else if (marker.creationDate >= last7Days) { + currentGroupDateId = -3; + currentGroupItem = MarkerGroupItem.LAST_SEVEN_DAYS_HEADER; + } else if (markerDate.startsWith(monthMinus1)) { + currentGroupDateId = -5; + } else if (markerDate.startsWith(monthMinus2)) { + currentGroupDateId = -6; + } else if (markerDate.startsWith(monthMinus3)) { + currentGroupDateId = -7; + } else if (markerDate.startsWith(thisYear)) { + currentGroupItem = MarkerGroupItem.THIS_YEAR_HEADER; + currentGroupDateId = -4; + } else { + markerCalendar.setTimeInMillis(marker.creationDate); + currentGroupDateId = markerCalendar.get(Calendar.YEAR); + } + if (previousGroupDateId != currentGroupDateId) { + if (currentGroupItem != null) { + items.add(currentGroupItem); + } else if(currentGroupDateId < 0) { + SimpleDateFormat monthdateFormat = new SimpleDateFormat("LLLL", Locale.getDefault()); + String monthStr = monthdateFormat.format(new Date(marker.creationDate)); + if (monthStr.length() > 1) { + monthStr = Algorithms.capitalizeFirstLetter(monthStr); + } + items.add(new MarkerGroupItem(monthStr)); + } else { + items.add(new MarkerGroupItem(currentGroupDateId + "")); } - } else if (previousDateHeader != markerYear) { - items.add(markerYear); - previousDateHeader = markerYear; + previousGroupDateId = currentGroupDateId; } items.add(marker); } @@ -379,23 +413,10 @@ public class MapMarkersGroupsAdapter extends RecyclerView.Adapter 1) { - monthStr = Character.toUpperCase(monthStr.charAt(0)) + monthStr.substring(1); + + public static class MarkerGroupItem { + + static final MarkerGroupItem TODAY_HEADER = new MarkerGroupItem(R.string.today); + static final MarkerGroupItem YESTERDAY_HEADER = new MarkerGroupItem(R.string.yesterday); + static final MarkerGroupItem LAST_SEVEN_DAYS_HEADER = new MarkerGroupItem(R.string.last_seven_days); + static final MarkerGroupItem THIS_YEAR_HEADER = new MarkerGroupItem(R.string.this_year); + private @StringRes int iname; + protected String name; + + public MarkerGroupItem(@StringRes int name) { + this.iname = name; + } + + public MarkerGroupItem(String name) { + this.name = name; + } + + public String getName(OsmandApplication app) { + if (name == null && iname != 0) { + name = app.getString(iname); + } + return name; } - return monthStr; } public class CategoriesSubHeader { From 72ca4055fca9f1b5bb5b3af45e605ba4f7acd3bc Mon Sep 17 00:00:00 2001 From: vshcherb Date: Thu, 22 Apr 2021 10:04:09 +0200 Subject: [PATCH 23/29] Update OsmandSettings.java --- .../src/net/osmand/plus/settings/backend/OsmandSettings.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java index 5b770bafda..b3f23444eb 100644 --- a/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java +++ b/OsmAnd/src/net/osmand/plus/settings/backend/OsmandSettings.java @@ -958,7 +958,7 @@ public class OsmandSettings { DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.BICYCLE, 2.77f); DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.PEDESTRIAN, 1.11f); DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.BOAT, 1.38f); - DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.AIRCRAFT, 40f); + DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.AIRCRAFT, 200f); DEFAULT_SPEED.setModeDefaultValue(ApplicationMode.SKI, 1.38f); } @@ -2888,4 +2888,4 @@ public class OsmandSettings { setPreference(QUICK_ACTION.getId(), actionState, mode); } } -} \ No newline at end of file +} From 32dff8b9e202cff936745135df84cc44345f01b2 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Thu, 22 Apr 2021 13:02:16 +0300 Subject: [PATCH 24/29] Fix #11362 name of underground station --- .../controllers/TransportStopController.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java index 2337031400..5a7ac0d665 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/controllers/TransportStopController.java @@ -189,7 +189,24 @@ public class TransportStopController extends MenuController { } } - private static void sortTransportStops(@NonNull LatLon latLon, List transportStops) { + private static void sortTransportStopsExits(@NonNull LatLon latLon, @NonNull List transportStops) { + for (TransportStop transportStop : transportStops) { + for (TransportStopExit exit : transportStop.getExits()) { + int distance = (int) MapUtils.getDistance(latLon, exit.getLocation()); + if (transportStop.distance > distance) { + transportStop.distance = distance; + } + } + } + Collections.sort(transportStops, new Comparator() { + @Override + public int compare(TransportStop s1, TransportStop s2) { + return Algorithms.compare(s1.distance, s2.distance); + } + }); + } + + private static void sortTransportStops(@NonNull LatLon latLon, @NonNull List transportStops) { for (TransportStop transportStop : transportStops) { transportStop.distance = (int) MapUtils.getDistance(latLon, transportStop.getLocation()); } @@ -227,6 +244,8 @@ public class TransportStopController extends MenuController { if (isSubwayEntrance) { stopAggregated = processTransportStopsForAmenity(transportStops, amenity); + sortTransportStopsExits(loc, stopAggregated.getLocalTransportStops()); + sortTransportStopsExits(loc, stopAggregated.getNearbyTransportStops()); } else { stopAggregated = new TransportStopAggregated(); stopAggregated.setAmenity(amenity); From 1ac919b8d32c5b4f3038928b0e0365e4b367e132 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Thu, 22 Apr 2021 14:12:49 +0300 Subject: [PATCH 25/29] RTL: fix Live Updates screen --- OsmAnd/res/drawable/rectangle_rounded_left.xml | 7 +++++++ OsmAnd/res/drawable/ripple_rectangle_rounded_left.xml | 11 +++++++++++ OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java | 3 +++ .../osmand/plus/liveupdates/LiveUpdatesFragment.java | 8 ++++---- .../bottomsheets/BooleanPreferenceBottomSheet.java | 8 +++++--- 5 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 OsmAnd/res/drawable/rectangle_rounded_left.xml create mode 100644 OsmAnd/res/drawable/ripple_rectangle_rounded_left.xml diff --git a/OsmAnd/res/drawable/rectangle_rounded_left.xml b/OsmAnd/res/drawable/rectangle_rounded_left.xml new file mode 100644 index 0000000000..56b3235c6c --- /dev/null +++ b/OsmAnd/res/drawable/rectangle_rounded_left.xml @@ -0,0 +1,7 @@ + + + + diff --git a/OsmAnd/res/drawable/ripple_rectangle_rounded_left.xml b/OsmAnd/res/drawable/ripple_rectangle_rounded_left.xml new file mode 100644 index 0000000000..c63df94daf --- /dev/null +++ b/OsmAnd/res/drawable/ripple_rectangle_rounded_left.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java index 5fdea403d3..8b3fc01882 100644 --- a/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java +++ b/OsmAnd/src/net/osmand/plus/ContextMenuAdapter.java @@ -445,6 +445,9 @@ public class ContextMenuAdapter { ImageView imageView = (ImageView) convertView.findViewById(R.id.secondary_icon); imageView.setImageDrawable(drawable); imageView.setVisibility(View.VISIBLE); + if (secondaryDrawable == R.drawable.ic_action_additional_option) { + UiUtilities.rotateImageByLayoutDirection(imageView); + } } else { ImageView imageView = (ImageView) convertView.findViewById(R.id.secondary_icon); if (imageView != null) { diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index c4fa160e08..7bebeda1f2 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -275,16 +275,14 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL TextViewEx toolbarTitle = (TextViewEx) toolbar.findViewById(R.id.toolbar_title); toolbarTitle.setText(R.string.osm_live); - View closeButton = toolbar.findViewById(R.id.close_button); + ImageView closeButton = (ImageView) toolbar.findViewById(R.id.close_button); + UiUtilities.rotateImageByLayoutDirection(closeButton); closeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dismiss(); } }); - if (closeButton instanceof ImageView) { - UiUtilities.rotateImageByLayoutDirection((ImageView) closeButton); - } FrameLayout iconHelpContainer = toolbar.findViewById(R.id.action_button); int iconColorResId = nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light; @@ -443,6 +441,8 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL boolean isLastChild, View convertView, ViewGroup parent) { LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); convertView = inflater.inflate(R.layout.list_item_triple_row_icon_and_menu, parent, false); + ImageView secondaryIcon = (ImageView) convertView.findViewById(R.id.secondary_icon); + UiUtilities.rotateImageByLayoutDirection(secondaryIcon); LiveMapsViewHolder viewHolder = new LiveMapsViewHolder(convertView); convertView.setTag(viewHolder); viewHolder.bindLocalIndexInfo(getChild(groupPosition, childPosition).getFileName()); diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java index 858e32c962..1fd19e00c1 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java @@ -134,6 +134,7 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { public static void updateCustomButtonView(OsmandApplication app, ApplicationMode mode, View customView, boolean checked, boolean nightMode) { Context themedCtx = UiUtilities.getThemedContext(app, nightMode); + boolean isLayoutRtl = AndroidUtils.isLayoutRtl(themedCtx); LinearLayout buttonView = customView.findViewById(R.id.button_container); int bgColor; @@ -149,10 +150,11 @@ public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { ContextCompat.getColor(app, getActivePrimaryColorId(nightMode)), checked ? 0.3f : 0.5f); } - int bgResId = R.drawable.rectangle_rounded_right; + int bgResId = isLayoutRtl ? R.drawable.rectangle_rounded_left : R.drawable.rectangle_rounded_right; if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { - int selectableResId = R.drawable.ripple_rectangle_rounded_right; - + int selectableResId = isLayoutRtl ? + R.drawable.ripple_rectangle_rounded_left : + R.drawable.ripple_rectangle_rounded_right; Drawable bgDrawable = app.getUIUtilities().getPaintedIcon(bgResId, bgColor); Drawable selectable = app.getUIUtilities().getPaintedIcon(selectableResId, selectedColor); Drawable[] layers = {bgDrawable, selectable}; From 42604ac3b619d83c02c6bcf63241e02b4a9217af Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Thu, 22 Apr 2021 15:02:10 +0300 Subject: [PATCH 26/29] RTL: fix slider on Announcement Time dialog --- .../seekbar_progress_announcement_time.xml | 15 ---- .../seekbar_thumb_announcement_time.xml | 13 --- .../seekbar_tickmark_announcement_time.xml | 8 -- .../layout/bottom_sheet_announcement_time.xml | 14 +-- .../AnnouncementTimeBottomSheet.java | 86 ++++++------------- 5 files changed, 30 insertions(+), 106 deletions(-) delete mode 100644 OsmAnd/res/drawable/seekbar_progress_announcement_time.xml delete mode 100644 OsmAnd/res/drawable/seekbar_thumb_announcement_time.xml delete mode 100644 OsmAnd/res/drawable/seekbar_tickmark_announcement_time.xml diff --git a/OsmAnd/res/drawable/seekbar_progress_announcement_time.xml b/OsmAnd/res/drawable/seekbar_progress_announcement_time.xml deleted file mode 100644 index 794539923e..0000000000 --- a/OsmAnd/res/drawable/seekbar_progress_announcement_time.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OsmAnd/res/drawable/seekbar_thumb_announcement_time.xml b/OsmAnd/res/drawable/seekbar_thumb_announcement_time.xml deleted file mode 100644 index a126aee222..0000000000 --- a/OsmAnd/res/drawable/seekbar_thumb_announcement_time.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/OsmAnd/res/drawable/seekbar_tickmark_announcement_time.xml b/OsmAnd/res/drawable/seekbar_tickmark_announcement_time.xml deleted file mode 100644 index d6662da81f..0000000000 --- a/OsmAnd/res/drawable/seekbar_tickmark_announcement_time.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/OsmAnd/res/layout/bottom_sheet_announcement_time.xml b/OsmAnd/res/layout/bottom_sheet_announcement_time.xml index 246ffe3476..308ad0278a 100644 --- a/OsmAnd/res/layout/bottom_sheet_announcement_time.xml +++ b/OsmAnd/res/layout/bottom_sheet_announcement_time.xml @@ -62,18 +62,12 @@ osmand:typeface="@string/font_roboto_medium" tools:text="Normal" /> - + android:layout_marginLeft="@dimen/content_padding" + android:layout_marginRight="@dimen/content_padding" /> Date: Thu, 22 Apr 2021 16:54:12 +0300 Subject: [PATCH 27/29] Fix test backup screen --- OsmAnd/src/net/osmand/plus/backup/BackupHelper.java | 9 ++++----- .../net/osmand/plus/development/TestBackupActivity.java | 5 ----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java b/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java index be81017d42..326315b7d1 100644 --- a/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java +++ b/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java @@ -131,10 +131,6 @@ public class BackupHelper { return token.matches("[0-9]+"); } - public boolean hasOsmLiveUpdates() { - return InAppPurchaseHelper.isSubscribedToLiveUpdates(app); - } - @Nullable public String getOrderId() { InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper(); @@ -167,7 +163,10 @@ public class BackupHelper { public void registerUser(@NonNull String email, @Nullable final OnRegisterUserListener listener) { Map params = new HashMap<>(); params.put("email", email); - params.put("orderid", getOrderId()); + String orderId = getOrderId(); + if (!Algorithms.isEmpty(orderId)) { + params.put("orderid", orderId); + } params.put("deviceid", app.getUserAndroidId()); AndroidNetworkUtils.sendRequestAsync(app, USER_REGISTER_URL, params, "Register user", true, true, new OnRequestResultListener() { @Override diff --git a/OsmAnd/src/net/osmand/plus/development/TestBackupActivity.java b/OsmAnd/src/net/osmand/plus/development/TestBackupActivity.java index a5d0daddf5..3b38b1469b 100644 --- a/OsmAnd/src/net/osmand/plus/development/TestBackupActivity.java +++ b/OsmAnd/src/net/osmand/plus/development/TestBackupActivity.java @@ -89,11 +89,6 @@ public class TestBackupActivity extends OsmandActionBarActivity { } }); - if (!backupHelper.hasOsmLiveUpdates()) { - findViewById(R.id.main_view).setVisibility(View.GONE); - return; - } - buttonRegister = findViewById(R.id.btn_register); UiUtilities.setupDialogButton(nightMode, buttonRegister, DialogButtonType.PRIMARY, "Register"); buttonVerify = findViewById(R.id.btn_verify); From e2d659e859b0719af9e0325a773eefcd312b1061 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Thu, 22 Apr 2021 18:43:37 +0300 Subject: [PATCH 28/29] Fix #11423 Wikipedia labels on the map shown on few languages --- .../osmand/plus/views/layers/POIMapLayer.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java index 1adeed7671..49e5d49a56 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/POIMapLayer.java @@ -357,19 +357,7 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon @Override public PointDescription getObjectName(Object o) { if (o instanceof Amenity) { - Amenity amenity = (Amenity) o; - String preferredLang = app.getSettings().MAP_PREFERRED_LOCALE.get(); - boolean transliterateNames = app.getSettings().MAP_TRANSLITERATE_NAMES.get(); - - if (amenity.getType().isWiki()) { - if (Algorithms.isEmpty(preferredLang)) { - preferredLang = app.getLanguage(); - } - preferredLang = OsmandPlugin.onGetMapObjectsLocale(amenity, preferredLang); - } - - return new PointDescription(PointDescription.POINT_TYPE_POI, - amenity.getName(preferredLang, transliterateNames)); + return new PointDescription(PointDescription.POINT_TYPE_POI, getAmenityName((Amenity) o)); } return null; } @@ -431,8 +419,20 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon @Override public String getText(Amenity o) { - return o.getName(view.getSettings().MAP_PREFERRED_LOCALE.get(), - view.getSettings().MAP_TRANSLITERATE_NAMES.get()); + return getAmenityName(o); + } + + private String getAmenityName(Amenity amenity) { + String locale = app.getSettings().MAP_PREFERRED_LOCALE.get(); + + if (amenity.getType().isWiki()) { + if (Algorithms.isEmpty(locale)) { + locale = app.getLanguage(); + } + locale = OsmandPlugin.onGetMapObjectsLocale(amenity, locale); + } + + return amenity.getName(locale, app.getSettings().MAP_TRANSLITERATE_NAMES.get()); } @Override From 974ad80734acbfdd4f10ab97060ad671a3b09ef5 Mon Sep 17 00:00:00 2001 From: max-klaus Date: Thu, 22 Apr 2021 20:35:27 +0300 Subject: [PATCH 29/29] Fix backup sync and progress --- .../src/net/osmand/AndroidNetworkUtils.java | 45 +++++++++++++++++-- .../net/osmand/plus/backup/BackupHelper.java | 22 +++++---- .../net/osmand/plus/backup/BackupTask.java | 17 ++++--- .../plus/development/TestBackupActivity.java | 6 +++ 4 files changed, 73 insertions(+), 17 deletions(-) diff --git a/OsmAnd/src/net/osmand/AndroidNetworkUtils.java b/OsmAnd/src/net/osmand/AndroidNetworkUtils.java index b25fb1b2d4..f25d08565b 100644 --- a/OsmAnd/src/net/osmand/AndroidNetworkUtils.java +++ b/OsmAnd/src/net/osmand/AndroidNetworkUtils.java @@ -38,6 +38,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.Executor; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; @@ -92,6 +93,13 @@ public class AndroidNetworkUtils { public static void sendRequestsAsync(@Nullable final OsmandApplication ctx, @NonNull final List requests, @Nullable final OnSendRequestsListener listener) { + sendRequestsAsync(ctx, requests, listener, AsyncTask.THREAD_POOL_EXECUTOR); + } + + public static void sendRequestsAsync(@Nullable final OsmandApplication ctx, + @NonNull final List requests, + @Nullable final OnSendRequestsListener listener, + final Executor executor) { new AsyncTask>() { @@ -127,7 +135,7 @@ public class AndroidNetworkUtils { } } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); + }.executeOnExecutor(executor, (Void) null); } public static void sendRequestAsync(final OsmandApplication ctx, @@ -137,7 +145,18 @@ public class AndroidNetworkUtils { final boolean toastAllowed, final boolean post, final OnRequestResultListener listener) { + sendRequestAsync(ctx, url, parameters, userOperation, toastAllowed, post, listener, + AsyncTask.THREAD_POOL_EXECUTOR); + } + public static void sendRequestAsync(final OsmandApplication ctx, + final String url, + final Map parameters, + final String userOperation, + final boolean toastAllowed, + final boolean post, + final OnRequestResultListener listener, + final Executor executor) { new AsyncTask() { @Override @@ -156,7 +175,7 @@ public class AndroidNetworkUtils { } } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); + }.executeOnExecutor(executor, (Void) null); } public static void downloadFileAsync(final String url, @@ -183,6 +202,14 @@ public class AndroidNetworkUtils { final @NonNull List files, final @NonNull Map parameters, final @Nullable OnFilesDownloadCallback callback) { + downloadFilesAsync(url, files, parameters, callback, AsyncTask.THREAD_POOL_EXECUTOR); + } + + public static void downloadFilesAsync(final @NonNull String url, + final @NonNull List files, + final @NonNull Map parameters, + final @Nullable OnFilesDownloadCallback callback, + final Executor executor) { new AsyncTask>() { @@ -247,7 +274,7 @@ public class AndroidNetworkUtils { } } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); + }.executeOnExecutor(executor, (Void) null); } public static String sendRequest(@Nullable OsmandApplication ctx, @NonNull String url, @@ -503,6 +530,16 @@ public class AndroidNetworkUtils { final @NonNull Map parameters, final @Nullable Map headers, final OnFilesUploadCallback callback) { + uploadFilesAsync(url, files, gzip, parameters, headers, callback, AsyncTask.THREAD_POOL_EXECUTOR); + } + + public static void uploadFilesAsync(final @NonNull String url, + final @NonNull List files, + final boolean gzip, + final @NonNull Map parameters, + final @Nullable Map headers, + final OnFilesUploadCallback callback, + final Executor executor) { new AsyncTask>() { @@ -557,7 +594,7 @@ public class AndroidNetworkUtils { } } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); + }.executeOnExecutor(executor, (Void) null); } private static void showToast(OsmandApplication ctx, String message) { diff --git a/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java b/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java index 326315b7d1..87423ec582 100644 --- a/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java +++ b/OsmAnd/src/net/osmand/plus/backup/BackupHelper.java @@ -37,6 +37,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; public class BackupHelper { @@ -45,6 +48,9 @@ public class BackupHelper { private final FavouritesDbHelper favouritesHelper; private final GpxDbHelper gpxHelper; + private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(1, 1, 0L, + TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); + private static final String SERVER_URL = "https://osmand.net"; private static final String USER_REGISTER_URL = SERVER_URL + "/userdata/user-register"; @@ -196,7 +202,7 @@ public class BackupHelper { listener.onRegisterUser(status, message); } } - }); + }, EXECUTOR); } public void registerDevice(String token, @Nullable final OnRegisterDeviceListener listener) { @@ -238,7 +244,7 @@ public class BackupHelper { listener.onRegisterDevice(status, message); } } - }); + }, EXECUTOR); } public void uploadFiles(@NonNull List gpxFiles, @Nullable final OnUploadFilesListener listener) throws UserNotRegisteredException { @@ -294,7 +300,7 @@ public class BackupHelper { listener.onFilesUploadDone(errors); } } - }); + }, EXECUTOR); } public void deleteFiles(@NonNull List userFiles, @Nullable final OnDeleteFilesListener listener) throws UserNotRegisteredException { @@ -349,7 +355,7 @@ public class BackupHelper { listener.onFilesDeleteDone(errors); } } - }); + }, EXECUTOR); } public void downloadFileList(@Nullable final OnDownloadFileListListener listener) throws UserNotRegisteredException { @@ -391,7 +397,7 @@ public class BackupHelper { listener.onDownloadFileList(status, message, userFiles); } } - }); + }, EXECUTOR); } public void downloadFiles(@NonNull final Map filesMap, @Nullable final OnDownloadFileListener listener) throws UserNotRegisteredException { @@ -432,7 +438,7 @@ public class BackupHelper { listener.onFilesDownloadDone(errors); } } - }); + }, EXECUTOR); } @SuppressLint("StaticFieldLeak") @@ -514,7 +520,7 @@ public class BackupHelper { } } }; - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + task.executeOnExecutor(EXECUTOR); } @SuppressLint("StaticFieldLeak") @@ -575,6 +581,6 @@ public class BackupHelper { } } }; - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + task.executeOnExecutor(EXECUTOR); } } diff --git a/OsmAnd/src/net/osmand/plus/backup/BackupTask.java b/OsmAnd/src/net/osmand/plus/backup/BackupTask.java index a2fc299463..27a698f73d 100644 --- a/OsmAnd/src/net/osmand/plus/backup/BackupTask.java +++ b/OsmAnd/src/net/osmand/plus/backup/BackupTask.java @@ -11,7 +11,6 @@ import net.osmand.AndroidUtils; import net.osmand.GPXUtilities; import net.osmand.GPXUtilities.GPXFile; import net.osmand.plus.GPXDatabase.GpxDataItem; -import net.osmand.plus.GpxDbHelper; import net.osmand.plus.OsmandApplication; import net.osmand.plus.ProgressImplementation; import net.osmand.plus.backup.BackupHelper.BackupInfo; @@ -113,7 +112,7 @@ public class BackupTask { tasks.push(backupTasks[i]); } this.runningTasks = tasks; - onTasksInit(); + onBackupTasksInit(); } private void initRestoreTasks() { @@ -123,7 +122,7 @@ public class BackupTask { tasks.push(restoreTasks[i]); } this.runningTasks = tasks; - onTasksInit(); + onRestoreTasksInit(); } private void initData() { @@ -275,14 +274,22 @@ public class BackupTask { } } - private void onTasksInit() { + private void onBackupTasksInit() { Context ctx = contextRef.get(); - if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx) && progress != null) { + if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx)) { progress = ProgressImplementation.createProgressDialog(ctx, "Backup data", "Initializing...", ProgressDialog.STYLE_HORIZONTAL); } } + private void onRestoreTasksInit() { + Context ctx = contextRef.get(); + if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx)) { + progress = ProgressImplementation.createProgressDialog(ctx, + "Restore data", "Initializing...", ProgressDialog.STYLE_HORIZONTAL); + } + } + private void onTaskProgressUpdate(Object... objects) { Context ctx = contextRef.get(); if (ctx instanceof Activity && AndroidUtils.isActivityNotDestroyed((Activity) ctx) && progress != null) { diff --git a/OsmAnd/src/net/osmand/plus/development/TestBackupActivity.java b/OsmAnd/src/net/osmand/plus/development/TestBackupActivity.java index 3b38b1469b..8f78c63151 100644 --- a/OsmAnd/src/net/osmand/plus/development/TestBackupActivity.java +++ b/OsmAnd/src/net/osmand/plus/development/TestBackupActivity.java @@ -186,6 +186,7 @@ public class TestBackupActivity extends OsmandActionBarActivity { @Override public void onClick(View v) { if (backupInfo != null) { + buttonBackup.setEnabled(false); BackupTask task = new BackupTask(backupInfo, TestBackupActivity.this, new OnBackupListener() { @Override public void onBackupDone(@Nullable Map uploadErrors, @Nullable Map downloadErrors, @@ -203,6 +204,7 @@ public class TestBackupActivity extends OsmandActionBarActivity { a.infoView.setText(description); a.infoView.requestFocus(); a.prepareBackup(); + a.buttonBackup.setEnabled(true); } } }); @@ -214,6 +216,7 @@ public class TestBackupActivity extends OsmandActionBarActivity { @Override public void onClick(View v) { if (backupInfo != null) { + buttonRestore.setEnabled(false); BackupTask task = new BackupTask(backupInfo, TestBackupActivity.this, new OnBackupListener() { @Override public void onBackupDone(@Nullable Map uploadErrors, @Nullable Map downloadErrors, @@ -231,6 +234,7 @@ public class TestBackupActivity extends OsmandActionBarActivity { a.infoView.setText(description); a.infoView.requestFocus(); a.prepareBackup(); + a.buttonRestore.setEnabled(true); } } }); @@ -309,6 +313,7 @@ public class TestBackupActivity extends OsmandActionBarActivity { private void prepareBackup() { final WeakReference activityRef = new WeakReference<>(this); + buttonRefresh.setEnabled(false); PrepareBackupTask prepareBackupTask = new PrepareBackupTask(this, new OnPrepareBackupListener() { @Override public void onBackupPrepared(@Nullable BackupInfo backupInfo, @Nullable String error) { @@ -329,6 +334,7 @@ public class TestBackupActivity extends OsmandActionBarActivity { } a.infoView.setText(description); a.infoView.requestFocus(); + a.buttonRefresh.setEnabled(true); } } });