Can we use Openstreetmap in Flutter or can we only use Google Maps? I wanted to get another way to display a Map. Cause when using googlemaps api key they need to know a Cre
You may check out our Syncfusion Flutter Maps widget which allows you to render tiles/images from services like OpenStreetMaps, Bing Maps, etc. It provides features like zooming and panning interactions, adding markers in the desired locations, etc.
https://www.syncfusion.com/flutter-widgets/flutter-maps
Please find the demos in the below links.
Android: https://play.google.com/store/apps/details?id=com.syncfusion.flutter.examples&hl=en_US&gl=US
iOS: https://apps.apple.com/us/app/syncfusion-flutter-ui-widgets/id1475231341
Web: https://flutter.syncfusion.com/#/maps/tile-layer/osm
OpenStreetMaps may be used free of cost. However, we recommend you to check the licensing terms on their official website and ensure it.
Regarding the usage of Syncfusion widgets, we do have a community license. You can check the below link to know about whether you are eligible to use it.
https://www.syncfusion.com/products/communitylicense
Please note that I work for Syncfusion. If you need more details, feel free to contact us.
https://www.syncfusion.com/feedback
https://www.syncfusion.com/forums
https://www.syncfusion.com/support/directtrac/incidents/newincident
Regards,
Samsudeen
You can use the below plugin. An example is included in the repository.
https://github.com/apptreesoftware/flutter_map
Pub.dev link:
https://pub.dev/packages/flutter_map
Declare these dependencies in your pubspec.yaml
era_geojson: "^0.1.1+4"
latlong: "^0.5.3"
Then you can write your custom map like this:
import 'package:flutter/material.dart';
class CustomMap extends CustomPainter {
Size screenSize;
List<Offset> pointsRoads;
List<Offset> pointsBuilding;
List<Path> pointsBuildings;
final bgColor = const Color(0xFFF7F7F7);
final borderColor = const Color(0xFFCBCBCB);
final buildingColor = const Color(0xFFEFEFEF);
double scale = 1.0;
Offset delta = Offset.zero;
final Paint paintRoads = Paint()
..color = Colors.white
..strokeCap = StrokeCap.round
..strokeWidth = 3.0;
final Paint paintBorder = Paint()
..color = Colors.black12
..strokeCap = StrokeCap.round
..strokeWidth = 4.0;
final Paint paintBuilding = Paint()
..color = Color(0xFFEFEFEF)
..strokeCap = StrokeCap.round
..strokeWidth = 1.0;
final Paint paintBuildingBorder = Paint()
..color = Color(0xFFEFEFEF)
..strokeCap = StrokeCap.round
..strokeWidth = 1.0;
CustomMap(
{this.delta,
this.scale,
this.pointsRoads,
this.pointsBuilding,
this.pointsBuildings,
this.screenSize});
@override
void paint(Canvas canvas, Size size) {
canvas.translate(delta.dx, delta.dy);
canvas.scale(scale, scale);
canvas.drawColor(bgColor, BlendMode.color);
// Roads Start
if (pointsRoads != null && pointsRoads.length > 0) {
var start = DateTime.now().millisecondsSinceEpoch;
for (int i = 0; i < pointsRoads.length - 1; i++) {
if (isInScreen(pointsRoads[i], pointsRoads[i + 1])) {
canvas.drawLine(pointsRoads[i], pointsRoads[i + 1], paintBorder);
}
}
var end = DateTime.now().millisecondsSinceEpoch;
print("Draw Roads Border: ${end - start}");
var start2 = DateTime.now().millisecondsSinceEpoch;
for (int i = 0; i < pointsRoads.length - 1; i++) {
if (isInScreen(pointsRoads[i], pointsRoads[i + 1])) {
canvas.drawLine(pointsRoads[i], pointsRoads[i + 1], paintRoads);
}
}
var end2 = DateTime.now().millisecondsSinceEpoch;
print("Draw Roads: ${end2 - start2}");
}
// Roads End
// Buildings Start
var start = DateTime.now().millisecondsSinceEpoch;
for (int i = 0; i < pointsBuildings.length - 1; i++) {
canvas.drawPath(pointsBuildings[i], paintBuilding);
}
var end = DateTime.now().millisecondsSinceEpoch;
print("Draw Buildings: ${end - start}");
if (pointsBuilding != null && pointsBuilding.length > 0) {
var start = DateTime.now().millisecondsSinceEpoch;
for (int i = 0; i < pointsBuilding.length - 1; i++) {
if (isInScreen(pointsBuilding[i], pointsBuilding[i + 1])) {
canvas.drawLine(
pointsBuilding[i], pointsBuilding[i + 1], paintBuildingBorder);
}
}
var end = DateTime.now().millisecondsSinceEpoch;
print("Draw Buildings Border: ${end - start}");
}
// Buildings End
}
bool isInScreen(Offset first, Offset second) {
if (first != null && second != null) {
first = first.scale(scale, scale);
second = second.scale(scale, scale);
if ((first.dx > -1 &&
first.dy > -1 &&
first.dx < this.screenSize.width &&
first.dy < this.screenSize.height) ||
(second.dx > -1 &&
second.dy > -1 &&
second.dx < this.screenSize.width &&
second.dy < this.screenSize.height)) {
return true;
}
}
return false;
}
@override
bool shouldRepaint(CustomMap oldDelegate) => true;
}
and use it in a wrapping GestureDetector like this:
GestureDetector(
onPanUpdate: (DragUpdateDetails details) {
setState(() {
_delta = _delta + details.delta;
});
},
child: CustomPaint(
painter: CustomMap(
scale: _scale,
delta: _delta,
pointsRoads: _roadsPoints,
pointsBuilding: _buildingPoints,
pointsBuildings: _pointsBuildings,
screenSize: screenSize),
size: Size.infinite) // CustomPaint
)
See this complete example: https://github.com/aoinakanishi/flutter-openstreetmap-example