Skip to content

Commit

Permalink
0.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
mu-dawood committed Dec 13, 2021
1 parent c985c5e commit 92d65d5
Show file tree
Hide file tree
Showing 14 changed files with 158 additions and 77 deletions.
9 changes: 6 additions & 3 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class MyApp extends StatelessWidget {
onError: (context, error) {},
getCurrentLocation: _getCurrentLocationUsingLocationPackage,
reverseZoom: ReverseZoom.suburb,
getLocationStream: () => location.onLocationChanged.map((event) => LatLng(event.latitude!, event.longitude!)),
getLocationStream: () => location.onLocationChanged
.map((event) => LatLng(event.latitude!, event.longitude!)),
child: MaterialApp(
title: 'Flutter Demo',
locale: const Locale("ar"),
Expand Down Expand Up @@ -105,10 +106,12 @@ class _MyHomePageState extends State<MyHomePage> {
}

void showPicker(BuildContext context) {
Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) {
return OpenStreetMaps(
options: OpenMapOptions(),
bloc: CustomBloc(const OpenMapState.selected(SelectedLocation.single(null))),
bloc: CustomBloc(
const OpenMapState.selected(SelectedLocation.single(null))),
);
}));
}
Expand Down
6 changes: 4 additions & 2 deletions lib/src/bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ abstract class OpenMapBloc {
@freezed
class OpenMapState with _$OpenMapState {
const factory OpenMapState.selected(SelectedLocation selected) = _Selected;
const factory OpenMapState.reversing(SelectedLocation selected, LatLng reversing) = _Reversing;
const factory OpenMapState.reversing(
SelectedLocation selected, LatLng reversing) = _Reversing;

const factory OpenMapState.searching({
required SelectedLocation selected,
Expand All @@ -30,5 +31,6 @@ class OpenMapState with _$OpenMapState {
@freezed
class SelectedLocation with _$SelectedLocation {
const factory SelectedLocation.single(FormattedLocation? selected) = _Single;
const factory SelectedLocation.multi(List<FormattedLocation> selected) = _Multi;
const factory SelectedLocation.multi(List<FormattedLocation> selected) =
_Multi;
}
27 changes: 18 additions & 9 deletions lib/src/location_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,22 +89,27 @@ class FormattedLocation with _$FormattedLocation {
return FormattedLocation(
placeId: json["place_id"]!.toString(),
address: Address.fromMap(json["address"] ?? {}),
names: (json["namedetails"] as Map).map((key, value) => MapEntry(key.toString(), value)),
names: (json["namedetails"] as Map)
.map((key, value) => MapEntry(key.toString(), value)),
lat: double.parse(json['lat']?.toString() ?? ''),
lon: double.parse(json['lon']?.toString() ?? ''),
addresstype: json["addresstype"] ?? '',
boundingbox: LatLngBounds.fromPoints([
LatLng(double.parse(boundingBox[0].toString()), double.parse(boundingBox[2].toString())),
LatLng(double.parse(boundingBox[1].toString()), double.parse(boundingBox[3].toString())),
LatLng(double.parse(boundingBox[0].toString()),
double.parse(boundingBox[2].toString())),
LatLng(double.parse(boundingBox[1].toString()),
double.parse(boundingBox[3].toString())),
]),
category: json["category"] ?? '',
displayName: json["display_name"] ?? '',
extratags: (json["extratags"] as Map).map((key, value) => MapEntry(key.toString(), value)),
extratags: (json["extratags"] as Map)
.map((key, value) => MapEntry(key.toString(), value)),
geojson: GeoGeometry.fromMap(json["geojson"]),
importance: double.parse(json["importance"]?.toString() ?? ''),
licence: json["licence"] ?? '',
name: json["name"] ?? '',
namedetails: (json["namedetails"] as Map).map((key, value) => MapEntry(key.toString(), value)),
namedetails: (json["namedetails"] as Map)
.map((key, value) => MapEntry(key.toString(), value)),
osmId: int.parse(json["osm_id"]?.toString() ?? '0'),
osmType: json["osm_type"] ?? '',
placeRank: int.parse(json["place_rank"]?.toString() ?? '0'),
Expand Down Expand Up @@ -156,17 +161,21 @@ class Address {
class GeoGeometry with _$GeoGeometry {
const GeoGeometry._();
factory GeoGeometry.point(LatLng point, Color randomColor) = GeoPoint;
factory GeoGeometry.linestring(List<LatLng> points, Color randomColor) = GeoLinestring;
factory GeoGeometry.polygon(List<LatLng> points, Color randomColor) = GeoPolygon;
factory GeoGeometry.linestring(List<LatLng> points, Color randomColor) =
GeoLinestring;
factory GeoGeometry.polygon(List<LatLng> points, Color randomColor) =
GeoPolygon;
static GeoGeometry fromMap(Map<String, dynamic> json) {
var coords = json["coordinates"] as List;
var color = Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);
var color =
Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);

if (json["type"] == "Polygon") {
var points = coords.map((e) {
return (e as List).map((e) => _latLng(e)).toList();
}).toList();
return GeoGeometry.polygon(points.expand((element) => element).toList(), color);
return GeoGeometry.polygon(
points.expand((element) => element).toList(), color);
} else if (json["type"] == "LineString") {
var points = coords.map((e) => _latLng(e)).toList();
return GeoGeometry.linestring(points, color);
Expand Down
22 changes: 15 additions & 7 deletions lib/src/location_picker_field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import 'options.dart';

class _BaseFormField<T> extends StatefulWidget {
final T? intialValue;
final Function(FormFieldState<T> field, SelectedLocation selectedLocation) onDone;
final Function(FormFieldState<T> field, SelectedLocation selectedLocation)
onDone;
final FormFieldSetter<T>? onSaved;
final FormFieldValidator<T>? validator;
final InputDecoration decoration;
Expand Down Expand Up @@ -99,12 +100,14 @@ class __BaseFormFieldState<T> extends State<_BaseFormField<T>> {
initialValue: widget.intialValue,
onSaved: widget.onSaved,
builder: (FormFieldState<T> field) {
var effectiveDecoration = widget.decoration.applyDefaults(Theme.of(context).inputDecorationTheme);
var effectiveDecoration = widget.decoration
.applyDefaults(Theme.of(context).inputDecorationTheme);
var removeIcon = widget.removeIcon;
var _showRemove = !widget.isEmpty(field.value) && removeIcon != null;
effectiveDecoration = effectiveDecoration.copyWith(
errorText: field.errorText,
prefixIcon: effectiveDecoration.prefixIcon ?? const Icon(Icons.my_location_rounded),
prefixIcon: effectiveDecoration.prefixIcon ??
const Icon(Icons.my_location_rounded),
suffixIcon: _showRemove
? IconButton(
onPressed: () {
Expand Down Expand Up @@ -206,7 +209,8 @@ class OpenMapPicker extends StatelessWidget {
expands: expands,
focusNode: focusNode,
intialValue: intialValue,
options: (FormattedLocation? value) => OpenMapOptions(center: value?.toLatLng()),
options: (FormattedLocation? value) =>
OpenMapOptions(center: value?.toLatLng()),
onDone: (field, value) {
field.didChange(value.whenOrNull<FormattedLocation?>(
single: (selected) {
Expand Down Expand Up @@ -265,7 +269,8 @@ class MultiOpenMapPicker extends StatelessWidget {
@override
Widget build(BuildContext context) {
return _BaseFormField<List<FormattedLocation>>(
state: (value) => OpenMapState.selected(SelectedLocation.multi(value ?? [])),
state: (value) =>
OpenMapState.selected(SelectedLocation.multi(value ?? [])),
decoration: decoration,
display: (value) {
var v = value ?? [];
Expand Down Expand Up @@ -296,7 +301,9 @@ class MultiOpenMapPicker extends StatelessWidget {
if (list.isEmpty) {
return OpenMapOptions();
} else {
return OpenMapOptions.bounds(bounds: LatLngBounds.fromPoints(list.map((e) => e.toLatLng()).toList()));
return OpenMapOptions.bounds(
bounds: LatLngBounds.fromPoints(
list.map((e) => e.toLatLng()).toList()));
}
},
onDone: (field, value) {
Expand Down Expand Up @@ -327,7 +334,8 @@ class _OpenMapBloc extends OpenMapBloc {
_OpenMapBloc(this._state);
@override
OpenMapState get state => _state;
final StreamController<OpenMapState> _controller = StreamController<OpenMapState>.broadcast();
final StreamController<OpenMapState> _controller =
StreamController<OpenMapState>.broadcast();
@override
Stream<OpenMapState> get stream => _controller.stream;

Expand Down
3 changes: 2 additions & 1 deletion lib/src/map_app_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ class _MapAppBarState extends State<MapAppBar> {
"polygon_geojson": "1",
"extratags": "1",
"polygon_threshold": "1",
if (widget.searchFilters != null) ...(widget.searchFilters!.toJson())
if (widget.searchFilters != null)
...(widget.searchFilters!.toJson())
},
);
var response = await http.get(url);
Expand Down
47 changes: 31 additions & 16 deletions lib/src/map_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_map/plugin_api.dart';
import 'package:http/http.dart' as http;
import 'package:positioned_tap_detector_2/positioned_tap_detector_2.dart';

import './location_model.dart';
import './map_app_bar.dart';
Expand All @@ -18,7 +17,8 @@ import 'reverse_options.dart';
import 'selected_location_view.dart';
import 'shapes.dart';

typedef MyLocationButtonCallBack = Widget Function(Function(LatLng destLocation, [double destZoom]) callback);
typedef MyLocationButtonCallBack = Widget Function(
Function(LatLng destLocation, [double destZoom]) callback);

/// Map screen
/// - it can be used to display location
Expand Down Expand Up @@ -85,7 +85,8 @@ class OpenStreetMaps extends StatefulWidget {
_OpenStreetMapsState createState() => _OpenStreetMapsState();
}

class _OpenStreetMapsState extends State<OpenStreetMaps> with TickerProviderStateMixin {
class _OpenStreetMapsState extends State<OpenStreetMaps>
with TickerProviderStateMixin {
late final _MapControllerImpl _controller;
late final _MyAnimationController _animationController;
@override
Expand Down Expand Up @@ -128,14 +129,15 @@ class _OpenStreetMapsState extends State<OpenStreetMaps> with TickerProviderStat
return res.copyWith(
lat: loc.latitude,
lon: loc.longitude,
geojson: GeoGeometry.linestring([...line.points, loc], line.randomColor),
geojson:
GeoGeometry.linestring([...line.points, loc], line.randomColor),
);
},
polygon: (polygon) => res,
);
}

void _onTap(TapPosition position, LatLng latLng) async {
void _onTap(LatLng latLng) async {
var bloc = widget.bloc;
if (bloc != null) {
var _oldState = bloc.state;
Expand All @@ -148,9 +150,13 @@ class _OpenStreetMapsState extends State<OpenStreetMaps> with TickerProviderStat
bloc.emit(OpenMapState.selected(SelectedLocation.single(result)));
},
multi: (old) {
var exists = old.any((element) => element.identifier == result.identifier);
var _new =
exists ? old.map((e) => e.identifier == result.identifier ? result : e).toList() : [result, ...old];
var exists =
old.any((element) => element.identifier == result.identifier);
var _new = exists
? old
.map((e) => e.identifier == result.identifier ? result : e)
.toList()
: [result, ...old];
bloc.emit(OpenMapState.selected(SelectedLocation.multi(_new)));
},
);
Expand All @@ -164,7 +170,8 @@ class _OpenStreetMapsState extends State<OpenStreetMaps> with TickerProviderStat
}
}

void _onMapCreated(MapController controller, OpenMapSettings? settings) async {
void _onMapCreated(
MapController controller, OpenMapSettings? settings) async {
try {
if (settings?.getCurrentLocation != null) {
if (widget.options.center != null) return;
Expand Down Expand Up @@ -206,7 +213,8 @@ class _OpenStreetMapsState extends State<OpenStreetMaps> with TickerProviderStat
_animationController.addListener(() {
if (mounted) {
_controller.move(
LatLng(_latTween.evaluate(animation), _lngTween.evaluate(animation)),
LatLng(
_latTween.evaluate(animation), _lngTween.evaluate(animation)),
_zoomTween.evaluate(animation),
);
}
Expand Down Expand Up @@ -253,7 +261,7 @@ class _OpenStreetMapsState extends State<OpenStreetMaps> with TickerProviderStat
var options = widget.options.create(
controller: _controller,
onMapCreated: (_) => _onMapCreated(_, settings),
onTap: _onTap,
onTap: (_, pos) => _onTap(pos),
);
var bloc = widget.bloc;
if (bloc == null) return _buildMap(options, settings);
Expand All @@ -266,9 +274,12 @@ class _OpenStreetMapsState extends State<OpenStreetMaps> with TickerProviderStat
moveTo: moveTo,
onDone: widget.onDone,
searchFilters: widget.searchFilters ?? settings?.searchFilters,
srearchHint: widget.srearchHint ?? settings?.srearchHint?.call(context) ?? 'Search here',
srearchHint: widget.srearchHint ??
settings?.srearchHint?.call(context) ??
'Search here',
),
bottomNavigationBar: SelectedLocationView(bloc: bloc, fitBounds: fitBounds),
bottomNavigationBar:
SelectedLocationView(bloc: bloc, fitBounds: fitBounds),
floatingActionButton: _myCurrentLocation,
resizeToAvoidBottomInset: false,
body: _buildMap(options, settings),
Expand Down Expand Up @@ -304,7 +315,9 @@ class _OpenStreetMapsState extends State<OpenStreetMaps> with TickerProviderStat
child: tileWidget,
);
},
tileProvider: widget.tileProvider ?? settings?.defaultTileProvider ?? const NonCachingNetworkTileProvider(),
tileProvider: widget.tileProvider ??
settings?.defaultTileProvider ??
const NonCachingNetworkTileProvider(),
),
),
],
Expand All @@ -315,15 +328,17 @@ class _OpenStreetMapsState extends State<OpenStreetMaps> with TickerProviderStat
MapPolylines(bloc: widget.bloc!),
MapMarkers(bloc: widget.bloc!),
],
if (settings?.currentLocationMarker != null || settings?.getLocationStream != null)
if (settings?.currentLocationMarker != null ||
settings?.getLocationStream != null)
const MyCurrentLocationMarker()
],
);
}
}

class _MyAnimationController extends AnimationController {
_MyAnimationController(TickerProvider vsync) : super(vsync: vsync, duration: const Duration(milliseconds: 400));
_MyAnimationController(TickerProvider vsync)
: super(vsync: vsync, duration: const Duration(milliseconds: 400));

@override
void reset() {
Expand Down
6 changes: 4 additions & 2 deletions lib/src/map_view_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import 'reverse_options.dart';

typedef GetCurrentLocationCallBack = Future<LatLng?> Function();
typedef GetLocationStreamCallBack = Stream<LatLng> Function();
typedef LocationMarkerCallback = Marker Function(BuildContext context, FormattedLocation location);
typedef CurrentLocationMarkerCallback = Marker Function(BuildContext context, LatLng location);
typedef LocationMarkerCallback = Marker Function(
BuildContext context, FormattedLocation location);
typedef CurrentLocationMarkerCallback = Marker Function(
BuildContext context, LatLng location);

/// global settings for map
/// You can wrap material app with it or wrap entire screen to ovveride the globals
Expand Down
15 changes: 10 additions & 5 deletions lib/src/markers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ class MyCurrentLocationMarker extends StatefulWidget {
const MyCurrentLocationMarker({Key? key}) : super(key: key);

@override
_MyCurrentLocationMarkerState createState() => _MyCurrentLocationMarkerState();
_MyCurrentLocationMarkerState createState() =>
_MyCurrentLocationMarkerState();
}

class _MyCurrentLocationMarkerState extends State<MyCurrentLocationMarker> {
Expand All @@ -32,7 +33,8 @@ class _MyCurrentLocationMarkerState extends State<MyCurrentLocationMarker> {
}
if (settings?.getLocationStream != null) {
_lisner = settings!.getLocationStream!().listen((event) {
if (_currentLocation?.latitude == event.latitude && _currentLocation?.longitude == event.longitude) {
if (_currentLocation?.latitude == event.latitude &&
_currentLocation?.longitude == event.longitude) {
return;
}
if (mounted) {
Expand Down Expand Up @@ -67,7 +69,8 @@ class _MyCurrentLocationMarkerState extends State<MyCurrentLocationMarker> {
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Theme.of(context).primaryColor.withOpacity(0.5),
color:
Theme.of(context).primaryColor.withOpacity(0.5),
blurRadius: 5,
)
],
Expand Down Expand Up @@ -101,15 +104,17 @@ class MapMarkers extends StatelessWidget {
} else {
var loading = currentState.whenOrNull(reversing: (_, r) => r);
return currentState.selected.when(
single: (value) => _markers(context, value == null ? [] : [value], loading),
single: (value) =>
_markers(context, value == null ? [] : [value], loading),
multi: (values) => _markers(context, values, loading),
);
}
},
);
}

Widget _markers(BuildContext context, List<FormattedLocation> locations, LatLng? loadingPoint) {
Widget _markers(BuildContext context, List<FormattedLocation> locations,
LatLng? loadingPoint) {
var settings = OpenMapSettings.of(context);
var marker = settings?.locationMarker;
return MarkerLayerWidget(
Expand Down
Loading

0 comments on commit 92d65d5

Please sign in to comment.