Készíts egy interaktív weboldalt, amelyen a felhasználónak az a feladata, hogy megjelölje Magyarország térképén a rendszer által véletlenszerűen kiválasztott megyeszékhely helyét. A weboldal:
- térképet jelenít meg Leaflet
segítségével,
- adatokat olvas be egy JSON
fájlból,
- véletlenszerűen kiválaszt egy
várost,
- a felhasználó kattintásával
tippet ad,
- megmutatja az eltérés
távolságát,
- és új kérdést ad.
Szükséges technológiák
- HTML
- AngularJS (1.x)
- Leaflet.js
- OpenStreetMap
- Alapvető JavaScript és JSON
kezelés
A megye.json fájl
Hozz létre
egy megye.json fájlt, amely tartalmazza a megyeszékhelyeket és azok
koordinátáit:
[
{ "title": "Budapest",
"coordinates": { "lat": 47.4979, "lng": 19.0402 }
},
{ "title": "Debrecen",
"coordinates": { "lat": 47.5316, "lng": 21.6273 }
},
{ "title": "Szeged",
"coordinates": { "lat": 46.2530, "lng": 20.1414 }
},
{ "title": "Miskolc",
"coordinates": { "lat": 48.1030, "lng": 20.7784 }
},
{ "title": "Pécs",
"coordinates": { "lat": 46.0727, "lng": 18.2323 }
},
{ "title": "Győr",
"coordinates": { "lat": 47.6875, "lng": 17.6504 }
},
{ "title":
"Nyíregyháza", "coordinates": { "lat": 47.9554,
"lng": 21.7167 } },
{ "title": "Kecskemét",
"coordinates": { "lat": 46.9062, "lng": 19.6913 }
},
{ "title":
"Székesfehérvár", "coordinates": { "lat":
47.1860, "lng": 18.4221 } },
{ "title":
"Szombathely", "coordinates": { "lat": 47.2307,
"lng": 16.6218 } },
{ "title": "Eger",
"coordinates": { "lat": 47.9025, "lng": 20.3772 }
},
{ "title":
"Zalaegerszeg", "coordinates": { "lat": 46.8416,
"lng": 16.8465 } },
{ "title":
"Salgótarján", "coordinates": { "lat": 48.0982,
"lng": 19.8032 } },
{ "title": "Tatabánya",
"coordinates": { "lat": 47.5847, "lng": 18.3933 }
},
{
"title": "Szekszárd", "coordinates": {
"lat": 46.3481, "lng": 18.7045 } },
{ "title":
"Békéscsaba", "coordinates": { "lat": 46.6791,
"lng": 21.0877 } },
{ "title": "Veszprém",
"coordinates": { "lat": 47.0933, "lng": 17.9115 }
},
{ "title": "Kaposvár",
"coordinates": { "lat": 46.3593, "lng": 17.7969 }
}
]
HTML váz (index.html)
- Használd az alábbi könyvtárakat
a <head> szakaszban:
<!-- Leaflet CSS + JS -->
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"
/>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<!-- AngularJS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
- Készíts egy alap HTML szerkezetet, amely
tartalmaz:
- adj hozzá egy .container
osztályú elemet, aminek a szélessége 900px legyen, és helyezd el középen
az oldalon, adhatsz hozzá keretet vagy boksz árnyékot, hogylásd sikerült
e.
- egy #map elemet a térképnek, 500px
magas legyen.
- egy gombot az új kérdéshez
- egy szöveget a feladványhoz és
eredményhez
- ne pánikolj, mert lépésről
lépésre leírok mindent, mit kell csinálnod!
AngularJS
alkalmazás létrehozása
- Készítsd el
az AngularJS modult és kontrollert (
quizApp
,QuizController -> két paramétert kell hozzá adnod a $scope, és $http
)
A függvényen belül
először hozd létre a szükséges változókat:
- Hozd létre a következő js változókat, let
kulcsszóval: map, userMarker, realMarker, line
- Hozz létre egy üres tömböt és tárold el a $scope.places
változóba,
- Hozd létre a $scope.result változót, inicializáld
egy üres stringgel,
- Hozz létre egy üres objektumot $scope.currentPlace
néven.
calcDistance()
függvény létrehozása:
· A controller
függvényen belül hozz létre egy új (sima) javascript függvényt calcDistance
néven. Két paramétert adj neki: latlng1, latlng2.
·
A
függvény visszatérési értéke latlng1.distanceTo(latlng2) legyen amit el osztasz
1000-el.
Mindkettő Leaflet LatLng objektum típusú
(vagyis olyan objektum, amely tartalmaz lat és lng értékeket, pl. egy marker
helyzetét).
A
latlng1 és latlng2 a két pont (tipikusan L.latLng(...) objektumok).
A latlng1.distanceTo(latlng2) – ez egy
Leaflet beépített metódus, amely visszaadja a két pont közötti távolságot
méterben. Mivel méterben fogod megkapni, ezért kell elosztanod 1000-el, hogy
kilométer értéket kapj vissza.
nextPlace()
függvény
· Hozz létre egy AngularJs
függvényt, nextPlace néven, paramétert nem kell adni neki.
· Ezt a függvényt
hívd meg a html-ből az ng-click direktívával ha a user kattint a „Következő
hely tippelése” gombra.
· A függvényen belül
add hozzá a $scope.result változót újra, és inicializáld üres értékkel, ez a
lépés fogja a result változó előző tartalmát alaphelyzetbe állítani.
· A böngészőben,
amikor a user keresgél a térképen lehet el fogja húzni, jobbra vagy balra, és
amikor új feladatot kérünk akkor jó lenne, ha vissza állna középre. Ezért egy
if elágazással nézzük meg létezik e a map és ha igen akkor a map.setView([47.1625,
19.5033], 7); értékkel térjen vissza. Else ág nem kell.
Ø
Ez
azt ellenőrzi, hogy a map (Leaflet térkép) már létezik-e.
Ø
Ha
igen, visszaállítja a térkép nézetét Magyarország közepére:
Ø
47.1625
– Magyarország földrajzi szélessége
Ø
19.5033
– földrajzi hosszúsága
Ø
7
– a zoom szint (ez elég nagy ahhoz, hogy az egész ország látszódjon)
· Ez fontos, mert a
felhasználó elmozgathatta a térképet, és így mindig ugyanarról az alapállásból
indul az új kérdés.
· Ha létezik
userMarker (a játékos tippjének a jelölője)- itt írd meg az elágazást - , azt távolítsd
el a térképről: map.removeLayer(userMarker)
· Ha létezik a
valódi helyet jelölő marker, azt is távolítsd el, úgy mint az előzőt, mert új
kérdés jön: map.removeLayer(realMarker);
· Ha volt korábban
piros vonal (ami a két pont közti eltérést mutatta), azt is töröld: map.removeLayer(line);
· $scope.currentPlace
változót iniciáld a következő értékekkel:
Ø
$scope.places[]
tartalmazza a megyeszékhelyeket (azokat, amiket a JSON fájlból betöltöttünk).
Ø
Math.random()
→ ad egy véletlenszámot 0 és 1 között
Ø
Math.floor(...)
→ kerekíti lefelé, így egész szám lesz;
· Ez alapján
véletlenszerűen kiválasztunk egy új megyeszékhelyet, és ezt elmentjük a
$scope.currentPlace változóba.
Ez lesz a következő kérdés, amit a játékosnak ki kell
találnia a térképen! Tehát a A nextPlace():
· Törli
a korábbi játék nyomait (jelölők, vonal, eredmény),
· Visszaállítja
a térképet alaphelyzetbe,
· Új
véletlenszerű várost választ,
· Előkészíti
a következő kört.
Oké, jöhet a következő függvény, és innentől kezdve
mindent ebbe adsz meg.
$http.get()
· A
get metódussal kérd le az adatokat a megye.json fájlból.
· A
választ tárold el a $scope.places változóba.
· Hívd
meg a $scope.nextPlace() függvényt.
· Az
előzetesen létrehozott map változónak adjuk meg értékként Magyarország közepét:
map = L.map('map').setView([47.1625,
19.5033], 7);
Ezt
követően a következőket kell megadnod a függvényen belül a következőket kell
hozzáadnod:
Térképréteg betöltése – OpenStreetMap
L.
tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution:
'© OpenStreetMap contributors'
}).
addTo(map);
Mit
csinál ez?
- A
tileLayer
az, ami megjeleníti a térkép csempéit (tile-jait). - Az
https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png
egy OpenStreetMap sablon URL, ahol a{z}
a zoom-szintet,{x}
és{y}
a csempe koordinátáit jelöli. - Az
attribution
fontos: ez a jogi nyilatkozat, ami megjelenik a térképen, hogy tudjuk, ki a térkép forrása (OpenStreetMap).
addTo(map)
hozzáadja ezt a réteget a map
nevű Leaflet térképhez.
2. Kattintás esemény kezelése
map.
on(
'click',
function (
e) {
Ez a rész akkor fut le, amikor a felhasználó rákattint a térképre.
3. Megakadályozás, ha már van eredmény
if ($scope.
result)
return;
Ha már volt egy tipp és kiszámolták az
eltérést, akkor ne engedje újra
kattintani. Új kérdésig nincs új kattintás.
4. Tippelt pozíció mentése
const guessed = e.
latlng;
e.latlng
a Leaflet által adott objektum, amely a kattintás helyének GPS-koordinátáit tartalmazza.- Példa:
{lat: 47.5, lng: 19.1}
5. Valódi hely pozíciója
const actual = L.
latLng($scope.
currentPlace.
coordinates.
lat, $scope.
currentPlace.
coordinates.
lng);
- Ez átalakítja az aktuális megyeszékhely (
currentPlace
) koordinátáit Leaflet-értelmezhető formátumra. - Így a
distanceTo()
később működni fog.
6. Távolság kiszámítása
const distance =
calcDistance(guessed, actual).
toFixed(
2);
- Meghívja az előzőleg létrehozott
calcDistance()
függvényt, ami a két pont közötti távolságot méri km-ben. .toFixed(2)
→ két tizedesjegyre kerekíti, pl.124.37
7. Játékos tippjének megjelenítése
userMarker = L.
marker(guessed).
addTo(map).
bindPopup(
"Tipped: ").
openPopup();
- Elhelyez egy markert oda, ahová a játékos kattintott.
- Megnyit egy buborékot: „Tipped: ” (akár
bővítheted: „Tipped: itt gondoltad, hogy a város van”).
8. Valódi hely marker ikonja és popup
realMarker = L.
marker(actual, {
icon: L.
icon({
iconUrl:
'https://cdn-icons-png.flaticon.com/512/149/149059.png',
iconSize: [
30,
30],
iconAnchor: [
15,
30]
})
}).
addTo(map).
bindPopup(
`Helyes válasz: ${$scope.currentPlace.title}`).
openPopup();
- Elhelyez egy markert a helyes megyeszékhelyre
- Speciális ikont használ (
iconUrl
) - A popupban megjeleníti: „Helyes válasz: Eger” –
vagy bármelyik város
9. Vonal a két pont között
line = L.
polyline([guessed, actual], {
color:
'red'}).
addTo(map);
L.polyline([...])
rajzol egy piros vonalat a két pont közé:
Ø A játékos tippje
Ø A valódi
megyeszékhely
- Ez látványosan mutatja az eltérést.
10. Eltérés kiírása
$scope.
result =
`Eltérés: ${distance} km`;
$scope.$apply();
- Ezzel elmentjük az eltérés szövegét az Angular
modellbe
- A
{{result}}
szöveg a HTML-ben frissül - A
$scope.$apply()
arra kell, hogy az Angular figyelje meg a változást és frissítse a DOM-ot (mivel a változás egy külső eseményből – Leaflet – indult el)
Mit kell beadni?
- A teljes projektmappa:
Ø index.html
Ø megye.json
- Minden fájl működjön helyi szerveren (
Live Server
, XAMPP stb.) - A térkép és a kvíz funkció legyen tesztelhető és
hibamentes
Tesztelés
- Nyisd meg a projektet Live Serverrel
- Próbálj meg 3-4 választ adni
- Ellenőrizd: marker megjelenik? távolság jól
számolódik? új kérdés működik?
Ha valami nem működik, ne pánikolj,
ne add fel:
- Ellenőrizd a konzolt (
F12
→ Console) - Nézd meg, valóban betöltődött-e a
megye.json
fájl - Használj
console.log(...)
-ot a változók értékének megtekintéséhez
Minta:
IKT
Projekt feladat:
Kedves Csapat tudom szívesen
játszátok a találd ki hol van játékot. Ennek a feladatnak nyomán készítsetek saját
játékot. ChatGpt-vel írassatok különböző országokra, vagy földrészekre JSON
fájlt, és készítsétek el hozzá a saját játékotokat. Ezt követően lehet majd
tovább gondolni, regisztrációval, pont számlálóval, esetleges jövőbeni projekt
dolgozatnak. A csoporton belül, beszéljétek meg, melyik csapat melyik földrészre
vonatkozóan készíti el a játékot. Ezt követően össze lehet fűzni az összes
oldalt, úgy hogy egy fő oldalon, a user ki tudja választani egy select-ből,
hogy melyik földrészen szeretne játszani.
Nincsenek megjegyzések:
Megjegyzés küldése