Files
wheres-my-sign/lib/main.dart
Evan Richardson 8241e3601e Add title image
Move GMS API KEY to .env file
use better sign icon for pins
2025-04-17 19:03:55 -07:00

145 lines
3.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
import 'package:permission_handler/permission_handler.dart';
Future<void> main() async {
await dotenv.load(fileName: ".env");
runApp(SignLocatorApp());
}
class SignLocatorApp extends StatelessWidget {
const SignLocatorApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sign Locator',
theme: ThemeData(primarySwatch: Colors.blue),
home: SignMapScreen(),
);
}
}
class SignMapScreen extends StatefulWidget {
const SignMapScreen({super.key});
@override
SignMapScreenState createState() => SignMapScreenState();
}
class SignMapScreenState extends State<SignMapScreen> {
GoogleMapController? mapController;
Set<Marker> markers = {};
LatLng _initialPosition = const LatLng(37.7749, -122.4194); // Default: SF
BitmapDescriptor customIcon = BitmapDescriptor.defaultMarker;
void customMarker() {
BitmapDescriptor.asset(
ImageConfiguration(),
'assets/icons/sign_marker.png',
).then((icon) {
setState(() {
customIcon = icon;
});
});
}
@override
void initState() {
super.initState();
_requestPermissions();
customMarker();
}
Future<void> _requestPermissions() async {
await Permission.locationWhenInUse.request();
_goToUserLocation();
}
Future<void> _goToUserLocation() async {
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) return;
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied ||
permission == LocationPermission.deniedForever) {
permission = await Geolocator.requestPermission();
}
Position position = await Geolocator.getCurrentPosition();
_initialPosition = LatLng(position.latitude, position.longitude);
mapController?.animateCamera(CameraUpdate.newLatLng(_initialPosition));
}
void _addMarker() async {
Position position = await Geolocator.getCurrentPosition();
final markerId = MarkerId(DateTime.now().toString());
final newMarker = Marker(
markerId: markerId,
position: LatLng(position.latitude, position.longitude),
infoWindow: InfoWindow(title: 'Sign Location'),
icon: customIcon,
);
setState(() {
markers.add(newMarker);
});
}
void _clearMarkers() {
setState(() {
markers.clear();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: SizedBox(
width: MediaQuery.of(context).size.width,
child: Image.asset(
'assets/app_title.png', // Replace with your image path
fit: BoxFit.contain, // Adjust the height as needed
),
),
),
body: GoogleMap(
zoomGesturesEnabled: true,
scrollGesturesEnabled: true,
tiltGesturesEnabled: true,
rotateGesturesEnabled: true,
mapType: MapType.normal,
onMapCreated: (controller) {
mapController = controller;
},
initialCameraPosition: CameraPosition(
target: _initialPosition,
zoom: 14,
),
myLocationEnabled: true,
markers: markers,
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: _addMarker,
tooltip: 'Drop Pin',
child: Icon(Icons.add_location),
),
SizedBox(height: 12),
FloatingActionButton(
onPressed: _clearMarkers,
backgroundColor: Colors.red,
tooltip: 'Clear Pins',
child: Icon(Icons.clear),
),
],
),
);
}
}