Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/liodali/osm_flutter
OpenStreetMap plugin for flutter
https://github.com/liodali/osm_flutter
dart flutter kotlin map osm osm-flutter swift web-support
Last synced: 5 days ago
JSON representation
OpenStreetMap plugin for flutter
- Host: GitHub
- URL: https://github.com/liodali/osm_flutter
- Owner: liodali
- License: mit
- Created: 2020-02-22T11:32:54.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2024-10-24T20:17:18.000Z (13 days ago)
- Last Synced: 2024-10-26T07:25:38.987Z (11 days ago)
- Topics: dart, flutter, kotlin, map, osm, osm-flutter, swift, web-support
- Language: Dart
- Homepage: https://pub.dev/packages/flutter_osm_plugin
- Size: 27.8 MB
- Stars: 234
- Watchers: 4
- Forks: 97
- Open Issues: 142
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# flutter_osm_plugin
![pub](https://img.shields.io/badge/pub-v1.3.5-blue)
## Platform Support
| Android | iOS | Web |
|:---:|:---:|:---:|
| supported :heavy_check_mark: | supported :heavy_check_mark: (min iOS supported : 13) | supported :heavy_check_mark: |osm plugin for flutter apps
* current position (Android/iOS/web)
* change position (Android/iOS/web)
* create Marker manually (Android/iOS/web)
* tracking user location (Android/iOS/web)
* customize Icon Marker (Android/iOS/web)
* customize user Marker (Android/iOS/web)
* assisted selection position (Android/iOS)
* set BoundingBox (Android/iOS/Web)
* zoom into region (Android/iOS/web)
* draw Road (Android/iOS/web)
* draw dotted Road (Android/iOS/web)
* recuperate information (instruction/duration/distance) of the current road (Android/iOS/web)
* draw Road manually (Android/iOS/web)
* draw multiple Roads (Android/iOS/web)
* ClickListener on Marker (Android/iOS/web)
* ClickListener on Map (Android/iOS/web)
* calculate distance between 2 points
* address suggestion
* draw shapes (Android/iOS/web)
* simple dialog location picker (Android/iOS)
* listen to region change (Android/iOS/Web)
* set custom tiles (Android/iOS/Web)## Getting Started
## Installing
Add the following to your `pubspec.yaml` file:
dependencies:
flutter_osm_plugin: ^1.3.5## Integration with Hooks
> To use our map library with `Flutter_Hooks` library use our new extension library
https://pub.dev/packages/osm_flutter_hooks
many thanks for @ben-xD### Migration to `0.41.2` (Android Only)
> open file build.gradle inside android file
* change kotlin version from `1.5.21` to `1.7.20`
* change gradle version from `7.0.4` to `7.1.3`
* change compileSdkVersion to 33### Migration to `0.34.0` (Android Only)
> if you are using this plugin before Flutter 3> you should make some modification in build.gradle before that run flutter clean && flutter pub get
> open file build.gradle inside android file
* change kotlin version from `1.5.21` to `1.6.21`
* change gradle version from `7.0.2` to `7.1.3` or `7.0.4`
* change compileSdkVersion to 32
### Migration to `0.16.0` (Android Only)
> if you are using this plugin before Flutter 2> you should make some modification in build.gradle before that run flutter clean && flutter pub get
> open file build.gradle inside android file
* change kotlin version from `1.4.21` to `1.5.21`
* change gradle version from `4.1.1` to `7.0.2`### For web integration
> To show buttons,UI that have to manage user click over the map, you should use this library : `pointer_interceptor`
## Simple Usage
#### Creating a basic `OSMFlutter` :
```dart
OSMFlutter(
controller:mapController,
osmOption: OSMOption(
userTrackingOption: UserTrackingOption(
enableTracking: true,
unFollowUser: false,
),
zoomOption: ZoomOption(
initZoom: 8,
minZoomLevel: 3,
maxZoomLevel: 19,
stepZoom: 1.0,
),
userLocationMarker: UserLocationMaker(
personMarker: MarkerIcon(
icon: Icon(
Icons.location_history_rounded,
color: Colors.red,
size: 48,
),
),
directionArrowMarker: MarkerIcon(
icon: Icon(
Icons.double_arrow,
size: 48,
),
),
),
roadConfiguration: RoadOption(
roadColor: Colors.yellowAccent,
),
markerOption: MarkerOption(
defaultMarker: MarkerIcon(
icon: Icon(
Icons.person_pin_circle,
color: Colors.blue,
size: 56,
),
)
),
)
);```
## MapController
> Declare `MapController` to control OSM map
1) Initialisation> **Note**
> using the default constructor, you should use `initMapWithUserPosition` or `initPosition`
> if you want the map to initialize using static position use the named constructor `withPosition`
> or if you want to initialize the map with user position use `withUserPosition````dart
// default constructor
MapController controller = MapController(
initPosition: GeoPoint(latitude: 47.4358055, longitude: 8.4737324),
areaLimit: BoundingBox(
east: 10.4922941,
north: 47.8084648,
south: 45.817995,
west: 5.9559113,
),
);
// or set manually init position
final controller = MapController.withPosition(
initPosition: GeoPoint(
latitude: 47.4358055,
longitude: 8.4737324,
),
);
// init the position using the user location
final controller = MapController.withUserPosition(
trackUserLocation: UserTrackingOption(
enableTracking: true,
unFollowUser: false,
)
)// init the position using the user location and control map from outside
final controller = MapController.withUserPosition(
trackUserLocation: UserTrackingOption(
enableTracking: true,
unFollowUser: false,
),
useExternalTracking: true
)
```2) Dispose
```dart
controller.dispose();
```3) Properties of default `MapController`
> `MapController` has 2 named Constructor `MapController.withPosition`,
`MapController.withUserPosition` to control initialization of the Map| Properties | Description |
| ---------------------------- | ----------------------------------------------------------------------- |
| `initMapWithUserPosition` | (UserTrackingOption?) initialize map with user position |
| `initPosition` | (GeoPoint) if it isn't null, the map will be pointed at this position |
| `areaLimit` | (Bounding) set area limit of the map (default BoundingBox.world()) |
| `customLayer` | (CustomTile) set customer layer using different osm server , this attribute used only with named constructor `customLayer` |
| ` useExternalTracking` | (bool) if true,we will disable our logic to show userlocation marker or to move to the user position |3.1) Custom Layers with `MapController`
* To change the tile source in OSMFlutter, you should used our named constructor `customLayer`, see the example below
```dart
controller = MapController.customLayer(
initPosition: GeoPoint(
latitude: 47.4358055,
longitude: 8.4737324,
),
customTile: CustomTile(
sourceName: "opentopomap",
tileExtension: ".png",
minZoomLevel: 2,
maxZoomLevel: 19,
urlsServers: [
TileURLs(
//"https://tile.opentopomap.org/{z}/{x}/{y}"
url: "https://tile.opentopomap.org/",
subdomains: [],
)
],
tileSize: 256,
),
)```
* also,you can use our predefined custom tiles like
* `cyclOSMLayer` constructor for cycling tiles
* `publicTransportationLayer` constructor for transport tiles ,it's public osm server
* we support full server path like `("https://tile.opentopomap.org/{z}/{x}/{y}")`For more example see our example in `home_example.dart`
3.2) Change Layers in runtime```dart
await controller.changeTileLayer(tileLayer: CustomTile(...));
```
4) Set map on user current location```dart
await controller.currentLocation();```
5) Zoom IN```dart
await controller.setZoom(stepZoom: 2);
// or
await controller.zoomIn();
```5.1) Zoom Out
```dart
await controller.setZoom(stepZoom: -2);
// or
await controller.zoomOut();
```
5.2) change zoom level> `zoomLevel` should be between `minZoomLevel` and `maxZoomLevel`
```dart
await controller.setZoom(zoomLevel: 8);
```
5.3) zoom to specific bounding box```dart
await controller.zoomToBoundingBox(BoundingBox(),paddingInPixel:0)
```##### Note :
* For the box attribute ,If you don't have bounding box,you can use list of geopoint like this `BoundingBox.fromGeoPoints`
6) get current zoom level b>
```dart
await controller.getZoom();
```7) BoundingBox
> set bounding box in the map
```dart
await controller.limitAreaMap(BoundingBox( east: 10.4922941, north: 47.8084648, south: 45.817995, west: 5.9559113,));
```
> remove bounding box in the map```dart
await controller.removeLimitAreaMap();
```8) Track user current position
> for iOS,you should add those line in your info.plist file
```text
NSLocationWhenInUseUsageDescription
any text you want
NSLocationAlwaysUsageDescription
any text you want
```
> from version 0.40.0 we can call only `enableTracking` will animate to user location
without need to call `currentLocation`> when `enableStopFollow` is true,map will not be centered if the user location changed
> you can disable rotation of personIcon using [disableUserMarkerRotation] (default: false)
```dart
await controller.enableTracking(enableStopFollow:false,);
```
or> use this method below if you want to control the map(move to the user location and show the marker) while receiving the user location
```dart
await controller.startLocationUpdating();
```
9) Disable tracking user position```dart
await controller.disabledTracking();
```
or> use this method below if you already used `startLocationUpdating`
```dart
await controller.stopLocationUpdating();
```10) update the location
> Change the location without create marker
```dart
await controller.moveTo(GeoPoint(latitude: 47.35387, longitude: 8.43609),animate:true);
```11) recuperation current position
```dart
GeoPoint geoPoint = await controller.myLocation();
```
12) get center map```dart
GeoPoint centerMap = await controller.centerMap;
```
12.1) get geoPoint in the map* recuperate geoPoint of marker add it by user except static points
```dart
List geoPoints = await controller.geopoints;
```
13) get bounding box map```dart
BoundingBox bounds = await controller.bounds;
```14) Map Listener
> Get GeoPoint from listener from controller directly
(for more example: see home_example.dart )a.1) single tap listener
```dart
controller.listenerMapSingleTapping.addListener(() {
if (controller.listenerMapSingleTapping.value != null) {
/// put you logic here
}
});
```
a.2) long tap listener
```dart
controller.listenerMapLongTapping.addListener(() {
if (controller.listenerMapLongTapping.value != null) {
/// put you logic here
}
});
```
a.3) region change listener
```dart
controller.listenerRegionIsChanging.addListener(() {
if (controller.listenerRegionIsChanging.value != null) {
/// put you logic here
}
});
```
15) Create Marker Programmatically> you can change marker icon by using attribute `markerIcon`
> the angle value should be between [0,2pi]
> set anchor of ther Marker```dart
await controller.addMarker(GeoPoint,
markerIcon:MarkerIcon,
angle:pi/3,
anchor:IconAnchor(anchor: Anchor.top,)
);
```
15.1) Update Marker> you can change the location,icon,angle,anchor of the specific marker
> The old configuration of the Marker will be keep it the same if not specificied
```dart
await controller.changeLocationMarker(oldGeoPoint,newGeoPoint,MarkerIcon,angle,IconAnchor);
```15.2) Change Icon Marker
> You can change marker icon by using attribute `markerIcon` of existing Marker
> The GeoPoint/Marker should be exist```dart
await controller.setMarkerIcon(GeoPoint,MarkerIcon);
```15.3) Remove marker
```dart
await controller.removeMarker(geoPoint);
```
* PS : static position cannot be removed by this method16) Draw road,recuperate instructions ,distance in km and duration in sec
> you can add an middle position to pass your route through them
> change configuration of the road in runtime
> zoom into the region of the road
> change the type of the road that user want to use```dart
RoadInfo roadInfo = await controller.drawRoad(
GeoPoint(latitude: 47.35387, longitude: 8.43609),
GeoPoint(latitude: 47.4371, longitude: 8.6136),
roadType: RoadType.car,
intersectPoint : [ GeoPoint(latitude: 47.4361, longitude: 8.6156), GeoPoint(latitude: 47.4481, longitude: 8.6266)]
roadOption: RoadOption(
roadWidth: 10,
roadColor: Colors.blue,
zoomInto: true,
),
);
print("${roadInfo.distance}km");
print("${roadInfo.duration}sec");
print("${roadInfo.instructions}");
```### properties of `RoadOption`
| Properties | Description |
| ------------------------ | ----------------------------------- |
| `roadColor` | (Color) required Field, change the default color of the route in runtime |
| `roadWidth` | (double) change the road width, default value 5.0 |
| `roadBorderColor` | (Color?) set color of border polyline |
| `roadBorderWidth` | (double?) set border width of polyline, if width null or 0,polyline will drawed without border |
| `zoomInto` | (bool) change zoom level to make the all the road visible (default:true) |
| `isDotted` | (bool) to draw dotted polyline (default: false) |**Note** drawing dotted polyline has limitation on web where we cannot draw dotted poyline with borderWidth > 0
16.b) draw road manually
```dart
await controller.drawRoadManually(
waysPoint,
interestPointIcon: MarkerIcon(
icon: Icon(
Icons.location_history,
color: Colors.black,
),
),
interestPoints: [waysPoint[3],waysPoint[6]],
zoomInto: true
)
```17) Delete last road
```dart
await controller.removeLastRoad();
```18) draw multiple roads
```dart
final configs = [
MultiRoadConfiguration(
startPoint: GeoPoint(
latitude: 47.4834379430,
longitude: 8.4638911095,
),
destinationPoint: GeoPoint(
latitude: 47.4046149269,
longitude: 8.5046595453,
),
),
MultiRoadConfiguration(
startPoint: GeoPoint(
latitude: 47.4814981476,
longitude: 8.5244329867,
),
destinationPoint: GeoPoint(
latitude: 47.3982152237,
longitude: 8.4129691189,
),
roadOptionConfiguration: MultiRoadOption(
roadColor: Colors.orange,
)),
MultiRoadConfiguration(
startPoint: GeoPoint(
latitude: 47.4519015578,
longitude: 8.4371175094,
),
destinationPoint: GeoPoint(
latitude: 47.4321999727,
longitude: 8.5147623089,
),
),
];
await controller.drawMultipleRoad(
configs,
commonRoadOption: MultiRoadOption(
roadColor: Colors.red,
),
);```
19) delete all roads
```dart
await controller.clearAllRoads();
```20) Change static GeoPoint position
> add new staticPoints with empty list of geoPoints (notice: if you add static point without marker,they will get default maker used by plugin)
> change their position over time
> change orientation of the static GeoPoint with `GeoPointWithOrientation`
```dart
await controller.setStaticPosition(List geoPoints,String id );
```
21) Change/Add Marker old/new static GeoPoint position> add marker of new static point
> change their marker of existing static geoPoint over time
```dart
await controller.setMarkerOfStaticPoint(String id,MarkerIcon markerIcon );
```22) change orientation of the map
```dart
await controller.rotateMapCamera(degree);
```23) Draw Shape in the map
* Circle
```dart
/// to draw
await controller.drawCircle(CircleOSM(
key: "circle0",
centerPoint: GeoPoint(latitude: 47.4333594, longitude: 8.4680184),
radius: 1200.0,
color: Colors.red,
borderColor:Colors.green,
strokeWidth: 0.3,
)
);
/// to remove Circle using Key
await controller.removeCircle("circle0");/// to remove All Circle in the map
await controller.removeAllCircle();```
* Rect
```dart
/// to draw
await controller.drawRect(RectOSM(
key: "rect",
centerPoint: GeoPoint(latitude: 47.4333594, longitude: 8.4680184),
distance: 1200.0,
color: Colors.red.withOpacity(0.4),
borderColor:Colors.green,
strokeWidth: 0.3,
));
/// to remove Rect using Key
await controller.removeRect("rect");/// to remove All Rect in the map
await controller.removeAllRect();```
* remove all shapes in the map
```dart
await controller.removeAllShapes();
```### Interfaces:
* OSMMixinObserver :
> contain listener methods to get event from native map view like when mapIsReady,mapRestored> you should add ths line `controller.addObserver(this);` in initState
> override mapIsReady to implement your own logic after initialisation of the map
> `mapIsReady` will replace `listenerMapIsReady`
| Methods | Description |
| ----------------------------- | ----------------------------------- |
| `mapIsReady` | (callback) Should be override this method, to get notified when map is ready to go or not |
| `mapRestored` | (callback) Should be override this method, to get notified when map is restored you can also add you backup |
| `onSingleTap` | (callback) Called when the user makes single click on map |
| `onLongTap` | (callback) Called when the user makes long click on map |
| `onRegionChanged` | (callback) Notified when map is change region (on moves) |
| `onRoadTap` | (callback) Notified when user click on the polyline (road) |
| `onLocationChanged` | (callback) Notified when user location changed |** example
```dart
class YourOwnStateWidget extends State with OSMMixinObserver {//etc
@override
void initState() {
super.initState();
controller.addObserver(this);
}
@override
Future mapIsReady(bool isReady) async {
if (isReady) {
/// put you logic
}
}
@override
Future mapRestored() async {
super.mapRestored();
/// TODO
}
@override
void onSingleTap(GeoPoint position) {
super.onSingleTap();
/// TODO
}@override
void onLongTap(GeoPoint position) {
super.onLongTap();
/// TODO}
@override
void onRegionChanged(Region region) {
super.onRegionChanged();
/// TODO
}@override
void onRoadTap(RoadInfo road) {
super.onRoadTap();
/// TODO
}
@override
void onLocationChanged(GeoPoint userLocation) {
super.onLocationChanged();
/// TODO
}
}
```## `OSMFlutter`
| Properties | Description |
| ----------------------------- | ----------------------------------- |
| `mapIsLoading` | (Widget) show custom widget when the map finish initialization |
| `osmOption` | (OSMOption) used to configure OSM Map such as zoom,road,userLocationMarker |
| `onGeoPointClicked` | (callback) listener triggered when marker is clicked ,return current geoPoint of the marker |
| `onLocationChanged` | (callback) it is fired when you activate tracking and user position has been changed |
| `onMapMoved` | (callback) it is each the map moved user handler or navigate to another location using APIs |
| `onMapIsReady` | (callback) listener trigger to get map is initialized or not |## `OSMOption`
| Properties | Description |
| ----------------------------- | ----------------------------------- |
| `mapIsLoading` | (Widget) show custom widget when the map finish initialization |
| `trackMyPosition` | enable tracking user position. |
| `showZoomController` | show default zoom controller. |
| `userLocationMarker` | change user marker or direction marker icon in tracking location |
| `markerOption` | configure marker of osm map |
| `zoomOption` | set configuration for zoom in the Map
| `roadConfiguration` | (RoadOption) set default color,width,borderColor,borderWdith for polylines |
| `staticPoints` | List of Markers you want to show always ,should every marker have unique id |
| `showContributorBadgeForOSM` | (bool) enable to show copyright widget of osm in the map |
| `enableRotationByGesture` | (bool) enable to rotation gesture for map, default: false |
| `showDefaultInfoWindow` | (bool) enable/disable default infoWindow of marker (default = false) |
| `isPicker` | (bool) enable advanced picker from init of the map (default = false) |## `ZoomOption`
| Properties | Description |
| ----------------------------- | ------------------------------------------------------------ |
| `stepZoom` | set step zoom to use in zoomIn()/zoomOut() (default 1) |
| `initZoom` | set init zoom level in the map (default 10) |
| `maxZoomLevel` | set maximum zoom level in the map (2 <= x <= 19) |
| `minZoomLevel` | set minimum zoom level in the map (2 <= x <= 19 ) |### Custom Controller
> To create your own MapController to need to extends from `BaseMapController`,
> if you want to make a custom initialization to need to call init() and put your code after super.init()* example
```dart
class CustomMapController extends BaseMapController {@override
void dispose() {
/// TODO put you logic here
super.dispose();
}@override
void init() {
super.init();
/// TODO put you logic here
}
}
```
### STATIC Map:> using `OSMViewer` we can show static map that contain on location
```dart
OSMViewer(
controller: SimpleMapController(
initPosition: GeoPoint(
latitude: 47.4358055,
longitude: 8.4737324,
),
markerHome: const MarkerIcon(
icon: Icon(Icons.home),
),
),
zoomOption: const ZoomOption(
initZoom: 16,
minZoomLevel: 11,
)```
## STATIC METHODS:
1) Calculate distance between 2 geoPoint position
```dart
double distanceEnMetres = await distance2point(GeoPoint(longitude: 36.84612143139903,latitude: 11.099388684927824,),
GeoPoint( longitude: 36.8388023164018, latitude: 11.096959785428027, ),);
```2) Get search Suggestion of text
> you should know that i'm using public api, don't make lot of request
```dart
List suggestions = await addressSuggestion("address");
```## show dialog picker
> simple dialog location picker to selected user location
```dart
GeoPoint p = await showSimplePickerLocation(
context: context,
isDismissible: true,
title: "Title dialog",
textConfirmPicker: "pick",
initCurrentUserPosition: true,
)
```## CustomLocationPicker
> customizable widget to build search location> you should use `PickerMapController` as controller for the widget
see example : [ search widget ](https://github.com/liodali/osm_flutter/blob/master/example/lib/search_example.dart)#### Properties of `CustomLocationPicker`
| Properties | Description |
| ------------------------ | ----------------------------------- |
| `controller` | (PickerMapController) controller of the widget |
| `appBarPicker` | (AppBar) appbar for the widget |
| `topWidgetPicker` | (Widget?) widget will be show on top of osm map,for example to show address suggestion |
| `bottomWidgetPicker` | (Widget?) widget will be show at bottom of screen for example to show more details about selected location or more action |## NOTICE:
> `For now the map working for android,iOS , web will be available soon `> ` If you get ssl certfiction exception,use can use http by following instruction below `
> ` If you want to use http in Android PIE or above : `
* enable useSecureURL and add ` android:usesCleartextTraffic="true" ` in your manifest like example below :* `
`
> if you faced build error in fresh project you need to follow those instruction [#40](https://github.com/liodali/osm_flutter/issues/40)
1) remove flutter_osm_plugin from pubspec, after that pub get
2) open android module in android studio ( right click in name of project -> flutter-> open android module in android studio)
3) update gradle version to 4.1.1 ( IDE will show popup to make update)
4) update kotlin version to 1.4.21 & re-build the project
5) re-add flutter_osm_plugin in pubspec , pub get ( or flutter clean & pub get )> Before you publish your application using this library,
> you should take care about copyright of openStreetMap Data,
> that's why i add `CopyrightOSMWidget` see example and this issue [#101](https://github.com/liodali/osm_flutter/issues/101)#### MIT LICENCE