feat: switch to open street map

This commit is contained in:
log101 2024-01-17 09:07:38 +03:00
parent ccbe2e2213
commit 997d4d4967
6 changed files with 122 additions and 169 deletions

14
package-lock.json generated
View File

@ -13,6 +13,7 @@
"@astrojs/tailwind": "^5.1.0", "@astrojs/tailwind": "^5.1.0",
"@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-slot": "^1.0.2",
"@types/leaflet": "^1.9.8",
"@types/react": "^18.2.47", "@types/react": "^18.2.47",
"@types/react-dom": "^18.2.18", "@types/react-dom": "^18.2.18",
"astro": "^4.1.2", "astro": "^4.1.2",
@ -1325,6 +1326,11 @@
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
}, },
"node_modules/@types/geojson": {
"version": "7946.0.13",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.13.tgz",
"integrity": "sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ=="
},
"node_modules/@types/google.maps": { "node_modules/@types/google.maps": {
"version": "3.54.10", "version": "3.54.10",
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.54.10.tgz", "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.54.10.tgz",
@ -1339,6 +1345,14 @@
"@types/unist": "*" "@types/unist": "*"
} }
}, },
"node_modules/@types/leaflet": {
"version": "1.9.8",
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.8.tgz",
"integrity": "sha512-EXdsL4EhoUtGm2GC2ZYtXn+Fzc6pluVgagvo2VC1RHWToLGlTRwVYoDpqS/7QXa01rmDyBjJk3Catpf60VMkwg==",
"dependencies": {
"@types/geojson": "*"
}
},
"node_modules/@types/mdast": { "node_modules/@types/mdast": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz",

View File

@ -15,6 +15,7 @@
"@astrojs/tailwind": "^5.1.0", "@astrojs/tailwind": "^5.1.0",
"@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-slot": "^1.0.2",
"@types/leaflet": "^1.9.8",
"@types/react": "^18.2.47", "@types/react": "^18.2.47",
"@types/react-dom": "^18.2.18", "@types/react-dom": "^18.2.18",
"astro": "^4.1.2", "astro": "^4.1.2",

1
public/goal.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-goal"><path d="M12 13V2l8 4-8 4"/><path d="M20.55 10.23A9 9 0 1 1 8 4.94"/><path d="M8 10a5 5 0 1 0 8.9 2.02"/></svg>

After

Width:  |  Height:  |  Size: 319 B

1
src/env.d.ts vendored
View File

@ -1,2 +1,3 @@
/// <reference types="astro/client" /> /// <reference types="astro/client" />
/// <reference types="@types/google.maps" /> /// <reference types="@types/google.maps" />
/// <reference types="@types/leaflet" />

View File

@ -9,51 +9,18 @@ const googleSdkKey = import.meta.env.MAPS_SDK_KEY;
<meta name="description" content="Astro description" /> <meta name="description" content="Astro description" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""
/>
<script
is:inline
src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""></script>
<meta name="generator" content={Astro.generator} /> <meta name="generator" content={Astro.generator} />
<script define:vars={{ apiKey: googleSdkKey }}>
((g) => {
var h,
a,
k,
p = 'The Google Maps JavaScript API',
c = 'google',
l = 'importLibrary',
q = '__ib__',
m = document,
b = window;
b = b[c] || (b[c] = {});
var d = b.maps || (b.maps = {}),
r = new Set(),
e = new URLSearchParams(),
u = () =>
h ||
(h = new Promise(async (f, n) => {
await (a = m.createElement('script'));
e.set('libraries', [...r] + '');
for (k in g)
e.set(
k.replace(/[A-Z]/g, (t) => '_' + t[0].toLowerCase()),
g[k]
);
e.set('callback', c + '.maps.' + q);
a.src = `https://maps.${c}apis.com/maps/api/js?` + e;
d[q] = f;
a.onerror = () => (h = n(Error(p + ' could not load.')));
a.nonce = m.querySelector('script[nonce]')?.nonce || '';
m.head.append(a);
}));
d[l]
? console.warn(p + ' only loads once. Ignoring:', g)
: (d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)));
})({
language: 'tr',
region: 'TR',
key: apiKey,
v: 'beta',
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<title>Konulu Konum</title> <title>Konulu Konum</title>
</head> </head>
<body class="bg-purple-50 container"> <body class="bg-purple-50 container">

View File

@ -20,10 +20,10 @@ import LocationButton from '@/components/LockedContent';
<main class="flex flex-col gap-3 my-4 items-center"> <main class="flex flex-col gap-3 my-4 items-center">
<Card className="w-full"> <Card className="w-full">
<CardHeader> <CardHeader>
<CardTitle>Ayşe</CardTitle> <CardTitle>Abdurrahman</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<p>Aşağıdaki konuma gitmen</p> <p>Aşağıdaki konuma gitmen gerekiyor.</p>
</CardContent> </CardContent>
<CardFooter className="gap-2"> <CardFooter className="gap-2">
<CalendarIcon /> <CalendarIcon />
@ -41,140 +41,109 @@ import LocationButton from '@/components/LockedContent';
<script> <script>
// TODO: Move script to a seperate file // TODO: Move script to a seperate file
import distance from '../utils/distance'; import L from 'leaflet';
import type { LatLngTuple, Marker, LocationEvent, ErrorEvent } from 'leaflet';
let map: google.maps.Map, infoWindow: google.maps.InfoWindow; const TARGET_LOCATION: LatLngTuple = [41.01907795861253, 29.01715377829709];
async function initMap(): Promise<void> {
const { Map } = (await google.maps.importLibrary(
'maps'
)) as google.maps.MapsLibrary;
const { AdvancedMarkerElement } = (await google.maps.importLibrary( var map = L.map('map').setView(TARGET_LOCATION, 13);
'marker'
)) as google.maps.MarkerLibrary;
map = new Map(document.getElementById('map') as HTMLElement, { L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
center: { lat: -34.397, lng: 150.644 }, maxZoom: 19,
zoom: 8, attribution:
mapId: 'DEMO_MAP_ID', '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
mapTypeControl: false, }).addTo(map);
var targetLocationIcon = L.icon({
iconUrl: 'goal.svg',
iconSize: [32, 32],
}); });
const currentLocationIcon = document.createElement('img'); L.marker(TARGET_LOCATION, { icon: targetLocationIcon }).addTo(map);
currentLocationIcon.src = '/blue-dot.png';
const targetLocationIcon = document.createElement('img'); var currentLocationIcon = L.icon({
targetLocationIcon.src = '/goal.png'; iconUrl: 'blue-dot.png',
targetLocationIcon.height = 32; iconSize: [32, 32],
targetLocationIcon.width = 32;
const parser = new DOMParser();
// A marker with a custom inline SVG.
const pinSvgString =
'<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-goal"><path d="M12 13V2l8 4-8 4"/><path d="M20.55 10.23A9 9 0 1 1 8 4.94"/><path d="M8 10a5 5 0 1 0 8.9 2.02"/></svg>';
const pinSvg = parser.parseFromString(
pinSvgString,
'image/svg+xml'
).documentElement;
const currentLocationMarkerView = new AdvancedMarkerElement({
map,
position: { lat: 37.434, lng: -122.082 },
content: currentLocationIcon,
title: 'Current Location',
}); });
const targetLocationMarkerView = new AdvancedMarkerElement({ let currentLocationMarker: Marker;
map,
position: { lat: 37.434, lng: -122.082 },
content: pinSvg,
title: 'A marker using a custom PNG Image',
});
infoWindow = new google.maps.InfoWindow(); function onLocationFound(e: LocationEvent) {
var radius = e.accuracy;
if (currentLocationMarker) {
currentLocationMarker.setLatLng(e.latlng);
} else {
currentLocationMarker = L.marker(e.latlng, { icon: currentLocationIcon });
currentLocationMarker.addTo(map);
}
}
map.on('locationfound', onLocationFound);
function onLocationError(e: ErrorEvent) {
alert(e.message);
}
map.on('locationerror', onLocationError);
// @ts-expect-error extend object
L.Control.GoToCurrentLocation = L.Control.extend({
onAdd: function (map: L.Map) {
const locationButton = document.createElement('button'); const locationButton = document.createElement('button');
const locationInfo = document.createElement('button');
locationButton.textContent = 'Konumuma Git'; locationButton.textContent = 'Konumuma Git';
locationInfo.textContent = 'Mesafe hesaplanıyor...';
locationButton.classList.add('custom-map-control-button'); locationButton.classList.add('custom-map-control-button');
locationInfo.classList.add('custom-map-control-button');
map.controls[google.maps.ControlPosition.TOP_CENTER].push(locationButton);
map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(locationInfo);
setInterval(
() =>
navigator.geolocation.getCurrentPosition(
(position: GeolocationPosition) => {
const pos = {
lat: position.coords.latitude,
lng: position.coords.longitude,
};
const totalDistanceInKM = distance(
pos.lat,
pos.lng,
41.045227057192136,
28.98791224002213
).toFixed(0);
currentLocationMarkerView.position = pos;
targetLocationMarkerView.position = {
lat: 41.045227057192136,
lng: 28.98791224002213,
};
locationInfo.textContent = `Aradaki Mesafe: ${totalDistanceInKM} km`;
},
() => {
handleLocationError(true, infoWindow, map.getCenter()!);
}
),
3000
);
locationButton.addEventListener('click', () => { locationButton.addEventListener('click', () => {
// Try HTML5 geolocation. map.locate({ setView: true, maxZoom: 16 });
if (navigator.geolocation) { });
navigator.geolocation.getCurrentPosition(
(position: GeolocationPosition) => { return locationButton;
const pos = { },
lat: position.coords.latitude,
lng: position.coords.longitude, onRemove: function (map: L.Map) {
// Nothing to do here
},
});
// @ts-expect-error extend object
L.Control.GoToTargetLocation = L.Control.extend({
onAdd: function (map: L.Map) {
const locationButton = document.createElement('button');
locationButton.textContent = 'Hedefe Git';
locationButton.classList.add('custom-map-control-button');
locationButton.addEventListener('click', () => {
map.setView(TARGET_LOCATION, 16);
});
return locationButton;
},
onRemove: function (map: L.Map) {
// Nothing to do here
},
});
// @ts-expect-error extend object
L.control.currentLocation = function (opts) {
// @ts-expect-error extend object
return new L.Control.GoToCurrentLocation(opts);
}; };
map.setCenter(pos); // @ts-expect-error extend object
map.setZoom(12); L.control.targetLocation = function (opts) {
}, // @ts-expect-error extend object
() => { return new L.Control.GoToTargetLocation(opts);
handleLocationError(true, infoWindow, map.getCenter()!); };
}
);
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter()!);
}
});
}
function handleLocationError( // @ts-expect-error extend object
browserHasGeolocation: boolean, L.control.currentLocation({ position: 'bottomleft' }).addTo(map);
infoWindow: google.maps.InfoWindow,
pos: google.maps.LatLng
) {
infoWindow.setPosition(pos);
infoWindow.setContent(
browserHasGeolocation
? 'Error: Konumunuz tespit edilemedi.'
: 'Error: Tarayıcınız konum tespitini desteklemiyor.'
);
infoWindow.open(map);
}
initMap(); // @ts-expect-error extend object
L.control.targetLocation({ position: 'bottomleft' }).addTo(map);
</script> </script>