Add tap handlers for industry and false positive markers with clear dialog messages

- Industries and false positive markers are now interactive (tap to see info)
- Industry marker dialog: Shows 'It's an industry' with location details
- False positive marker dialog: Shows 'It's not a forest fire' with location details
- Improved type safety with proper casting for dynamic coordinates
- Clearer dialog titles to help users distinguish fire types
- Follows existing dialog pattern from fire notifications
This commit is contained in:
vjrj 2026-03-06 09:29:53 +01:00
parent d04064d17a
commit 989238bf76

View file

@ -156,7 +156,7 @@ class _genericMapState extends State<genericMap> {
// print('${positionCallback.center}, ${positionCallback.zoom}'); // print('${positionCallback.center}, ${positionCallback.zoom}');
//} //}
); );
var mapController = new MapController(); // var mapController = new MapController();
// mapController.fitBounds(bounds); // mapController.fitBounds(bounds);
// mapController.center // mapController.center
@ -402,14 +402,17 @@ class _genericMapState extends State<genericMap> {
List<Marker> markers = []; List<Marker> markers = [];
print( print(
'building markers: fires: ${fires.length} falsePos: ${falsePosList.length} industries: ${industries.length}, isNotif: $isNotif '); 'building markers: fires: ${fires.length} falsePos: ${falsePosList.length} industries: ${industries.length}, isNotif: $isNotif ');
const calibrate = false; // useful when we change the fire icons size // const calibrate = false; // useful when we change the fire icons size
falsePosList.forEach((falsePos) { falsePosList.forEach((falsePos) {
try { try {
var coords = falsePos['geo']['coordinates']; var coords = falsePos['geo']['coordinates'] as List<dynamic>;
// print('false pos: ${coords}'); // print('false pos: ${coords}');
var loc = LatLng(coords[1].toDouble(), coords[0].toDouble()); var loc = LatLng(
markers.add(FireMarker(loc, FireMarkType.falsePos)); (coords[1] as num).toDouble(), (coords[0] as num).toDouble());
if (calibrate) markers.add(FireMarker(loc, FireMarkType.pixel)); markers.add(FireMarker(loc, FireMarkType.falsePos, () {
_showFalsePositiveDialog(loc);
}));
// if (calibrate) markers.add(FireMarker(loc, FireMarkType.pixel));
} catch (e, stackTrace) { } catch (e, stackTrace) {
print('Failed to process $falsePos'); print('Failed to process $falsePos');
reportError(e, stackTrace); reportError(e, stackTrace);
@ -418,10 +421,13 @@ class _genericMapState extends State<genericMap> {
industries.forEach((industry) { industries.forEach((industry) {
try { try {
// print(fire['geo']['coordinates']); // print(fire['geo']['coordinates']);
var coords = industry['geo']['coordinates']; var coords = industry['geo']['coordinates'] as List<dynamic>;
var loc = LatLng(coords[1], coords[0]); var loc = LatLng(
markers.add(FireMarker(loc, FireMarkType.industry)); (coords[1] as num).toDouble(), (coords[0] as num).toDouble());
if (calibrate) markers.add(FireMarker(loc, FireMarkType.pixel)); markers.add(FireMarker(loc, FireMarkType.industry, () {
_showIndustryDialog(loc);
}));
// if (calibrate) markers.add(FireMarker(loc, FireMarkType.pixel));
} catch (e, stackTrace) { } catch (e, stackTrace) {
print('Failed to process $industry'); print('Failed to process $industry');
reportError(e, stackTrace); reportError(e, stackTrace);
@ -429,9 +435,11 @@ class _genericMapState extends State<genericMap> {
}); });
fires.forEach((fire) { fires.forEach((fire) {
try { try {
var loc = new LatLng(fire['lat'], fire['lon']); var loc = new LatLng(
(fire['lat'] as num).toDouble(), (fire['lon'] as num).toDouble());
markers.add(FireMarker(loc, FireMarkType.fire, () { markers.add(FireMarker(loc, FireMarkType.fire, () {
onFirePressed(loc, DateTime.parse(fire['when']), fire['type']); onFirePressed(loc, DateTime.parse(fire['when'].toString()),
(fire['type'] as String));
print('fire $fire pressed'); print('fire $fire pressed');
})); }));
markers.add(FireMarker(loc, FireMarkType.pixel)); markers.add(FireMarker(loc, FireMarkType.pixel));
@ -442,7 +450,7 @@ class _genericMapState extends State<genericMap> {
}); });
markers.add( markers.add(
FireMarker(pos, isNotif ? FireMarkType.fire : FireMarkType.position)); FireMarker(pos, isNotif ? FireMarkType.fire : FireMarkType.position));
if (calibrate) markers.add(FireMarker(pos, FireMarkType.pixel)); // if (calibrate) markers.add(FireMarker(pos, FireMarkType.pixel));
return markers; return markers;
} }
@ -470,4 +478,50 @@ class _genericMapState extends State<genericMap> {
)); ));
}); });
} }
void _showIndustryDialog(LatLng pos) {
getReverseLocation(lat: pos.latitude, lon: pos.longitude)
.then((reverseLoc) {
String industryDesc = '${S.of(context).itSeemsAIndustry}\n\n'
'Type: Industry\n'
'Location: $reverseLoc';
showDialog<bool>(
context: _scaffoldKey.currentContext!,
builder: (_) => new AlertDialog(
title: Text(S.of(context).notAWildfire),
content: new Text(industryDesc),
actions: <Widget>[
new TextButton(
child: Text(S.of(context).CLOSE),
onPressed: () {
Navigator.pop(context);
},
),
],
));
});
}
void _showFalsePositiveDialog(LatLng pos) {
getReverseLocation(lat: pos.latitude, lon: pos.longitude)
.then((reverseLoc) {
String falseDesc = '${S.of(context).itSeemsNotAtForesFire}\n\n'
'Type: False Positive\n'
'Location: $reverseLoc';
showDialog<bool>(
context: _scaffoldKey.currentContext!,
builder: (_) => new AlertDialog(
title: Text(S.of(context).notAWildfire),
content: new Text(falseDesc),
actions: <Widget>[
new TextButton(
child: Text(S.of(context).CLOSE),
onPressed: () {
Navigator.pop(context);
},
),
],
));
});
}
} }