To achieve your goal of displaying nearby hydrants on a Google Map based on the user's current location, you can follow these steps. I'll provide a complete solution, including the necessary Laravel controller, route, and JavaScript code.
Step 1: Set Up Your Laravel Route and Controller
First, create a route and a controller method to fetch hydrants within the current viewport.
web.php
use App\Http\Controllers\HydrantController;
Route::get('/hydrants', [HydrantController::class, 'index']);
HydrantController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Hydrant;
class HydrantController extends Controller
{
public function index(Request $request)
{
$ne_lat = $request->input('ne_lat');
$ne_lng = $request->input('ne_lng');
$sw_lat = $request->input('sw_lat');
$sw_lng = $request->input('sw_lng');
$hydrants = Hydrant::whereBetween('latitude', [$sw_lat, $ne_lat])
->whereBetween('longitude', [$sw_lng, $ne_lng])
->get();
return response()->json($hydrants);
}
}
Step 2: Create the Blade View
Create a Blade view to display the map and include the necessary JavaScript.
map.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Hydrants Map</title>
<style>
#map {
height: 100%;
width: 100%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>
</head>
<body>
<div id="map"></div>
<script>
let map;
let userMarker;
let hydrantMarkers = [];
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function (position) {
const userLocation = {
lat: position.coords.latitude,
lng: position.coords.longitude,
};
map.setCenter(userLocation);
userMarker = new google.maps.Marker({
position: userLocation,
map: map,
icon: {
url: 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png',
},
});
fetchHydrants();
},
function () {
handleLocationError(true, map.getCenter());
}
);
} else {
handleLocationError(false, map.getCenter());
}
map.addListener('idle', function () {
fetchHydrants();
});
}
function fetchHydrants() {
const bounds = map.getBounds();
const ne = bounds.getNorthEast();
const sw = bounds.getSouthWest();
fetch(`/hydrants?ne_lat=${ne.lat()}&ne_lng=${ne.lng()}&sw_lat=${sw.lat()}&sw_lng=${sw.lng()}`)
.then(response => response.json())
.then(hydrants => {
clearMarkers();
hydrants.forEach(hydrant => {
const hydrantMarker = new google.maps.Marker({
position: { lat: hydrant.latitude, lng: hydrant.longitude },
map: map,
});
const infoWindow = new google.maps.InfoWindow({
content: `
<div>
<h6>Hydrant ID: ${hydrant.id}</h6>
<p>Station: ${hydrant.station_id}</p>
<p>Shift: ${hydrant.shift_id}</p>
<a href="/hydrants/${hydrant.id}/photo" class="btn btn-primary btn-sm">Photo</a>
<a href="/hydrants/${hydrant.id}/inspection" class="btn btn-secondary btn-sm">Inspection</a>
</div>
`,
});
hydrantMarker.addListener('click', function () {
infoWindow.open(map, hydrantMarker);
});
hydrantMarkers.push(hydrantMarker);
});
});
}
function handleLocationError(browserHasGeolocation, pos) {
alert(
browserHasGeolocation
? "Error: The Geolocation service failed."
: "Error: Your browser doesn't support geolocation."
);
map.setCenter(pos);
}
function clearMarkers() {
hydrantMarkers.forEach(marker => marker.setMap(null));
hydrantMarkers = [];
}
window.onload = initMap;
</script>
</body>
</html>
Explanation
-
Laravel Route and Controller: The route
/hydrantscalls theindexmethod ofHydrantController, which fetches hydrants within the specified latitude and longitude bounds. -
Blade View: The
map.blade.phpfile includes the Google Maps API and initializes the map. It uses the Geolocation API to get the user's current location and centers the map on it. It then fetches hydrants within the current viewport and displays them as markers on the map. -
JavaScript: The JavaScript code handles map initialization, fetching hydrants, and displaying them with info windows. It also includes error handling for geolocation and a function to clear existing markers before adding new ones.
Replace YOUR_API_KEY with your actual Google Maps API key.
This solution should meet your requirements and display nearby hydrants on a Google Map based on the user's current location.