diff --git a/example/lib/main.dart b/example/lib/main.dart index 7465594fa..5fa84ff49 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,12 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_map_example/pages/map_inside_listview.dart'; import 'package:flutter_map_example/pages/network_tile_provider.dart'; +import 'package:flutter_map_example/pages/point_to_latlng.dart'; import './pages/animated_map_controller.dart'; import './pages/circle.dart'; import './pages/custom_crs/custom_crs.dart'; import './pages/esri.dart'; import './pages/home.dart'; +import './pages/interactive_test_page.dart'; import './pages/live_location.dart'; import './pages/many_markers.dart'; import './pages/map_controller.dart'; @@ -28,7 +30,6 @@ import './pages/tile_builder_example.dart'; import './pages/tile_loading_error_handle.dart'; import './pages/widgets.dart'; import './pages/wms_tile_layer.dart'; -import 'pages/interactive_test_page.dart'; void main() => runApp(MyApp()); @@ -72,6 +73,7 @@ class MyApp extends StatelessWidget { StatefulMarkersPage.route: (context) => StatefulMarkersPage(), MapInsideListViewPage.route: (context) => MapInsideListViewPage(), ResetTileLayerPage.route: (context) => ResetTileLayerPage(), + PointToLatLngPage.route: (context) => PointToLatLngPage(), }, ); } diff --git a/example/lib/pages/point_to_latlng.dart b/example/lib/pages/point_to_latlng.dart new file mode 100644 index 000000000..3e4e6c156 --- /dev/null +++ b/example/lib/pages/point_to_latlng.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_map/flutter_map.dart'; +import 'package:latlong2/latlong.dart'; + +import '../widgets/drawer.dart'; + +class PointToLatLngPage extends StatefulWidget { + static const String route = 'point_to_latlng'; + + @override + PointToLatlngPage createState() { + return PointToLatlngPage(); + } +} + +class PointToLatlngPage extends State { + late final MapController mapController; + final pointX = 100.0; + final pointY = 100.0; + final pointSize = 20.0; + late final mapEventSubscription; + + @override + void initState() { + super.initState(); + mapController = MapController(); + + mapEventSubscription = mapController.mapEventStream.listen(onMapEvent); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: Text('PointToLatlng')), + drawer: buildDrawer(context, PointToLatLngPage.route), + body: Stack( + children: [ + FlutterMap( + mapController: mapController, + options: MapOptions( + center: LatLng(51.5, -0.09), + zoom: 5.0, + maxZoom: 5.0, + minZoom: 3.0, + ), + layers: [ + TileLayerOptions( + urlTemplate: + 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', + subdomains: ['a', 'b', 'c']), + ], + ), + Positioned( + top: pointY, + left: pointX, + child: Container( + color: Colors.red, width: pointSize, height: pointSize)) + ], + ), + ); + } + + void onMapEvent(MapEvent mapEvent) { + if (mapEvent is MapEventMove) { + final latLng = mapController.pointToLatLng(CustomPoint(pointX, pointY)); + + print('top left of square is hovering $latLng'); + } + } +} diff --git a/example/lib/widgets/drawer.dart b/example/lib/widgets/drawer.dart index 087f91cdc..fa5921094 100644 --- a/example/lib/widgets/drawer.dart +++ b/example/lib/widgets/drawer.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_map_example/pages/map_inside_listview.dart'; import 'package:flutter_map_example/pages/marker_rotate.dart'; import 'package:flutter_map_example/pages/network_tile_provider.dart'; +import 'package:flutter_map_example/pages/point_to_latlng.dart'; import '../pages/animated_map_controller.dart'; import '../pages/circle.dart'; @@ -228,6 +229,8 @@ Drawer buildDrawer(BuildContext context, String currentRoute) { ), _buildMenuItem(context, const Text('Map inside listview'), MapInsideListViewPage.route, currentRoute), + _buildMenuItem(context, const Text('Point to LatLng'), + PointToLatLngPage.route, currentRoute), ], ), ); diff --git a/lib/flutter_map.dart b/lib/flutter_map.dart index bdd2a7225..dd5c7f804 100644 --- a/lib/flutter_map.dart +++ b/lib/flutter_map.dart @@ -141,6 +141,8 @@ abstract class MapController { Stream get mapEventStream; + LatLng? pointToLatLng(CustomPoint point); + factory MapController() => MapControllerImpl(); } diff --git a/lib/src/map/map.dart b/lib/src/map/map.dart index f7d977b33..328d1c372 100644 --- a/lib/src/map/map.dart +++ b/lib/src/map/map.dart @@ -77,6 +77,19 @@ class MapControllerImpl implements MapController { return _state.rotate(degree, id: id, source: MapEventSource.mapController); } + @override + LatLng? pointToLatLng(CustomPoint localPoint) { + final width = _state.size.x; + final height = _state.size.y; + + var localPointCenterDistance = + CustomPoint((width / 2) - localPoint.x, (height / 2) - localPoint.y); + var mapCenter = _state.options.crs.latLngToPoint(_state.center, _state.zoom); + + var point = mapCenter - localPointCenterDistance; + return _state.options.crs.pointToLatLng(point, _state.zoom); + } + @override Stream get mapEventStream => _mapEventSink.stream; }