fluttermobileyandex-mapsflutter-packagesfluttermap

Location lat-lng getting wrong when using Yandex Map with flutter_map package


I am using flutter_map with yandex map like below. When I mark a location, Getting location lat and lon are wrong. So If I draw a polygon on the map, It drawn on wrong location. How to fix this?

 FlutterMap(
  options: MapOptions(
    center: LatLng(41.334554,36.269617),
    zoom: 11.0,
    maxZoom: 18,
    minZoom: 5,
    plugins: [
      DragMarkerPlugin(),
    ],
    onTap: (value){
      print(value.toString());
      markLocation(value);
    },
  ),
  layers: [
    TileLayerOptions(
        urlTemplate: 'https://core-sat.maps.yandex.net/tiles?l=sat&v=3.569.0&x={x}&y={y}&z={z}&lang=tr_TR'
    ),
    TileLayerOptions(
        urlTemplate: 'http://vec{s}.maps.yandex.net/tiles?l=skl&v=20.06.03&z={z}&x={x}&y={y}&scale=1&lang=tr_TR',
        subdomains: ['01', '02', '03', '04'],
        backgroundColor: Colors.transparent
    ),
    CircleLayerOptions(
        circles: _circles
    ),
    PolygonLayerOptions(
      polygons: getPolygons()
    ),
    DragMarkerPluginOptions(
      markers: _markers
    )
  ],
  mapController: _mapController,
)

Actual position of polygon:

enter image description here

And How to looks on device?

enter image description here


Solution

  • I used custom csr for solve this problem. Thanks to dmitrienkop for his answer.

    https://github.com/fleaflet/flutter_map/issues/642

    import 'dart:math' as math;
    import 'package:flutter_map/plugin_api.dart';
    import 'package:latlong/latlong.dart';
    
    class Epsg3395 extends Earth {
      @override
      final String code = 'EPSG:3395';
    
      @override
      final Projection projection = const Mercator();
    
      @override
      final Transformation transformation = const Transformation(_scale, 0.5, -_scale, 0.5);
    
      static const num _scale = 0.5 / (math.pi * Mercator.r);
    
      const Epsg3395() : super();
    }
    
    class Mercator extends Projection {
      static const int r = 6378137;
      static const double rMinor = 6356752.314245179;
      static final Bounds<double> _bounds = Bounds<double>(
        CustomPoint<double>(-20037508.34279, -15496570.73972),
        CustomPoint<double>(20037508.34279, 18764656.23138),
      );
    
      const Mercator() : super();
    
      @override
      Bounds<double> get bounds => _bounds;
    
      @override
      CustomPoint project(LatLng latlng) {
        var d = math.pi / 180;
        var y = latlng.latitude * d;
        var tmp = rMinor / r;
        var e = math.sqrt(1 - tmp * tmp);
        var con = e * math.sin(y);
    
        var ts = math.tan(math.pi / 4 - y / 2) / math.pow((1 - con) / (1 + con), e / 2);
        y = -r * math.log(math.max(ts, 1E-10));
    
        return CustomPoint(latlng.longitude * d * r, y);
      }
    
      @override
      LatLng unproject(CustomPoint point) {
        var d = 180 / math.pi;
        var tmp = rMinor / r;
        var e = math.sqrt(1 - tmp * tmp);
        var ts = math.exp(-point.y / r);
        var phi = math.pi / 2 - 2 * math.atan(ts);
    
        for (var i = 0, dphi = 0.1, con; i < 15 && dphi.abs() > 1e-7; i++) {
                con = e * math.sin(phi);
                con = math.pow((1 - con) / (1 + con), e / 2);
                dphi = math.pi / 2 - 2 * math.atan(ts * con) - phi;
                phi += dphi;
            }
    
        return LatLng(phi * d, point.x * d / r);
      }
    }