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",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.0.2",
"@types/leaflet": "^1.9.8",
"@types/react": "^18.2.47",
"@types/react-dom": "^18.2.18",
"astro": "^4.1.2",
@ -1325,6 +1326,11 @@
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
"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": {
"version": "3.54.10",
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.54.10.tgz",
@ -1339,6 +1345,14 @@
"@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": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz",

View File

@ -15,6 +15,7 @@
"@astrojs/tailwind": "^5.1.0",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.0.2",
"@types/leaflet": "^1.9.8",
"@types/react": "^18.2.47",
"@types/react-dom": "^18.2.18",
"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="@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="viewport" content="width=device-width" />
<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} />
<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>
</head>
<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">
<Card className="w-full">
<CardHeader>
<CardTitle>Ayşe</CardTitle>
<CardTitle>Abdurrahman</CardTitle>
</CardHeader>
<CardContent>
<p>Aşağıdaki konuma gitmen</p>
<p>Aşağıdaki konuma gitmen gerekiyor.</p>
</CardContent>
<CardFooter className="gap-2">
<CalendarIcon />
@ -41,140 +41,109 @@ import LocationButton from '@/components/LockedContent';
<script>
// 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;
async function initMap(): Promise<void> {
const { Map } = (await google.maps.importLibrary(
'maps'
)) as google.maps.MapsLibrary;
const TARGET_LOCATION: LatLngTuple = [41.01907795861253, 29.01715377829709];
const { AdvancedMarkerElement } = (await google.maps.importLibrary(
'marker'
)) as google.maps.MarkerLibrary;
var map = L.map('map').setView(TARGET_LOCATION, 13);
map = new Map(document.getElementById('map') as HTMLElement, {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
mapId: 'DEMO_MAP_ID',
mapTypeControl: false,
});
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution:
'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(map);
const currentLocationIcon = document.createElement('img');
currentLocationIcon.src = '/blue-dot.png';
var targetLocationIcon = L.icon({
iconUrl: 'goal.svg',
iconSize: [32, 32],
});
const targetLocationIcon = document.createElement('img');
targetLocationIcon.src = '/goal.png';
targetLocationIcon.height = 32;
targetLocationIcon.width = 32;
L.marker(TARGET_LOCATION, { icon: targetLocationIcon }).addTo(map);
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>';
var currentLocationIcon = L.icon({
iconUrl: 'blue-dot.png',
iconSize: [32, 32],
});
const pinSvg = parser.parseFromString(
pinSvgString,
'image/svg+xml'
).documentElement;
let currentLocationMarker: Marker;
const currentLocationMarkerView = new AdvancedMarkerElement({
map,
position: { lat: 37.434, lng: -122.082 },
content: currentLocationIcon,
title: 'Current Location',
});
function onLocationFound(e: LocationEvent) {
var radius = e.accuracy;
const targetLocationMarkerView = new AdvancedMarkerElement({
map,
position: { lat: 37.434, lng: -122.082 },
content: pinSvg,
title: 'A marker using a custom PNG Image',
});
infoWindow = new google.maps.InfoWindow();
const locationButton = document.createElement('button');
const locationInfo = document.createElement('button');
locationButton.textContent = 'Konumuma Git';
locationInfo.textContent = 'Mesafe hesaplanıyor...';
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', () => {
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
(position: GeolocationPosition) => {
const pos = {
lat: position.coords.latitude,
lng: position.coords.longitude,
};
map.setCenter(pos);
map.setZoom(12);
},
() => {
handleLocationError(true, infoWindow, map.getCenter()!);
}
);
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter()!);
}
});
if (currentLocationMarker) {
currentLocationMarker.setLatLng(e.latlng);
} else {
currentLocationMarker = L.marker(e.latlng, { icon: currentLocationIcon });
currentLocationMarker.addTo(map);
}
}
function handleLocationError(
browserHasGeolocation: boolean,
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);
map.on('locationfound', onLocationFound);
function onLocationError(e: ErrorEvent) {
alert(e.message);
}
initMap();
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');
locationButton.textContent = 'Konumuma Git';
locationButton.classList.add('custom-map-control-button');
locationButton.addEventListener('click', () => {
map.locate({ setView: true, maxZoom: 16 });
});
return locationButton;
},
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);
};
// @ts-expect-error extend object
L.control.targetLocation = function (opts) {
// @ts-expect-error extend object
return new L.Control.GoToTargetLocation(opts);
};
// @ts-expect-error extend object
L.control.currentLocation({ position: 'bottomleft' }).addTo(map);
// @ts-expect-error extend object
L.control.targetLocation({ position: 'bottomleft' }).addTo(map);
</script>